diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs index 5145be0af6..5c2f78a1d0 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnector.cs @@ -97,16 +97,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private long m_messagesSent = 0; private long m_messagesReceived = 0; - private QuarkSubsriptionInfo m_subscribedQuarks; + //private QuarkSubsriptionInfo m_subscribedQuarks; private IConfig m_sysConfig; //members for load balancing purpose //private TcpClient m_loadMigrationSouceEnd = null; - private LoadMigrationEndPoint m_loadMigrationSouceEnd = null; + //private LoadMigrationEndPoint m_loadMigrationSouceEnd = null; private Thread m_loadMigrationSrcRcvLoop; - private LoadMigrationListener m_loadMigrationListener = null; + //private LoadMigrationListener m_loadMigrationListener = null; //List of queued messages, when the space that the updated object is located is being migrated private List m_updateMsgQueue = new List(); @@ -130,17 +130,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule SceneToPhysEngineSyncServer.logDir = m_sysConfig.GetString("PhysLogDir", "."); //assume we are connecting to the whole scene as one big quark - m_subscribedQuarks = new QuarkSubsriptionInfo(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize); - } - - private List GetQuarkStringList() - { - List quarkList = new List(); - foreach (QuarkInfo quark in m_subscribedQuarks.QuarkList) - { - quarkList.Add(quark.QuarkStringRepresentation); - } - return quarkList; + //m_subscribedQuarks = new QuarkSubsriptionInfo(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize); } // Start the RegionSyncPhysEngine client thread @@ -195,21 +185,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } - private void SendQuarkSubscription() - { - List quarkStringList = GetQuarkStringList(); - string quarkString = RegionSyncUtil.QuarkStringListToString(quarkStringList); - - m_log.Debug(LogHeader + ": subscribe to quarks: " + quarkString); - //Send(quarkString); - RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.QuarkSubscription, quarkString); - Send(msg); - } - + /* public void SetQuarkSubscription(QuarkSubsriptionInfo quarks) { m_subscribedQuarks = quarks; } + * */ public void RegisterIdle() { @@ -246,8 +227,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //stop the migration connections //ShutdownClient(m_loadMigrationSouceEnd); - if (m_loadMigrationListener != null) - m_loadMigrationListener.Shutdown(); + //if (m_loadMigrationListener != null) + // m_loadMigrationListener.Shutdown(); } public void ReportStatus() diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs index 174def40bb..9e370bede4 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/PhysEngineToSceneConnectorModule.cs @@ -107,17 +107,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_syncConfig = syncConfig; m_debugWithViewer = syncConfig.GetBoolean("PhysEngineDebugWithViewer", false); - //read in the quark size information - //QuarkInfo.SizeX = syncConfig.GetInt("QuarkSizeX", (int)Constants.RegionSize); - //QuarkInfo.SizeY = syncConfig.GetInt("QuarkSizeY", (int)Constants.RegionSize); - QuarkInfo.SizeX = syncConfig.GetInt("QuarkSizeX", (int)Constants.RegionSize); - QuarkInfo.SizeY = syncConfig.GetInt("QuarkSizeY", (int)Constants.RegionSize); - - //m_quarkListString = syncConfig.GetString("InitQuarkSet", ""); //if not specified, dost not subscribe to any quark - //if (m_quarkListString.Equals("all")) - //{ - // m_quarkListString = RegionSyncUtil.QuarkStringListToString(RegionSyncUtil.GetAllQuarkStringInScene(QuarkInfo.SizeX, QuarkInfo.SizeY)); - //} m_subscriptionSpaceString = syncConfig.GetString("InitSubscriptionSpace", "0_0,256_256"); @@ -317,14 +306,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule Command cmdSyncSetQuarks = new Command("quarkSpace", CommandIntentions.COMMAND_HAZARDOUS, SetQuarkList, "Set the set of quarks to subscribe to. For debugging purpose. Should be issued before \"sync start\""); cmdSyncSetQuarks.AddArgument("quarkSpace", "The (rectangle) space of quarks to subscribe, represented by x0_y0,x1_y1, the left-bottom and top-right corners of the rectangel space", "String"); - Command cmdSyncSetQuarkSize = new Command("quarksize", CommandIntentions.COMMAND_HAZARDOUS, SetQuarkSize, "Set the size of each quark. For debugging purpose. Should be issued before \"sync quarks\""); - cmdSyncSetQuarkSize.AddArgument("quarksizeX", "The size on x axis of each quark", "Integer"); - cmdSyncSetQuarkSize.AddArgument("quarksizeY", "The size on y axis of each quark", "Integer"); + //Command cmdSyncSetQuarkSize = new Command("quarksize", CommandIntentions.COMMAND_HAZARDOUS, SetQuarkSize, "Set the size of each quark. For debugging purpose. Should be issued before \"sync quarks\""); + //cmdSyncSetQuarkSize.AddArgument("quarksizeX", "The size on x axis of each quark", "Integer"); + //cmdSyncSetQuarkSize.AddArgument("quarksizeY", "The size on y axis of each quark", "Integer"); m_commander.RegisterCommand("start", cmdSyncStart); m_commander.RegisterCommand("stop", cmdSyncStop); m_commander.RegisterCommand("status", cmdSyncStatus); - m_commander.RegisterCommand("quarkSpace", cmdSyncSetQuarks); + //m_commander.RegisterCommand("quarkSpace", cmdSyncSetQuarks); lock (m_scene) { @@ -386,12 +375,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule InitPhysEngineToSceneConnector(m_subscriptionSpaceString); } - private void SetQuarkSize(Object[] args) - { - QuarkInfo.SizeX = (int)args[0]; - QuarkInfo.SizeY = (int)args[1]; - - } private void InitPhysEngineToSceneConnector(string space) { diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs index 0652dc9291..8a5043aaf8 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs @@ -119,12 +119,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule string peServerPort = scene.RegionInfo.RegionName + "_SceneToPESyncServerPort"; m_peSyncServerport = syncConfig.GetInt(peServerPort, DefaultPort); DefaultPort++; - - // m_symsync = syncConfig.GetBoolean("SymSync", false); - - //Get quark information - QuarkInfo.SizeX = syncConfig.GetInt("QuarkSizeX", (int)Constants.RegionSize); - QuarkInfo.SizeY = syncConfig.GetInt("QuarkSizeY", (int)Constants.RegionSize); m_scene = scene; m_scene.RegisterModuleInterface(this); @@ -178,14 +172,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_statsTimer.Start(); } - if (!m_seSyncServeraddr.Equals(IPAddrUnknown) && m_seSyncServerport != PortUnknown) - { - m_log.Warn("[REGION SYNC SERVER MODULE] Starting SceneToScriptEngineSyncServer"); - //Start the sync server for script engines - m_sceneToSESyncServer = new SceneToScriptEngineSyncServer(m_scene, m_seSyncServeraddr, m_seSyncServerport); - m_sceneToSESyncServer.Start(); - } - m_peSyncServeraddr = m_scene.RegionInfo.PhysicsSyncServerAddress; m_peSyncServerport = m_scene.RegionInfo.PhysicsSyncServerPort; if (!m_peSyncServeraddr.Equals(IPAddrUnknown) && m_peSyncServerport != PortUnknown) @@ -422,8 +408,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //when an object is deleted, this function (DeleteObject) could be triggered more than once. So we check //if the object part is already removed is the scene (part==null) //m_log.Debug("Inform script engine about the deleted object"); - if(m_sceneToSESyncServer!=null) - m_sceneToSESyncServer.SendToSE(rsm, part.ParentGroup); + //if(m_sceneToSESyncServer!=null) + // m_sceneToSESyncServer.SendToSE(rsm, part.ParentGroup); } } @@ -438,8 +424,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { get { - //if (m_server == null || !m_server.Synced) - if((m_server == null || !m_server.Synced) && (m_sceneToSESyncServer==null || !m_sceneToSESyncServer.Synced)) + if (m_server == null || !m_server.Synced) + //if((m_server == null || !m_server.Synced) && (m_sceneToSESyncServer==null || !m_sceneToSESyncServer.Synced)) return false; return true; } @@ -450,9 +436,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString()); if(m_server!=null) m_server.Broadcast(msg); - //KittyL: added for SE - if(m_sceneToSESyncServer!=null) - m_sceneToSESyncServer.SendToAllConnectedSE(msg); } #region cruft @@ -514,7 +497,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //Sync-server for script engines private string m_seSyncServeraddr; private int m_seSyncServerport; - private SceneToScriptEngineSyncServer m_sceneToSESyncServer = null; + //private SceneToScriptEngineSyncServer m_sceneToSESyncServer = null; //Sync-server for physics engines private string m_peSyncServeraddr; @@ -561,7 +544,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule SceneObjectGroup sog = (SceneObjectGroup)entity; m_server.BroadcastToCM(RegionSyncMessage.MsgType.NewObject, sog); - m_sceneToSESyncServer.SendToSE(RegionSyncMessage.MsgType.NewObject, sog); + //m_sceneToSESyncServer.SendToSE(RegionSyncMessage.MsgType.NewObject, sog); } else @@ -582,7 +565,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //m_server.Broadcast(rsm); SceneObjectGroup sog = (SceneObjectGroup)copy; m_server.BroadcastToCM(RegionSyncMessage.MsgType.NewObject, sog); - m_sceneToSESyncServer.SendToSE(RegionSyncMessage.MsgType.NewObject, sog); + //m_sceneToSESyncServer.SendToSE(RegionSyncMessage.MsgType.NewObject, sog); } else { @@ -611,7 +594,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //when an object is deleted, this function (DeleteObject) could be triggered more than once. So we check //if the object part is already removed is the scene (part==null) //m_log.Debug("Inform script engine about the deleted object"); - m_sceneToSESyncServer.SendToSE(rsm, part.ParentGroup); + //m_sceneToSESyncServer.SendToSE(rsm, part.ParentGroup); } } else diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncUtil.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncUtil.cs index 81a71cc8ca..4d72b5dda1 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncUtil.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncUtil.cs @@ -53,256 +53,5 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } return data; } - - #region Quark operations - - //Convert a list of quarks, each identified by "x_y", where (x,y) are the offset position (in a 256x256 scene) of the left-bottom corner, to a single string - public static string QuarkStringListToString(List quarks) - { - string quarkString = ""; - foreach (string quark in quarks) - { - quarkString += quark + ","; - } - //trim the last ',' - char[] trimChar = {','}; - return quarkString.TrimEnd(trimChar); - //return quarkString; - } - - //Convert a list of quarks, each identified by a QuarkInfo data structure, to a single string - public static string QuarkInfoToString(List quarks) - { - string quarkString = ""; - foreach (QuarkInfo quark in quarks) - { - quarkString += quark.QuarkStringRepresentation + ","; - } - //trim the last ',' - char[] trimChar = { ',' }; - return quarkString.TrimEnd(trimChar); - //return quarkString; - } - - public static List QuarkStringToStringList(string quarkString) - { - string[] data = quarkString.Split(new char[] { ',' }); - List quarkList = new List(data); - - return quarkList; - } - - //public static List GetQuarkInfoList(List quarkStringList, int quarkSizeX, int quarkSizeY) - public static List GetQuarkInfoList(List quarkStringList) - { - List quarkInfoList = new List(); - foreach (string quarkString in quarkStringList) - { - QuarkInfo quark = new QuarkInfo(quarkString); - quarkInfoList.Add(quark); - } - return quarkInfoList; - } - - //public static List GetAllQuarksInScene(int QuarkInfo.SizeX, int QuarkInfo.SizeY) - public static List GetAllQuarksInScene() - { - List quarkList = new List(); - int xSlots =(int) Constants.RegionSize / QuarkInfo.SizeX; - int ySlots = (int) Constants.RegionSize / QuarkInfo.SizeY; - - for (int i = 0; i < xSlots; i++) - { - int posX = i * QuarkInfo.SizeX; - for (int j = 0; j < ySlots; j++) - { - int posY = j * QuarkInfo.SizeY; - QuarkInfo quark = new QuarkInfo(posX, posY); - quarkList.Add(quark); - } - } - return quarkList; - } - - //public static List GetAllQuarkStringInScene(int QuarkInfo.SizeX, int QuarkInfo.SizeY) - public static List GetAllQuarkStringInScene() - { - List quarkStringList = new List(); - int xSlots = (int)Constants.RegionSize / QuarkInfo.SizeX; - int ySlots = (int)Constants.RegionSize / QuarkInfo.SizeY; - - for (int i = 0; i < xSlots; i++) - { - int posX = i * QuarkInfo.SizeX; - for (int j = 0; j < ySlots; j++) - { - int posY = j * QuarkInfo.SizeY; - string quarkString = ""; - quarkString += posX + "_" + posY; - quarkStringList.Add(quarkString); - } - } - return quarkStringList; - } - - //public static string GetQuarkIDByPosition(Vector3 pos, int QuarkInfo.SizeX, int QuarkInfo.SizeY) - public static string GetQuarkIDByPosition(Vector3 pos) - { - float x, y; - if (pos.X < 0) - { - x = 0; - } - else if (pos.X >= Constants.RegionSize) - { - x = (int)Constants.RegionSize - 1; - } - else - x = pos.X; - - if (pos.Y < 0) - { - y = 0; - } - else if (pos.Y >= Constants.RegionSize) - { - y = (int)Constants.RegionSize - 1; - } - else - y = pos.Y; - - int xRange = (int) x / QuarkInfo.SizeX; - int yRange = (int) y / QuarkInfo.SizeY; - - int quarkPosX = xRange * QuarkInfo.SizeX; - int quarkPosY = yRange * QuarkInfo.SizeY; - - string qID = quarkPosX + "_" + quarkPosX; - return qID; - } - - //public static List GetQuarkSubscriptions(int QuarkInfo.SizeX, int QuarkInfo.SizeY, int xmin, int ymin, int xmax, int ymax) - public static List GetQuarkSubscriptions(int xmin, int ymin, int xmax, int ymax) - { - List quarkList = new List(); - int xStart = (int)xmin / QuarkInfo.SizeX; - int yStart = (int)ymin / QuarkInfo.SizeY; - int xEnd = (int)xmax / QuarkInfo.SizeX; - int yEnd = (int)ymax / QuarkInfo.SizeY; - - for (int i = xStart; i < xEnd; i++) - { - int posX = i * QuarkInfo.SizeX; - for (int j = yStart; j < yEnd; j++) - { - int posY = j * QuarkInfo.SizeY; - QuarkInfo quark = new QuarkInfo(posX, posY); - quarkList.Add(quark); - } - } - return quarkList; - } - - public static int[] GetCornerCoordinates(string space) - { - if (space == "") return null; - string[] corners = space.Split(new char[] { ',' }); - string leftBottom = corners[0]; - string rightTop = corners[1]; - string[] coordinates = leftBottom.Split(new char[] { '_' }); - - int [] results = new int[4]; - results[0] = Convert.ToInt32(coordinates[0]); - results[1] = Convert.ToInt32(coordinates[1]); - coordinates = rightTop.Split(new char[] { '_' }); - results[2] = Convert.ToInt32(coordinates[0]); - results[3] = Convert.ToInt32(coordinates[1]); - return results; - } - - public static string GetSpaceStringRepresentationByCorners(int minX, int minY, int maxX, int maxY) - { - string spaceString = minX + "_" + minY+","+maxX+"_"+maxY; - return spaceString; - } - - public static Dictionary BinarySpaceParition(int minX, int minY, int maxX, int maxY) - { - int xLen = maxX - minX; - int yLen = maxY - minY; - - //We always return the half space that share the same right-top corner, (maxX, maxY), with the original space. - int upperPlainStartX, upperPlainStartY; - int upperPlainEndX = maxX, upperPlainEndY = maxY; - - bool partitionOnX; - if (xLen >= yLen) - { - //partition along x axis - partitionOnX = true; - int partXLen = xLen / 2; - upperPlainStartX = minX + partXLen; - upperPlainStartY = minY; - } - else - { - //partition along y axis - partitionOnX = false; - int partYLen = yLen / 2; - upperPlainStartY = minY + partYLen; - upperPlainStartX = minX; - } - Dictionary partitionedSpace = new Dictionary(); - - //upper plain refers to the right (if partition along x) or top (if partition along y) part - int[] upperPlain = new int[4]; - upperPlain[0] = upperPlainStartX; - upperPlain[1] = upperPlainStartY; - upperPlain[2] = upperPlainEndX; - upperPlain[3] = upperPlainEndY; - - int[] lowerPlain = new int[4]; - if (partitionOnX) - { - lowerPlain[0] = minX; - lowerPlain[1] = minY; - lowerPlain[2] = upperPlainStartX; - lowerPlain[3] = maxY; - } - else - { - lowerPlain[0] = minX; - lowerPlain[1] = minY; - lowerPlain[2] = maxX; - lowerPlain[3] = upperPlainStartY; - } - - partitionedSpace.Add("lower", lowerPlain); - partitionedSpace.Add("upper", upperPlain); - - return partitionedSpace; - } - - public static int[] RemoveSpace(int originMinX, int originMinY, int originMaxX, int originMaxY, int toRemoveMinX, int toRemoveMinY, int toRemoveMaxX, int toRemoveMaxY) - { - int[] remainingBox = new int[4]; - remainingBox[0] = originMinX; - remainingBox[1] = originMinY; - if (originMinX == toRemoveMinX) - { - //partitioned along Y - remainingBox[2] = originMaxX; - remainingBox[3] = toRemoveMinY; - } - else - { - //partitioned along X - remainingBox[2] = toRemoveMinX; - remainingBox[3] = originMaxY; - } - return remainingBox; - } - - #endregion Quark operations } } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs index eab80bd26f..a37f24af28 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineConnector.cs @@ -147,12 +147,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //private int QuarkInfo.SizeX; //private int QuarkInfo.SizeY; //private List m_quarkSubscriptions; + /* Dictionary m_quarkSubscriptions; public Dictionary QuarkSubscriptionList { get { return m_quarkSubscriptions; } } - + */ #endregion @@ -453,6 +454,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule return; } + /* //For simplicity, we assume the subscription sent by PhysEngine is legistimate (no overlapping with other script engines, etc) private void HandleQuarkSubscription(RegionSyncMessage msg) { @@ -470,6 +472,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_quarkSubscriptions.Add(quark.QuarkStringRepresentation, quark); } } + * */ private RegionSyncMessage PrepareObjectUpdateMessage(RegionSyncMessage.MsgType msgType, SceneObjectGroup sog) { diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs index 84dbd8852b..d63b6c0759 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToPhysEngineSyncServer.cs @@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //List of all quarks, each using the concatenation of x,y values of its left-bottom corners, // where the x,y values are the offset position in the scene. - private Dictionary m_quarksInScene = new Dictionary(); + //private Dictionary m_quarksInScene = new Dictionary(); private string LogHeader = "[SCENE TO PHYS ENGINE SYNC SERVER]"; @@ -307,11 +307,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule // Constructor public SceneToPhysEngineSyncServer(Scene scene, string addr, int port) { - if (QuarkInfo.SizeX == -1 || QuarkInfo.SizeY == -1) - { - m_log.Error(LogHeader + " QuarkInfo.SizeX or QuarkInfo.SizeY has not been configured yet."); - Environment.Exit(0); ; - } m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); //m_log.Warn(LogHeader + "Constructed"); @@ -327,7 +322,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_allScenes.Add(m_scene); } - InitQuarksInScene(); + //InitQuarksInScene(); SubscribeToEvents(); m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; InstallInterfaces(); @@ -376,15 +371,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule UnSubscribeToEvents(); } - private void InitQuarksInScene() - { - List quarkList = RegionSyncUtil.GetAllQuarksInScene(); - foreach (QuarkInfo quark in quarkList) - { - m_quarksInScene.Add(quark.QuarkStringRepresentation, quark); - } - } - + /* public void RegisterQuarkSubscription(List quarkSubscriptions, SceneToPhysEngineConnector peConnector) { foreach (QuarkInfo quark in quarkSubscriptions) @@ -395,6 +382,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_log.Debug(LogHeader + ": " + quarkID + " subscribed by "+peConnector.Description); } } + * */ // Add a connector to a physics engine public void AddSyncedPhysEngine(SceneToPhysEngineConnector peConnector) @@ -524,9 +512,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } else { - //Find the right SceneToSEConnector by the object's position - //TO FINISH: Map the object to a quark first, then map the quark to SceneToSEConnector - string quarkID = RegionSyncUtil.GetQuarkIDByPosition(sog.AbsolutePosition); // TODO: connection of physics engine to quarks. Next line commented out // SceneToPhysEngineConnector peConnector = m_quarksInScene[quarkID].PEConnector; diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToScriptEngineConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToScriptEngineConnector.cs deleted file mode 100644 index 7880ae4df5..0000000000 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToScriptEngineConnector.cs +++ /dev/null @@ -1,662 +0,0 @@ -/* Copyright 2011 (c) Intel Corporation - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The name of the copyright holder may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Collections.Generic; -using System.Threading; -using OpenMetaverse; -using OpenMetaverse.Packets; -using OpenMetaverse.StructuredData; -using OpenSim.Framework; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Scenes.Serialization; -using OpenSim.Region.Framework.Interfaces; -using log4net; - -namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule -{ - - - - //KittyL: NOTE -- We need to define an interface for all actors to connect into the Scene, - // e.g. IActorConnector, that runs on the Scene side, processes messages from actors, - // and apply Scene/Object operations. - - // The SceneToScriptEngineConnector acts as a thread on the RegionSyncServer to handle incoming - // messages from ScriptEngineToSceneConnectors that run on Script Engines. It connects the - // authoratative Scene with remote script engines. - public class SceneToScriptEngineConnector - { - #region SceneToScriptEngineConnector members - - object stats = new object(); - private DateTime lastStatTime; - private long msgsIn; - private long msgsOut; - private long bytesIn; - private long bytesOut; - private long pollBlocks; - private int lastTotalCount; - private int lastLocalCount; - private int lastRemoteCount; - - private int msgCount = 0; - - // The TcpClient this view uses to communicate with its RegionSyncClient - private TcpClient m_tcpclient; - // Set the addr and port for TcpListener - private IPAddress m_addr; - private Int32 m_port; - private int m_connection_number; - private Scene m_scene; - - object m_syncRoot = new object(); - Dictionary m_syncedAvatars = new Dictionary(); - - // A queue for incoming and outgoing traffic - private OpenMetaverse.BlockingQueue inbox = new OpenMetaverse.BlockingQueue(); - private OpenMetaverse.BlockingQueue outbox = new OpenMetaverse.BlockingQueue(); - - private ILog m_log; - - private Thread m_receive_loop; - private string m_regionName; - - private SceneToScriptEngineSyncServer m_syncServer = null; - - // A string of the format [REGION SYNC SCRIPT API (regionname)] for use in log headers - private string LogHeader - { - get - { - if (m_regionName == null) - return String.Format("[SceneToScriptEngineConnector #{0}]", m_connection_number); - return String.Format("[SceneToScriptEngineConnector #{0} ({1:10})]", m_connection_number, m_regionName); - } - } - - // A string of the format "RegionSyncClientView #X" for use in describing the object itself - public string Description - { - get - { - if (m_regionName == null) - return String.Format("RegionSyncScriptAPI #{0}", m_connection_number); - return String.Format("RegionSyncScriptAPI #{0} ({1:10})", m_connection_number, m_regionName); - } - } - - public int ConnectionNum - { - get { return m_connection_number; } - } - - public string GetStats() - { - int syncedAvCount; - string ret; - //lock (m_syncRoot) - // syncedAvCount = m_syncedAvatars.Count; - lock (stats) - { - double secondsSinceLastStats = DateTime.Now.Subtract(lastStatTime).TotalSeconds; - lastStatTime = DateTime.Now; - - ret = String.Format("[{0,4}/{1,4}], [{2,4}/{3,4}], [{4,4}/{5,4}], [{6,4} ({7,4})], [{8,8} ({9,8:00.00})], [{10,4} ({11,4})], [{12,8} ({13,8:00.00})], [{14,8} ({15,4}]", - //lastTotalCount, totalAvCount, // TOTAL AVATARS - //lastLocalCount, syncedAvCount, // LOCAL TO THIS CLIENT VIEW - //lastRemoteCount, totalAvCount - syncedAvCount, // REMOTE (SHOULD = TOTAL - LOCAL) - msgsIn, (int)(msgsIn / secondsSinceLastStats), - bytesIn, 8 * (bytesIn / secondsSinceLastStats / 1000000), // IN - msgsOut, (int)(msgsOut / secondsSinceLastStats), - bytesOut, 8 * (bytesOut / secondsSinceLastStats / 1000000), // OUT - pollBlocks, (int)(pollBlocks / secondsSinceLastStats)); // NUMBER OF TIMES WE BLOCKED WRITING TO SOCKET - - msgsIn = msgsOut = bytesIn = bytesOut = pollBlocks = 0; - } - return ret; - } - - // Check if the client is connected - public bool Connected - { get { return m_tcpclient.Connected; } } - - //private int QuarkInfo.SizeX; - //private int QuarkInfo.SizeY; - //private List m_quarkSubscriptions; - Dictionary m_quarkSubscriptions; - public Dictionary QuarkSubscriptionList - { - get { return m_quarkSubscriptions; } - } - - - - #endregion - - - - // Constructor - public SceneToScriptEngineConnector(int num, Scene scene, TcpClient client, SceneToScriptEngineSyncServer syncServer) - { - m_connection_number = num; - m_scene = scene; - m_tcpclient = client; - m_addr = ((IPEndPoint)client.Client.RemoteEndPoint).Address; - m_port = ((IPEndPoint)client.Client.RemoteEndPoint).Port; - m_syncServer = syncServer; - - //QuarkInfo.SizeX = quarkSizeX; - //QuarkInfo.SizeY = quarkSizeY; - - m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - //m_log.WarnFormat("{0} Constructed", LogHeader); - - //Register for events from Scene.EventManager - //m_scene.EventManager.OnRezScript += SEConnectorOnRezScript; - //m_scene.EventManager.OnScriptReset += SEConnectorOnScriptReset; - //m_scene.EventManager.OnUpdateScript += SEConnectorOnUpdateScript; - // Create a thread for the receive loop - m_receive_loop = new Thread(new ThreadStart(delegate() { ReceiveLoop(); })); - m_receive_loop.Name = Description; - //m_log.WarnFormat("{0} Started thread: {1}", LogHeader, m_receive_loop.Name); - m_receive_loop.Start(); - - //tell the remote script engine about the locX, locY of this authoritative scene - SendSceneLoc(); - } - - // Stop the listening thread, disconnecting the RegionSyncScriptEngine - public void Shutdown() - { - m_syncServer.RemoveSyncedScriptEngine(this); - // m_scene.EventManager.OnChatFromClient -= EventManager_OnChatFromClient; - // Abort ReceiveLoop Thread, close Socket and TcpClient - m_receive_loop.Abort(); - m_tcpclient.Client.Close(); - m_tcpclient.Close(); - - //m_scene.EventManager.OnRezScript -= SEConnectorOnRezScript; - //m_scene.EventManager.OnScriptReset -= SEConnectorOnScriptReset; - //m_scene.EventManager.OnUpdateScript -= SEConnectorOnUpdateScript; - } - - #region Send/Receive messages to/from the remote Script Engine - - // Listen for messages from a RegionSyncClient - // *** This is the main thread loop for each connected client - private void ReceiveLoop() - { - // Reset stats and time - lastStatTime = DateTime.Now; - msgsIn = msgsOut = bytesIn = bytesOut = 0; - - try - { - while (true) - { - RegionSyncMessage msg = GetMessage(); - lock (stats) - { - msgsIn++; - bytesIn += msg.Length; - } - lock (m_syncRoot) - HandleMessage(msg); - } - } - catch (Exception e) - { - m_log.WarnFormat("{0}: has disconnected: {1}", LogHeader, e.Message); - } - Shutdown(); - } - - // Get a message from the RegionSyncClient - private RegionSyncMessage GetMessage() - { - // Get a RegionSyncMessager from the incoming stream - RegionSyncMessage msg = new RegionSyncMessage(m_tcpclient.GetStream()); - //m_log.WarnFormat("{0} Received {1}", LogHeader, msg.ToString()); - return msg; - } - - // Handle an incoming message - // *** Perhaps this should not be synchronous with the receive - // We could handle messages from an incoming Queue - private void HandleMessage(RegionSyncMessage msg) - { - msgCount++; - //string handlerMessage = ""; - switch (msg.Type) - { - case RegionSyncMessage.MsgType.QuarkSubscription: - HandleQuarkSubscription(msg); - return; - case RegionSyncMessage.MsgType.RegionName: - { - m_regionName = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.RegionName, m_scene.RegionInfo.RegionName)); - RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Syncing to region \"{0}\"", m_regionName)); - return; - } - case RegionSyncMessage.MsgType.GetTerrain: - { - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString())); - RegionSyncMessage.HandleSuccess(LogHeader, msg, "Terrain sent"); - return; - } - case RegionSyncMessage.MsgType.GetObjects: - { - //List entities = m_scene.GetEntities(); - - //This should be a function of Scene, but since we don't have the quark concept in Scene yet, - //for now we implement it here. - List objectsInSpace = GetObjectsInGivenSpace(m_scene, m_quarkSubscriptions); - foreach (SceneObjectGroup sog in objectsInSpace) - { - Send(PrepareObjectUpdateMessage(RegionSyncMessage.MsgType.NewObject, sog)); - } - RegionSyncMessage.HandleSuccess(LogHeader, msg, "Sent all scene objects"); - return; - } - case RegionSyncMessage.MsgType.SetObjectProperty: - { - OSDMap data = RegionSyncUtil.DeserializeMessage(msg, LogHeader); - if (!data.ContainsKey("UUID") || !data.ContainsKey("name")) - { - m_log.WarnFormat("{0} Parameters missing in SetObjectProperty request, need \"UUID\", \"name\" (property-name), and \"valParams\" (property-value)", LogHeader); - return; - } - UUID objID = data["UUID"].AsUUID(); - string pName = data["name"].AsString(); - //valParams - SetObjectProperty(objID, pName, data); - } - return; - case RegionSyncMessage.MsgType.ActorStop: - { - Shutdown(); - } - return; - case RegionSyncMessage.MsgType.LoadBalanceRequest: - { - m_syncServer.HandleLoadBalanceRequest(this); - return; - } - - case RegionSyncMessage.MsgType.ActorStatus: - { - string status = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); - ActorStatus actorStatus = (ActorStatus)Convert.ToInt32(status); - if (actorStatus == ActorStatus.Sync) - { - m_log.Debug(LogHeader + ": received ActorStatus " + actorStatus.ToString()); - m_syncServer.AddSyncedScriptEngine(this); - } - else - { - m_log.Warn(LogHeader + ": not supposed to received RegionSyncMessage.MsgType.ActorStatus==" + status.ToString()); - } - return; - } - - default: - { - m_log.WarnFormat("{0} Unable to handle unsupported message type", LogHeader); - return; - } - } - } - - //For simplicity, we assume the subscription sent by ScriptEngine is legistimate (no overlapping with other script engines, etc) - private void HandleQuarkSubscription(RegionSyncMessage msg) - { - string quarkString = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); - m_log.Debug(LogHeader + ": received quark-string: " + quarkString); - - List quarkStringList = RegionSyncUtil.QuarkStringToStringList(quarkString); - //m_quarkSubscriptions = RegionSyncUtil.GetQuarkInfoList(quarkStringList, QuarkInfo.SizeX, QuarkInfo.SizeY); - List quarkList = RegionSyncUtil.GetQuarkInfoList(quarkStringList); - m_syncServer.RegisterQuarkSubscription(quarkList, this); - - m_quarkSubscriptions = new Dictionary(); - foreach (QuarkInfo quark in quarkList) - { - m_quarkSubscriptions.Add(quark.QuarkStringRepresentation, quark); - } - } - - private RegionSyncMessage PrepareObjectUpdateMessage(RegionSyncMessage.MsgType msgType, SceneObjectGroup sog) - { - OSDMap data = new OSDMap(3); - data["locX"] = OSD.FromUInteger(m_scene.RegionInfo.RegionLocX); - data["locY"] = OSD.FromUInteger(m_scene.RegionInfo.RegionLocY); - string sogxml = SceneObjectSerializer.ToXml2Format(sog); - data["sogXml"] = OSD.FromString(sogxml); - - RegionSyncMessage rsm = new RegionSyncMessage(msgType, OSDParser.SerializeJsonString(data)); - return rsm; - } - - private void SendSceneLoc() - { - uint locX = m_scene.RegionInfo.RegionLocX; - uint locY = m_scene.RegionInfo.RegionLocY; - - OSDMap data = new OSDMap(2); - data["locX"] = OSD.FromUInteger(locX); - data["locY"] = OSD.FromUInteger(locY); - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.SceneLocation, OSDParser.SerializeJsonString(data))); - } - - public void Send(RegionSyncMessage msg) - { - if (msg.Type == RegionSyncMessage.MsgType.AvatarAppearance) - m_log.WarnFormat("{0} Sending AvatarAppearance to client manager", LogHeader); - - Send(msg.ToBytes()); - } - - private void Send(byte[] data) - { - if (m_tcpclient.Connected) - { - try - { - lock (stats) - { - msgsOut++; - bytesOut += data.Length; - } - m_tcpclient.GetStream().BeginWrite(data, 0, data.Length, ar => - { - if (m_tcpclient.Connected) - { - try - { - m_tcpclient.GetStream().EndWrite(ar); - } - catch (Exception) - { } - } - }, null); - } - catch (IOException) - { - m_log.WarnFormat("{0} Script Engine has disconnected.", LogHeader); - } - } - } - - public void SendObjectUpdate(RegionSyncMessage.MsgType msgType, SceneObjectGroup sog) - { - Send(PrepareObjectUpdateMessage(msgType, sog)); - } - - #endregion Send/Receive messages to/from the remote Script Engine - - #region stub functions for remote actors to set object properties - - //NOTE: the current implementation of setting various object properties is mimicking the way script engine sets object properties - // (i.e. as implemented in LSL_Api.cs. But the function calls are meant to be generic for all actors. We may need to change - // the implementation details later to accomdate more actors, and move it to the Scene implementation. - - //TODO: These functions should eventually be part of DSG interface, rather than part of SceneToScriptEngineConnector. - - private void SetObjectProperty(UUID primID, string pName, OSDMap valParams) - { - //m_log.Debug(LogHeader + " received SetObjectProperty request, " + primID + ", " + pName); - switch (pName) - { - case "object_rez": - //rez a new object, rather than update an existing object's property - RezObjectOnScene(primID, valParams); - break; - case "color": - SetPrimColor(primID, valParams); - break; - case "pos": - SetPrimPos(primID, valParams); - break; - default: - break; - } - } - - //Triggered when an object is rez'ed by script. Followed the implementation in LSL_Api.llRezAtRoot(). - //TODO: the real rez object part should be executed by Scene class, not here - private void RezObjectOnScene(UUID primID, OSDMap data) - { - if(data["inventory"] == null || data["pos"]==null || data["vel"] == null || data["rot"]==null || data["param"]==null){ - m_log.Warn(LogHeader + ": not enough parameters for setting color on " + primID); - return; - } - string inventory = data["inventory"].AsString(); - Vector3 pos = data["pos"].AsVector3(); - Vector3 vel = data["vel"].AsVector3(); - Quaternion rot = data["rot"].AsQuaternion(); - int param = data["param"].AsInteger(); - SceneObjectPart primToFetchObject = m_scene.GetSceneObjectPart(primID); - - if (primToFetchObject == null) - return; - - TaskInventoryDictionary partInventory = (TaskInventoryDictionary)primToFetchObject.TaskInventory.Clone(); - - foreach (KeyValuePair inv in partInventory) - { - if (inv.Value.Name == inventory) - { - // make sure we're an object. - if (inv.Value.InvType != (int)InventoryType.Object) - { - //llSay(0, "Unable to create requested object. Object is missing from database."); - m_log.Warn(LogHeader + ": Unable to create requested object. Object is missing from database."); - return; - } - - Vector3 llpos = pos; - Vector3 llvel = vel; - - // need the magnitude later - float velmag = (float)Util.GetMagnitude(llvel); - - SceneObjectGroup new_group = m_scene.RezObject(primToFetchObject, inv.Value, llpos, rot, llvel, param); - - // If either of these are null, then there was an unknown error. - if (new_group == null) - continue; - if (new_group.RootPart == null) - continue; - - // objects rezzed with this method are die_at_edge by default. - new_group.RootPart.SetDieAtEdge(true); - - /* - m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( - "object_rez", new Object[] { - new LSL_String( - new_group.RootPart.UUID.ToString()) }, - new DetectParams[0])); - * */ - //NOTE: should replace the above code with the following and implement TriggerRezObject. However, since - // nothing is really doen with "object_rez" in XEngine, we ignore posting the event for now. - //m_scene.EventManager.TriggerRezObject(); - - float groupmass = new_group.GetMass(); - - if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero) - { - //Recoil. - //llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); - //copy the implementation of llApplyImpulse here. - Vector3 v = new Vector3(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass); - if (v.Length() > 20000.0f) - { - v.Normalize(); - v = v * 20000.0f; - } - new_group.RootPart.ApplyImpulse(v, false); - } - return; - } - } - - } - - private void SetPrimColor(UUID primID, OSDMap data) - { - if (!data.ContainsKey("color") || !data.ContainsKey("face")) - { - m_log.Warn(LogHeader + ": not enough parameters for setting color on " + primID); - return; - } - SceneObjectPart primToUpdate = m_scene.GetSceneObjectPart(primID); - if (primToUpdate == null) - return; - Vector3 color = data["color"].AsVector3(); - int face = data["face"].AsInteger(); - - //m_log.DebugFormat("{0}: Set Color request, to set ({1}) on face {2}", LogHeader, color.ToString(), face); - - primToUpdate.SetFaceColor(color, face); - } - - //Whichever actor that triggers this function call shall have already checked the legitimacy of the position. - private void SetPrimPos(UUID primID, OSDMap data) - { - if (!data.ContainsKey("pos")) - { - m_log.Warn(LogHeader + ": not enough parameters for setting pos on " + primID); - return; - } - Vector3 pos = data["pos"].AsVector3(); - SceneObjectPart primToUpdate = m_scene.GetSceneObjectPart(primID); - - if (primToUpdate == null) - return; - - SceneObjectGroup parent = primToUpdate.ParentGroup; - - if (parent.RootPart == primToUpdate) - { - //the prim is the root-part of the object group, set the position of the whole group - parent.UpdateGroupPosition(pos); - } - else - { - //the prim is not the root-part, set the offset position - primToUpdate.OffsetPosition = pos; - parent.HasGroupChanged = true; - //parent.ScheduleGroupForTerseUpdate(); - parent.ScheduleGroupForTerseUpdate(new List(){SceneObjectPartSyncProperties.OffsetPosition}); - } - } - - #endregion - - #region Event Handlers - //calling by SceneToSESyncServer - public void SEConnectorOnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource) - { - m_log.Debug(LogHeader + ": Caught event OnRezScript, send message to Script Engine"); - - OSDMap data = new OSDMap(7); - data["localID"] = OSD.FromUInteger(localID); - data["itemID"] = OSD.FromUUID(itemID); - data["script"] = OSD.FromString(script); - data["startParam"] = OSD.FromInteger(startParam); - data["postOnRez"] = OSD.FromBoolean(postOnRez); - data["engine"] = OSD.FromString(engine); - data["stateSource"] = OSD.FromInteger(stateSource); - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.OnRezScript, OSDParser.SerializeJsonString(data))); - } - - public void SEConnectorOnScriptReset(uint localID, UUID itemID) - { - m_log.Debug(LogHeader + ": Caught event OnScriptReset, send message to Script Engine"); - - OSDMap data = new OSDMap(2); - data["localID"] = OSD.FromUInteger(localID); - data["itemID"] = OSD.FromUUID(itemID); - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.OnScriptReset, OSDParser.SerializeJsonString(data))); - } - - public void SEConnectorOnUpdateScript(UUID agentID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) - { - m_log.Debug(LogHeader + ": Caught event OnUpdateScript, send message to Script Engine"); - - OSDMap data = new OSDMap(5); - data["agentID"] = OSD.FromUUID(agentID); - data["itemID"] = OSD.FromUUID(itemId); - data["primID"] = OSD.FromUUID(primId); - data["running"] = OSD.FromBoolean(isScriptRunning); - data["assetID"] = OSD.FromUUID(newAssetID); - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.OnUpdateScript, OSDParser.SerializeJsonString(data))); - } - - #endregion Event Handlers - - #region Spacial query functions (should be eventually implemented within Scene) - - //This should be a function of Scene, but since we don't have the quark concept in Scene yet, - //for now we implement it here. - //Ideally, for quark based space representation, the Scene has a list of quarks, and each quark points - //to a list of objects within that quark. Then it's much easier to return the right set of objects within - //a certain space. (Or use DB that supports spatial queries.) - List GetObjectsInGivenSpace(Scene scene, Dictionary quarkSubscriptions) - { - EntityBase[] entities = m_scene.GetEntities(); - List sogList = new List(); - foreach (EntityBase e in entities) - { - if (e is SceneObjectGroup) - { - SceneObjectGroup sog = (SceneObjectGroup)e; - string quarkID = RegionSyncUtil.GetQuarkIDByPosition(sog.AbsolutePosition); - if (m_quarkSubscriptions.ContainsKey(quarkID)) - { - sogList.Add(sog); - } - } - } - - return sogList; - } - - #endregion - - #region Load balancing functions - public void SendLoadBalanceRejection(string response) - { - RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.LoadBalanceRejection, response); - Send(msg); - } - #endregion - } -} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToScriptEngineSyncServer.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToScriptEngineSyncServer.cs deleted file mode 100644 index 6b648e7f6e..0000000000 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SceneToScriptEngineSyncServer.cs +++ /dev/null @@ -1,628 +0,0 @@ -/* Copyright 2011 (c) Intel Corporation - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The name of the copyright holder may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Collections.Generic; -using System.Threading; -using OpenSim.Framework; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Interfaces; -using log4net; - -using OpenMetaverse; -using OpenMetaverse.StructuredData; -using OpenSim.Region.Framework.Scenes.Serialization; - -namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule -{ - public class QuarkInfo - { - public static int SizeX = -1; //the length along X axis, should be same for all quarks, need to be set by either the SyncServer on Scene, or by an ActorToSceneConnectorModule. - public static int SizeY = -1; //the length along Y axis, should be same for all quarks - - public int PosX = 0; //the offset position of the left-bottom corner (0~255) - public int PosY = 0; - - private ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - private int maxX, maxY; - - //this field is only meaning for the QuarkInfo records on the Scene side - private SceneToScriptEngineConnector m_seConnector=null; - public SceneToScriptEngineConnector SEConnector - { - get { return m_seConnector; } - set { m_seConnector = value; } - } - - private string m_quarkString = ""; - public string QuarkStringRepresentation - { - get { return m_quarkString;} - } - - //public QuarkInfo(int x, int y, int sizeX, int sizeY) - public QuarkInfo(int x, int y) - { - PosX = x; - PosY = y; - //SizeX = sizeX; - //SizeY = sizeY; - maxX = PosX + SizeX; - maxY = PosY + SizeY; - m_quarkString = PosX + "_" + PosY; - } - - //public QuarkInfo(string xy, int sizeX, int sizeY) - public QuarkInfo(string xy) - { - string[] coordinate = xy.Split(new char[] { '_' }); - if (coordinate.Length < 2) - { - m_log.Warn("[QUARK INFO] QuarkInfo Constructor: missing x or y value, format expected x_y: " + xy); - return; - } - PosX = Convert.ToInt32(coordinate[0]); - PosY = Convert.ToInt32(coordinate[1]); - //SizeX = sizeX; - //SizeY = sizeY; - maxX = PosX + SizeX; - maxY = PosY + SizeY; - m_quarkString = PosX + "_" + PosY; - } - - //public void SetPartitionedSceneInfo(int x, int y, int sizeX, int sizeY) - public void SetPartitionedSceneInfo(int x, int y) - { - PosX = x; - PosY = y; - //SizeX = sizeX; - //SizeY = sizeY; - maxX = PosX + SizeX; - maxY = PosY + SizeY; - m_quarkString = PosX + "_" + PosY; - } - - public bool IsPositionInQuarkSpace(Vector3 pos) - { - if (pos.X >= PosX && pos.X <= maxX && pos.Y >= PosY && pos.Y <= maxY) - return true; - else - return false; - } - - } - - //Information of a registered idle script engine. - //Note, this is a temporary solution to inlcude idle script engines here. - //In the future, there might be a independent load balaner that keeps track - //of available idle hardware. - public class IdleScriptEngineInfo - { - public TcpClient TClient; - //public IPAddress ScriptEngineIPAddr; - //public int ScriptEnginePort; - public string ID; - - //Will be used to store the overloaded SE that has send LB request and paired with this idle SE - public SceneToScriptEngineConnector AwaitOverloadedSE=null; - - public IdleScriptEngineInfo(TcpClient tclient) - { - if(tclient==null) return; - TClient = tclient; - IPAddress ipAddr = ((IPEndPoint)tclient.Client.RemoteEndPoint).Address; - int port = ((IPEndPoint)tclient.Client.RemoteEndPoint).Port; - ID = ipAddr.ToString()+":"+port; - } - } - - //Here is the per actor type listening server for Script Engines. - public class SceneToScriptEngineSyncServer - { - #region SceneToScriptEngineSyncServer members - // Set the addr and port for TcpListener - private IPAddress m_addr; - private Int32 m_port; - - private int seCounter; - - // The local scene. - private Scene m_scene; - - private ILog m_log; - - // The listener and the thread which listens for connections from client managers - private TcpListener m_listener; - private Thread m_listenerThread; - - private object m_scriptEngineConnector_lock = new object(); - //private Dictionary m_scriptEngineConnectors = new Dictionary(); - private List m_scriptEngineConnectors = new List(); - - //list of idle script engines that have registered. - private List m_idleScriptEngineList = new List(); - - //List of all quarks, each using the concatenation of x,y values of its left-bottom corners, where the x,y values are the offset - //position in the scene. - private Dictionary m_quarksInScene = new Dictionary(); - - private string LogHeader = "[SCENE TO SCRIPT ENGINE SYNC SERVER]"; - - //Quark related info - //private int QuarkInfo.SizeX; - //private int QuarkInfo.SizeY; - - // Check if any of the client views are in a connected state - public bool Synced - { - get - { - return (m_scriptEngineConnectors.Count > 0); - } - } - - - - #endregion - - // Constructor - public SceneToScriptEngineSyncServer(Scene scene, string addr, int port) - { - if (QuarkInfo.SizeX == -1 || QuarkInfo.SizeY == -1) - { - m_log.Error(LogHeader + " QuarkInfo.SizeX or QuarkInfo.SizeY has not been configured yet."); - Environment.Exit(0); ; - } - - m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - //m_log.Warn(LogHeader + "Constructed"); - m_scene = scene; - m_addr = IPAddress.Parse(addr); - m_port = port; - - InitQuarksInScene(); - SubscribeToEvents(); - } - - - private void SubscribeToEvents() - { - m_scene.EventManager.OnRezScript += SESyncServerOnRezScript; - m_scene.EventManager.OnScriptReset += SESyncServerOnScriptReset; - m_scene.EventManager.OnUpdateScript += SESyncServerOnUpdateScript; - } - - private void UnSubscribeToEvents() - { - m_scene.EventManager.OnRezScript -= SESyncServerOnRezScript; - m_scene.EventManager.OnScriptReset -= SESyncServerOnScriptReset; - m_scene.EventManager.OnUpdateScript -= SESyncServerOnUpdateScript; - } - - // Start the server - public void Start() - { - m_listenerThread = new Thread(new ThreadStart(Listen)); - m_listenerThread.Name = "SceneToScriptEngineSyncServer Listener"; - m_log.WarnFormat(LogHeader + ": Starting {0} thread", m_listenerThread.Name); - m_listenerThread.Start(); - //m_log.Warn("[REGION SYNC SERVER] Started"); - } - - - - // Stop the server and disconnect all RegionSyncClients - public void Shutdown() - { - // Stop the listener and listening thread so no new clients are accepted - m_listener.Stop(); - m_listenerThread.Abort(); - m_listenerThread = null; - - // Stop all existing SceneTOSEConnectors - //TO FINISH - foreach (SceneToScriptEngineConnector seConnector in m_scriptEngineConnectors) - { - seConnector.Shutdown(); - } - m_scriptEngineConnectors.Clear(); - - UnSubscribeToEvents(); - } - - private void InitQuarksInScene() - { - List quarkList = RegionSyncUtil.GetAllQuarksInScene(); - foreach (QuarkInfo quark in quarkList) - { - m_quarksInScene.Add(quark.QuarkStringRepresentation, quark); - } - } - - public void RegisterQuarkSubscription(List quarkSubscriptions, SceneToScriptEngineConnector seConnector) - { - foreach (QuarkInfo quark in quarkSubscriptions) - { - string quarkID = quark.QuarkStringRepresentation; - m_quarksInScene[quarkID].SEConnector = seConnector; - m_log.Debug(LogHeader + ": " + quarkID + " subscribed by "+seConnector.Description); - } - } - - // Add a connector to a script engine - public void AddSyncedScriptEngine(SceneToScriptEngineConnector seConnector) - { - lock (m_scriptEngineConnector_lock) - { - //Dictionary currentlist = m_scriptEngineConnectors; - //Dictionary newlist = new Dictionary(currentlist); - m_scriptEngineConnectors.Add(seConnector); - // Threads holding the previous version of the list can keep using it since - // they will not hold it for long and get a new copy next time they need to iterate - //m_scriptEngineConnectors = newlist; - } - } - - // Remove the client view from the list and decrement synced client counter - public void RemoveSyncedScriptEngine(SceneToScriptEngineConnector seConnector) - { - lock (m_scriptEngineConnector_lock) - { - //Dictionary currentlist = m_scriptEngineConnectors; - //Dictionary newlist = new Dictionary(currentlist); - m_scriptEngineConnectors.Remove(seConnector); - // Threads holding the previous version of the list can keep using it since - // they will not hold it for long and get a new copy next time they need to iterate - //m_scriptEngineConnectors = newlist; - } - } - - // Listen for connections from a new RegionSyncClient - // When connected, start the ReceiveLoop for the new client - private void Listen() - { - m_listener = new TcpListener(m_addr, m_port); - - try - { - // Start listening for clients - m_listener.Start(); - while (true) - { - // *** Move/Add TRY/CATCH to here, but we don't want to spin loop on the same error - m_log.WarnFormat(LogHeader + ": Listening for new connections on port {0}...", m_port.ToString()); - TcpClient tcpclient = m_listener.AcceptTcpClient(); - IPAddress addr = ((IPEndPoint)tcpclient.Client.RemoteEndPoint).Address; - int port = ((IPEndPoint)tcpclient.Client.RemoteEndPoint).Port; - - ActorStatus actorStatus = GetActorStatus(tcpclient); - - switch (actorStatus) - { - case ActorStatus.Sync: - // Add the SceneToScriptEngineConnector to the list - SceneToScriptEngineConnector sceneToSEConnector = new SceneToScriptEngineConnector(++seCounter, m_scene, tcpclient, this); - AddSyncedScriptEngine(sceneToSEConnector); - break; - case ActorStatus.Idle: - IdleScriptEngineInfo idleSE = new IdleScriptEngineInfo(tcpclient); - m_log.Debug(": adding an idle SE ("+addr+","+port+")"); - m_idleScriptEngineList.Add(idleSE); - break; - default: - break; - } - - } - } - catch (SocketException e) - { - m_log.WarnFormat(LogHeader + " [Listen] SocketException: {0}", e); - } - } - - /* - public void RegisterSyncedScriptEngine(SceneToScriptEngineConnector sceneToSEConnector) - { - //first, remove it from the idle list - m_idleScriptEngineList.Remove(sceneToSEConnector); - - //now, added to the synced SE list - AddSyncedScriptEngine(sceneToSEConnector); - } - * */ - - - // Broadcast a message to all connected RegionSyncClients - public void SendToAllConnectedSE(RegionSyncMessage msg) - { - if (m_scriptEngineConnectors.Count > 0) - { - m_log.Debug(LogHeader + ": region " + m_scene.RegionInfo.RegionName + " Broadcast to ScriptEngine, msg " + msg.Type); - foreach (SceneToScriptEngineConnector seConnector in m_scriptEngineConnectors) - { - seConnector.Send(msg); - } - } - - } - - //TO FINISH: Find the right SceneToSEConnector to forward the message - public void SendToSE(RegionSyncMessage.MsgType msgType, SceneObjectGroup sog) - { - SceneToScriptEngineConnector seConnector = GetSceneToSEConnector(sog); - if (seConnector != null) - { - seConnector.SendObjectUpdate(msgType, sog); - } - } - - //This is to send a message, rsm, to script engine, and the message is about object SOG. E.g. RemovedObject - public void SendToSE(RegionSyncMessage rsm, SceneObjectGroup sog) - { - SceneToScriptEngineConnector seConnector = GetSceneToSEConnector(sog); - if (seConnector != null) - { - seConnector.Send(rsm); - } - } - - - private SceneToScriptEngineConnector GetSceneToSEConnector(SceneObjectGroup sog) - { - if (m_scriptEngineConnectors.Count == 0) - return null; - if (sog == null) - { - return m_scriptEngineConnectors[0]; - } - else - { - //Find the right SceneToSEConnector by the object's position - //TO FINISH: Map the object to a quark first, then map the quark to SceneToSEConnector - string quarkID = RegionSyncUtil.GetQuarkIDByPosition(sog.AbsolutePosition); - SceneToScriptEngineConnector seConnector = m_quarksInScene[quarkID].SEConnector; - - if (seConnector == null) - { - m_log.Warn(LogHeader + sog.AbsolutePosition.ToString() + " not covered by any script engine"); - } - - return seConnector; - } - - } - - private ActorStatus GetActorStatus(TcpClient tcpclient) - { - m_log.Debug(LogHeader+ ": Get Actor status"); - - RegionSyncMessage msg = new RegionSyncMessage(tcpclient.GetStream()); - ActorStatus actorStatus; - switch (msg.Type) - { - case RegionSyncMessage.MsgType.ActorStatus: - { - string status = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); - m_log.Debug(LogHeader + ": recv status: " + status); - actorStatus = (ActorStatus)Convert.ToInt32(status); - break; - } - default: - { - m_log.Error(LogHeader + ": Expect Message Type: ActorStatus"); - RegionSyncMessage.HandleError("[REGION SYNC SERVER]", msg, String.Format("{0} Expect Message Type: ActorType", "[REGION SYNC SERVER]")); - return ActorStatus.Null; - } - } - return actorStatus; - } - - - #region Event Handlers - - private void SESyncServerOnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource) - { - SceneObjectGroup sog = m_scene.GetSceneObjectPart(localID).ParentGroup; - if (sog != null) - { - //First, figure out which script engine to forward the event - SceneToScriptEngineConnector seConnector = GetSceneToSEConnector(sog); - if (seConnector != null) - { - m_log.Debug(LogHeader + ": Caught event OnRezScript, send message to Script Engine " + seConnector.Description); - - seConnector.SEConnectorOnRezScript(localID, itemID, script, startParam, postOnRez, engine, stateSource); - } - } - } - - private void SESyncServerOnScriptReset(uint localID, UUID itemID) - { - - SceneObjectGroup sog = m_scene.GetSceneObjectPart(localID).ParentGroup; - if (sog != null) - { - //First, figure out which script engine to forward the event - SceneToScriptEngineConnector seConnector = GetSceneToSEConnector(sog); - if (seConnector != null) - { - m_log.Debug(LogHeader + ": Caught event OnScriptReset, send message to Script Engine " + seConnector.Description); - - seConnector.SEConnectorOnScriptReset(localID, itemID); - } - } - } - - private void SESyncServerOnUpdateScript(UUID agentID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) - { - SceneObjectGroup sog = m_scene.GetSceneObjectPart(primId).ParentGroup; - if (sog != null) - { - //First, figure out which script engine to forward the event - SceneToScriptEngineConnector seConnector = GetSceneToSEConnector(sog); - if (seConnector != null) - { - m_log.Debug(LogHeader + ": Caught event OnScriptReset, send message to Script Engine " + seConnector.Description); - - seConnector.SEConnectorOnUpdateScript(agentID, itemId, primId, isScriptRunning, newAssetID); - } - } - } - - #endregion Event Handlers - - #region Load balancing members and functions - //keep track of idle script engines that are in the process of load balancing (they are off the idle list, but not a working script engine yet (not sync'ing with Scene yet)). - private Dictionary m_loadBalancingIdleSEs = new Dictionary(); - public void HandleLoadBalanceRequest(SceneToScriptEngineConnector seConnctor) - { - //Let's start a thread to do the job, so that we can return quickly and don't block on ReceiveLoop() - - Thread partitionThread = new Thread(new ParameterizedThreadStart(TriggerLoadBalanceProcess)); - partitionThread.Name = "TriggerLoadBalanceProcess"; - partitionThread.Start((object)seConnctor); - } - - public void TriggerLoadBalanceProcess(object arg) - { - SceneToScriptEngineConnector seConnctor = (SceneToScriptEngineConnector)arg; - IdleScriptEngineInfo idleScriptEngineInfo = GetIdleScriptEngineConnector(); - if (idleScriptEngineInfo != null) - { - RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.LoadMigrationNotice); - Send(idleScriptEngineInfo.TClient, msg.ToBytes()); - m_log.Debug(LogHeader + ": HandleLoadBalanceRequest from " + seConnctor.Description + ", picked idle SE: " + idleScriptEngineInfo.ID); - - //keep track of which overload script engine is paired up with which idle script engine - idleScriptEngineInfo.AwaitOverloadedSE = seConnctor; - m_loadBalancingIdleSEs.Add(idleScriptEngineInfo.ID, idleScriptEngineInfo); - - m_log.Debug("ToSEConnector portal: local -" + - ((IPEndPoint)idleScriptEngineInfo.TClient.Client.LocalEndPoint).Address.ToString() + ":" + ((IPEndPoint)idleScriptEngineInfo.TClient.Client.LocalEndPoint).Port - + "; remote - " + ((IPEndPoint)idleScriptEngineInfo.TClient.Client.RemoteEndPoint).Address.ToString() + ":" - + ((IPEndPoint)idleScriptEngineInfo.TClient.Client.RemoteEndPoint).Port); - - //Now we expect the idle script engine to reply back - msg = new RegionSyncMessage(idleScriptEngineInfo.TClient.GetStream()); - if (msg.Type != RegionSyncMessage.MsgType.LoadMigrationListenerInitiated) - { - m_log.Warn(LogHeader + ": should receive a message of type LoadMigrationListenerInitiated, but received " + msg.Type.ToString()); - } - else - { - //Before the load is migrated from overloaded script engine to the idle engine, sync with the DB to update the state in DB - EntityBase[] entities = m_scene.GetEntities(); - foreach (EntityBase entity in entities) - { - if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged) - { - m_scene.ForceSceneObjectBackup((SceneObjectGroup)entity); - } - } - - OSDMap data = DeserializeMessage(msg); - if (!data.ContainsKey("ip") || !data.ContainsKey("port") ) - { - m_log.Warn(LogHeader + ": parameters missing in SceneLocation message from Scene, need to have ip, port"); - return; - } - //echo the information back to the overloaded script engine - seConnctor.Send(new RegionSyncMessage(RegionSyncMessage.MsgType.LoadBalanceResponse, OSDParser.SerializeJsonString(data))); - - m_log.Debug(LogHeader + " now remove script engine " + idleScriptEngineInfo.ID + " from idle SE list, and create SceneToScriptEngineConnector to it"); - //create a SceneToSEConnector for the idle script engine, who will be sync'ing with this SyncServer soon - SceneToScriptEngineConnector sceneToSEConnector = new SceneToScriptEngineConnector(++seCounter, m_scene, idleScriptEngineInfo.TClient, this); - //Now remove the script engine from the idle SE list - m_idleScriptEngineList.Remove(idleScriptEngineInfo); - //AddSyncedScriptEngine(sceneToSEConnector); - } - - } - else - { - seConnctor.SendLoadBalanceRejection("no idle script engines"); - } - } - - HashSet exceptions = new HashSet(); - private OSDMap DeserializeMessage(RegionSyncMessage msg) - { - OSDMap data = null; - try - { - data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)) as OSDMap; - } - catch (Exception e) - { - lock (exceptions) - // If this is a new message, then print the underlying data that caused it - if (!exceptions.Contains(e.Message)) - m_log.Error(LogHeader + " " + Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); - data = null; - } - return data; - } - - private void Send(TcpClient tcpclient, byte[] data) - { - if (tcpclient.Connected) - { - try - { - tcpclient.GetStream().BeginWrite(data, 0, data.Length, ar => - { - if (tcpclient.Connected) - { - try - { - tcpclient.GetStream().EndWrite(ar); - } - catch (Exception) - { } - } - }, null); - } - catch (IOException) - { - m_log.WarnFormat("{0} Script Engine has disconnected.", LogHeader); - } - } - } - - private IdleScriptEngineInfo GetIdleScriptEngineConnector() - { - if (m_idleScriptEngineList.Count == 0) - return null; - IdleScriptEngineInfo idleSEInfo = m_idleScriptEngineList[0]; - m_idleScriptEngineList.Remove(idleSEInfo); - return idleSEInfo; - } - - #endregion Load balancing functions - } -} diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/ScriptEngineToSceneConnector.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/ScriptEngineToSceneConnector.cs deleted file mode 100644 index bd59710916..0000000000 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/ScriptEngineToSceneConnector.cs +++ /dev/null @@ -1,1445 +0,0 @@ -/* Copyright 2011 (c) Intel Corporation - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The name of the copyright holder may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Threading; -using OpenMetaverse; -using OpenMetaverse.Packets; -using OpenMetaverse.StructuredData; -using OpenSim.Framework; -using OpenSim.Services.Interfaces; -using OpenSim.Framework.Client; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Scenes.Serialization; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes.Types; -using log4net; - -using Nini.Config; - -//SYNC_SE: Added by KittyL, 06/21/2010 -namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule -{ - //The data structure that maintains the list of quarks a script engine subscribes to. - //It might be better to organize the quarks in a k-d tree structure, for easier - //partitioning of the quarks based on spatial information. - //But for now, we just assume the quarks each script engine operates on form a rectangle shape. - //So we just use xmin,ymin and xmax,ymax to identify the rectange; and use a List structure to - //store the quarks. - //Quark size is defined in QuarkInfo.SizeX and QuarkInfo.SizeY. - public class QuarkSubsriptionInfo - { - private List m_quarks; - private int m_minX; - private int m_minY; - private int m_maxX; - private int m_maxY; - //public static int QuarkSizeX; - //public static int QuarkSizeY; - - public int MinX - { - get { return m_minX; } - } - - public int MinY - { - get { return m_minY; } - } - - public int MaxX - { - get { return m_maxX; } - } - - public int MaxY - { - get { return m_maxY; } - } - - public QuarkSubsriptionInfo(int xmin, int ymin, int xmax, int ymax) - { - //QuarkInfo.SizeX = quarkSizeX; - //QuarkInfo.SizeY = quarkSizeY; - m_minX = xmin; - m_minY = ymin; - m_maxX = xmax; - m_maxY = ymax; - m_quarks = RegionSyncUtil.GetQuarkSubscriptions(xmin, ymin, xmax, ymax); - } - - public QuarkSubsriptionInfo(string space) - { - //QuarkInfo.SizeX = quarkSizeX; - //QuarkInfo.SizeY = quarkSizeY; - int[] coordinates = RegionSyncUtil.GetCornerCoordinates(space); - m_minX = coordinates[0]; - m_minY = coordinates[1]; - m_maxX = coordinates[2]; - m_maxY = coordinates[3]; - - m_quarks = RegionSyncUtil.GetQuarkSubscriptions(m_minX, m_minY, m_maxX, m_maxY); - } - - public List QuarkList - { - get { return m_quarks; } - } - - /// - /// Test if a given position is in the space of the quarks. - /// - /// - /// - public bool IsInSpace(Vector3 pos) - { - //For now, the test is simple: we just compare with the corners of the rectangle space. - //Need to be modified when we later support irregular quark unions. - if (pos.X < MinX || pos.X >= MaxX || pos.Y < MinY || pos.Y >= MaxY) - { - return false; - } - else - return true; - } - - public string StringRepresentation() - { - return RegionSyncUtil.QuarkInfoToString(m_quarks); - } - - public void RemoveQuarks(QuarkSubsriptionInfo remQuarks) - { - //First, remove the given quarks. - QuarkInfo toRemoveQuark; - foreach (QuarkInfo rQuark in remQuarks.QuarkList) - { - toRemoveQuark = null; - foreach (QuarkInfo originalQuark in m_quarks) - { - if (rQuark.QuarkStringRepresentation.Equals(originalQuark.QuarkStringRepresentation)) - { - toRemoveQuark = originalQuark; - break; - } - } - if (toRemoveQuark != null) - { - m_quarks.Remove(toRemoveQuark); - } - } - - //Second, adjust the space bounding box - //The removed space should share the same top-right corner with the original space (simple binary space partition) - int[] remainingBoundingBox = RegionSyncUtil.RemoveSpace(m_minX, m_minY, m_maxX, m_maxY, remQuarks.MinX, remQuarks.MinY, remQuarks.MaxX, remQuarks.MaxY); - m_minX = remainingBoundingBox[0]; - m_minY = remainingBoundingBox[1]; - m_maxX = remainingBoundingBox[2]; - m_maxY = remainingBoundingBox[3]; - } - } - - // The RegionSyncScriptEngine has a receive thread to process messages from the RegionSyncServer. - // It is the client side of the synchronization channel, and send to and receive updates from the - // Auth. Scene. The server side thread handling the sync channel is implemented in RegionSyncScriptAPI.cs. - // - // The current implementation is very similar to RegionSyncClient. - // TODO: eventually the same RegionSyncSceneAPI should handle all traffic from different actors, e.g. - // using a pub/sub model. - public class ScriptEngineToSceneConnector - { - #region ScriptEngineToSceneConnector members - - // Set the addr and port of RegionSyncServer - private IPAddress m_addr; - private string m_addrString; - private Int32 m_port; - - // A reference to the local scene - private Scene m_validLocalScene; - - // The avatars added to this client manager for clients on other client managers - object m_syncRoot = new object(); - - // The logfile - private ILog m_log; - - private string LogHeader = "[SCRIPT ENGINE TO SCENE CONNECTOR]"; - - // The listener and the thread which listens for connections from client managers - private Thread m_rcvLoop; - - // The client connection to the RegionSyncServer - private TcpClient m_client = new TcpClient(); - - private string m_authSceneName; - - //KittyL: Comment out m_statsTimer for now, will figure out whether we need it for ScriptEngine later - //private System.Timers.Timer m_statsTimer = new System.Timers.Timer(30000); - - // The queue of incoming messages which need handling - //private Queue m_inQ = new Queue(); - - //KittyL: added to identify different actors - private ActorType m_actorType = ActorType.ScriptEngine; - - private bool m_debugWithViewer = false; - - private QuarkSubsriptionInfo m_subscribedQuarks; - - - private IConfig m_sysConfig; - - //members for load balancing purpose - //private TcpClient m_loadMigrationSouceEnd = null; - private LoadMigrationEndPoint m_loadMigrationSouceEnd = null; - private Thread m_loadMigrationSrcRcvLoop; - private LoadMigrationListener m_loadMigrationListener = null; - - //List of queued messages, when the space that the updated object is located is being migrated - private List m_updateMsgQueue = new List(); - - #endregion - - - // Constructor - public ScriptEngineToSceneConnector(Scene validLocalScene, string addr, int port, bool debugWithViewer, string authSceneName, IConfig sysConfig) - { - m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - m_validLocalScene = validLocalScene; - m_addr = IPAddress.Parse(addr); - m_addrString = addr; - m_port = port; - m_debugWithViewer = debugWithViewer; - m_authSceneName = authSceneName; - //m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed); - m_sysConfig = sysConfig; - - //assume we are connecting to the whole scene as one big quark - m_subscribedQuarks = new QuarkSubsriptionInfo(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize); - } - - /// - /// Create a ScriptEngineToSceneConnector based on the space it is supposed to subscribe (and operate) on. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public ScriptEngineToSceneConnector(Scene validLocalScene, string addr, int port, bool debugWithViewer, string authSceneName, - string subscriptionSpace, IConfig sysConfig) - { - if (QuarkInfo.SizeX == -1 || QuarkInfo.SizeY == -1) - { - m_log.Error("QuarkInfo.SizeX or QuarkInfo.SizeY has not been configured."); - Environment.Exit(0); - } - - m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - m_validLocalScene = validLocalScene; - m_addr = IPAddress.Parse(addr); - m_addrString = addr; - m_port = port; - m_debugWithViewer = debugWithViewer; - m_authSceneName = authSceneName; - //m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed); - m_sysConfig = sysConfig; - - m_subscribedQuarks = new QuarkSubsriptionInfo(subscriptionSpace); - } - - public ScriptEngineToSceneConnectorModule GetSEToSceneConnectorMasterModule() - { - if (m_validLocalScene == null) - return null; - return (ScriptEngineToSceneConnectorModule)m_validLocalScene.ScriptEngineToSceneConnectorModule; - } - - public Scene GetValidLocalScene() - { - return m_validLocalScene; - } - - - private List GetQuarkStringList() - { - List quarkList = new List(); - foreach (QuarkInfo quark in m_subscribedQuarks.QuarkList) - { - quarkList.Add(quark.QuarkStringRepresentation); - } - return quarkList; - } - - - - /// - /// Get the reference to the local scene that is supposed to be mapped to the remote auth. scene. - /// - /// - /// - private Scene GetLocalScene(string authSceneName) - { - ScriptEngineToSceneConnectorModule connectorModule = GetSEToSceneConnectorMasterModule(); - return connectorModule.GetLocalScene(authSceneName); - } - - // Start the RegionSyncScriptEngine client thread - public bool Start() - { - if (EstablishConnection()) - { - StartStateSync(); - return true; - } - else - { - return false; - } - } - - private bool EstablishConnection() - { - if (m_client.Connected) - { - m_log.Warn(LogHeader + ": already connected"); - return false; - } - - try - { - m_client.Connect(m_addr, m_port); - } - catch (Exception e) - { - m_log.WarnFormat("{0} [Start] Could not connect to SceneToScriptEngineSyncServer at {1}:{2}", LogHeader, m_addr, m_port); - m_log.Warn(e.Message); - return false; - } - - m_log.WarnFormat("{0} Connected to SceneToScriptEngineSyncServer at {1}:{2}", LogHeader, m_addr, m_port); - - m_rcvLoop = new Thread(new ThreadStart(ReceiveLoop)); - m_rcvLoop.Name = "ScriptEngineToSceneConnector ReceiveLoop"; - m_log.WarnFormat("{0} Starting {1} thread", LogHeader, m_rcvLoop.Name); - m_rcvLoop.Start(); - return true; - } - - private void StartStateSync() - { - RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.ActorStatus, Convert.ToString((int)ActorStatus.Sync)); - Send(msg); - SendQuarkSubscription(); - Thread.Sleep(100); - DoInitialSync(); - } - - - private void SendQuarkSubscription() - { - List quarkStringList = GetQuarkStringList(); - string quarkString = RegionSyncUtil.QuarkStringListToString(quarkStringList); - - m_log.Debug(LogHeader + ": subscribe to quarks: " + quarkString); - //Send(quarkString); - RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.QuarkSubscription, quarkString); - Send(msg); - } - - public void SetQuarkSubscription(QuarkSubsriptionInfo quarks) - { - m_subscribedQuarks = quarks; - } - - public void RegisterIdle() - { - EstablishConnection(); - RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.ActorStatus, Convert.ToString((int)ActorStatus.Idle)); - Send(msg); - } - - private void DoInitialSync() - { - m_validLocalScene.DeleteAllSceneObjects(); - //m_log.Debug(LogHeader + ": send actor type " + m_actorType); - //Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ActorType, Convert.ToString((int)m_actorType))); - //KittyL??? Do we need to send in RegionName? - - //Send(new RegionSyncMessage(RegionSyncMessage.MsgType.RegionName, m_scene.RegionInfo.RegionName)); - //m_log.WarnFormat("Sending region name: \"{0}\"", m_scene.RegionInfo.RegionName); - - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain)); - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetObjects)); - - // Register for events which will be forwarded to authoritative scene - // m_scene.EventManager.OnNewClient += EventManager_OnNewClient; - //m_scene.EventManager.OnClientClosed += new EventManager.ClientClosed(RemoveLocalClient); - } - - // Disconnect from the RegionSyncServer and close client thread - public void Stop() - { - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ActorStop, "stop")); - // The remote scene will remove the SceneToScriptEngineConnector when we disconnect - m_rcvLoop.Abort(); - ShutdownClient(); - - //stop the migration connections - //ShutdownClient(m_loadMigrationSouceEnd); - if (m_loadMigrationListener != null) - m_loadMigrationListener.Shutdown(); - } - - public void ReportStatus() - { - m_log.WarnFormat("{0} Synchronized to RegionSyncServer at {1}:{2}", LogHeader, m_addr, m_port); - lock (m_syncRoot) - { - //TODO: should be reporting about the information of the objects/scripts - } - } - - private void ShutdownClient() - { - m_log.WarnFormat("{0} Disconnected from RegionSyncServer. Shutting down.", LogHeader); - - //TODO: remove the objects and scripts - //lock (m_syncRoot) - //{ - - //} - - if (m_client != null) - { - // Close the connection - m_client.Client.Close(); - m_client.Close(); - } - - } - - // Listen for messages from a RegionSyncServer - // *** This is the main thread loop for each connected client - private void ReceiveLoop() - { - m_log.WarnFormat("{0} Thread running: {1}", LogHeader, m_rcvLoop.Name); - while (true && m_client.Connected) - { - RegionSyncMessage msg; - // Try to get the message from the network stream - try - { - msg = new RegionSyncMessage(m_client.GetStream()); - //m_log.WarnFormat("{0} Received: {1}", LogHeader, msg.ToString()); - } - // If there is a problem reading from the client, shut 'er down. - catch - { - ShutdownClient(); - return; - } - // Try handling the message - try - { - //lock (m_syncRoot) -- KittyL: why do we need to lock here? We could lock inside HandleMessage if necessary, and lock on different objects for better performance - HandleMessage(msg); - } - catch (Exception e) - { - m_log.WarnFormat("{0} Encountered an exception: {1} (MSGTYPE = {2})", LogHeader, e.Message, msg.ToString()); - } - } - } - - #region SEND - //DSG-TODO: for Scene based DSG, Send() also needs to figure out which Scene to send to, e.g. needs a switching function based on object position - - // Send a message to a single connected RegionSyncServer - private void Send(string msg) - { - byte[] bmsg = System.Text.Encoding.ASCII.GetBytes(msg + System.Environment.NewLine); - Send(bmsg); - } - - private void Send(RegionSyncMessage msg) - { - Send(msg.ToBytes()); - //m_log.WarnFormat("{0} Sent {1}", LogHeader, msg.ToString()); - } - - private void Send(byte[] data) - { - if (m_client.Connected) - { - try - { - m_client.GetStream().Write(data, 0, data.Length); - } - // If there is a problem reading from the client, shut 'er down. - // *** Still need to alert the module that it's no longer connected! - catch - { - ShutdownClient(); - } - } - } - - /// - /// Send requests to update object properties in the remote authoratative Scene. - /// - /// UUID of the object - /// name of the property to be updated - /// parameters of the value of the property - /// - public void SendSetPrimProperties(UUID primID, string pName, object val) - { - OSDMap data = new OSDMap(); - data["UUID"] = OSD.FromUUID(primID); - data["name"] = OSD.FromString(pName); - object[] valParams = (object[])val; - //data["param"] = OSD.FromString(presence.ControllingClient.LastName); - Vector3 pos, vel; - switch (pName) - { - case "object_rez": - //this is to rez an object from the prim's inventory, rather than change the prim's property - if(valParams.Length<5){ - m_log.Warn(LogHeader+": values for object's "+pName+" property should include: inventory, pos, velocity, rotation, param"); - return; - } - string inventory = (string)valParams[0]; - pos = (Vector3)valParams[1]; - vel = (Vector3)valParams[2]; - Quaternion rot = (Quaternion)valParams[3]; - int param = (int)valParams[4]; - data["inventory"]=OSD.FromString(inventory); - data["pos"]=OSD.FromVector3(pos); - data["vel"] = OSD.FromVector3(vel); - data["rot"] = OSD.FromQuaternion(rot); - data["param"] = OSD.FromInteger(param); - break; - case "color": - if(valParams.Length<2){ - m_log.Warn(LogHeader+": values for object's "+pName+" property should include: color-x, color-y, color-z, face"); - return; - } - //double cx = (double)valParams[0]; - //double cy = (double)valParams[1]; - //double cz = (double)valParams[2]; - //Vector3 color = new Vector3((float)cx, (float)cy, (float)cz); - Vector3 color = (Vector3)valParams[0]; - data["color"] = OSD.FromVector3(color); - data["face"] = OSD.FromInteger((int)valParams[1]); - - //m_log.DebugFormat("{0}: to set color {1} on face {2} of prim {3}", LogHeader, color.ToString(), (int)valParams[1], primID); - - break; - case "pos": - if (valParams.Length < 1) - { - m_log.Warn(LogHeader + ": values for object's " + pName + " property should include: pos(vector)"); - return; - } - //double px = (double)valParams[0]; - //double py = (double)valParams[1]; - //double pz = (double)valParams[2]; - //Vector3 pos = new Vector3((float)px, (float)py, (float)pz); - pos = (Vector3)valParams[0]; - data["pos"] = OSD.FromVector3(pos); - - m_log.DebugFormat("{0}: to set pos {1} for prim {2}", LogHeader, pos.ToString(), primID); - break; - default: - // - break; - } - - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.SetObjectProperty, OSDParser.SerializeJsonString(data))); - } - #endregion SEND - - //KittyL: Has to define SendCoarseLocations() here, since it's defined in IRegionSyncClientModule. - // But should not do much as being ScriptEngine, not ClientManager - public void SendCoarseLocations() - { - } - - // Handle an incoming message - // Dan-TODO: This should not be synchronous with the receive! - // Instead, handle messages from an incoming Queue so server doesn't block sending - // - // KittyL: This is the function that ScriptEngine and ClientManager have the most different implementations - private void HandleMessage(RegionSyncMessage msg) - { - //TO FINISH: - - switch (msg.Type) - { - case RegionSyncMessage.MsgType.RegionName: - { - string authSceneName = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); - if (authSceneName != m_authSceneName) - { - //This should not happen. If happens, check the configuration files (OpenSim.ini) on other sides. - m_log.Warn(": !!! Mismatch between configurations of authoritative scene. Script Engine's config: "+m_authSceneName+", Scene's config: "+authSceneName); - return; - } - RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Syncing to region \"{0}\"", m_authSceneName)); - return; - } - case RegionSyncMessage.MsgType.Terrain: - { - //We need to handle terrain differently as we handle objects: we really will set the HeightMap - //of each local scene that is the shadow copy of its auth. scene. - Scene localScene = GetLocalScene(m_authSceneName); - if (localScene == null) - { - m_log.Warn("no local Scene mapped to "+m_authSceneName); - return; - } - localScene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); - RegionSyncMessage.HandleSuccess(LogHeader, msg, "Synchronized terrain"); - return; - } - case RegionSyncMessage.MsgType.NewObject: - case RegionSyncMessage.MsgType.UpdatedObject: - { - HandleAddOrUpdateObjectInLocalScene(msg); - return; - } - case RegionSyncMessage.MsgType.RemovedObject: - { - HandleRemoveObject(msg); - return; - } - case RegionSyncMessage.MsgType.ResetScene: - { - m_validLocalScene.DeleteAllSceneObjects(); - return; - } - case RegionSyncMessage.MsgType.OnRezScript: - { - HandleOnRezScript(msg); - return; - } - case RegionSyncMessage.MsgType.OnScriptReset: - { - HandleOnScriptReset(msg); - return; - } - case RegionSyncMessage.MsgType.OnUpdateScript: - { - HandleOnUpdateScript(msg); - return; - } - case RegionSyncMessage.MsgType.SceneLocation: - { - HandleSceneLocation(msg); - return; - } - case RegionSyncMessage.MsgType.LoadMigrationNotice: - { - HanldeLoadMigrationNotice(msg); - return; - } - case RegionSyncMessage.MsgType.LoadBalanceRejection: - { - HandleLoadBalanceRejection(msg); - return; - } - case RegionSyncMessage.MsgType.LoadBalanceResponse: - { - HandleLoadBalanceResponse(msg); - return; - } - default: - { - RegionSyncMessage.HandleError(LogHeader, msg, String.Format("{0} Unsupported message type: {1}", LogHeader, ((int)msg.Type).ToString())); - return; - } - } - - } - - #region Utility functions - - private OSDMap GetOSDMap(string strdata) - { - OSDMap args = null; - OSD buffer = OSDParser.DeserializeJson(strdata); - if (buffer.Type == OSDType.Map) - { - args = (OSDMap)buffer; - return args; - } - return null; - - } - - HashSet exceptions = new HashSet(); - private OSDMap DeserializeMessage(RegionSyncMessage msg) - { - OSDMap data = null; - try - { - data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)) as OSDMap; - } - catch (Exception e) - { - lock (exceptions) - // If this is a new message, then print the underlying data that caused it - if (!exceptions.Contains(e.Message)) - m_log.Error(LogHeader + " " + Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); - data = null; - } - return data; - } - - - - public string GetServerAddressAndPort() - { - return m_addr.ToString() + ":" + m_port.ToString(); - } - - #endregion Utility functions - - #region Handlers for Scene events - - private void HandleAddOrUpdateObjectInLocalScene(RegionSyncMessage msg) - { - OSDMap data = DeserializeMessage(msg); - /* - if (data["locX"] == null || data["locY"] == null || data["sogXml"] == null) - { - m_log.Warn(LogHeader + ": parameters missing in NewObject/UpdatedObject message, need to have locX, locY, sogXml"); - return; - } - * */ - uint locX = data["locX"].AsUInteger(); - uint locY = data["locY"].AsUInteger(); - string sogxml = data["sogXml"].AsString(); - SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); - - if (sog.IsDeleted) - { - RegionSyncMessage.HandleTrivial(LogHeader, msg, String.Format("Ignoring update on deleted LocalId {0}.", sog.LocalId.ToString())); - return; - } - else - { - //We record the object's location (locX, locY), the coordinates of the left-bottom corner of the scene - sog.LocX = locX; - sog.LocY = locY; - bool added = m_validLocalScene.AddOrUpdateObjectInLocalScene(sog, m_debugWithViewer); - - if (added) - { - //m_log.DebugFormat("[{0} Object \"{1}\" ({1}) ({2}) added.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()); - //rez script - sog.CreateScriptInstances(0, false, m_validLocalScene.DefaultScriptEngine, 0); - sog.ResumeScripts(); - } - else - { - //m_log.DebugFormat("[{0} Object \"{1}\" ({1}) ({2}) updated.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()); - } - } - } - - private void HandleRemoveObject(RegionSyncMessage msg) - { - // Get the data from message and error check - OSDMap data = DeserializeMessage(msg); - if (data == null) - { - RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data."); - return; - } - - if (!data.ContainsKey("UUID")) - { - m_log.Warn(LogHeader + ": parameters missing in RemoveObject message from Scene, need to have object UUID"); - return; - } - - // Get the parameters from data - //ulong regionHandle = data["regionHandle"].AsULong(); - // UUID objID = data["sogUUID"].AsUUID(); - UUID primID = data["UUID"].AsUUID(); - - // Find the object in the scene - SceneObjectGroup sog = m_validLocalScene.SceneGraph.GetGroupByPrim(primID); - if (sog == null) - { - //RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("localID {0} not found.", localID.ToString())); - return; - } - - // Delete the object from the scene - m_validLocalScene.DeleteSceneObject(sog, false); - RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("object {0} deleted.", primID.ToString())); - } - - private void HandleOnRezScript(RegionSyncMessage msg) - { - - OSDMap data = DeserializeMessage(msg); - /* - if (!data.ContainsKey("localID") || !data.ContainsKey("itemID") || !data.ContainsKey("script") || !data.ContainsKey("startParam") - || !data.ContainsKey("postOnRez") || !data.ContainsKey("engine") || !data.ContainsKey("stateSource")) - { - if (!data.ContainsKey("localID")) m_log.Debug("missing localID"); - if (!data.ContainsKey("itemID")) m_log.Debug("missing itemID"); - if (!data.ContainsKey("script")) m_log.Debug("missing script"); - if (!data.ContainsKey("startParam")) m_log.Debug("missing startParam"); - if (!data.ContainsKey("postOnRez")) m_log.Debug("missing postOnRez"); - if (!data.ContainsKey("engine")) m_log.Debug("missing engine"); - if (!data.ContainsKey("stateSource")) m_log.Debug("missing stateSource"); - - m_log.Warn(LogHeader+": parameters missing in OnRezScript message from Scene, need to have localID, itemID, script,startParam, postOnRez, engine, and stateSource"); - return; - } - * */ - - uint localID = data["localID"].AsUInteger(); - UUID itemID = data["itemID"].AsUUID(); - string script = data["script"].AsString(); - int startParam = data["startParam"].AsInteger(); - bool postOnRez = data["postOnRez"].AsBoolean(); - string engine = data["engine"].AsString(); - int stateSource = data["stateSource"].AsInteger(); - - m_log.Debug(LogHeader + ": TriggerRezScript"); - //Trigger OnRezScrip to start script engine's execution - m_validLocalScene.EventManager.TriggerRezScript(localID, itemID, script, startParam, postOnRez, engine, stateSource); - } - - private void HandleOnScriptReset(RegionSyncMessage msg) - { - OSDMap data = DeserializeMessage(msg); - /* - if (data["localID"] == null || data["itemID"] == null) - { - m_log.Warn(LogHeader + ": parameters missing in OnScriptReset message from Scene, need to have localID, itemID"); - return; - } - * */ - - uint localID = data["localID"].AsUInteger(); - UUID itemID = data["itemID"].AsUUID(); - m_log.Debug(LogHeader + ": TriggerScriptReset"); - //Trigger OnScriptReset to start script engine's execution - m_validLocalScene.EventManager.TriggerScriptReset(localID, itemID); - } - - private void HandleOnUpdateScript(RegionSyncMessage msg) - { - OSDMap data = DeserializeMessage(msg); - /* - if (!data.ContainsKey("agentID") == null || !data.ContainsKey("itemID") == null || !data.ContainsKey("primID") == null || !data.ContainsKey("running") == null) - { - m_log.Warn(LogHeader + ": parameters missing in OnUpdateScript message from Scene, need to have agentID, itemID, primID, isRunning, and assetID"); - return; - } - * */ - UUID agentID = data["agentID"].AsUUID(); - UUID itemID = data["itemID"].AsUUID(); - UUID primID = data["primID"].AsUUID(); - bool isScriptRunning = data["running"].AsBoolean(); - UUID newAssetID = data["assetID"].AsUUID(); - m_log.Debug(LogHeader + ": HandleOnUpdateScript"); - //m_scene.EventManager.TriggerUpdateTaskInventoryScriptAsset(agentID, itemID, primID, isScriptRunning); - ArrayList errors = m_validLocalScene.OnUpdateScript(agentID, itemID, primID, isScriptRunning, newAssetID); - - //now the script is re-rez'ed, return complication errors if there are - - } - - private void HandleSceneLocation(RegionSyncMessage msg) - { - OSDMap data = DeserializeMessage(msg); - /* - if (!data.ContainsKey("locX")|| !data.ContainsKey("locY")) - { - m_log.Warn(LogHeader + ": parameters missing in SceneLocation message from Scene, need to have locX, locY"); - return; - } - * */ - uint locX = data["locX"].AsUInteger(); - uint locY = data["locY"].AsUInteger(); - - ScriptEngineToSceneConnectorModule connectorModule = GetSEToSceneConnectorMasterModule(); - connectorModule.RecordSceneLocation(m_addrString, m_port, locX, locY); - } - - private void HandleLoadBalanceRejection(RegionSyncMessage msg) - { - string reason = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); - m_log.Debug(LogHeader + ": Load balance request rejected: " + reason); - } - - private void HandleLoadBalanceResponse(RegionSyncMessage msg) - { - //Start a seperate thread to handle the load migration process - - Thread migrationThread = new Thread(new ParameterizedThreadStart(TriggerLoadMigrationProcess)); - migrationThread.Name = "TriggerLoadMigrationProcess"; - migrationThread.Start((object)msg); - } - - #endregion Handlers for events/updates from Scene - - #region Load migration functions: source side for migrating load away - - - public void SendLoadBalanceRequest() - { - //Send a request to Scene, which, is also a load balancing server - RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.LoadBalanceRequest); - Send(msg); - } - - //Migration process handler. For now, we do binary space partitioning to balance load. - private void TriggerLoadMigrationProcess(object arg) - { - if (m_loadMigrationSouceEnd!=null) - { - m_log.Warn(LogHeader + ": already in load balancing process"); - return; - } - - RegionSyncMessage msg = (RegionSyncMessage)arg; - OSDMap data = DeserializeMessage(msg); - if (!data.ContainsKey("ip") || !data.ContainsKey("port")) - { - m_log.Warn(LogHeader + ": parameters missing in SceneLocation message from Scene, need to have ip, port"); - return; - } - - string idleSEAddr = data["ip"].AsString(); - int idleSEPort = data["port"].AsInteger(); - m_log.Debug(LogHeader + " receive LB response: idle SE listening at " + idleSEAddr + ":" + idleSEPort); - - Thread.Sleep(500); - //connect to the idle script engine's load migration listening port - TcpClient loadMigrationSrc = new TcpClient(); - try - { - m_log.Debug(LogHeader + ", connecting to " + idleSEAddr + "," + idleSEPort); - loadMigrationSrc.Connect(idleSEAddr, idleSEPort); - } - catch (Exception e) - { - m_log.WarnFormat("{0} [Start] In load migration. Could not connect to {1}:{2}", LogHeader, idleSEAddr, idleSEPort); - m_log.Warn(e.Message); - return; - } - m_log.WarnFormat("{0} Connected to Load migration destination at {1}:{2}", LogHeader, idleSEAddr, idleSEPort); - - //Get the quarks that will be migrated out - QuarkSubsriptionInfo migratingQuarks = PartitionLoad(m_subscribedQuarks); - - //Create an EndPoint to manage the migration process - m_loadMigrationSouceEnd = new LoadMigrationEndPoint(loadMigrationSrc, migratingQuarks, this, m_log); - - OSDMap outData = GetMigrationSpaceDescription(migratingQuarks); - msg = new RegionSyncMessage(RegionSyncMessage.MsgType.MigrationSpace, OSDParser.SerializeJsonString(outData)); - m_loadMigrationSouceEnd.Send(msg); - - } - - - //For now, we simply implement a simple binary space partitioning. - //Ideally, a k-d tree structure should be used and we can divide the quarks accordingly - /// - /// Partition the suscribed quarks, and return the quarks that should be migrated away. - /// - /// - /// - private QuarkSubsriptionInfo PartitionLoad(QuarkSubsriptionInfo quarkSubscription) - { - Dictionary partitionedPlains = RegionSyncUtil.BinarySpaceParition(quarkSubscription.MinX, quarkSubscription.MinY, quarkSubscription.MaxX, quarkSubscription.MaxY); - - int[] upperPlain = partitionedPlains["upper"]; - string partitionedSpace = RegionSyncUtil.GetSpaceStringRepresentationByCorners(upperPlain[0], upperPlain[1], upperPlain[2], upperPlain[3]); - QuarkSubsriptionInfo partitionedQuarks = new QuarkSubsriptionInfo(partitionedSpace); - - return partitionedQuarks; - } - - //For now, since all the quarks form a rectangle shape, we simple use the corners to represent the space. - /// - /// Return a OSDMap that describes the set of quarks that are being migrated. - /// - /// - /// - private OSDMap GetMigrationSpaceDescription(QuarkSubsriptionInfo quarks) - { - - OSDMap outData = new OSDMap(5); - - //send the parameters as uint, to avoid seemingly some bugs in SerializeJsonString that somehow does not serialize integer '0' correctly - outData["minX"] = OSD.FromUInteger((uint)quarks.MinX); - outData["minY"] = OSD.FromUInteger((uint)quarks.MinY); - outData["maxX"] = OSD.FromUInteger((uint)quarks.MaxX); - outData["maxY"] = OSD.FromUInteger((uint)quarks.MaxY); - - outData["regionName"] = OSD.FromString(m_authSceneName); - - return outData; - } - - public void RemoveQuarks(QuarkSubsriptionInfo removedQuarks) - { - //Remove the given quarks - m_subscribedQuarks.RemoveQuarks(removedQuarks); - - //Inform Scene with the updated quark subscription - SendQuarkSubscription(); - } - - #endregion Load migration functions: source side for migrating load away - - #region Load migration functions: load receiving side - - private void HanldeLoadMigrationNotice(RegionSyncMessage msg) - { - m_log.Debug(LogHeader + " received LoadMigrationNotice"); - - if (m_loadMigrationListener == null) - { - - //set up a listening thread for receiving load - string addr = m_sysConfig.GetString("LoadBalancingListenerAddr", "127.0.0.1"); - int port = m_sysConfig.GetInt("LoadBalancingListenerAddrPort", 14000); - m_loadMigrationListener = new LoadMigrationListener(addr, port, this, m_log); - m_loadMigrationListener.Start(); - - m_log.Debug("Scene's LB connector portal: local - " - + ((IPEndPoint)m_client.Client.LocalEndPoint).Address.ToString() + ":" + ((IPEndPoint)m_client.Client.LocalEndPoint).Port - + "; remote -" - + ((IPEndPoint)m_client.Client.RemoteEndPoint).Address.ToString() + ":"+((IPEndPoint)m_client.Client.RemoteEndPoint).Port); - //reply back with the ip:port - OSDMap data = new OSDMap(2); - data["ip"] = OSD.FromString(addr); - data["port"] = OSD.FromInteger(port); - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.LoadMigrationListenerInitiated, OSDParser.SerializeJsonString(data))); - } - else - { - //otherwise, this script engine is already expecting incoming load, should reject the notice - //TO FINISH - } - - } - - public void LoadObjectsToValidLocalScene(string regionName) - { - - m_validLocalScene.LoadPrimsFromStorageInGivenSpace(regionName, m_subscribedQuarks.MinX, m_subscribedQuarks.MinY, m_subscribedQuarks.MaxX, m_subscribedQuarks.MaxY); - - //set the LocX,LocY information of each object's copy, so that later we can figure out which SEtoSceneConnector to forwards setproperty request - OpenSim.Services.Interfaces.GridRegion regionInfo = m_validLocalScene.GridService.GetRegionByName(UUID.Zero, regionName); - EntityBase[] entities = m_validLocalScene.GetEntities(); - foreach (EntityBase group in entities) - { - if (group is SceneObjectGroup) - { - SceneObjectGroup sog = (SceneObjectGroup)group; - //seems the returned regionInfo.RegionLocX is the absolute coordinates. need to convert it to the region loc values (e.g. 1000,1000) - sog.LocX = (uint)regionInfo.RegionLocX / Constants.RegionSize; - sog.LocY = (uint)regionInfo.RegionLocY / Constants.RegionSize; - } - } - } - - - public void StartSyncAfterLoadMigration() - { - //First, register new status with Scene (that it is sync'ing now, not idle anymore) - RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.ActorStatus, Convert.ToString((int)ActorStatus.Sync)); - Send(msg); - - //Second, modify the local record, from an idle connector to a busy sync'ing one - ScriptEngineToSceneConnectorModule connectorModule = GetSEToSceneConnectorMasterModule(); - connectorModule.RecordSyncStartAfterLoadMigration(this); - - //Next, send the quark list to Scene, and start syncing (download terrian, start script instances, etc) - SendQuarkSubscription(); - Thread.Sleep(100); - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain)); - Thread.Sleep(100); - - m_log.Debug(LogHeader + ": next start script instances"); - //m_validLocalScene.CreateScriptInstances(); - - EntityBase[] entities = m_validLocalScene.GetEntities(); - foreach (EntityBase group in entities) - { - if (group is SceneObjectGroup) - { - ((SceneObjectGroup)group).RootPart.ParentGroup.CreateScriptInstances(0, false, m_validLocalScene.DefaultScriptEngine, 1); - ((SceneObjectGroup)group).ResumeScripts(); - } - } - } - -#endregion Load migration functions: load receiving side - } - - - public class LoadMigrationListener - { - // The listener and the thread which listens for connections from overloaded script engines - private TcpListener m_listener; - private Thread m_listenerThread; - //private TcpClient m_tcpClient; - private LoadMigrationEndPoint m_loadMigrationReceiver = null; - private IPAddress m_addr; - private int m_port; - private ILog m_log; - private string LogHeader = "LoadMigrationListener"; - private ScriptEngineToSceneConnector m_seToSceneConnector; - - public LoadMigrationListener(string ip, int port, ScriptEngineToSceneConnector sceneConnector, ILog log) - { - m_addr = IPAddress.Parse(ip); - m_port = port; - m_log = log; - m_seToSceneConnector = sceneConnector; - - m_log.Debug(LogHeader + ": to create a new LoadMigrationListener on " + m_addr + "," + m_port); - } - - // Start the server - public void Start() - { - m_listenerThread = new Thread(new ThreadStart(Listen)); - m_listenerThread.Name = "LoadMigrationListener Listener"; - m_log.WarnFormat(LogHeader + ": Starting {0} thread", m_listenerThread.Name); - m_listenerThread.Start(); - //m_log.Warn("[REGION SYNC SERVER] Started"); - } - - private void Listen() - { - m_listener = new TcpListener(m_addr, m_port); - - try - { - // Start listening for clients - m_listener.Start(); - while (true) - { - // *** Move/Add TRY/CATCH to here, but we don't want to spin loop on the same error - m_log.WarnFormat(LogHeader + ": Listening for new connections on ip {0} port {1}...", m_addr.ToString(), m_port.ToString()); - TcpClient tcpClient = m_listener.AcceptTcpClient(); - - IPAddress addr = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address; - int port = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port; - - m_log.Debug(LogHeader + ": accepted new client - " + addr.ToString() + ", " + port); - - m_loadMigrationReceiver = new LoadMigrationEndPoint(tcpClient, m_seToSceneConnector, m_log); - } - } - catch (SocketException e) - { - m_log.Warn(LogHeader + " [Listen] SocketException"); - } - } - - public void Shutdown() - { - m_listener.Stop(); - m_listenerThread.Abort(); - if(m_loadMigrationReceiver!=null) - m_loadMigrationReceiver.Shutdown(); - } - } - - //The tcp EndPoint of either end of load migration (source or receiving side). - public class LoadMigrationEndPoint - { - private Thread m_receive_loop; - private TcpClient m_tcpclient; - private ILog m_log; - private ScriptEngineToSceneConnector m_seToSceneConnector; - //private int m_minX; - //private int m_minY; - //private int m_maxX; - //private int m_maxY; - //private int QuarkInfo.SizeX; - //private int QuarkInfo.SizeY; - private QuarkSubsriptionInfo m_quarks; - private bool m_inScriptStateSync = false; - private Scene m_validLocalScene = null; - - public QuarkSubsriptionInfo QuarksInfo - { - get { return m_quarks; } - set { m_quarks = value; } - } - - public LoadMigrationEndPoint(TcpClient tcpClient, QuarkSubsriptionInfo quarks, ScriptEngineToSceneConnector sceneConnector, ILog log) - { - m_log = log; - m_tcpclient = tcpClient; - m_seToSceneConnector = sceneConnector; - m_quarks = quarks; - //QuarkInfo.SizeX = quarks.QuarkSizeX; - //QuarkInfo.SizeY = quarks.QuarkSizeY; - - m_receive_loop = new Thread(new ThreadStart(delegate() { ReceiveLoop(); })); - m_receive_loop.Name = "LoadMigrationReceiver"; - //m_log.WarnFormat("{0} Started thread: {1}", LogHeader, m_receive_loop.Name); - m_receive_loop.Start(); - - m_validLocalScene = sceneConnector.GetValidLocalScene(); - } - - public LoadMigrationEndPoint(TcpClient tcpClient, ScriptEngineToSceneConnector sceneConnector, ILog log) - { - m_log = log; - m_tcpclient = tcpClient; - m_seToSceneConnector = sceneConnector; - m_validLocalScene = sceneConnector.GetValidLocalScene(); - //QuarkInfo.SizeX = quarkSizeX; - //QuarkInfo.SizeY = quarkSizeY; - - m_receive_loop = new Thread(new ThreadStart(delegate() { ReceiveLoop(); })); - m_receive_loop.Name = "LoadMigrationReceiver"; - //m_log.WarnFormat("{0} Started thread: {1}", LogHeader, m_receive_loop.Name); - m_receive_loop.Start(); - } - - public void SetQuarksInfo (QuarkSubsriptionInfo quarks){ - m_quarks = quarks; - } - - private void ReceiveLoop() - { - try - { - while (true) - { - RegionSyncMessage msg = new RegionSyncMessage(m_tcpclient.GetStream()); - HandleMessage(msg); - } - } - catch (Exception e) - { - //m_log.WarnFormat("LoadMigrationEndPoint: has disconnected: {1}", e.Message); - m_log.Warn("LoadMigrationEndPoint: has disconnected:"); - } - Shutdown(); - } - - public void Shutdown() - { - // Abort ReceiveLoop Thread, close Socket and TcpClient - m_receive_loop.Abort(); - m_tcpclient.Client.Close(); - m_tcpclient.Close(); - } - - private void HandleMessage(RegionSyncMessage msg) - { - switch (msg.Type) - { - case RegionSyncMessage.MsgType.MigrationSpace: - HandleMigrationSpaceNotice(msg); - break; - case RegionSyncMessage.MsgType.ScriptStateSyncRequest: - HandleScriptStateSyncRequest(msg); - break; - case RegionSyncMessage.MsgType.ScriptStateSyncStart: - m_log.Debug("LoadMigration receiving end: received ScriptStateSyncStart"); - m_inScriptStateSync = true; - break; - case RegionSyncMessage.MsgType.ScriptStateSyncPerObject: - HandleScriptStateSyncPerObject(msg); - break; - case RegionSyncMessage.MsgType.ScriptStateSyncEnd: - HandleScriptStateSyncEnd(msg); - break; - - default: - break; - } - } - - private void HandleMigrationSpaceNotice(RegionSyncMessage msg) - { - //get the space description, - OSDMap data = DeserializeMessage(msg); - if (!data.ContainsKey("minX") || !data.ContainsKey("minY") || !data.ContainsKey("maxX") || !data.ContainsKey("maxY") || !data.ContainsKey("regionName")) - { - m_log.Warn("Load migration receiving end : parameters missing in MigratingSpace message from migration source, need to have (minX,minY),(maxX,maxY),regionName"); - return; - } - int minX = (int) data["minX"].AsUInteger(); - int minY = (int) data["minY"].AsUInteger(); - int maxX = (int) data["maxX"].AsUInteger(); - int maxY = (int) data["maxY"].AsUInteger(); - string regionName = data["regionName"].AsString(); - m_log.Debug("Load migration receiving end: space migrating in -- (" + minX + "," + minY + ")" + ", (" + maxX + "," + maxY + ")"); - - //set the quark subscription information - m_quarks = new QuarkSubsriptionInfo( minX, minY, maxX, maxY); - m_seToSceneConnector.SetQuarkSubscription(m_quarks); - - //load the objects into local scene - //TO FINISH: only load the objects with scripts, but not creating script instances yet - m_seToSceneConnector.LoadObjectsToValidLocalScene(regionName); - - //request script state from the migration source - //RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.ScriptStateSyncRequest, OSDParser.SerializeJsonString(data)); - RegionSyncMessage outMsg = new RegionSyncMessage(RegionSyncMessage.MsgType.ScriptStateSyncRequest); - Send(outMsg); - } - - //Upon receiving a ScriptStateSyncRequest from the receiving side, the source needs to suspend script execution, save - //the script's state, and migrate the state to the receiving end. - private void HandleScriptStateSyncRequest(RegionSyncMessage msg) - { - EntityBase[] entities = m_validLocalScene.GetEntities(); - List sogInMigrationSpace = new List(); - - //Inform the receiving end the script state synchronization now starts. - m_inScriptStateSync = true; - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ScriptStateSyncStart)); - - foreach (EntityBase e in entities) - { - if (e is SceneObjectGroup) - { - SceneObjectGroup sog = (SceneObjectGroup)e; - - //m_log.Debug("check object " + sog.UUID + ", at position " + sog.AbsolutePosition.ToString()); - - if (m_quarks.IsInSpace(sog.AbsolutePosition)) - { - //m_log.Debug("object " + sog.UUID + " in space of " + m_quarks.StringRepresentation()); - - sogInMigrationSpace.Add(sog); - sog.SuspendScripts(); - string scriptStateXml = sog.GetStateSnapshot(); - OSDMap data = new OSDMap(2); - data["UUID"] = OSD.FromUUID(sog.UUID); - data["state"] = OSD.FromString(scriptStateXml); - RegionSyncMessage stateMsg = new RegionSyncMessage(RegionSyncMessage.MsgType.ScriptStateSyncPerObject, OSDParser.SerializeJsonString(data)); - Send(stateMsg); - } - } - } - - //Inform the receiving end the script state synchronization now ends. - Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ScriptStateSyncEnd)); - m_inScriptStateSync = false; - - //Next, remove the space, objects/scripts in the space, - foreach (SceneObjectGroup sog in sogInMigrationSpace) - { - m_validLocalScene.DeleteSceneObject(sog, true); - } - //udpate the quark subscriptions, and informs Scene about the quark subscription changes - m_seToSceneConnector.RemoveQuarks(m_quarks); - } - - private void HandleScriptStateSyncPerObject(RegionSyncMessage msg) - { - OSDMap data = DeserializeMessage(msg); - if (!data.ContainsKey("UUID") || !data.ContainsKey("state")) - { - m_log.Warn("LoadMigrationReceiver: ScriptStateSyncPerObject message missing parameters, need object's UUID and its script's state (string)"); - return; - } - - UUID objID = data["UUID"].AsUUID(); - string stateXml = data["state"].AsString(); - - SceneObjectGroup sog = m_validLocalScene.GetSceneObjectPart(objID).ParentGroup; - sog.SetState(stateXml, m_validLocalScene); - - //m_log.Debug("LoadMigration receiving end: set state for object " + objID + ", script state: " + stateXml); - } - - private void HandleScriptStateSyncEnd(RegionSyncMessage msg) - { - m_log.Debug("LoadMigration receiving end: received ScriptStateSyncEnd"); - m_inScriptStateSync = false; - - //Start sync'ing state with Scene: send quark subscription, get terrian, and start script execution - m_seToSceneConnector.StartSyncAfterLoadMigration(); - } - - private OSDMap DeserializeMessage(RegionSyncMessage msg) - { - OSDMap data = null; - try - { - data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)) as OSDMap; - } - catch (Exception e) - { - m_log.Error("LoadMigrationEndPoint " + Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); - data = null; - } - return data; - } - - - public void Send(RegionSyncMessage msg) - { - byte[] data = msg.ToBytes(); - if (m_tcpclient.Connected) - { - try - { - m_tcpclient.GetStream().Write(data, 0, data.Length); - } - // If there is a problem reading from the client, shut 'er down. - // *** Still need to alert the module that it's no longer connected! - catch - { - Shutdown(); - } - } - } - - } -} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/ScriptEngineToSceneConnectorModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/ScriptEngineToSceneConnectorModule.cs deleted file mode 100644 index 5894d5a140..0000000000 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/ScriptEngineToSceneConnectorModule.cs +++ /dev/null @@ -1,840 +0,0 @@ -/* Copyright 2011 (c) Intel Corporation - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The name of the copyright holder may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using Nini.Config; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Client; -using OpenSim.Region.CoreModules.Framework.InterfaceCommander; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using log4net; -using System.Net; -using System.Net.Sockets; - -namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule -{ - //The information of the authoratative copy of a scene - public class AuthSceneInfo - { - public string Name; - public string Addr; - public int Port; - public int LocX=-1; - public int LocY=-1; - - public AuthSceneInfo(string name, string addr, int port) - { - Name = name; - Addr = addr; - Port = port; - } - - public AuthSceneInfo(string name, string addr, int port, int locX, int locY) - { - Name = name; - Addr = addr; - Port = port; - LocX = locX; - LocY = locY; - } - } - - //The connector that connects the local Scene (cache) and remote authoratative Scene - public class ScriptEngineToSceneConnectorModule : IRegionModule, IScriptEngineToSceneConnectorModule, ICommandableModule - { - #region IRegionModule Members - - public void Initialise(Scene scene, IConfigSource config) - { - m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - m_active = false; //set to false unless this is the valid local scene - - //Read in configuration - IConfig syncConfig = config.Configs["RegionSyncModule"]; - - if (syncConfig == null) - { - m_log.Warn("[REGION SYNC SCRIPT ENGINE MODULE] No RegionSyncModule config section found. Shutting down."); - return; - } - else if (!syncConfig.GetBoolean("Enabled", false)) - { - m_log.Warn("[REGION SYNC SCRIPT ENGINE MODULE] RegionSyncModule is not enabled. Shutting down."); - return; - } - else - { - scene.RegionSyncEnabled = true; - m_regionSyncMode = syncConfig.GetString("Mode", ""); - if (m_regionSyncMode == null || m_regionSyncMode.ToLower() != "script_engine") - { - m_log.WarnFormat("[REGION SYNC SCRIPT ENGINE MODULE] RegionSyncModule is not in script_engine mode. Shutting down."); - return; - } - } - /* - if (syncConfig != null && syncConfig.GetString("Enabled", "").ToLower() == "true") - { - scene.RegionSyncEnabled = true; - } - else - { - scene.RegionSyncEnabled = false; - } - - m_regionSyncMode = syncConfig.GetString("Mode", ""); - if (syncConfig == null || m_regionSyncMode == null || m_regionSyncMode.ToLower() != "script_engine") - { - m_log.Warn("[REGION SYNC SCRIPT ENGINE MODULE] Not in script_engine mode. Shutting down."); - return; - } - * */ - - //get the name of the valid region for script engine, i.e., that region that will holds all objects and scripts - //if not matching m_scene's name, simply return - string validLocalScene = syncConfig.GetString("ValidScriptEngineScene", ""); - if (!validLocalScene.Equals(scene.RegionInfo.RegionName)) - { - m_log.Warn("Not the valid local scene, shutting down"); - return; - } - m_active = true; - m_validLocalScene = validLocalScene; - - m_log.Debug("Init SEToSceneConnectorModule, for local scene " + scene.RegionInfo.RegionName); - - //get the number of regions this script engine subscribes - m_sceneNum = syncConfig.GetInt("SceneNumber", 1); - - //get the mapping of local scenes to auth. scenes - List authScenes = new List(); - for (int i = 0; i < m_sceneNum; i++) - { - string localScene = "LocalScene" + i; - string localSceneName = syncConfig.GetString(localScene, ""); - string masterScene = localScene + "Master"; - string masterSceneName = syncConfig.GetString(masterScene, ""); - - if (localSceneName.Equals("") || masterSceneName.Equals("")) - { - m_log.Warn(localScene + " or " + masterScene+ " has not been assigned a value in configuration. Shutting down."); - return; - } - - //m_localToAuthSceneMapping.Add(localSceneName, masterSceneName); - RecordLocalAuthSceneMappings(localSceneName, masterSceneName); - authScenes.Add(masterSceneName); - m_localScenesByName.Add(localSceneName, null); - } - - int defaultPort = 13000; - //get the addr:port info of the authoritative scenes - for (int i = 0; i < m_sceneNum; i++) - { - string authSceneName = authScenes[i]; - //string serverAddr = authSceneName + "_ServerIPAddress"; - //string serverPort = authSceneName + "_ServerPort"; - string serverAddr = authSceneName + "_SceneToSESyncServerIP"; - string addr = syncConfig.GetString(serverAddr, "127.0.0.1"); - string serverPort = authSceneName + "_SceneToSESyncServerPort"; - int port = syncConfig.GetInt(serverPort, defaultPort); - defaultPort++; - - AuthSceneInfo authSceneInfo = new AuthSceneInfo(authSceneName, addr, port); - m_authScenesInfoByName.Add(authSceneName, authSceneInfo); - } - - m_scene = scene; - m_scene.RegisterModuleInterface(this); - m_syncConfig = syncConfig; - m_debugWithViewer = syncConfig.GetBoolean("ScriptEngineDebugWithViewer", false); - - //read in the quark size information - //QuarkInfo.SizeX = syncConfig.GetInt("QuarkSizeX", (int)Constants.RegionSize); - //QuarkInfo.SizeY = syncConfig.GetInt("QuarkSizeY", (int)Constants.RegionSize); - QuarkInfo.SizeX = syncConfig.GetInt("QuarkSizeX", (int)Constants.RegionSize); - QuarkInfo.SizeY = syncConfig.GetInt("QuarkSizeY", (int)Constants.RegionSize); - - //m_quarkListString = syncConfig.GetString("InitQuarkSet", ""); //if not specified, dost not subscribe to any quark - //if (m_quarkListString.Equals("all")) - //{ - // m_quarkListString = RegionSyncUtil.QuarkStringListToString(RegionSyncUtil.GetAllQuarkStringInScene(QuarkInfo.SizeX, QuarkInfo.SizeY)); - //} - m_subscriptionSpaceString = syncConfig.GetString("InitSubscriptionSpace", "0_0,256_256"); - - - // Setup the command line interface - m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; - InstallInterfaces(); - - m_log.Warn("[REGION SYNC SCRIPT ENGINE MODULE] Initialised"); - } - - public void PostInitialise() - { - if (!m_active) - return; - - //m_log.Warn("[REGION SYNC CLIENT MODULE] Post-Initialised"); - m_scene.EventManager.OnPopulateLocalSceneList += OnPopulateLocalSceneList; - } - - public void Close() - { - if (m_active) - { - m_scene.EventManager.OnPopulateLocalSceneList -= OnPopulateLocalSceneList; - } - m_scene = null; - m_active = false; - } - - public string Name - { - get { return "RegionSyncScriptEngineModule"; } - } - - public bool IsSharedModule - { - get { return false; } - } - #endregion - - #region ICommandableModule Members - private readonly Commander m_commander = new Commander("sync"); - public ICommander CommandInterface - { - get { return m_commander; } - } - #endregion - - #region IScriptEngineToSceneConnectorModule members - - - public bool Active - { - get { return m_active; } - } - - public bool Synced - { - get - { - lock(m_client_lock) - { - //return (m_scriptEngineToSceneConnector != null); - return (m_SEToSceneConnectors.Count > 0); - } - } - } - - - #endregion - - #region ScriptEngineToSceneConnectorModule members and functions - - private bool m_active = false; - private string m_serveraddr; - private int m_serverport; - private Scene m_scene; - private ILog m_log; - private Object m_client_lock = new Object(); - //private ScriptEngineToSceneConnector m_scriptEngineToSceneConnector = null; - private IConfig m_syncConfig = null; - private bool m_debugWithViewer = false; - private string m_regionSyncMode = ""; - - //Variables relavant for multi-scene subscription. - private int m_sceneNum = 0; - private string m_validLocalScene = ""; - private Dictionary m_localToAuthSceneMapping = new Dictionary(); //1-1 mapping from local shadow scene to authoratative scene - private Dictionary m_authToLocalSceneMapping = new Dictionary(); //1-1 mapping from authoratative scene to local shadow scene - private Dictionary m_localScenesByName = new Dictionary(); //name and references to local scenes - private Dictionary m_authScenesInfoByName = new Dictionary(); //info of each auth. scene's connector port, stored by each scene's name - private Dictionary m_SEToSceneConnectors = new Dictionary(); //connector for each auth. scene - private Dictionary m_authScenesInfoByLoc = new Dictionary(); //IP and port number of each auth. scene's connector port - private string LogHeader = "[ScriptEngineToSceneConnectorModule]"; - private ScriptEngineToSceneConnector m_idleSEToSceneConnector = null; - - //quark information - //private int QuarkInfo.SizeX; - //private int QuarkInfo.SizeY; - //private string m_quarkListString; - private string m_subscriptionSpaceString; - - public IConfig SyncConfig - { - get { return m_syncConfig; } - } - - public bool DebugWithViewer - { - get { return m_debugWithViewer; } - } - - //Record the locX and locY of one auth. scene (identified by addr:port) this ScriptEngine connects to - public void RecordSceneLocation(string addr, int port, uint locX, uint locY) - { - string loc = SceneLocToString(locX, locY); - if (m_authScenesInfoByLoc.ContainsKey(loc)) - { - m_log.Warn(": have already registered info for Scene at " + loc); - m_authScenesInfoByLoc.Remove(loc); - } - - foreach (KeyValuePair valPair in m_authScenesInfoByName) - { - AuthSceneInfo authSceneInfo = valPair.Value; - if (authSceneInfo.Addr == addr && authSceneInfo.Port == port) - { - authSceneInfo.LocX = (int)locX; - authSceneInfo.LocY = (int)locY; - m_authScenesInfoByLoc.Add(loc, authSceneInfo); - break; - } - } - } - - /// - /// Set the property of a prim located in the given scene (identified by locX, locY) - /// - /// - /// - /// - /// - /// - public void SendSetPrimProperties(uint locX, uint locY, UUID primID, string pName, object pValue) - { - if (!Active || !Synced) - return; - - ScriptEngineToSceneConnector connector = GetSEToSceneConnector(locX, locY); - connector.SendSetPrimProperties(primID, pName, pValue); - } - - public Scene GetLocalScene(string authSceneName) - { - if (!m_authToLocalSceneMapping.ContainsKey(authSceneName)) - { - m_log.Warn(LogHeader + ": no authoritative scene with name "+authSceneName+" recorded"); - return null; - } - string localSceneName = m_authToLocalSceneMapping[authSceneName]; - if (m_localScenesByName.ContainsKey(localSceneName)) - { - return m_localScenesByName[localSceneName]; - } - else - return null; - } - - private string SceneLocToString(uint locX, uint locY) - { - string loc = locX + "-" + locY; - return loc; - } - - //Get the right instance of ScriptEngineToSceneConnector, given the location of the authoritative scene - private ScriptEngineToSceneConnector GetSEToSceneConnector(uint locX, uint locY) - { - string loc = SceneLocToString(locX, locY); - if (!m_authScenesInfoByLoc.ContainsKey(loc)) - return null; - string authSceneName = m_authScenesInfoByLoc[loc].Name; - if (!m_SEToSceneConnectors.ContainsKey(authSceneName)) - { - return null; - } - return m_SEToSceneConnectors[authSceneName]; - } - - - private void RecordLocalAuthSceneMappings(string localSceneName, string authSceneName) - { - if (m_localToAuthSceneMapping.ContainsKey(localSceneName)) - { - m_log.Warn(LogHeader + ": already registered " + localSceneName+", authScene was recorded as "+ m_localToAuthSceneMapping[localSceneName]); - } - else - { - m_localToAuthSceneMapping.Add(localSceneName, authSceneName); - } - if (m_authToLocalSceneMapping.ContainsKey(authSceneName)) - { - m_log.Warn(LogHeader + ": already registered " + authSceneName + ", authScene was recorded as " + m_authToLocalSceneMapping[authSceneName]); - } - else - { - m_authToLocalSceneMapping.Add(authSceneName, localSceneName); - } - } - - //Get the name of the authoritative scene the given local scene maps to. Return null if not found. - private string GetAuthSceneName(string localSceneName) - { - if (m_localToAuthSceneMapping.ContainsKey(localSceneName)) - { - m_log.Warn(LogHeader + ": " + localSceneName + " not registered in m_localToAuthSceneMapping"); - return null; - } - return m_localToAuthSceneMapping[localSceneName]; - } - - //get the name of the local scene the given authoritative scene maps to. Return null if not found. - private string GetLocalSceneName(string authSceneName) - { - if (!m_authToLocalSceneMapping.ContainsKey(authSceneName)) - { - m_log.Warn(LogHeader + ": " + authSceneName + " not registered in m_authToLocalSceneMapping"); - return null; - } - return m_authToLocalSceneMapping[authSceneName]; - } - - #endregion - - #region Event Handlers - - public void OnPopulateLocalSceneList(List localScenes) - //public void OnPopulateLocalSceneList(List localScenes, string[] cmdparams) - { - if (!Active) - return; - - //populate the dictionary m_localScenes - foreach (Scene lScene in localScenes) - { - string name = lScene.RegionInfo.RegionName; - if(!m_localScenesByName.ContainsKey(name)){ - m_log.Warn(LogHeader+": has not reigstered a local scene named "+name); - continue; - } - m_localScenesByName[name] = lScene; - - //lScene.RegionSyncMode = m_regionSyncMode; - lScene.IsOutsideScenes = IsOutSideSceneSubscriptions; - } - - //test position conversion - /* - //Vector3 pos = new Vector3(290, 100, 10); - uint preLocX = Convert.ToUInt32(cmdparams[2]); - uint preLocY = Convert.ToUInt32(cmdparams[3]); - float posX = (float)Convert.ToDouble(cmdparams[4]); - float posY = (float)Convert.ToDouble(cmdparams[5]); - float posZ = (float)Convert.ToDouble(cmdparams[6]); - Vector3 pos = new Vector3(posX, posY, posZ); - uint locX, locY; - Vector3 newPos; - ConvertPosition(1000, 1000, pos, out locX, out locY, out newPos); - * */ - } - - #endregion - - private string GetAllSceneNames() - { - string scenes = ""; - foreach (KeyValuePair valPair in m_localScenesByName) - { - Scene lScene = valPair.Value; - string authScene = m_localToAuthSceneMapping[lScene.RegionInfo.RegionName]; - scenes += authScene + ","; - - } - return scenes; - } - - //public bool IsOutSideSceneSubscriptions(Scene currentScene, Vector3 pos) - public bool IsOutSideSceneSubscriptions(uint locX, uint locY, Vector3 pos) - { - string sceneNames = GetAllSceneNames(); - m_log.Debug(LogHeader + ": IsOutSideSceneSubscriptions called. Conceptually, we are checking inside scene-subscriptions: " + sceneNames); - - //First, convert the position to a scene s.t. the attempting position is contained withing that scene - uint curLocX, curLocY; - Vector3 curPos; - bool converted = ConvertPosition(locX, locY, pos, out curLocX, out curLocY, out curPos); - - if (!converted) - { - m_log.Warn("("+locX+","+locY+","+pos+")"+" converts to scenes with negative coordinates."); - return false; - } - //See of the quark identified by (curLocX,curLocY) is one we subscribed to - string sceneLoc = SceneLocToString(curLocX, curLocY); - if (m_authScenesInfoByLoc.ContainsKey(sceneLoc)) - { - return false; - } - else - { - return true; - } - } - - //When the offset position is outside the range of current scene, convert it to the offset position in the right quark. - //Return null if the new scene's left-bottom corner X or Y value is negative. - //Assumption: A position is uniquely identified by (locX, locY, offsetPos). - private bool ConvertPosition(uint preLocX, uint preLocY, Vector3 prePos, out uint curLocX, out uint curLocY, out Vector3 curPos) - { - Vector3 newPos; - int newLocX; - int newLocY; - //code copied from EntityTransferModule.Cross() - - newPos = prePos; - newLocX = (int)preLocX; - newLocY = (int)preLocY; - - int changeX = 1; - int changeY = 1; - - //Adjust the X values, if going east, changeX is positive, otherwise, it is negative - if (prePos.X >= 0) - { - changeX = (int)(prePos.X / (int)Constants.RegionSize); - } - else - { - changeX = (int)(prePos.X / (int)Constants.RegionSize) - 1 ; - } - newLocX = (int)preLocX + changeX; - newPos.X = prePos.X - (changeX * Constants.RegionSize); - - if (prePos.Y >= 0) - { - changeY = (int)(prePos.Y / (int)Constants.RegionSize); - } - else - { - changeY = (int)(prePos.Y / (int)Constants.RegionSize) - 1; - } - changeY = (int)(prePos.Y / (int)Constants.RegionSize); - newLocY = (int)preLocY + changeY; - newPos.Y = prePos.Y - (changeY * Constants.RegionSize); - - curLocX = (uint)newLocX; - curLocY = (uint)newLocY; - curPos = newPos; - - if (newLocX < 0 || newLocY < 0) - { - //reset the position - curLocX = preLocX; - curLocY = preLocY; - if (newLocX < 0) - { - curPos.X = 2; - } - if(newLocY<0) - { - curPos.Y = 2; - } - return false; - } - else - return true; - } - - - private void DebugSceneStats() - { - return; - /* - List avatars = m_scene.GetAvatars(); - List entities = m_scene.GetEntities(); - m_log.WarnFormat("There are {0} avatars and {1} entities in the scene", avatars.Count, entities.Count); - */ - } - - #region Console Command Interface - //IMPORTANT: these functions should only be actived for the ScriptEngineToSceneConnectorModule that is associated with the valid local scene - - private void InstallInterfaces() - { - Command cmdSyncStart = new Command("start", CommandIntentions.COMMAND_HAZARDOUS, SyncStart, "Begins synchronization with RegionSyncServer."); - //cmdSyncStart.AddArgument("server_port", "The port of the server to synchronize with", "Integer"); - - Command cmdSyncStop = new Command("stop", CommandIntentions.COMMAND_HAZARDOUS, SyncStop, "Stops synchronization with RegionSyncServer."); - //cmdSyncStop.AddArgument("server_address", "The IP address of the server to synchronize with", "String"); - //cmdSyncStop.AddArgument("server_port", "The port of the server to synchronize with", "Integer"); - - Command cmdSyncStatus = new Command("status", CommandIntentions.COMMAND_HAZARDOUS, SyncStatus, "Displays synchronization status."); - - //The following two commands are more for easier debugging purpose - Command cmdSyncSetQuarks = new Command("quarkSpace", CommandIntentions.COMMAND_HAZARDOUS, SetQuarkList, "Set the set of quarks to subscribe to. For debugging purpose. Should be issued before \"sync start\""); - cmdSyncSetQuarks.AddArgument("quarkSpace", "The (rectangle) space of quarks to subscribe, represented by x0_y0,x1_y1, the left-bottom and top-right corners of the rectangel space", "String"); - - Command cmdSyncSetQuarkSize = new Command("quarksize", CommandIntentions.COMMAND_HAZARDOUS, SetQuarkSize, "Set the size of each quark. For debugging purpose. Should be issued before \"sync quarks\""); - cmdSyncSetQuarkSize.AddArgument("quarksizeX", "The size on x axis of each quark", "Integer"); - cmdSyncSetQuarkSize.AddArgument("quarksizeY", "The size on y axis of each quark", "Integer"); - - Command cmdSyncRegister = new Command("register", CommandIntentions.COMMAND_HAZARDOUS, SyncRegister, "Register as an idle script engine. Sync'ing with Scene won't start until \"sync start\". "); - - //For debugging load balancing and migration process - Command cmdSyncStartLB = new Command("startLB", CommandIntentions.COMMAND_HAZARDOUS, SyncStartLB, "Register as an idle script engine. Sync'ing with Scene won't start until \"sync start\". "); - - m_commander.RegisterCommand("start", cmdSyncStart); - m_commander.RegisterCommand("stop", cmdSyncStop); - m_commander.RegisterCommand("status", cmdSyncStatus); - m_commander.RegisterCommand("quarkSpace", cmdSyncSetQuarks); - m_commander.RegisterCommand("register", cmdSyncRegister); - m_commander.RegisterCommand("startLB", cmdSyncStartLB); - - lock (m_scene) - { - // Add this to our scene so scripts can call these functions - m_scene.RegisterModuleCommander(m_commander); - } - } - - - /// - /// Processes commandline input. Do not call directly. - /// - /// Commandline arguments - private void EventManager_OnPluginConsole(string[] args) - { - if (args[0] == "sync") - { - if (args.Length == 1) - { - m_commander.ProcessConsoleCommand("help", new string[0]); - return; - } - - string[] tmpArgs = new string[args.Length - 2]; - int i; - for (i = 2; i < args.Length; i++) - tmpArgs[i - 2] = args[i]; - - m_commander.ProcessConsoleCommand(args[1], tmpArgs); - } - } - - private void SyncStart(Object[] args) - { - lock (m_client_lock) - { - //if (m_scriptEngineToSceneConnector != null) - if(m_SEToSceneConnectors.Count>0) - { - string authScenes = ""; - foreach (KeyValuePair valPair in m_SEToSceneConnectors) - { - authScenes += valPair.Key + ", "; - } - m_log.WarnFormat(LogHeader+": Already synchronized to "+authScenes); - return; - } - //m_log.Warn("[REGION SYNC CLIENT MODULE] Starting synchronization"); - m_log.Warn(LogHeader + ": Starting RegionSyncScriptEngine"); - - if (m_sceneNum > 1) - { - //If there is no arguments following "sync start", then be default we will connect to one or more scenes. - //we need to create a connector to each authoritative scene - foreach (KeyValuePair valPair in m_authScenesInfoByName) - { - string authSceneName = valPair.Key; - AuthSceneInfo authSceneInfo = valPair.Value; - - //create a new connector, the local end of each connector, however, is linked to the ValidScene only, - //since all objects will be contained in this scene only - ScriptEngineToSceneConnector scriptEngineToSceneConnector = new ScriptEngineToSceneConnector(m_scene, authSceneInfo.Addr, authSceneInfo.Port, m_debugWithViewer, authSceneName, m_syncConfig); - if (scriptEngineToSceneConnector.Start()) - { - m_SEToSceneConnectors.Add(authSceneName, scriptEngineToSceneConnector); - } - } - } - else - { - //Only one remote scene to connect to. Subscribe to whatever specified in the config file. - //List quarkStringList = RegionSyncUtil.QuarkStringToStringList(m_quarkListString); - //InitScriptEngineToSceneConnector(quarkStringList); - InitScriptEngineToSceneConnector(m_subscriptionSpaceString); - } - } - } - - private void SyncRegister(Object[] args) - { - //This should not happen. No-validLocalScene should not have register handlers for the command - //if (m_scene.RegionInfo.RegionName != m_validLocalScene) - // return; - - //Registration only, no state sync'ing yet. So only start the connector for the validLocalScene. (For now, we only test this with one scene, and - //quarks are smaller than a 256x256 scene. - string authSceneName = m_localToAuthSceneMapping[m_validLocalScene]; - AuthSceneInfo authSceneInfo = m_authScenesInfoByName[authSceneName]; - m_idleSEToSceneConnector = new ScriptEngineToSceneConnector(m_scene, authSceneInfo.Addr, authSceneInfo.Port, m_debugWithViewer, authSceneName, m_syncConfig); - m_idleSEToSceneConnector.RegisterIdle(); - } - - /// - /// The given ScriptEngineToSceneConnector, after having connected to the Scene (called its Start()), will - /// call this function to remove it self as an idle connector, and to be recorded as one working connector. - /// - /// - public void RecordSyncStartAfterLoadMigration(ScriptEngineToSceneConnector seToSceneConnector) - { - foreach (KeyValuePair valPair in m_authScenesInfoByName) - { - string authSceneName = valPair.Key; - AuthSceneInfo authSceneInfo = valPair.Value; - - string localScene = m_authToLocalSceneMapping[authSceneName]; - - if (localScene != m_scene.RegionInfo.RegionName) - continue; - - if (m_SEToSceneConnectors.ContainsKey(authSceneName)) - { - m_log.Warn(LogHeader + ": Connector to " + authSceneName + " is already considered connected"); - return; - } - - m_SEToSceneConnectors.Add(authSceneName, seToSceneConnector); - //there should only be one element in the dictionary if we reach this loop, anyway, we break from it. - break; - } - m_idleSEToSceneConnector = null; - } - - private void SyncStartLB(Object[] args) - { - string authSceneName = m_localToAuthSceneMapping[m_validLocalScene]; - ScriptEngineToSceneConnector sceneConnector = m_SEToSceneConnectors[authSceneName]; - sceneConnector.SendLoadBalanceRequest(); - } - - private void SetQuarkList(Object[] args) - { - m_subscriptionSpaceString = (string)args[0]; - - InitScriptEngineToSceneConnector(m_subscriptionSpaceString); - } - - private void SetQuarkSize(Object[] args) - { - QuarkInfo.SizeX = (int)args[0]; - QuarkInfo.SizeY = (int)args[1]; - - } - - private void InitScriptEngineToSceneConnector(string space) - { - - foreach (KeyValuePair valPair in m_authScenesInfoByName) - { - string authSceneName = valPair.Key; - AuthSceneInfo authSceneInfo = valPair.Value; - - string localScene = m_authToLocalSceneMapping[authSceneName]; - - if (localScene != m_scene.RegionInfo.RegionName) - continue; - - //create a new connector, the local end of each connector, however, is set of the ValidScene only, - //since all objects will be contained in this scene only - ScriptEngineToSceneConnector scriptEngineToSceneConnector = new ScriptEngineToSceneConnector(m_scene, authSceneInfo.Addr, authSceneInfo.Port, - m_debugWithViewer, authSceneName, space, m_syncConfig); - if (scriptEngineToSceneConnector.Start()) - { - m_SEToSceneConnectors.Add(authSceneName, scriptEngineToSceneConnector); - } - - break; //there should only be one element in the dictionary if we reach this loop, anyway, we break from it. - } - } - - private void SyncStop(Object[] args) - { - lock (m_client_lock) - { - //if (m_scriptEngineToSceneConnector == null) - if(m_SEToSceneConnectors.Count==0 && m_idleSEToSceneConnector==null) - { - m_log.WarnFormat("[REGION SYNC SCRIPT ENGINE MODULE] Already stopped"); - return; - } - - if (m_SEToSceneConnectors.Count > 0) - { - foreach (KeyValuePair valPair in m_SEToSceneConnectors) - { - ScriptEngineToSceneConnector connector = valPair.Value; - if (connector == null) - { - continue; - } - connector.Stop(); - } - m_SEToSceneConnectors.Clear(); - } - else if (m_idleSEToSceneConnector != null) - { - m_idleSEToSceneConnector.Stop(); - m_idleSEToSceneConnector = null; - } - - //m_scriptEngineToSceneConnector.Stop(); - //m_scriptEngineToSceneConnector = null; - m_log.Warn(LogHeader+": Stopping synchronization"); - } - - m_authScenesInfoByLoc.Clear(); - - //save script state and stop script instances - m_scene.EventManager.TriggerScriptEngineSyncStop(); - //remove all objects - m_scene.DeleteAllSceneObjects(); - - } - - private void SyncStatus(Object[] args) - { - lock (m_client_lock) - { - if (m_SEToSceneConnectors.Count == 0) - { - m_log.WarnFormat("[REGION SYNC SCRIPT ENGINE MODULE] Not currently synchronized"); - return; - } - m_log.WarnFormat("[REGION SYNC SCRIPT ENGINE MODULE] Synchronized"); - foreach (KeyValuePair pair in m_SEToSceneConnectors) - { - ScriptEngineToSceneConnector sceneConnector = pair.Value; - sceneConnector.ReportStatus(); - } - } - } - #endregion - } -} diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 07f2f302ca..e7854ce9d8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -285,7 +285,7 @@ namespace OpenSim.Region.Framework.Scenes { return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); } - + /// /// The absolute position of this scene object in the scene /// @@ -299,22 +299,23 @@ namespace OpenSim.Region.Framework.Scenes if (Scene != null) { if ((Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) - || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) + || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) { m_scene.CrossPrimGroupIntoNewRegion(val, this, true); } } + if (RootPart.GetStatusSandbox()) { if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) { RootPart.ScriptSetPhysicsStatus(false); - + if (Scene != null) Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); - + return; } } @@ -330,43 +331,11 @@ namespace OpenSim.Region.Framework.Scenes //m_rootPart.GroupPosition.Z); //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); //} - + if (Scene != null) Scene.EventManager.TriggerParcelPrimCountTainted(); } } - public void SetAbsolutePosition(Vector3 value) - { - Vector3 val = value; - - //REGION SYNC touched - - //if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) - // || m_scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || m_scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) - // && !IsAttachmentCheckFull()) - if (m_scene.IsBorderCrossing(LocX, LocY, val) && !IsAttachmentCheckFull() && (!m_scene.LoadingPrims)) - { - m_scene.CrossPrimGroupIntoNewRegion(val, this, true); - } - //end REGION SYNC touched - if (RootPart.GetStatusSandbox()) - { - if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) - { - RootPart.ScriptSetPhysicsStatus(false); - Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), - ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); - return; - } - } - - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - { - parts[i].GroupPosition = val; - //parts[i].SetGroupPosition(val); - } - } public override uint LocalId { @@ -3531,24 +3500,6 @@ namespace OpenSim.Region.Framework.Scenes #endregion -#region REGION SYNC - - //the LocX and LocY of the authoritative scene that this object is located - - private uint m_locX; - private uint m_locY; - public uint LocX - { - get { return m_locX; } - set { m_locX = value; } - } - public uint LocY - { - get { return m_locY; } - set { m_locY = value; } - } - -#endregion #region DSG SYNC @@ -3966,11 +3917,7 @@ namespace OpenSim.Region.Framework.Scenes // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the // position of linkset prims. IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and // unmoved prims! - //ResetChildPrimPhysicsPositions(); - //EntityBase sogBase = (EntityBase)this; - //sogBase.AbsolutePosition = AbsolutePosition; - SetAbsolutePosition(AbsolutePosition); - + ResetChildPrimPhysicsPositions(); } private void LinkNonRootPartBySync(SceneObjectPart linkPart, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum)