Merge branch 'dev' of ssh://island.sciencesim.com/home/sceneapi/sceneapi into dev
						commit
						7a89cf5a68
					
				|  | @ -64,10 +64,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|         // The client connection to the RegionSyncServer | ||||
|         private TcpClient m_client = new TcpClient(); | ||||
| 
 | ||||
| 
 | ||||
|         //KittyL: Comment out m_statsTimer for now, will figure out whether we need it for PhysEngine later | ||||
|         //private System.Timers.Timer m_statsTimer = new System.Timers.Timer(30000); | ||||
| 
 | ||||
|         // The queue of incoming messages which need handling | ||||
|         //private Queue<string> m_inQ = new Queue<string>(); | ||||
| 
 | ||||
|  | @ -105,11 +101,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             m_addrString = addr; | ||||
|             m_port = port; | ||||
|             m_debugWithViewer = debugWithViewer; | ||||
|             //m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed); | ||||
|             m_sysConfig = sysConfig; | ||||
| 
 | ||||
|             SceneToPhysEngineSyncServer.logEnabled = m_sysConfig.GetBoolean("LogEnabled", false); | ||||
|             SceneToPhysEngineSyncServer.logDir = m_sysConfig.GetString("LogDir", "."); | ||||
|             SceneToPhysEngineSyncServer.logEnabled = m_sysConfig.GetBoolean("PhysLogEnabled", false); | ||||
|             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); | ||||
|  | @ -534,5 +529,29 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
| 
 | ||||
|         #endregion Handlers for events/updates from Scene | ||||
| 
 | ||||
|         public string StatisticIdentifier() | ||||
|         { | ||||
|             return "PhysEngineToSceneConnector"; | ||||
|         } | ||||
| 
 | ||||
|         public string StatisticLine(bool clearFlag) | ||||
|         { | ||||
|             string ret = ""; | ||||
|             /* | ||||
|             lock (stats) | ||||
|             { | ||||
|                 ret = String.Format("{0},{1},{2},{3},{4},{5}", | ||||
|                     msgsIn, msgsOut, bytesIn, bytesOut | ||||
|                     ); | ||||
|                 if (clearFlag) | ||||
|                     msgsIn = msgsOut = bytesIn = bytesOut = 0; | ||||
|             } | ||||
|             */ | ||||
|             return ret; | ||||
|         } | ||||
|         public string StatisticTitle() | ||||
|         { | ||||
|             return "msgsIn,msgsOut,bytesIn,bytesOut"; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|     // The SceneToPhysEngineConnector acts as a thread on the RegionSyncServer to handle incoming | ||||
|     // messages from PhysEngineToSceneConnectors that run on Physics Engines. It connects the  | ||||
|     // authoratative Scene with remote script engines. | ||||
|     public class SceneToPhysEngineConnector | ||||
|     public class SceneToPhysEngineConnector : ISyncStatistics | ||||
|     { | ||||
|         #region SceneToPhysEngineConnector members | ||||
| 
 | ||||
|  | @ -38,9 +38,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|         private long bytesIn; | ||||
|         private long bytesOut; | ||||
|         private long pollBlocks; | ||||
|         private int lastTotalCount; | ||||
|         private int lastLocalCount; | ||||
|         private int lastRemoteCount; | ||||
| 
 | ||||
|         private int msgCount = 0; | ||||
| 
 | ||||
|  | @ -49,7 +46,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|         // Set the addr and port for TcpListener | ||||
|         private IPAddress m_addr; | ||||
|         private Int32 m_port; | ||||
|         private int m_connection_number; | ||||
|         private static int m_connection_number = 0; | ||||
|         private Scene m_scene; | ||||
| 
 | ||||
|         object m_syncRoot = new object(); | ||||
|  | @ -93,32 +90,33 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             get { return m_connection_number; } | ||||
|         } | ||||
| 
 | ||||
|         public string GetStats() | ||||
|         public string StatisticIdentifier() | ||||
|         { | ||||
|             string ret; | ||||
|             //lock (m_syncRoot) | ||||
|             //    syncedAvCount = m_syncedAvatars.Count; | ||||
|             return "SceneToPhysEngineConnector" + ConnectionNum.ToString(); | ||||
|         } | ||||
| 
 | ||||
|         public string StatisticLine(bool clearFlag) | ||||
|         { | ||||
|             string ret = ""; | ||||
|             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}]", | ||||
|                 ret = String.Format("[{0,4}/{1,4}], [{2,6}/{3,6}], [{4,4}/{5,4}], [{6,6} ({7,6})], [{8,4} ({9,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; | ||||
|                 ret = String.Format("{0},{1},{2},{3},{4}", | ||||
|                     msgsIn, msgsOut, bytesIn, bytesOut, pollBlocks | ||||
|                     ); | ||||
|                 if (clearFlag) | ||||
|                     msgsIn = msgsOut = bytesIn = bytesOut = pollBlocks = 0; | ||||
|             } | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public string StatisticTitle() | ||||
|         { | ||||
|             return "msgsIn,msgsOut,bytesIn,bytesOut,pollBlocks"; | ||||
|         } | ||||
| 
 | ||||
|         // Check if the client is connected | ||||
|         public bool Connected | ||||
|         { get { return m_tcpclient.Connected; } } | ||||
|  | @ -163,6 +161,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             //m_log.WarnFormat("{0} Started thread: {1}", LogHeader, m_receive_loop.Name); | ||||
|             m_receive_loop.Start(); | ||||
| 
 | ||||
|             SyncStatisticCollector.Register(this); | ||||
| 
 | ||||
|             //tell the remote script engine about the locX, locY of this authoritative scene | ||||
|             // SendSceneLoc(); | ||||
|             m_log.DebugFormat("{0}: SceneToPhysEngineConnector initialized", LogHeader); | ||||
|  |  | |||
|  | @ -174,7 +174,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                 m_log.Warn(LogHeader + " Synchronized"); | ||||
|                 foreach (SceneToPhysEngineConnector pec in m_physEngineConnectors) | ||||
|                 { | ||||
|                     m_log.Warn(pec.GetStats()); | ||||
|                     m_log.Warn(pec.StatisticLine(true)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -681,7 +681,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|         #region Message Logging | ||||
|         public static bool logInput = false; | ||||
|         public static bool logOutput = true; | ||||
|         public static bool logEnabled = true; | ||||
|         public static bool logEnabled = false; | ||||
|         private class PhysMsgLogger | ||||
|         { | ||||
|             public DateTime startTime; | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ using OpenMetaverse.StructuredData; | |||
| namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | ||||
| { | ||||
|     [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AttachmentsModule")] | ||||
|     public class RegionSyncModule : INonSharedRegionModule, IRegionSyncModule, ICommandableModule | ||||
|     public class RegionSyncModule : INonSharedRegionModule, IRegionSyncModule, ICommandableModule, ISyncStatistics | ||||
|     //public class RegionSyncModule : IRegionModule, IRegionSyncModule, ICommandableModule | ||||
|     { | ||||
|         #region INonSharedRegionModule | ||||
|  | @ -73,6 +73,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             m_log.Warn("[REGION SYNC MODULE] Initialised for actor "+ m_actorID); | ||||
| 
 | ||||
|             //The ActorType configuration will be read in and process by an ActorSyncModule, not here. | ||||
| 
 | ||||
|             // parameters for statistic logging | ||||
|             SyncStatisticCollector.LogEnabled = m_sysConfig.GetBoolean("SyncLogEnabled", false); | ||||
|             SyncStatisticCollector.LogDirectory = m_sysConfig.GetString("SyncLogDirectory", "."); | ||||
|             SyncStatisticCollector.LogInterval = m_sysConfig.GetInt("SyncLogInterval", 5000); | ||||
|             SyncStatisticCollector.LogMaxFileTimeMin = m_sysConfig.GetInt("SyncLogMaxFileTimeMin", 5); | ||||
|             SyncStatisticCollector.LogFileHeader = m_sysConfig.GetString("SyncLogFileHeader", "sync-"); | ||||
|         } | ||||
| 
 | ||||
|         //Called after Initialise() | ||||
|  | @ -122,6 +129,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
| 
 | ||||
|             //Start symmetric synchronization initialization automatically | ||||
|             //SyncStart(null); | ||||
| 
 | ||||
|             // connect to statistics system | ||||
|             SyncStatisticCollector.Register(this); | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|  | @ -198,15 +208,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|              | ||||
|             foreach (string bucketName in m_propertyBucketNames) | ||||
|             { | ||||
|                 if (m_isSyncRelay || part.HasPropertyUpdatedLocallyInGivenBucket(bucketName)) | ||||
|                 //if (m_isSyncRelay || part.HasPropertyUpdatedLocallyInGivenBucket(bucketName)) | ||||
|                 if(ToSendoutUpdate(part, bucketName)) | ||||
|                 {         | ||||
|                     lock (m_primUpdateLocks[bucketName]) | ||||
|                     { | ||||
|                         m_log.Debug("Queueing to bucket " + bucketName + " with part " + part.Name + ", " + part.UUID); | ||||
|                         m_primUpdates[bucketName][part.UUID] = part; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             }    | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -245,6 +256,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             { | ||||
|                 if (m_primUpdates[bucketName].Count > 0) | ||||
|                 { | ||||
|                     //m_log.Debug(m_primUpdates[bucketName].Count + " updated parts in bucket " + bucketName); | ||||
|                     lock (m_primUpdateLocks[bucketName]) | ||||
|                     { | ||||
|                         updated = true; | ||||
|  | @ -299,6 +311,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                                 } | ||||
|                             } | ||||
|                              * */ | ||||
|                             //m_log.Debug(LogHeader + " calling update sender for bucket " + bucketName); | ||||
|                             m_primUpdatesPerBucketSender[bucketName](bucketName, primUpdates[bucketName]); | ||||
|                         } | ||||
|                     } | ||||
|  | @ -373,6 +386,24 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Send a sync message to add the given object to other sync nodes. | ||||
|         /// </summary> | ||||
|         /// <param name="sog"></param> | ||||
|         public void SendNewObject(SceneObjectGroup sog) | ||||
|         { | ||||
|             if (!IsSyncingWithOtherActors()) | ||||
|             { | ||||
|                 //no SyncConnector connected. Do nothing. | ||||
|                 return; | ||||
|             } | ||||
|             m_log.DebugFormat(LogHeader + "SendNewObject called for object {0}, {1}", sog.Name, sog.UUID); | ||||
| 
 | ||||
|             string sogxml = SceneObjectSerializer.ToXml2Format(sog); | ||||
|             SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.NewObject, sogxml); | ||||
|             SendObjectUpdateToRelevantSyncConnectors(sog, rsm); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Send a sync message to remove the given objects in all connected actors.  | ||||
|         /// UUID is used for identified a removed object. This function now should | ||||
|  | @ -432,6 +463,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                 partNum++; | ||||
|             } | ||||
| 
 | ||||
|             m_log.Debug(LogHeader + " to SendLinkObject to link " + children.Count + " parts to " + root.Name); | ||||
|             m_log.Debug("LinkedObject: "+sogxml); | ||||
| 
 | ||||
|             SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.LinkObject, OSDParser.SerializeJsonString(data)); | ||||
|             SendObjectUpdateToRelevantSyncConnectors(linkedGroup, rsm); | ||||
|         } | ||||
|  | @ -522,20 +556,29 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                     OnLocalScriptReset((uint)evArgs[0], (UUID)evArgs[1]); | ||||
|                     return; | ||||
|                 case EventManager.EventNames.ChatFromClient: | ||||
|                     if (evArgs.Length < 2) | ||||
|                     /*if (evArgs.Length < 2) | ||||
|                     { | ||||
|                         m_log.Error(LogHeader + " not enough event args for ChatFromClient"); | ||||
|                         return; | ||||
|                     } | ||||
|                     OnLocalChatFromClient(evArgs[0], (OSChatMessage)evArgs[1]); | ||||
|                     return; | ||||
|                     return;*/  | ||||
|                 case EventManager.EventNames.ChatFromWorld: | ||||
|                     if (evArgs.Length < 2) | ||||
|                     /*if (evArgs.Length < 2) | ||||
|                     { | ||||
|                         m_log.Error(LogHeader + " not enough event args for ChatFromWorld"); | ||||
|                         return; | ||||
|                     } | ||||
|                     OnLocalChatFromWorld(evArgs[0], (OSChatMessage)evArgs[1]); | ||||
|                     return;*/  | ||||
|                 case EventManager.EventNames.ChatBroadcast: | ||||
|                     if (evArgs.Length < 2) | ||||
|                     { | ||||
|                         m_log.Error(LogHeader + " not enough event args for ChatFromWorld"); | ||||
|                         return; | ||||
|                     } | ||||
|                     //OnLocalChatBroadcast(evArgs[0], (OSChatMessage)evArgs[1]); | ||||
|                     OnLocalChatEvents(ev, evArgs[0], (OSChatMessage)evArgs[1]);  | ||||
|                     return; | ||||
|                 case EventManager.EventNames.ObjectGrab: | ||||
|                     OnLocalGrabObject((uint)evArgs[0], (uint)evArgs[1], (Vector3)evArgs[2], (IClientAPI)evArgs[3], (SurfaceTouchEventArgs)evArgs[4]); | ||||
|  | @ -581,10 +624,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             //for debugging purpose | ||||
|             Command cmdSyncDebug = new Command("debug", CommandIntentions.COMMAND_HAZARDOUS, SyncDebug, "Trigger some debugging functions"); | ||||
| 
 | ||||
|             //for sync state comparison,  | ||||
|             Command cmdSyncStateReport = new Command("state", CommandIntentions.COMMAND_HAZARDOUS, SyncStateReport, "Trigger synchronization state comparision functions"); | ||||
| 
 | ||||
|             m_commander.RegisterCommand("start", cmdSyncStart); | ||||
|             m_commander.RegisterCommand("stop", cmdSyncStop); | ||||
|             m_commander.RegisterCommand("status", cmdSyncStatus); | ||||
|             m_commander.RegisterCommand("debug", cmdSyncDebug); | ||||
|             m_commander.RegisterCommand("state", cmdSyncStateReport); | ||||
| 
 | ||||
|             lock (m_scene) | ||||
|             { | ||||
|  | @ -671,6 +718,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
| 
 | ||||
|         private delegate void PrimUpdatePerBucketSender(string bucketName, List<SceneObjectPart> primUpdates); | ||||
|         private Dictionary<string, PrimUpdatePerBucketSender> m_primUpdatesPerBucketSender = new Dictionary<string, PrimUpdatePerBucketSender>(); | ||||
|         //Timestamps that record the last time each any updates have been sent out for a given bucket | ||||
|         private Dictionary<string, long> m_lastUpdateSentTime = new Dictionary<string, long>(); | ||||
| 
 | ||||
|         private object m_updateScenePresenceLock = new object(); | ||||
|         private Dictionary<UUID, ScenePresence> m_presenceUpdates = new Dictionary<UUID, ScenePresence>(); | ||||
|  | @ -698,6 +747,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|         //Going forward, we may serialize the properties differently, e.g. using OSDMap  | ||||
|         private void PrimUpdatesGeneralBucketSender(string bucketName, List<SceneObjectPart> primUpdates) | ||||
|         { | ||||
|             UpdateBucektLastSentTime(bucketName); | ||||
| 
 | ||||
|             Dictionary<UUID, SceneObjectGroup> updatedObjects = new Dictionary<UUID, SceneObjectGroup>(); | ||||
|             foreach (SceneObjectPart part in primUpdates) | ||||
|             { | ||||
|  | @ -708,24 +759,24 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                 sog.UpdateTaintedBucketSyncInfo(bucketName, DateTime.Now.Ticks); //this update the timestamp and clear the taint info of the bucket | ||||
|                 string sogxml = SceneObjectSerializer.ToXml2Format(sog); | ||||
|                 SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml); | ||||
|                 lock (m_stats) m_statSOGBucketOut++; | ||||
|                 SendObjectUpdateToRelevantSyncConnectors(sog, syncMsg); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         private void PrimUpdatesPhysicsBucketSender(string bucketName, List<SceneObjectPart> primUpdates) | ||||
|         { | ||||
|             UpdateBucektLastSentTime(bucketName); | ||||
| 
 | ||||
|             foreach (SceneObjectPart updatedPart in primUpdates) | ||||
|             { | ||||
|                 updatedPart.UpdateTaintedBucketSyncInfo(bucketName, DateTime.Now.Ticks); | ||||
| 
 | ||||
|                 Physics.Manager.PhysicsActor pa = updatedPart.PhysActor; | ||||
|                 if (pa == null) | ||||
|                     return; | ||||
| 
 | ||||
|                 OSDMap data = new OSDMap(); | ||||
| 
 | ||||
|                 // data["UUID"] = OSD.FromUUID(updatedPart.UUID); | ||||
|                 data["UUID"] = OSD.FromUUID(pa.UUID); | ||||
|                 data["UUID"] = OSD.FromUUID(updatedPart.UUID); | ||||
|                 //data["UUID"] = OSD.FromUUID(pa.UUID); | ||||
|                 data["Bucket"] = OSD.FromString(bucketName); | ||||
| 
 | ||||
|                 data["GroupPosition"] = OSD.FromVector3(updatedPart.GroupPosition); | ||||
|  | @ -733,29 +784,70 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                 data["Scale"] = OSD.FromVector3(updatedPart.Scale); | ||||
|                 data["AngularVelocity"] = OSD.FromVector3(updatedPart.AngularVelocity); | ||||
|                 data["RotationOffset"] = OSD.FromQuaternion(updatedPart.RotationOffset); | ||||
|                 data["Size"] = OSD.FromVector3(pa.Size); | ||||
|                 data["Position"] = OSD.FromVector3(pa.Position); | ||||
|                 data["Force"] = OSD.FromVector3(pa.Force); | ||||
|                 data["Velocity"] = OSD.FromVector3(pa.Velocity); | ||||
|                 data["RotationalVelocity"] = OSD.FromVector3(pa.RotationalVelocity); | ||||
|                 data["PA_Acceleration"] = OSD.FromVector3(pa.Acceleration); | ||||
|                 data["Torque"] = OSD.FromVector3(pa.Torque); | ||||
|                 data["Orientation"] = OSD.FromQuaternion(pa.Orientation); | ||||
|                 data["IsPhysical"] = OSD.FromBoolean(pa.IsPhysical); | ||||
|                 data["Flying"] = OSD.FromBoolean(pa.Flying); | ||||
|                 data["Kinematic"] = OSD.FromBoolean(pa.Kinematic); | ||||
|                 data["Buoyancy"] = OSD.FromReal(pa.Buoyancy); | ||||
|                 data["CollidingGround"] = OSD.FromBoolean(pa.CollidingGround); | ||||
|                 data["IsColliding"] = OSD.FromBoolean(pa.IsColliding); | ||||
| 
 | ||||
|                 Physics.Manager.PhysicsActor pa = updatedPart.PhysActor; | ||||
|                 if (pa != null) | ||||
|                 { | ||||
| 
 | ||||
|                     data["Size"] = OSD.FromVector3(pa.Size); | ||||
|                     data["Position"] = OSD.FromVector3(pa.Position); | ||||
|                     data["Force"] = OSD.FromVector3(pa.Force); | ||||
|                     data["Velocity"] = OSD.FromVector3(pa.Velocity); | ||||
|                     data["RotationalVelocity"] = OSD.FromVector3(pa.RotationalVelocity); | ||||
|                     data["PA_Acceleration"] = OSD.FromVector3(pa.Acceleration); | ||||
|                     data["Torque"] = OSD.FromVector3(pa.Torque); | ||||
|                     data["Orientation"] = OSD.FromQuaternion(pa.Orientation); | ||||
|                     data["IsPhysical"] = OSD.FromBoolean(pa.IsPhysical); | ||||
|                     data["Flying"] = OSD.FromBoolean(pa.Flying); | ||||
|                     data["Kinematic"] = OSD.FromBoolean(pa.Kinematic); | ||||
|                     data["Buoyancy"] = OSD.FromReal(pa.Buoyancy); | ||||
|                     data["CollidingGround"] = OSD.FromBoolean(pa.CollidingGround); | ||||
|                     data["IsColliding"] = OSD.FromBoolean(pa.IsColliding); | ||||
|                 } | ||||
| 
 | ||||
|                 data["LastUpdateTimeStamp"] = OSD.FromLong(updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp); | ||||
|                 data["LastUpdateActorID"] = OSD.FromString(updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID); | ||||
| 
 | ||||
|                 //m_log.Debug(LogHeader + " Send out Physics Bucket updates for " + updatedPart.Name + ". GroupPosition: " + updatedPart.GroupPosition.ToString()); | ||||
| 
 | ||||
|                 SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedBucketProperties, OSDParser.SerializeJsonString(data)); | ||||
|                 //m_log.DebugFormat("{0}: PhysBucketSender for {1}, pos={2}", LogHeader, updatedPart.UUID.ToString(), pa.Position.ToString()); | ||||
|                 lock (m_stats) m_statPhysBucketOut++; | ||||
|                 SendObjectUpdateToRelevantSyncConnectors(updatedPart, syncMsg); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         private void UpdateBucektLastSentTime(string bucketName) | ||||
|         { | ||||
|             long timeStamp = DateTime.Now.Ticks; | ||||
|             /* | ||||
|             if (m_lastUpdateSentTime.ContainsKey(bucketName)) | ||||
|             { | ||||
|                 m_lastUpdateSentTime[bucketName] = timeStamp; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 m_lastUpdateSentTime.Add(bucketName, timeStamp); | ||||
|             } | ||||
|              * */ | ||||
|             m_lastUpdateSentTime[bucketName] = timeStamp; | ||||
|         } | ||||
| 
 | ||||
|         private bool ToSendoutUpdate(SceneObjectPart part, string bucketName) | ||||
|         { | ||||
|             if (!m_isSyncRelay) | ||||
|             { | ||||
|                 return part.HasPropertyUpdatedLocallyInGivenBucket(bucketName); | ||||
|             } | ||||
| 
 | ||||
|             //if this is a relay node, forward out the updates that have not been sent out since lastUpdateSentTime | ||||
|             if (m_lastUpdateSentTime[bucketName] <= part.BucketSyncInfoList[bucketName].LastUpdateTimeStamp) | ||||
|                 return true; | ||||
|             else | ||||
|                 return false; | ||||
|         } | ||||
| 
 | ||||
|         //If nothing configured in the config file, this is the default settings for grouping properties into different bucket | ||||
|         private void PopulatePropertyBuketMapByDefault() | ||||
|         { | ||||
|  | @ -770,6 +862,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             m_primUpdatesPerBucketSender.Add("General", PrimUpdatesGeneralBucketSender); | ||||
|             m_primUpdatesPerBucketSender.Add("Physics", PrimUpdatesPhysicsBucketSender); | ||||
| 
 | ||||
|             m_lastUpdateSentTime.Add("General", 0); | ||||
|             m_lastUpdateSentTime.Add("Physics", 0); | ||||
| 
 | ||||
|             //Mapping properties to buckets. | ||||
|             foreach (SceneObjectPartProperties property in Enum.GetValues(typeof(SceneObjectPartProperties))) | ||||
|             { | ||||
|  | @ -825,6 +920,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             { | ||||
|                 //string sogxml = SceneObjectSerializer.ToXml2Format(sog); | ||||
|                 //SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml); | ||||
| 
 | ||||
|                 connector.EnqueueOutgoingUpdate(sog.UUID, syncMsg.ToBytes()); | ||||
|             } | ||||
|         } | ||||
|  | @ -1156,15 +1252,41 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                     m_scene.EventManager.TriggerOnSymmetricSyncStop(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         private void SyncStatus(Object[] args) | ||||
|         { | ||||
|             //TO BE IMPLEMENTED | ||||
|             m_log.Warn("[REGION SYNC MODULE]: SyncStatus() TO BE IMPLEMENTED !!!"); | ||||
|             int connectorCount = 0; | ||||
|             m_log.Warn(LogHeader + ": " + this.StatisticTitle()); | ||||
|             m_log.Warn(LogHeader + ": " + this.StatisticLine(true)); | ||||
|             ForEachSyncConnector(delegate(SyncConnector connector) | ||||
|             { | ||||
|                 if (connectorCount++ == 0) | ||||
|                     m_log.WarnFormat("[REGION SYNC MODULE]: Description: {0}", connector.StatisticTitle()); | ||||
|                 m_log.WarnFormat("{0}: {1}: {2}", "[REGION SYNC MODULE}", connector.Description, connector.StatisticLine(true)); | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         private void SyncStateReport(Object[] args) | ||||
|         { | ||||
|             //Preliminary implementation | ||||
|             EntityBase[] entities = m_scene.GetEntities(); | ||||
|             List<SceneObjectGroup> sogList = new List<SceneObjectGroup>(); | ||||
|             foreach (EntityBase entity in entities) | ||||
|             { | ||||
|                 if (entity is SceneObjectGroup) | ||||
|                 { | ||||
|                     sogList.Add((SceneObjectGroup)entity); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             int primCount = 0; | ||||
|             foreach (SceneObjectGroup sog in sogList) | ||||
|             { | ||||
|                 primCount += sog.Parts.Length; | ||||
|             } | ||||
| 
 | ||||
|             m_log.WarnFormat("SyncStateReport -- Object count: {0}, Prim Count {1} ", sogList.Count, primCount); | ||||
|         } | ||||
| 
 | ||||
|         private void SyncDebug(Object[] args) | ||||
|  | @ -1374,6 +1496,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|         /// <param name="senderActorID">ActorID of the sender</param> | ||||
|         public void HandleIncomingMessage(SymmetricSyncMessage msg, string senderActorID) | ||||
|         { | ||||
|             lock (m_stats) m_statMsgsIn++; | ||||
|             //Added senderActorID, so that we don't have to include actorID in sync messages -- TODO | ||||
|             switch (msg.Type) | ||||
|             { | ||||
|  | @ -1410,6 +1533,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                         return; | ||||
|                     } | ||||
|                 case SymmetricSyncMessage.MsgType.NewObject: | ||||
|                     HandleAddNewObject(msg, senderActorID); | ||||
|                     break; | ||||
|                 case SymmetricSyncMessage.MsgType.UpdatedObject: | ||||
|                     { | ||||
|                         HandleAddOrUpdateObjectBySynchronization(msg, senderActorID); | ||||
|  | @ -1442,6 +1567,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                 case SymmetricSyncMessage.MsgType.ScriptReset: | ||||
|                 case SymmetricSyncMessage.MsgType.ChatFromClient: | ||||
|                 case SymmetricSyncMessage.MsgType.ChatFromWorld: | ||||
|                 case SymmetricSyncMessage.MsgType.ChatBroadcast: | ||||
|                 case SymmetricSyncMessage.MsgType.ObjectGrab: | ||||
|                 case SymmetricSyncMessage.MsgType.ObjectGrabbing: | ||||
|                 case SymmetricSyncMessage.MsgType.ObjectDeGrab: | ||||
|  | @ -1476,10 +1602,31 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             m_log.Debug(LogHeader + ": Synchronized terrain"); | ||||
|         } | ||||
| 
 | ||||
|         private void HandleAddNewObject(SymmetricSyncMessage msg, string senderActorID) | ||||
|         { | ||||
|             string sogxml = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); | ||||
|             SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); | ||||
| 
 | ||||
|             m_log.DebugFormat("{0}: received NewObject sync message from {1}, for object {1}, {2}", LogHeader, senderActorID, sog.Name, sog.UUID); | ||||
| 
 | ||||
|             Scene.ObjectUpdateResult updateResult = m_scene.AddOrUpdateObjectBySynchronization(sog); | ||||
|         } | ||||
| 
 | ||||
|         private void HandleAddOrUpdateObjectBySynchronization(SymmetricSyncMessage msg, string senderActorID) | ||||
|         { | ||||
|             string sogxml = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); | ||||
|             SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); | ||||
|             lock (m_stats) m_statSOGBucketIn++; | ||||
| 
 | ||||
|             //SYNC DEBUG | ||||
|             /* | ||||
|             string partnames = ""; | ||||
|             foreach (SceneObjectPart part in sog.Parts) | ||||
|             { | ||||
|                 partnames += "(" + part.Name + ", " + part.UUID + ")"; | ||||
|             } | ||||
|             m_log.Debug(LogHeader+" received "+msg.Type.ToString()+" from "+senderActorID+" about obj "+sog.Name+", "+sog.UUID+"; parts -- "+partnames); | ||||
|              * */  | ||||
| 
 | ||||
|             if (sog.IsDeleted) | ||||
|             { | ||||
|  | @ -1520,6 +1667,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             lock (m_stats) m_statPhysBucketIn++; | ||||
| 
 | ||||
|             UUID partUUID = data["UUID"].AsUUID(); | ||||
|             string bucketName = data["Bucket"].AsString(); | ||||
| 
 | ||||
|  | @ -1603,6 +1752,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             return data; | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
|         private void HandleAddNewObject(SceneObjectGroup sog) | ||||
|         { | ||||
|             //RegionSyncModule only add object to SceneGraph. Any actor specific actions will be implemented  | ||||
|  | @ -1614,6 +1764,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                 m_log.Debug(LogHeader + ": added obj " + sog.UUID); | ||||
|             } | ||||
|         } | ||||
|          * */  | ||||
| 
 | ||||
|         private void HandleRemovedObject(SymmetricSyncMessage msg, string senderActorID) | ||||
|         { | ||||
|  | @ -1657,6 +1808,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
| 
 | ||||
|         private void HandleLinkObject(SymmetricSyncMessage msg, string senderActorID) | ||||
|         { | ||||
| 
 | ||||
|             // Get the data from message and error check | ||||
|             OSDMap data = DeserializeMessage(msg); | ||||
|             if (data == null) | ||||
|  | @ -1678,6 +1830,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                 childrenIDs.Add(data[partTempID].AsUUID()); | ||||
|             } | ||||
| 
 | ||||
|             m_log.Debug(LogHeader + " received LinkObject from " + senderActorID); | ||||
|             //m_log.Debug("LinkedObject: " + sogxml); | ||||
| 
 | ||||
|             m_scene.LinkObjectBySync(linkedGroup, rootID, childrenIDs); | ||||
| 
 | ||||
|             //if this is a relay node, forwards the event | ||||
|  | @ -1752,6 +1907,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             lock (m_stats) m_statEventIn++; | ||||
|             string init_actorID = data["actorID"].AsString(); | ||||
|             ulong evSeqNum = data["seqNum"].AsULong(); | ||||
| 
 | ||||
|  | @ -1767,10 +1923,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|                     HandleRemoteEvent_OnScriptReset(init_actorID, evSeqNum, data); | ||||
|                     break; | ||||
|                 case SymmetricSyncMessage.MsgType.ChatFromClient: | ||||
|                     HandleRemoteEvent_OnChatFromClient(init_actorID, evSeqNum, data); | ||||
|                     break; | ||||
|                     //HandleRemoteEvent_OnChatFromClient(init_actorID, evSeqNum, data); | ||||
|                     //break; | ||||
|                 case SymmetricSyncMessage.MsgType.ChatFromWorld: | ||||
|                     HandleRemoteEvent_OnChatFromWorld(init_actorID, evSeqNum, data); | ||||
|                     //HandleRemoteEvent_OnChatFromWorld(init_actorID, evSeqNum, data); | ||||
|                     //break; | ||||
|                 case SymmetricSyncMessage.MsgType.ChatBroadcast: | ||||
|                     //HandleRemoteEvent_OnChatBroadcast(init_actorID, evSeqNum, data); | ||||
|                     HandleRemoveEvent_OnChatEvents(msg.Type, init_actorID, evSeqNum, data); | ||||
|                     break; | ||||
|                 case SymmetricSyncMessage.MsgType.ObjectGrab: | ||||
|                     HandleRemoteEvent_OnObjectGrab(init_actorID, evSeqNum, data); | ||||
|  | @ -1878,6 +2038,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             m_scene.EventManager.TriggerScriptResetLocally(part.LocalId, itemID); | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
|         /// <summary> | ||||
|         /// Special actions for remote event ChatFromClient | ||||
|         /// </summary> | ||||
|  | @ -1918,16 +2079,59 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             //ScenePresence sp; | ||||
|             //m_scene.TryGetScenePresence(id, out sp); | ||||
| 
 | ||||
|             m_log.Debug(LogHeader + " TriggerOnChatFromWorldLocally "); | ||||
| 
 | ||||
|             m_scene.EventManager.TriggerOnChatFromWorldLocally(m_scene, args); | ||||
|         } | ||||
| 
 | ||||
|         private void HandleRemoteEvent_OnChatBroadcast(string actorID, ulong evSeqNum, OSDMap data) | ||||
|         { | ||||
|              | ||||
|         } | ||||
|          * */  | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Handlers for remote chat events: ChatFromClient, ChatFromWorld, ChatBroadcast | ||||
|         /// </summary> | ||||
|         /// <param name="msgType"></param> | ||||
|         /// <param name="actorID"></param> | ||||
|         /// <param name="evSeqNum"></param> | ||||
|         /// <param name="data">The args of the event</param> | ||||
|         private void HandleRemoveEvent_OnChatEvents(SymmetricSyncMessage.MsgType msgType, string actorID, ulong evSeqNum, OSDMap data) | ||||
|         { | ||||
|             OSChatMessage args = new OSChatMessage(); | ||||
|             args.Channel = data["channel"].AsInteger(); | ||||
|             args.Message = data["msg"].AsString(); | ||||
|             args.Position = data["pos"].AsVector3(); | ||||
|             args.From = data["name"].AsString(); | ||||
|             UUID id = data["id"].AsUUID(); | ||||
|             args.Scene = m_scene; | ||||
|             args.Type = (ChatTypeEnum)data["type"].AsInteger(); | ||||
| 
 | ||||
|             switch (msgType) | ||||
|             { | ||||
|                 case SymmetricSyncMessage.MsgType.ChatFromClient: | ||||
|                     ScenePresence sp; | ||||
|                     m_scene.TryGetScenePresence(id, out sp); | ||||
|                     m_scene.EventManager.TriggerOnChatFromClientLocally(sp, args); //Let WorldCommModule and other modules to catch the event | ||||
|                     m_scene.EventManager.TriggerOnChatFromWorldLocally(sp, args); //This is to let ChatModule to get the event and deliver it to avatars | ||||
|                     break; | ||||
|                 case SymmetricSyncMessage.MsgType.ChatFromWorld: | ||||
|                     m_scene.EventManager.TriggerOnChatFromWorldLocally(m_scene, args); | ||||
|                     break; | ||||
|                 case SymmetricSyncMessage.MsgType.ChatBroadcast: | ||||
|                     m_scene.EventManager.TriggerOnChatBroadcastLocally(m_scene, args); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Special actions for remote event ChatFromClient | ||||
|         /// </summary> | ||||
|         /// <param name="data">OSDMap data of event args</param> | ||||
|         private void HandleRemoteEvent_OnObjectGrab(string actorID, ulong evSeqNum, OSDMap data) | ||||
|         { | ||||
|             m_log.Debug(LogHeader + ", " + m_actorID + ": received GrabObject from " + actorID + ", seq " + evSeqNum); | ||||
|            // m_log.Debug(LogHeader + ", " + m_actorID + ": received GrabObject from " + actorID + ", seq " + evSeqNum); | ||||
| 
 | ||||
| 
 | ||||
|             UUID agentID = data["agentID"].AsUUID(); | ||||
|  | @ -1964,7 +2168,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
| 
 | ||||
|         private void HandleRemoteEvent_OnObjectGrabbing(string actorID, ulong evSeqNum, OSDMap data) | ||||
|         { | ||||
|             m_log.Debug(LogHeader + ", " + m_actorID + ": received GrabObject from " + actorID + ", seq " + evSeqNum); | ||||
|            // m_log.Debug(LogHeader + ", " + m_actorID + ": received GrabObject from " + actorID + ", seq " + evSeqNum); | ||||
| 
 | ||||
|             UUID agentID = data["agentID"].AsUUID(); | ||||
|             UUID primID = data["primID"].AsUUID(); | ||||
|  | @ -2001,7 +2205,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
| 
 | ||||
|         private void HandleRemoteEvent_OnObjectDeGrab(string actorID, ulong evSeqNum, OSDMap data) | ||||
|         { | ||||
|             m_log.Debug(LogHeader + ", " + m_actorID + ": received GrabObject from " + actorID + ", seq " + evSeqNum); | ||||
|            // m_log.Debug(LogHeader + ", " + m_actorID + ": received GrabObject from " + actorID + ", seq " + evSeqNum); | ||||
| 
 | ||||
|             UUID agentID = data["agentID"].AsUUID(); | ||||
|             UUID primID = data["primID"].AsUUID(); | ||||
|  | @ -2129,7 +2333,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             SendSceneEvent(SymmetricSyncMessage.MsgType.ScriptReset, data); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /* | ||||
|         private void OnLocalChatFromClient(Object sender, OSChatMessage chat) | ||||
|         { | ||||
|             ScenePresence avatar = m_scene.GetScenePresence(chat.SenderUUID); | ||||
|  | @ -2162,6 +2366,37 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             data["id"] = OSD.FromUUID(chat.SenderUUID); | ||||
|             data["type"] = OSD.FromInteger((int)chat.Type); | ||||
|             SendSceneEvent(SymmetricSyncMessage.MsgType.ChatFromWorld, data); | ||||
|         } | ||||
|          * */  | ||||
| 
 | ||||
|         private void OnLocalChatBroadcast(Object sender, OSChatMessage chat) | ||||
|         { | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         private void OnLocalChatEvents(EventManager.EventNames evType, Object sender, OSChatMessage chat) | ||||
|         { | ||||
|             OSDMap data = new OSDMap(); | ||||
|             data["channel"] = OSD.FromInteger(chat.Channel); | ||||
|             data["msg"] = OSD.FromString(chat.Message); | ||||
|             data["pos"] = OSD.FromVector3(chat.Position); | ||||
|             data["name"] = OSD.FromString(chat.From); //note this is different from OnLocalChatFromClient | ||||
|             data["id"] = OSD.FromUUID(chat.SenderUUID); | ||||
|             data["type"] = OSD.FromInteger((int)chat.Type); | ||||
| 
 | ||||
|             switch (evType) | ||||
|             { | ||||
|                 case EventManager.EventNames.ChatFromClient: | ||||
|                     SendSceneEvent(SymmetricSyncMessage.MsgType.ChatFromClient, data); | ||||
|                     break; | ||||
|                 case EventManager.EventNames.ChatFromWorld: | ||||
|                     SendSceneEvent(SymmetricSyncMessage.MsgType.ChatFromWorld, data); | ||||
|                     break; | ||||
|                 case EventManager.EventNames.ChatBroadcast: | ||||
|                     SendSceneEvent(SymmetricSyncMessage.MsgType.ChatBroadcast, data); | ||||
|                     break;  | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         private void OnLocalAttach(uint localID, UUID itemID, UUID avatarID) | ||||
|  | @ -2300,6 +2535,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             SymmetricSyncMessage rsm = new SymmetricSyncMessage(msgType, OSDParser.SerializeJsonString(data)); | ||||
| 
 | ||||
|             //send to actors who are interested in the event | ||||
|             lock (m_stats) m_statEventOut++; | ||||
|             SendSceneEventToRelevantSyncConnectors(m_actorID, rsm); | ||||
|         } | ||||
| 
 | ||||
|  | @ -2321,6 +2557,50 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
| 
 | ||||
|         #endregion //RegionSyncModule members and functions | ||||
| 
 | ||||
|         #region ISyncStatistics | ||||
|         private object m_stats = new object(); | ||||
|         private int m_statMsgsIn = 0; | ||||
|         private int m_statMsgsOut = 0; | ||||
|         private int m_statSOGBucketIn = 0; | ||||
|         private int m_statSOGBucketOut = 0; | ||||
|         private int m_statPhysBucketIn = 0; | ||||
|         private int m_statPhysBucketOut = 0; | ||||
|         private int m_statEventIn = 0; | ||||
|         private int m_statEventOut = 0; | ||||
|         public string StatisticIdentifier() | ||||
|         { | ||||
|             // RegionSyncModule(actor/region) | ||||
|             return "RegionSyncModule" + "(" + ActorID + "/" + m_scene.RegionInfo.RegionName + ")"; | ||||
|         } | ||||
| 
 | ||||
|         public string StatisticLine(bool clearFlag) | ||||
|         { | ||||
|             string statLine = ""; | ||||
|             lock (m_stats) | ||||
|             { | ||||
|                 statLine = String.Format("{0},{1},{2},{3},{4},{5},{6},{7}", | ||||
|                     m_statMsgsIn, m_statMsgsOut, | ||||
|                     m_statSOGBucketIn, m_statSOGBucketOut, | ||||
|                     m_statPhysBucketIn, m_statPhysBucketOut, | ||||
|                     m_statEventIn, m_statEventOut | ||||
|                 ); | ||||
|                 if (clearFlag) | ||||
|                 { | ||||
|                     m_statMsgsIn = m_statMsgsOut = 0; | ||||
|                     m_statSOGBucketIn = m_statSOGBucketOut = 0; | ||||
|                     m_statPhysBucketIn = m_statPhysBucketOut = 0; | ||||
|                     m_statEventIn = m_statEventOut = 0; | ||||
|                 } | ||||
|             } | ||||
|             return statLine; | ||||
|         } | ||||
| 
 | ||||
|         public string StatisticTitle() | ||||
|         { | ||||
|             return "MsgsIn,MsgsOut,SOGIn,SOGOut,PhysIn,PhysOut,EventIn,EventOut"; | ||||
|         } | ||||
|         #endregion ISyncStatistics | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public class RegionSyncListenerInfo | ||||
|  |  | |||
|  | @ -172,7 +172,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|         { | ||||
|             if (entity is SceneObjectGroup) | ||||
|             { | ||||
|                 m_log.Warn(LogHeader + ": start script for obj " + entity.UUID); | ||||
|                 m_log.Debug(LogHeader + ": start script for obj " + entity.UUID); | ||||
|                 SceneObjectGroup sog = (SceneObjectGroup)entity;  | ||||
|                 sog.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, 0); | ||||
|                 sog.ResumeScripts(); | ||||
|  |  | |||
|  | @ -42,6 +42,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             ScriptReset, | ||||
|             ChatFromClient, | ||||
|             ChatFromWorld, | ||||
|             ChatBroadcast, | ||||
|             ObjectGrab, | ||||
|             ObjectGrabbing, | ||||
|             ObjectDeGrab, | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ using OpenMetaverse; | |||
| namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | ||||
| { | ||||
|     // For implementations, a lot was copied from RegionSyncClientView, especially the SendLoop/ReceiveLoop. | ||||
|     public class SyncConnector | ||||
|     public class SyncConnector : ISyncStatistics | ||||
|     { | ||||
|         private TcpClient m_tcpConnection = null; | ||||
|         private RegionSyncListenerInfo m_remoteListenerInfo = null; | ||||
|  | @ -33,13 +33,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|         private long msgsOut=0; | ||||
|         private long bytesIn=0; | ||||
|         private long bytesOut=0; | ||||
|         private int msgCount = 0; | ||||
|         private DateTime lastStatTime; | ||||
|         // A queue for outgoing traffic.  | ||||
|         private BlockingUpdateQueue m_outQ = new BlockingUpdateQueue(); | ||||
| 
 | ||||
|         private RegionSyncModule m_regionSyncModule = null; | ||||
| 
 | ||||
|         private int m_connectorNum; | ||||
|         // unique connector number across all regions | ||||
|         private static int m_connectorNum = 0; | ||||
|         public int ConnectorNum | ||||
|         { | ||||
|             get { return m_connectorNum; } | ||||
|  | @ -69,8 +70,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             get | ||||
|             { | ||||
|                 if (m_syncOtherSideRegionName == null) | ||||
|                     return String.Format("SyncConnector #{0}", m_connectorNum); | ||||
|                 return String.Format("SyncConnector #{0} (Actor {2}, Region {1:10})", m_connectorNum, m_syncOtherSideRegionName, m_syncOtherSideActorID); | ||||
|                     return String.Format("SyncConnector{0}", m_connectorNum); | ||||
|                 return String.Format("SyncConnector{0}({2}/{1:10})", | ||||
|                             m_connectorNum, m_syncOtherSideRegionName, m_syncOtherSideActorID); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -84,6 +86,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             m_tcpConnection = tcpclient; | ||||
|             m_connectorNum = connectorNum; | ||||
|             m_regionSyncModule = syncModule; | ||||
|             lastStatTime = DateTime.Now; | ||||
|             SyncStatisticCollector.Register(this); | ||||
|             m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         } | ||||
| 
 | ||||
|  | @ -97,6 +101,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             m_remoteListenerInfo = listenerInfo; | ||||
|             m_connectorNum = connectorNum; | ||||
|             m_regionSyncModule = syncModule; | ||||
|             lastStatTime = DateTime.Now; | ||||
|             SyncStatisticCollector.Register(this); | ||||
|             m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         } | ||||
| 
 | ||||
|  | @ -261,7 +267,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|         private void HandleMessage(SymmetricSyncMessage msg) | ||||
|         { | ||||
| 
 | ||||
|             msgCount++; | ||||
|             msgsIn++; | ||||
|             bytesIn += msg.Data.Length; | ||||
|             switch (msg.Type) | ||||
|             { | ||||
|                 case SymmetricSyncMessage.MsgType.RegionName: | ||||
|  | @ -294,5 +301,32 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | |||
|             //Later on, we may deliver messages to different modules, say sync message to RegionSyncModule and event message to ActorSyncModule. | ||||
|             m_regionSyncModule.HandleIncomingMessage(msg, m_syncOtherSideActorID); | ||||
|         } | ||||
| 
 | ||||
|         public string StatisticIdentifier() | ||||
|         { | ||||
|             return this.Description; | ||||
|         } | ||||
| 
 | ||||
|         public string StatisticLine(bool clearFlag) | ||||
|         { | ||||
|             string statLine = ""; | ||||
|             lock (stats) | ||||
|             { | ||||
|                 double secondsSinceLastStats = DateTime.Now.Subtract(lastStatTime).TotalSeconds; | ||||
|                 lastStatTime = DateTime.Now; | ||||
|                 statLine = String.Format("{0},{1},{2},{3},{4},{5},{6}", | ||||
|                         msgsIn, msgsOut, bytesIn, bytesOut, m_outQ.Count, | ||||
|                         8 * (bytesIn / secondsSinceLastStats / 1000000), | ||||
|                         8 * (bytesOut / secondsSinceLastStats / 1000000) ); | ||||
|                 if (clearFlag) | ||||
|                     msgsIn = msgsOut = bytesIn = bytesOut = 0; | ||||
|             } | ||||
|             return statLine; | ||||
|         } | ||||
| 
 | ||||
|         public string StatisticTitle() | ||||
|         { | ||||
|             return "msgsIn,msgsOut,bytesIn,bytesOut,queueSize,Mbps In,Mbps Out"; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,162 @@ | |||
| /* 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.IO; | ||||
| using System.Text; | ||||
| using System.Timers; | ||||
| 
 | ||||
| namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule | ||||
| { | ||||
|     public interface ISyncStatistics | ||||
|     { | ||||
|         // return an identifier for this statistics source | ||||
|         string StatisticIdentifier(); | ||||
|         // a line of comma separated values | ||||
|         string StatisticLine(bool clearFlag); | ||||
|         // a line of comma separated field descriptions (describes what StatisticLine returns) | ||||
|         string StatisticTitle(); | ||||
|     } | ||||
| 
 | ||||
|     public class SyncStatisticCollector | ||||
|     { | ||||
|         public static bool LogEnabled = false; | ||||
|         public static string LogDirectory = "."; | ||||
|         public static int LogInterval = 5000; | ||||
|         public static int LogMaxFileTimeMin = 5;    // 5 minutes | ||||
|         public static string LogFileHeader = "stats-"; | ||||
| 
 | ||||
|         private static List<ISyncStatistics> s_staters = new List<ISyncStatistics>(); | ||||
|         private static object s_statersLock = new object(); | ||||
|         private static Timer s_timer = null; | ||||
| 
 | ||||
|         static SyncStatisticCollector() | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public SyncStatisticCollector() | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Any implementor of ISyncStatistics will call Register to put themselves in | ||||
|         /// the list of routines to collect statistics from. This will run periodically | ||||
|         /// and suck statistics from the registered routines. | ||||
|         /// </summary> | ||||
|         /// <param name="stat"></param> | ||||
|         public static void Register(ISyncStatistics stat) | ||||
|         { | ||||
|             if (!LogEnabled) return; | ||||
|             lock (SyncStatisticCollector.s_statersLock) | ||||
|             { | ||||
|                 // set up logging timer | ||||
|                 if (SyncStatisticCollector.s_timer == null) | ||||
|                 { | ||||
|                     SyncStatisticCollector.s_timer = new Timer(); | ||||
|                     SyncStatisticCollector.s_timer.Interval = LogInterval; | ||||
|                     SyncStatisticCollector.s_timer.Enabled = true; | ||||
|                     SyncStatisticCollector.s_timer.Elapsed += Tick; | ||||
| 
 | ||||
|                 } | ||||
|                 SyncStatisticCollector.s_staters.Add(stat); | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         public static void Close() | ||||
|         { | ||||
|             lock (SyncStatisticCollector.s_statersLock) | ||||
|             { | ||||
|                 SyncStatisticCollector.LogEnabled = false; | ||||
|                 if (SyncStatisticCollector.s_timer != null) | ||||
|                 { | ||||
|                     SyncStatisticCollector.s_timer.Enabled = false; | ||||
|                     SyncStatisticCollector.s_timer.Dispose(); | ||||
|                     SyncStatisticCollector.s_timer = null; | ||||
|                 } | ||||
|                 if (SyncStatisticCollector.LogFile != null) | ||||
|                 { | ||||
|                     SyncStatisticCollector.LogFile.Close(); | ||||
|                     SyncStatisticCollector.LogFile.Dispose(); | ||||
|                     SyncStatisticCollector.LogFile = null; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         private static void Tick(object sender, EventArgs e) | ||||
|         { | ||||
|             if (!LogEnabled) return; | ||||
|             lock (SyncStatisticCollector.s_statersLock) | ||||
|             { | ||||
|                 foreach (ISyncStatistics iss in s_staters) | ||||
|                 { | ||||
|                     LogWriter(iss.StatisticIdentifier() + "," + iss.StatisticLine(true)); | ||||
|                 } | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         private static DateTime LogStartTime; | ||||
|         private static System.IO.TextWriter LogFile = null; | ||||
|         private static void LogWriter(string line) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 DateTime now = DateTime.Now; | ||||
|                 if (LogFile == null || (now > (LogStartTime + new TimeSpan(0, LogMaxFileTimeMin, 0)))) | ||||
|                 { | ||||
|                     if (LogFile != null) | ||||
|                     { | ||||
|                         LogFile.Close(); | ||||
|                         LogFile.Dispose(); | ||||
|                         LogFile = null; | ||||
|                     } | ||||
| 
 | ||||
|                     // First log file or time has expired, start writing to a new log file | ||||
|                     LogStartTime = now; | ||||
|                     string path = (LogDirectory.Length > 0 ? LogDirectory  | ||||
|                                 + System.IO.Path.DirectorySeparatorChar.ToString() : "") | ||||
|                             + String.Format("{0}{1}.log", LogFileHeader, now.ToString("yyyyMMddHHmmss")); | ||||
|                     LogFile = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write)); | ||||
|                 } | ||||
|                 if (LogFile != null) | ||||
|                 { | ||||
|                     StringBuilder buff = new StringBuilder(); | ||||
|                     // buff.Append(now.ToString("yyyyMMddHHmmssfff")); | ||||
|                     buff.Append(now.ToString("yyyyMMddHHmmss")); | ||||
|                     buff.Append(","); | ||||
|                     buff.Append(line); | ||||
|                     buff.Append("\r\n"); | ||||
|                     LogFile.Write(buff.ToString()); | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 // m_log.ErrorFormat("{0}: FAILURE WRITING TO LOGFILE: {1}", LogHeader, e); | ||||
|                 LogEnabled = false; | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -252,7 +252,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap | |||
| 
 | ||||
|             SetPartMediaFlags(part, face, me != null); | ||||
|             //part.ScheduleFullUpdate(); | ||||
|             part.ScheduleFullUpdate(new List<SceneObjectPartProperties>(){SceneObjectPartProperties.MediaUrl}); | ||||
|             part.ScheduleFullUpdate(new List<SceneObjectPartProperties>() { SceneObjectPartProperties.MediaUrl, SceneObjectPartProperties.Shape}); | ||||
| 
 | ||||
|             part.TriggerScriptChangedEvent(Changed.MEDIA); | ||||
|         } | ||||
|  |  | |||
|  | @ -72,6 +72,7 @@ namespace OpenSim.Region.Framework.Interfaces | |||
| 
 | ||||
|         //The folloiwng calls deal with object updates, and will insert each update into an outgoing queue of each SyncConnector | ||||
|         void SendSceneUpdates(); | ||||
|         void SendNewObject(SceneObjectGroup sog); | ||||
|         void SendDeleteObject(SceneObjectGroup sog, bool softDelete); | ||||
|         void SendLinkObject(SceneObjectGroup linkedGroup, SceneObjectPart root, List<SceneObjectPart> children); | ||||
|         void SendDeLinkObject(List<SceneObjectPart> prims, List<SceneObjectGroup> beforeDelinkGroups, List<SceneObjectGroup> afterDelinkGroups); | ||||
|  |  | |||
|  | @ -55,6 +55,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             ScriptReset, | ||||
|             ChatFromClient, //chats from avatars | ||||
|             ChatFromWorld,  //chats from objects | ||||
|             ChatBroadcast, //broadcast  | ||||
|             ObjectGrab, | ||||
|             ObjectGrabbing, | ||||
|             ObjectDeGrab, | ||||
|  | @ -154,10 +155,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         } | ||||
|         #endregion //ChatFromClient | ||||
| 
 | ||||
| #region ChatBroadcast | ||||
| 
 | ||||
|         public override void TriggerOnChatBroadcast(Object sender, OSChatMessage chat) | ||||
|         { | ||||
|             if (m_scene.RegionSyncModule != null) | ||||
|             { | ||||
|                 Object[] eventArgs = new Object[2]; | ||||
|                 eventArgs[0] = sender; | ||||
|                 eventArgs[1] = (Object)chat; | ||||
|                 m_scene.RegionSyncModule.PublishSceneEvent(EventNames.ChatBroadcast, eventArgs); | ||||
|             } | ||||
|             TriggerOnChatBroadcastLocally(sender, chat); | ||||
|         } | ||||
| 
 | ||||
|         public void TriggerOnChatBroadcastLocally(Object sender, OSChatMessage chat)  | ||||
|         { | ||||
|             base.TriggerOnChatBroadcast(sender, chat); | ||||
|         } | ||||
| #endregion  | ||||
| 
 | ||||
| 
 | ||||
|         #region ChatFromWorld | ||||
| 
 | ||||
|  | @ -1874,7 +1891,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void TriggerOnChatBroadcast(Object sender, OSChatMessage chat) | ||||
|         //public void TriggerOnChatBroadcast(Object sender, OSChatMessage chat) | ||||
|         public virtual void TriggerOnChatBroadcast(Object sender, OSChatMessage chat) | ||||
|         { | ||||
|             ChatBroadcastEvent handlerChatBroadcast = OnChatBroadcast; | ||||
|             if (handlerChatBroadcast != null) | ||||
|  |  | |||
|  | @ -333,11 +333,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             ArrayList errors = new ArrayList(); | ||||
| 
 | ||||
|             //In the old async model, this function is supposed to be executed only on a remote script engine, not an authorative Scene | ||||
|             /* | ||||
|             if (RegionSyncModule==null && !IsSyncedScriptEngine()) | ||||
|             { | ||||
|                 m_log.Warn("This is not the script engine. Should not have received OnUpdateScript event."); | ||||
|                 return errors; | ||||
|             } | ||||
|              * */  | ||||
|             SceneObjectPart part = GetSceneObjectPart(primID); | ||||
|             SceneObjectGroup group = part.ParentGroup; | ||||
|             if (isScriptRunning) | ||||
|  | @ -2194,7 +2196,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|                          | ||||
|             AddNewSceneObject(group, true, pos, rot, vel); | ||||
|              | ||||
| 
 | ||||
|             //SYNC DEBUG | ||||
|             string partnames = ""; | ||||
|             foreach (SceneObjectPart part in group.Parts){ | ||||
|                 partnames += "(" + part.Name + ", " + part.UUID + ")";  | ||||
|             } | ||||
|             m_log.DebugFormat("[SCENE] RezObject {0} with InvItem name {1} at pos {2} with parts {3}", group.UUID.ToString(), item.Name, group.RootPart.GroupPosition.ToString(), partnames); | ||||
| 
 | ||||
|             // We can only call this after adding the scene object, since the scene object references the scene | ||||
|             // to find out if scripts should be activated at all. | ||||
|             group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); | ||||
|  |  | |||
|  | @ -508,6 +508,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             //Only Auth. Scene should trigger scritp rez by remote script engine. | ||||
|             return IsSyncedServer(); | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         /////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|         //RA: Physics Engine | ||||
|  | @ -543,12 +544,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|         /////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| 
 | ||||
|         //!!! Obsolete function. Shouldn't be used anymore. | ||||
| 
 | ||||
|         //This function should only be called by an actor who's local Scene is just a cache of the authorative Scene. | ||||
|         //If the object already exists, use the new copy to replace it. | ||||
|         //Return true if added, false if just updated | ||||
|         public bool AddOrUpdateObjectInLocalScene(SceneObjectGroup sog, bool debugWithViewer) | ||||
|         { | ||||
|             return m_sceneGraph.AddOrUpdateObjectInScene(sog, debugWithViewer); | ||||
|             return false; | ||||
|             //return m_sceneGraph.AddOrUpdateObjectInScene(sog, debugWithViewer); | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|  | @ -790,11 +794,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 m_log.Debug("to link part " + part.DebugObjectPartProperties()); | ||||
|                 //m_log.Debug("to link part " + part.DebugObjectPartProperties()); | ||||
|                 m_log.Debug("to link part " + part.Name + "," + part.UUID + "; its SOG has " + part.ParentGroup.Parts + " parts"); | ||||
| 
 | ||||
|                 children.Add(part); | ||||
|             } | ||||
| 
 | ||||
|             //m_log.Debug("to link " + children.Count + " parts with " + root.Name); | ||||
| 
 | ||||
|             //Leverage the LinkObject implementation to get the book keeping of Group and Parts relations right | ||||
|             m_sceneGraph.LinkObjectsBySync(root, children); | ||||
| 
 | ||||
|  |  | |||
|  | @ -382,10 +382,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             m_numPrim += children.Length; | ||||
| 
 | ||||
|             sceneObject.AttachToScene(m_parentScene); | ||||
| 
 | ||||
|             if (sendClientUpdates) | ||||
|                 //sceneObject.ScheduleGroupForFullUpdate(); | ||||
|                 sceneObject.ScheduleGroupForFullUpdate(new List<SceneObjectPartProperties>(){SceneObjectPartProperties.None});  | ||||
|              | ||||
|             Entities.Add(sceneObject); | ||||
| 
 | ||||
|  | @ -409,6 +405,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; | ||||
|             } | ||||
| 
 | ||||
|             //SYMMETRIC SYNC: sending NewObject event, and sending it before calling ScheduleGroupForFullUpdate | ||||
|             if (m_parentScene.RegionSyncModule != null) | ||||
|             { | ||||
|                 m_parentScene.RegionSyncModule.SendNewObject(sceneObject); | ||||
|             } | ||||
| 
 | ||||
|             if (sendClientUpdates) | ||||
|                 //sceneObject.ScheduleGroupForFullUpdate(); | ||||
|                 sceneObject.ScheduleGroupForFullUpdate(new List<SceneObjectPartProperties>() { SceneObjectPartProperties.None });  | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|  | @ -468,7 +474,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             lock (m_updateList) | ||||
|             { | ||||
|                 m_updateList[obj.UUID] = obj; | ||||
|                 //m_log.Debug("added " + obj.UUID + " to m_updateList"); | ||||
|                 //m_log.Debug("added " + obj.Name+","+ obj.UUID + " to m_updateList"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -489,12 +495,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 { | ||||
|                     updates = new List<SceneObjectGroup>(m_updateList.Values); | ||||
| 
 | ||||
|                     /* | ||||
|                      | ||||
|                     if (updates.Count > 0) | ||||
|                     { | ||||
|                         m_log.Debug("SceneGraph: " + updates.Count + " objects to send updates for"); | ||||
|                         //m_log.Debug("SceneGraph.UpdateObjectGroups: " + updates.Count + " objects to send updates for"); | ||||
|                     } | ||||
|                      * */  | ||||
|                       | ||||
| 
 | ||||
| 
 | ||||
|                     m_updateList.Clear(); | ||||
|  | @ -1948,6 +1954,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|          | ||||
|         //Return false if the entity with the UUID is not a SceneObjectGroup,  | ||||
|         //otherwise, return true. | ||||
|         /* | ||||
|         protected internal bool AddOrUpdateObjectInScene(SceneObjectGroup updatedSog, bool debugWithViewer) | ||||
|         { | ||||
|             UUID sogID = updatedSog.UUID; | ||||
|  | @ -1989,6 +1996,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
| 
 | ||||
|         } | ||||
|          * */  | ||||
| 
 | ||||
|         #endregion // REGION SYNC | ||||
| 
 | ||||
|  | @ -2018,7 +2026,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|             else | ||||
|             { | ||||
|                 m_log.Debug("AddSceneObjectByStateSynch to be called"); | ||||
|                 m_log.Debug(updatedSog.Name+" "+updatedSog.UUID+" not found in Entities list. Need to add"); | ||||
|                 AddSceneObjectByStateSynch(updatedSog); | ||||
|                 updateResult = Scene.ObjectUpdateResult.New; | ||||
|             } | ||||
|  | @ -2062,6 +2070,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|             m_numPrim += children.Length; | ||||
| 
 | ||||
|             m_log.Debug("Attached obj " + sceneObject.Name + "," + sceneObject.UUID + " to Scene"); | ||||
| 
 | ||||
|             sceneObject.AttachToScene(m_parentScene); | ||||
| 
 | ||||
|             //Take some special care of the case of this object being an attachment | ||||
|  |  | |||
|  | @ -1950,7 +1950,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         //public void ScheduleGroupForTerseUpdate() | ||||
|         public void ScheduleGroupForTerseUpdate(List<SceneObjectPartProperties> updatedProperties) | ||||
|         { | ||||
| //            m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); | ||||
|            // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); | ||||
| 
 | ||||
|             SceneObjectPart[] parts = m_parts.GetArray(); | ||||
|             for (int i = 0; i < parts.Length; i++) | ||||
|  |  | |||
|  | @ -2795,7 +2795,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     m_parentGroup.AbsolutePosition = newpos; | ||||
|                     return; | ||||
|                 } | ||||
|                 m_log.DebugFormat("[PHYSICS]: TerseUpdate: UUID={0}, newpos={1}", PhysActor.UUID.ToString(), newpos.ToString()); | ||||
|                 // m_log.DebugFormat("[PHYSICS]: TerseUpdate: UUID={0}, newpos={1}", PhysActor.UUID.ToString(), newpos.ToString()); | ||||
|                 //m_parentGroup.RootPart.m_groupPosition = newpos; | ||||
|             } | ||||
|             //ScheduleTerseUpdate(); | ||||
|  | @ -2980,9 +2980,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); | ||||
|                 m_updateFlag = 1; | ||||
| 
 | ||||
|             //                m_log.DebugFormat( | ||||
|             //                    "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", | ||||
|             //                    UUID, Name, TimeStampTerse); | ||||
|                             //m_log.DebugFormat( | ||||
|                             //    "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", | ||||
|                             //    UUID, Name, TimeStampTerse); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -3203,7 +3203,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|             //SYMMETRIC SYNC | ||||
|             if (m_parentGroup.Scene.RegionSyncModule != null) | ||||
|             { | ||||
|             {                 | ||||
|                 m_parentGroup.Scene.RegionSyncModule.QueueSceneObjectPartForUpdate((SceneObjectPart)this); | ||||
|             } | ||||
|             //end of SYMMETRIC SYNC | ||||
|  | @ -5504,16 +5504,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         //buckets may not be filled at all in "updatedPart". | ||||
|         private void PhysicsBucketUpdateProcessor(Object updatedPartO, string bucketName) | ||||
|         { | ||||
|             SceneObjectPart localPart = this; | ||||
| 
 | ||||
|             if (updatedPartO is SceneObjectPart) | ||||
|             { | ||||
|                 SceneObjectPart updatedPart = (SceneObjectPart)updatedPartO; | ||||
| 
 | ||||
|                 localPart.GroupPosition = updatedPart.GroupPosition; | ||||
|                 localPart.OffsetPosition = updatedPart.OffsetPosition; | ||||
|                 localPart.Scale = updatedPart.Scale; | ||||
|                 localPart.Velocity = updatedPart.Velocity; | ||||
|                 localPart.AngularVelocity = updatedPart.AngularVelocity; | ||||
|                 localPart.RotationOffset = updatedPart.RotationOffset; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if (!(updatedPartO is OSDMap)) return; | ||||
|             OSDMap data = (OSDMap)updatedPartO; | ||||
| 
 | ||||
|             //If needed, we could define new set functions for these properties, and cast this SOP to SOPBase to  | ||||
|             //invoke the set functions in SOPBase  | ||||
|             //SceneObjectPartBase localPart = (SceneObjectPartBase)this;  | ||||
|             SceneObjectPart localPart = this; | ||||
|             //SceneObjectPart localPart = this; | ||||
|             PhysicsActor pa = localPart.PhysActor; | ||||
| 
 | ||||
|             m_log.DebugFormat("{0}: PhysicsBucketUpdateProcessor. pos={1}", "[SCENE OBJECT PART]", data["Position"].AsVector3().ToString()); | ||||
|             //m_log.Debug("Received Physics Bucket updates for " + localPart.Name + ". GroupPosition: " + data["GroupPosition"].AsVector3().ToString() | ||||
|             //    + ", Position = " + data["Position"].AsVector3().ToString()); | ||||
| 
 | ||||
|             lock (m_bucketUpdateLocks[bucketName]) | ||||
|             { | ||||
|  | @ -5612,12 +5628,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     { | ||||
|                         bucketSynInfo.TaintBucket(); | ||||
|                     } | ||||
|                     // m_log.DebugFormat("{0}: TaintBucketSyncInfo: FullUpdate", "[SCENE OBJECT PART]"); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     string bucketName = m_primPropertyBucketMap[property]; | ||||
|                     //m_bucketSyncTainted[bucketName] = true; | ||||
|                     m_bucketSyncInfoList[bucketName].TaintBucket(); | ||||
|                     // m_log.DebugFormat("{0}: TaintBucketSyncInfo: tainting bucket {1} for {2}",  | ||||
|                     //             "[SCENE OBJECT PART]", bucketName, property.ToString()); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -5758,6 +5777,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 //Second, if need to update local properties, call each bucket's update process | ||||
|                 if (m_bucketUpdateProcessors.ContainsKey(bucketName)) | ||||
|                 { | ||||
|                     //m_log.Debug("Update properties in " + bucketName + " buckets"); | ||||
| 
 | ||||
|                     m_bucketUpdateProcessors[bucketName](updatedPart, bucketName); | ||||
|                     partUpdateResult = Scene.ObjectUpdateResult.Updated; | ||||
|                 } | ||||
|  |  | |||
|  | @ -1353,7 +1353,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             SetScale(m_host, scale); | ||||
|         } | ||||
| 
 | ||||
|         //REGION SYNC TOUCHED -- set via sync'ing with remote Scene | ||||
|         protected void SetScale(SceneObjectPart part, LSL_Vector scale) | ||||
|         { | ||||
|             // TODO: this needs to trigger a persistance save as well | ||||
|  | @ -1383,21 +1382,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             if (scale.z > World.m_maxNonphys) | ||||
|                 scale.z = World.m_maxNonphys; | ||||
| 
 | ||||
|             if (World.ScriptEngineToSceneConnectorModule==null) | ||||
|             { | ||||
|                 //If Script engine is local to Scene (REGION SYNC mode=server, and XEngine enabled=true, and no remote Script Engine connected) | ||||
|                 Vector3 tmp = part.Scale; | ||||
|                 tmp.X = (float)scale.x; | ||||
|                 tmp.Y = (float)scale.y; | ||||
|                 tmp.Z = (float)scale.z; | ||||
|                 part.Scale = tmp; | ||||
|                 part.SendFullUpdateToAllClients(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 //set via sync'ing with remote Scene | ||||
|                 World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(part.ParentGroup.LocX, part.ParentGroup.LocY, part.UUID, "scale", scale); | ||||
|             } | ||||
|             Vector3 tmp = part.Scale; | ||||
|             tmp.X = (float)scale.x; | ||||
|             tmp.Y = (float)scale.y; | ||||
|             tmp.Z = (float)scale.z; | ||||
|             part.Scale = tmp; | ||||
|             part.SendFullUpdateToAllClients(); | ||||
|         } | ||||
| 
 | ||||
|         public LSL_Vector llGetScale() | ||||
|  | @ -1416,7 +1406,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         //REGION SYNC TOUCHED -- set via sync'ing with remote Scene | ||||
|         public void llSetColor(LSL_Vector color, int face) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|  | @ -1424,22 +1413,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             if (face == ScriptBaseClass.ALL_SIDES) | ||||
|                 face = SceneObjectPart.ALL_SIDES; | ||||
| 
 | ||||
|             // REGION SYNC | ||||
|             if (World.ScriptEngineToSceneConnectorModule == null) | ||||
|             { | ||||
|                 m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 object[] valParams = new object[2]; | ||||
|                 //valParams[0] = (object)color.x; | ||||
|                 //valParams[1] = (object)color.y; | ||||
|                 //valParams[2] = (object)color.z; | ||||
|                 Vector3 vcolor = new Vector3((float)color.x, (float)color.y, (float)color.z); | ||||
|                 valParams[0] = (object)vcolor; | ||||
|                 valParams[1] = (object)face; | ||||
|                 World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "color", (object)valParams); | ||||
|             } | ||||
|             m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); | ||||
|         } | ||||
| 
 | ||||
|         public void SetTexGen(SceneObjectPart part, int face,int style) | ||||
|  | @ -2766,7 +2740,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             ScriptSleep(100); | ||||
|         } | ||||
| 
 | ||||
|         //REGION SYNC TOUCHED -- set via sync'ing with remote Scene | ||||
|         public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) | ||||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|  | @ -2778,39 +2751,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             if (dist > m_ScriptDistanceFactor * 10.0f) | ||||
|                 return; | ||||
| 
 | ||||
|             if (World.ScriptEngineToSceneConnectorModule == null) | ||||
|             TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); | ||||
| 
 | ||||
|             foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) | ||||
|             { | ||||
|                 //if Scene co-locates with Script Engine | ||||
| 
 | ||||
|                 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); | ||||
| 
 | ||||
|                 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) | ||||
|                 if (inv.Value.Name == inventory) | ||||
|                 { | ||||
|                     if (inv.Value.Name == inventory) | ||||
|                     // make sure we're an object. | ||||
|                     if (inv.Value.InvType != (int)InventoryType.Object) | ||||
|                     { | ||||
|                         // 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."); | ||||
|                             return; | ||||
|                         } | ||||
|                         llSay(0, "Unable to create requested object. Object is missing from database."); | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                         Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); | ||||
|                         Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z); | ||||
|                     Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); | ||||
|                     Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z); | ||||
| 
 | ||||
|                         // need the magnitude later | ||||
|                         float velmag = (float)Util.GetMagnitude(llvel); | ||||
|                     // need the magnitude later | ||||
|                     float velmag = (float)Util.GetMagnitude(llvel); | ||||
| 
 | ||||
|                         SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param); | ||||
|                     SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(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; | ||||
|                     // 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); | ||||
|                     // objects rezzed with this method are die_at_edge by default. | ||||
|                     new_group.RootPart.SetDieAtEdge(true); | ||||
| 
 | ||||
|                     new_group.ResumeScripts(); | ||||
| 
 | ||||
|  | @ -2818,45 +2787,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                             "object_rez", new Object[] { | ||||
|                             new LSL_String( | ||||
|                             new_group.RootPart.UUID.ToString()) }, | ||||
|                                 new DetectParams[0])); | ||||
|                             new DetectParams[0])); | ||||
| 
 | ||||
|                         float groupmass = new_group.GetMass(); | ||||
|                     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); | ||||
|                         } | ||||
|                         // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | ||||
|                         ScriptSleep((int)((groupmass * velmag) / 10)); | ||||
|                         ScriptSleep(100); | ||||
|                         return; | ||||
|                     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); | ||||
|                     } | ||||
|                     // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | ||||
|                     ScriptSleep((int)((groupmass * velmag) / 10)); | ||||
|                     ScriptSleep(100); | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 llSay(0, "Could not find object " + inventory); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 //Scene does not co-locate with Script Engine | ||||
|                 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); | ||||
|                 Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z); | ||||
|                 Quaternion llrot = Rot2Quaternion(rot); | ||||
|                 object[] valParams = new object[5]; | ||||
|                 valParams[0] = (object)inventory; | ||||
|                 valParams[1] = (object)llpos; | ||||
|                 valParams[2] = (object)llpos; | ||||
|                 valParams[3] = (object)llrot; | ||||
|                 valParams[4] = (object)param; | ||||
|                 //we borrow the implementation SendSetPrimProperties to send the message to Scene | ||||
|                 World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "object_rez", (object)valParams); | ||||
| 
 | ||||
|                 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | ||||
|                 //ScriptSleep((int)((groupmass * velmag) / 10)); | ||||
|                 ScriptSleep(100); | ||||
|             } | ||||
|             llSay(0, "Could not find object " + inventory); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) | ||||
|         { | ||||
|             llRezAtRoot(inventory, pos, vel, rot, param); | ||||
|  | @ -3412,8 +3362,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 item = m_host.TaskInventory[invItemID]; | ||||
|             } | ||||
| 
 | ||||
|             if (agentID == UUID.Zero || perm == 0) // Releasing permissions | ||||
|             { | ||||
|             //if (agentID == UUID.Zero || perm == 0) // Releasing permissions | ||||
|             //{ | ||||
|                 llReleaseControls(); | ||||
| 
 | ||||
|                 item.PermsGranter = UUID.Zero; | ||||
|  | @ -3425,7 +3375,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                         new DetectParams[0])); | ||||
| 
 | ||||
|                 return; | ||||
|             } | ||||
|             //} | ||||
| 
 | ||||
|             if (item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) | ||||
|                 llReleaseControls(); | ||||
|  | @ -3635,6 +3585,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 return; // Fail silently if attached | ||||
|             SceneObjectGroup parentPrim = null, childPrim = null; | ||||
| 
 | ||||
|             //SYEMMETRIC SYNC | ||||
|             List<SceneObjectPart> children = new List<SceneObjectPart>(); | ||||
| 
 | ||||
|             if (targetPart != null) | ||||
|             { | ||||
|                 if (parent != 0) { | ||||
|  | @ -3646,6 +3599,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     parentPrim = targetPart.ParentGroup; | ||||
|                     childPrim = m_host.ParentGroup; | ||||
|                 } | ||||
|                 children.Add(childPrim.RootPart); | ||||
| 
 | ||||
| //                byte uf = childPrim.RootPart.UpdateFlag; | ||||
|                 childPrim.RootPart.UpdateFlag = 0; | ||||
|                 parentPrim.LinkToGroup(childPrim); | ||||
|  | @ -3664,7 +3619,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             { | ||||
|                 //Tell other actors to link the SceneObjectParts together as a new group.  | ||||
|                 //parentGroup.SyncInfoUpdate(); | ||||
|                 World.RegionSyncModule.SendLinkObject(parentPrim, parentPrim.RootPart, new List<SceneObjectPart>(childPrim.Parts)); | ||||
|                 World.RegionSyncModule.SendLinkObject(parentPrim, parentPrim.RootPart, children); | ||||
|             } | ||||
|             m_host.ScheduleFullUpdate(new List<SceneObjectPartProperties>(){SceneObjectPartProperties.None}); //SendLinkObject above will synchronize the link operation, no need to taint updates here | ||||
|             //end of SYMMETRIC SYNC | ||||
|  |  | |||
|  | @ -741,7 +741,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
|                         } | ||||
|                         catch (Exception e) | ||||
|                         { | ||||
|                              m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message); | ||||
|                             m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message); | ||||
|                             m_InEvent = false; | ||||
|                             m_CurrentEvent = String.Empty; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Dan Lake
						Dan Lake