internal void InternalSaveWorld()
        {
            try
            {
                DateTime saveStartTime = DateTime.Now;

                Type   type     = BackingObject.GetType();
                Type[] argTypes = new Type[1];
                argTypes[0] = typeof(string);
                bool result = (bool)BaseObject.InvokeEntityMethod(BackingObject, WorldManagerSaveWorldMethod, new object[] { null }, argTypes);

                if (result)
                {
                    TimeSpan timeToSave = DateTime.Now - saveStartTime;
                    LogManager.APILog.WriteLineAndConsole("Save complete and took " + timeToSave.TotalSeconds + " seconds");
                    m_isSaving = false;

                    EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
                    newEvent.type      = EntityEventManager.EntityEventType.OnSectorSaved;
                    newEvent.timestamp = DateTime.Now;
                    newEvent.entity    = null;
                    newEvent.priority  = 0;
                    EntityEventManager.Instance.AddEvent(newEvent);
                }
                else
                {
                    LogManager.APILog.WriteLineAndConsole("Save failed!");
                    m_isSaving = false;
                }
            }
            catch (Exception ex)
            {
                LogManager.ErrorLog.WriteLine(ex);
            }
        }
 private static void TriggerWorldSendEvent(ulong steamId)
 {
     EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
     newEvent.type      = EntityEventManager.EntityEventType.OnPlayerWorldSent;
     newEvent.timestamp = DateTime.Now;
     newEvent.entity    = steamId;
     newEvent.priority  = 0;
     EntityEventManager.Instance.AddEvent(newEvent);
 }
Пример #3
0
        public CharacterEntity(MyObjectBuilder_Character definition, Object backingObject)
            : base(definition, backingObject)
        {
            m_inventory = new InventoryEntity(definition.Inventory, InternalGetCharacterInventory());

            EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
            newEvent.type = EntityEventManager.EntityEventType.OnCharacterCreated;
            newEvent.timestamp = DateTime.Now;
            newEvent.entity = this;
            newEvent.priority = 1;
            EntityEventManager.Instance.AddEvent(newEvent);
        }
Пример #4
0
        internal void InternalSaveWorld( )
        {
            try
            {
                DateTime saveStartTime = DateTime.Now;

                Type   type     = BackingObject.GetType( );
                Type[] argTypes = new Type[1];
                argTypes[0] = typeof(string);
                bool result = (bool)BaseObject.InvokeEntityMethod(BackingObject, WorldManagerSaveWorldMethod, new object[] { null }, argTypes);

                if (result)
                {
                    TimeSpan timeToSave = DateTime.Now - saveStartTime;
                    ApplicationLog.BaseLog.Info("Save complete and took {0} seconds", timeToSave.TotalSeconds);
                    m_isSaving = false;

                    EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent( );
                    newEvent.type      = EntityEventManager.EntityEventType.OnSectorSaved;
                    newEvent.timestamp = DateTime.Now;
                    newEvent.entity    = null;
                    newEvent.priority  = 0;
                    EntityEventManager.Instance.AddEvent(newEvent);
                }
                else
                {
                    ApplicationLog.BaseLog.Error("Save failed!");
                }

                OnWorldSaved( );
            }
            catch (Exception ex)
            {
                ApplicationLog.BaseLog.Error(ex);
            }
            finally
            {
                m_isSaving = false;
            }
        }
Пример #5
0
        public void AsynchronousSaveWorld( )
        {
            if (m_isSaving)
            {
                ApplicationLog.BaseLog.Error("Tried to initiate a save while another is already in progress!");
                return;
            }

            m_isSaving = true;

            try
            {
                ApplicationLog.BaseLog.Info("Asynchronous save started");
                DateTime saveStartTime = DateTime.Now;
                Task.Run(() =>
                {
                    SandboxGameAssemblyWrapper.Instance.GameAction(() =>
                    {
                        MyAsyncSaving.Start(() =>
                        {
                            MySector.ResetEyeAdaptation = true;
                            ApplicationLog.BaseLog.Info("Asynchronous Save Setup Started: {0}ms",
                                                        (DateTime.Now - saveStartTime)
                                                        .TotalMilliseconds);
                        });
                    });

                    // Autosave can fail to complete sometimes; alert the admin when this happens
                    DateTime start            = DateTime.Now;
                    FastResourceLock saveLock = InternalGetResourceLock();
                    while (!saveLock.Owned)
                    {
                        if (DateTime.Now - start > TimeSpan.FromMilliseconds(20000))
                        {
                            ApplicationLog.BaseLog.Warn("Autosave failed to start!");
                            return;
                        }

                        Thread.Sleep(1);
                    }

                    while (saveLock.Owned)
                    {
                        if (DateTime.Now - start > TimeSpan.FromMilliseconds(120000))
                        {
                            ApplicationLog.BaseLog.Warn("Autosave has ran for 120 seconds--something is wrong! The save will most likely not complete!");
                            MyAPIGateway.Utilities.SendMessage("Warning: SESE Autosave failed! Alert the server admin!");
                            return;
                        }

                        Thread.Sleep(1);
                    }

                    ApplicationLog.BaseLog.Info($"Asynchronous Save Completed: {(DateTime.Now - saveStartTime).TotalMilliseconds}ms");
                    OnWorldSaved();
                    EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent
                    {
                        type      = EntityEventManager.EntityEventType.OnSectorSaved,
                        timestamp = DateTime.Now,
                        entity    = null,
                        priority  = 0
                    };
                    EntityEventManager.Instance.AddEvent(newEvent);
                });
            }
            catch (Exception ex)
            {
                ApplicationLog.BaseLog.Error(ex, "Exception in asynchronous save.");
            }
            finally
            {
                m_isSaving = false;
            }

            /*
             * try
             * {
             *      DateTime saveStartTime = DateTime.Now;
             *
             *      // It looks like keen as an overloaded save function that returns the WorldResourceManager after setting up a save, and then
             *      // allows you to write to disk from a separate thread?  Why aren't they using this on normal saves?!
             *      bool result = false;
             *      String arg0 = null;
             *      Object[] parameters =
             *      {
             *              null,
             *              arg0,
             *      };
             *
             *      Type[] paramTypes =
             *      {
             *              SandboxGameAssemblyWrapper.Instance.GetAssemblyType(WorldResourceManagerNamespace, WorldResourceManagerClass).MakeByRefType(),
             *              typeof(string),
             *      };
             *
             *      // Run overloaded save function with extra an out parameter that is set to a WorldResourceManagerClass
             *      SandboxGameAssemblyWrapper.Instance.GameAction(() =>
             *      {
             *              result = (bool)BaseObject.InvokeEntityMethod(BackingObject, WorldManagerSaveWorldMethod, parameters, paramTypes);
             *      });
             *
             *
             *      // Write to disk on a different thread using the WorldResourceManagerClass in the parameter
             *      ThreadPool.QueueUserWorkItem(new WaitCallback((object state) =>
             *      {
             *              if (result)
             *              {
             *                      ApplicationLog.BaseLog.Info((string.Format("Asynchronous Save Setup Time: {0}ms", (DateTime.Now - saveStartTime).TotalMilliseconds));
             *                      saveStartTime = DateTime.Now;
             *                      result = (bool)BaseObject.InvokeEntityMethod(parameters[0], WorldManagerSaveSnapshot);
             *              }
             *              else
             *              {
             *                      ApplicationLog.BaseLog.Error("Failed to save world (1)");
             *                      return;
             *              }
             *
             *              if (result)
             *              {
             *                      ApplicationLog.BaseLog.Info((string.Format("Asynchronous Save Successful: {0}ms", (DateTime.Now - saveStartTime).TotalMilliseconds));
             *              }
             *              else
             *              {
             *                      ApplicationLog.BaseLog.Error("Failed to save world (2)");
             *                      return;
             *              }
             *
             *              EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
             *              newEvent.type = EntityEventManager.EntityEventType.OnSectorSaved;
             *              newEvent.timestamp = DateTime.Now;
             *              newEvent.entity = null;
             *              newEvent.priority = 0;
             *              EntityEventManager.Instance.AddEvent(newEvent);
             *      }));
             * }
             * catch (Exception ex)
             * {
             *      ApplicationLog.BaseLog.Error(ex);
             * }
             * finally
             * {
             *      m_isSaving = false;
             * }
             */
        }
Пример #6
0
        public void AsynchronousSaveWorld( )
        {
            if (m_isSaving)
            {
                return;
            }

            m_isSaving = true;

            try
            {
                DateTime saveStartTime = DateTime.Now;

                Task.Factory.StartNew(() =>
                {
                    SandboxGameAssemblyWrapper.Instance.GameAction(() =>
                    {
                        Type type = SandboxGameAssemblyWrapper.Instance.GetAssemblyType(WorldSnapshotNamespace, WorldSnapshotStaticClass);
                        BaseObject.InvokeStaticMethod(type,
                                                      WorldSnapshotSaveMethod,
                                                      new object[]
                        {
                            new Action(() =>
                            {
                                ApplicationLog.BaseLog.Info("Asynchronous Save Setup Started: {0}ms",
                                                            (DateTime.Now - saveStartTime)
                                                            .TotalMilliseconds);
                            }),
                            null
                        });
                    });

                    // Ugly -- Get rid of this?
                    DateTime start            = DateTime.Now;
                    FastResourceLock saveLock = InternalGetResourceLock( );
                    while (!saveLock.Owned)
                    {
                        if (DateTime.Now - start > TimeSpan.FromMilliseconds(20000))
                        {
                            return;
                        }

                        Thread.Sleep(1);
                    }

                    while (saveLock.Owned)
                    {
                        if (DateTime.Now - start > TimeSpan.FromMilliseconds(60000))
                        {
                            return;
                        }

                        Thread.Sleep(1);
                    }

                    ApplicationLog.BaseLog.Info("Asynchronous Save Completed: {0}ms", (DateTime.Now - saveStartTime).TotalMilliseconds);
                    OnWorldSaved( );
                    EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent
                    {
                        type      = EntityEventManager.EntityEventType.OnSectorSaved,
                        timestamp = DateTime.Now,
                        entity    = null,
                        priority  = 0
                    };
                    EntityEventManager.Instance.AddEvent(newEvent);
                });
            }
            catch (Exception ex)
            {
            }
            finally
            {
                m_isSaving = false;
            }

            /*
             * try
             * {
             *      DateTime saveStartTime = DateTime.Now;
             *
             *      // It looks like keen as an overloaded save function that returns the WorldResourceManager after setting up a save, and then
             *      // allows you to write to disk from a separate thread?  Why aren't they using this on normal saves?!
             *      bool result = false;
             *      String arg0 = null;
             *      Object[] parameters =
             *      {
             *              null,
             *              arg0,
             *      };
             *
             *      Type[] paramTypes =
             *      {
             *              SandboxGameAssemblyWrapper.Instance.GetAssemblyType(WorldResourceManagerNamespace, WorldResourceManagerClass).MakeByRefType(),
             *              typeof(string),
             *      };
             *
             *      // Run overloaded save function with extra an out parameter that is set to a WorldResourceManagerClass
             *      SandboxGameAssemblyWrapper.Instance.GameAction(() =>
             *      {
             *              result = (bool)BaseObject.InvokeEntityMethod(BackingObject, WorldManagerSaveWorldMethod, parameters, paramTypes);
             *      });
             *
             *
             *      // Write to disk on a different thread using the WorldResourceManagerClass in the parameter
             *      ThreadPool.QueueUserWorkItem(new WaitCallback((object state) =>
             *      {
             *              if (result)
             *              {
             *                      ApplicationLog.BaseLog.Info((string.Format("Asynchronous Save Setup Time: {0}ms", (DateTime.Now - saveStartTime).TotalMilliseconds));
             *                      saveStartTime = DateTime.Now;
             *                      result = (bool)BaseObject.InvokeEntityMethod(parameters[0], WorldManagerSaveSnapshot);
             *              }
             *              else
             *              {
             *                      ApplicationLog.BaseLog.Error("Failed to save world (1)");
             *                      return;
             *              }
             *
             *              if (result)
             *              {
             *                      ApplicationLog.BaseLog.Info((string.Format("Asynchronous Save Successful: {0}ms", (DateTime.Now - saveStartTime).TotalMilliseconds));
             *              }
             *              else
             *              {
             *                      ApplicationLog.BaseLog.Error("Failed to save world (2)");
             *                      return;
             *              }
             *
             *              EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
             *              newEvent.type = EntityEventManager.EntityEventType.OnSectorSaved;
             *              newEvent.timestamp = DateTime.Now;
             *              newEvent.entity = null;
             *              newEvent.priority = 0;
             *              EntityEventManager.Instance.AddEvent(newEvent);
             *      }));
             * }
             * catch (Exception ex)
             * {
             *      ApplicationLog.BaseLog.Error(ex);
             * }
             * finally
             * {
             *      m_isSaving = false;
             * }
             */
        }
Пример #7
0
        public override void Dispose()
        {
            m_isDisposed = true;

            if(SandboxGameAssemblyWrapper.IsDebugging)
                LogManager.APILog.WriteLine("Disposing CubeBlockEntity '" + Name + "'");

            Parent.DeleteCubeBlock(this);

            //Only enable events for non-structural blocks, for now
            if (ObjectBuilder.EntityId != 0)
            {
                EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
                newEvent.type = EntityEventManager.EntityEventType.OnCubeBlockDeleted;
                newEvent.timestamp = DateTime.Now;
                newEvent.entity = this;
                newEvent.priority = 1;
                EntityEventManager.Instance.AddEvent(newEvent);
            }

            base.Dispose();
        }
Пример #8
0
		public override void Dispose( )
		{
			if ( IsDisposed )
				return;

			base.Dispose( );

			if ( BackingObject != null )
			{
				//Only remove if the backing object isn't already disposed
				bool isDisposed = (bool)InvokeEntityMethod( BackingObject, BaseEntityGetIsDisposedMethod );
				if ( !isDisposed )
				{
					m_networkManager.RemoveEntity( );

					MySandboxGame.Static.Invoke( InternalRemoveEntity );
				}
			}

			if ( EntityId != 0 )
			{
				GameEntityManager.RemoveEntity( EntityId );
			}

			EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent( );
			newEvent.type = EntityEventManager.EntityEventType.OnBaseEntityDeleted;
			newEvent.timestamp = DateTime.Now;
			newEvent.entity = this;
			newEvent.priority = 1;
			EntityEventManager.Instance.AddEvent( newEvent );
		}
Пример #9
0
        protected void InternalEntityMovedEvent(Object entity)
        {
            try
            {
                if (IsDisposed)
                    return;

                EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
                newEvent.type = EntityEventManager.EntityEventType.OnBaseEntityMoved;
                newEvent.timestamp = DateTime.Now;
                newEvent.entity = this;
                newEvent.priority = 10;
                EntityEventManager.Instance.AddEvent(newEvent);
            }
            catch (Exception ex)
            {
                LogManager.ErrorLog.WriteLine(ex);
            }
        }
Пример #10
0
		public override void Dispose( )
		{
			m_isDisposed = true;

			Parent.DeleteCubeBlock( this );

			EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent( );
			newEvent.type = EntityEventManager.EntityEventType.OnCubeBlockDeleted;
			newEvent.timestamp = DateTime.Now;
			newEvent.entity = this;
			newEvent.priority = (ushort)( ( EntityId != 0 ) ? 1 : 2 );
			EntityEventManager.Instance.AddEvent( newEvent );

			if ( EntityId != 0 )
			{
				GameEntityManager.RemoveEntity( EntityId );
			}

			base.Dispose( );
		}
        public override void Dispose( )
        {
            if ( ExtenderOptions.IsDebugging )
                ApplicationLog.BaseLog.Debug( "Disposing CubeGridEntity '" + Name + "' ..." );

            //Dispose the cube grid by disposing all of the blocks
            //This may be slow but it's reliable ... so far
            /*
            List<CubeBlockEntity> blocks = CubeBlocks;
            int blockCount = blocks.Count;
            foreach (CubeBlockEntity cubeBlock in blocks)
            {
                cubeBlock.Dispose();
            }
            if (ExtenderOptions.IsDebugging)
                ApplicationLog.BaseLog.Debug("Disposed " + blockCount.ToString() + " blocks on CubeGridEntity '" + Name + "'");
            */
            //Broadcast the removal to the clients just to save processing time for the clients
            BaseNetworkManager.RemoveEntity( );

            m_isDisposed = true;

            if ( EntityId != 0 )
            {
                GameEntityManager.RemoveEntity( EntityId );
            }

            EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent
            {
                type = EntityEventManager.EntityEventType.OnCubeGridDeleted,
                timestamp = DateTime.Now,
                entity = this,
                priority = 1
            };
            EntityEventManager.Instance.AddEvent( newEvent );
        }
        public CubeGridEntity( MyObjectBuilder_CubeGrid definition, Object backingObject )
            : base(definition, backingObject)
        {
            _cubeBlockManager = new CubeBlockManager( this, backingObject, CubeGridGetCubeBlocksHashSetMethod );
            _cubeBlockManager.Refresh( );

            _networkManager = new CubeGridNetworkManager( this );
            _managerManager = new CubeGridManagerManager( this, GetManagerManager( ) );

            EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent
            {
                type = EntityEventManager.EntityEventType.OnCubeGridCreated,
                timestamp = DateTime.Now,
                entity = this,
                priority = 1
            };
            EntityEventManager.Instance.AddEvent( newEvent );

            _lastNameRefresh = DateTime.Now;
            _name = "Cube Grid";
        }
Пример #13
0
        public override void Dispose()
        {
            if(SandboxGameAssemblyWrapper.IsDebugging)
                LogManager.APILog.WriteLine("Disposing CubeGridEntity '" + Name + "' ...");

            //Dispose the cube grid by disposing all of the blocks
            //This may be slow but it's reliable ... so far
            List<CubeBlockEntity> blocks = CubeBlocks;
            int blockCount = blocks.Count;
            foreach (CubeBlockEntity cubeBlock in blocks)
            {
                cubeBlock.Dispose();
            }

            if (SandboxGameAssemblyWrapper.IsDebugging)
                LogManager.APILog.WriteLine("Disposed " + blockCount.ToString() + " blocks on CubeGridEntity '" + Name + "'");

            //Broadcast the removal to the clients just to save processing time for the clients
            BaseNetworkManager.RemoveEntity();

            m_isDisposed = true;

            EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
            newEvent.type = EntityEventManager.EntityEventType.OnCubeGridDeleted;
            newEvent.timestamp = DateTime.Now;
            newEvent.entity = this;
            newEvent.priority = 1;
            EntityEventManager.Instance.AddEvent(newEvent);
        }
Пример #14
0
        public void Update()
        {
            if (!Initialized)
                return;
            if (!SandboxGameAssemblyWrapper.Instance.IsGameStarted)
                return;

            m_lastUpdateTime = DateTime.Now - m_lastUpdate;
            m_averageUpdateInterval = (m_averageUpdateTime + m_lastUpdateTime.TotalMilliseconds) / 2;
            m_lastUpdate = DateTime.Now;

            EntityEventManager.Instance.ResourceLocked = true;

            List<EntityEventManager.EntityEvent> events = EntityEventManager.Instance.EntityEvents;
            List<ChatManager.ChatEvent> chatEvents = ChatManager.Instance.ChatEvents;

            //Generate the player join/leave events here
            List<ulong> connectedPlayers = PlayerManager.Instance.ConnectedPlayers;
            try
            {
                foreach (ulong steamId in connectedPlayers)
                {
                    if (!m_lastConnectedPlayerList.Contains(steamId))
                    {
                        EntityEventManager.EntityEvent playerEvent = new EntityEventManager.EntityEvent();
                        playerEvent.priority = 1;
                        playerEvent.timestamp = DateTime.Now;
                        playerEvent.type = EntityEventManager.EntityEventType.OnPlayerJoined;
                        //TODO - Find a way to stall the event long enough for a linked character entity to exist - this is impossible because of cockpits and respawnships
                        //For now, create a dummy entity just for passing the player's steam id along
                        playerEvent.entity = (Object)steamId;
                        events.Add(playerEvent);
                    }
                }
                foreach (ulong steamId in m_lastConnectedPlayerList)
                {
                    if (!connectedPlayers.Contains(steamId))
                    {
                        EntityEventManager.EntityEvent playerEvent = new EntityEventManager.EntityEvent();
                        playerEvent.priority = 1;
                        playerEvent.timestamp = DateTime.Now;
                        playerEvent.type = EntityEventManager.EntityEventType.OnPlayerLeft;
                        //TODO - Find a way to stall the event long enough for a linked character entity to exist - this is impossible because of cockpits and respawnships
                        //For now, create a dummy entity just for passing the player's steam id along
                        playerEvent.entity = (Object)steamId;
                        events.Add(playerEvent);
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.APILog.WriteLine("PluginManager.Update() Exception in player discovery: " + ex.ToString());
            }
            m_lastConnectedPlayerList = new List<ulong>(connectedPlayers);

            //Run the update threads on the plugins
            foreach (var key in m_plugins.Keys)
            {
                var plugin = m_plugins[key];

                if (!m_pluginState.ContainsKey(key))
                    continue;

                PluginManagerThreadParams parameters = new PluginManagerThreadParams();
                parameters.plugin = plugin;
                parameters.key = key;
                parameters.events = new List<EntityEventManager.EntityEvent>(events);
                parameters.chatEvents = new List<ChatManager.ChatEvent>(chatEvents);

                Thread pluginThread = new Thread(DoUpdate);
                pluginThread.Start(parameters);
            }

            //Capture profiling info if debugging is on
            if (SandboxGameAssemblyWrapper.IsDebugging)
            {
                m_averageEvents = (m_averageEvents + (events.Count + chatEvents.Count)) / 2;

                TimeSpan updateTime = DateTime.Now - m_lastUpdate;
                m_averageUpdateTime = (m_averageUpdateTime + updateTime.TotalMilliseconds) / 2;

                TimeSpan timeSinceAverageOutput = DateTime.Now - m_lastAverageOutput;
                if (timeSinceAverageOutput.TotalSeconds > 30)
                {
                    m_lastAverageOutput = DateTime.Now;

                    LogManager.APILog.WriteLine("PluginManager - Update interval = " + m_averageUpdateInterval.ToString() + "ms");
                    LogManager.APILog.WriteLine("PluginManager - Update time = " + m_averageUpdateTime.ToString() + "ms");
                    LogManager.APILog.WriteLine("PluginManager - Events per update = " + m_averageEvents.ToString());
                }
            }

            //Clean up the event managers
            EntityEventManager.Instance.ClearEvents();
            EntityEventManager.Instance.ResourceLocked = false;
            ChatManager.Instance.ClearEvents();
        }
Пример #15
0
		internal void InternalSaveWorld( )
		{
			try
			{
				DateTime saveStartTime = DateTime.Now;

				Type type = BackingObject.GetType( );
				Type[ ] argTypes = new Type[ 1 ];
				argTypes[ 0 ] = typeof( string );
				bool result = (bool)BaseObject.InvokeEntityMethod( BackingObject, WorldManagerSaveWorldMethod, new object[ ] { null }, argTypes );

				if ( result )
				{
					TimeSpan timeToSave = DateTime.Now - saveStartTime;
					ApplicationLog.BaseLog.Info( "Save complete and took {0} seconds", timeToSave.TotalSeconds );
					m_isSaving = false;

					EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent( );
					newEvent.type = EntityEventManager.EntityEventType.OnSectorSaved;
					newEvent.timestamp = DateTime.Now;
					newEvent.entity = null;
					newEvent.priority = 0;
					EntityEventManager.Instance.AddEvent( newEvent );
				}
				else
				{
					ApplicationLog.BaseLog.Error( "Save failed!" );
				}

				OnWorldSaved( );
			}
			catch ( Exception ex )
			{
				ApplicationLog.BaseLog.Error( ex );
			}
			finally
			{
				m_isSaving = false;
			}
		}
Пример #16
0
		public void AsynchronousSaveWorld( )
		{
			if ( m_isSaving )
				return;

			m_isSaving = true;

			try
			{
				DateTime saveStartTime = DateTime.Now;

				Task.Factory.StartNew( ( ) =>
				                       {
					                       SandboxGameAssemblyWrapper.Instance.GameAction( ( ) =>
					                                                                       {
						                                                                       Type type = SandboxGameAssemblyWrapper.Instance.GetAssemblyType( WorldSnapshotNamespace, WorldSnapshotStaticClass );
						                                                                       BaseObject.InvokeStaticMethod( type,
						                                                                                                      WorldSnapshotSaveMethod,
						                                                                                                      new object[ ]
						                                                                                                      {
							                                                                                                      new Action( ( ) =>
							                                                                                                                  {
								                                                                                                                  ApplicationLog.BaseLog.Info( "Asynchronous Save Setup Started: {0}ms",
								                                                                                                                                               ( DateTime.Now - saveStartTime )
									                                                                                                                                               .TotalMilliseconds );
							                                                                                                                  } ),
							                                                                                                      null
						                                                                                                      } );
					                                                                       } );

					                       // Ugly -- Get rid of this?
					                       DateTime start = DateTime.Now;
					                       FastResourceLock saveLock = InternalGetResourceLock( );
					                       while ( !saveLock.Owned )
					                       {
						                       if ( DateTime.Now - start > TimeSpan.FromMilliseconds( 20000 ) )
							                       return;

						                       Thread.Sleep( 1 );
					                       }

					                       while ( saveLock.Owned )
					                       {
						                       if ( DateTime.Now - start > TimeSpan.FromMilliseconds( 60000 ) )
							                       return;

						                       Thread.Sleep( 1 );
					                       }

					                       ApplicationLog.BaseLog.Info( "Asynchronous Save Completed: {0}ms", ( DateTime.Now - saveStartTime ).TotalMilliseconds );
					                       OnWorldSaved( );
					                       EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent
					                                                                 {
						                                                                 type = EntityEventManager.EntityEventType.OnSectorSaved,
						                                                                 timestamp = DateTime.Now,
						                                                                 entity = null,
						                                                                 priority = 0
					                                                                 };
					                       EntityEventManager.Instance.AddEvent( newEvent );
				                       } );

			}
			catch ( Exception ex )
			{
			}
			finally
			{
				m_isSaving = false;
			}

			/*
			try
			{
				DateTime saveStartTime = DateTime.Now;

				// It looks like keen as an overloaded save function that returns the WorldResourceManager after setting up a save, and then
				// allows you to write to disk from a separate thread?  Why aren't they using this on normal saves?!
				bool result = false;
				String arg0 = null;
				Object[] parameters =
				{
					null,
					arg0,
				};

				Type[] paramTypes =
				{
					SandboxGameAssemblyWrapper.Instance.GetAssemblyType(WorldResourceManagerNamespace, WorldResourceManagerClass).MakeByRefType(),
					typeof(string),
				};

				// Run overloaded save function with extra an out parameter that is set to a WorldResourceManagerClass
				SandboxGameAssemblyWrapper.Instance.GameAction(() =>
				{
					result = (bool)BaseObject.InvokeEntityMethod(BackingObject, WorldManagerSaveWorldMethod, parameters, paramTypes);
				});

			 *
				// Write to disk on a different thread using the WorldResourceManagerClass in the parameter
				ThreadPool.QueueUserWorkItem(new WaitCallback((object state) =>
				{
					if (result)
					{
						ApplicationLog.BaseLog.Info((string.Format("Asynchronous Save Setup Time: {0}ms", (DateTime.Now - saveStartTime).TotalMilliseconds));
						saveStartTime = DateTime.Now;
						result = (bool)BaseObject.InvokeEntityMethod(parameters[0], WorldManagerSaveSnapshot);
					}
					else
					{
						ApplicationLog.BaseLog.Error("Failed to save world (1)");
						return;
					}

					if (result)
					{
						ApplicationLog.BaseLog.Info((string.Format("Asynchronous Save Successful: {0}ms", (DateTime.Now - saveStartTime).TotalMilliseconds));
					}
					else
					{
						ApplicationLog.BaseLog.Error("Failed to save world (2)");
						return;
					}

					EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
					newEvent.type = EntityEventManager.EntityEventType.OnSectorSaved;
					newEvent.timestamp = DateTime.Now;
					newEvent.entity = null;
					newEvent.priority = 0;
					EntityEventManager.Instance.AddEvent(newEvent);
				}));
			}
			catch (Exception ex)
			{
				ApplicationLog.BaseLog.Error(ex);
			}
			finally
			{
				m_isSaving = false;
			}
			 */
		}
Пример #17
0
 protected void InternalCubeGridMovedEvent(Object entity)
 {
     try
     {
         EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
         newEvent.type = EntityEventManager.EntityEventType.OnCubeGridMoved;
         newEvent.timestamp = DateTime.Now;
         newEvent.entity = this;
         newEvent.priority = 9;
         EntityEventManager.Instance.AddEvent(newEvent);
     }
     catch (Exception ex)
     {
         LogManager.ErrorLog.WriteLine(ex);
     }
 }
 protected void InternalCubeGridMovedEvent( Object entity )
 {
     try
     {
         EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent
         {
             type = EntityEventManager.EntityEventType.OnCubeGridMoved,
             timestamp = DateTime.Now,
             entity = this,
             priority = 9
         };
         EntityEventManager.Instance.AddEvent( newEvent );
     }
     catch ( Exception ex )
     {
         ApplicationLog.BaseLog.Error( ex );
     }
 }
Пример #19
0
        public override void Dispose()
        {
            m_isDisposed = true;

            LogManager.APILog.WriteLine("Disposing CharacterEntity '" + Name + "'");

            EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
            newEvent.type = EntityEventManager.EntityEventType.OnCharacterDeleted;
            newEvent.timestamp = DateTime.Now;
            newEvent.entity = this;
            newEvent.priority = 1;
            EntityEventManager.Instance.AddEvent(newEvent);

            base.Dispose();
        }
Пример #20
0
        public override void Dispose()
        {
            if (IsDisposed)
                return;

            base.Dispose();

            if (BackingObject != null)
            {
                //Only move and remove if the backing object isn't already disposed
                bool isDisposed = (bool)BaseEntity.InvokeEntityMethod(BackingObject, BaseEntity.BaseEntityGetIsDisposedMethod);
                if (!isDisposed)
                {
                    m_networkManager.RemoveEntity();

                    Action action = InternalRemoveEntity;
                    SandboxGameAssemblyWrapper.Instance.EnqueueMainGameAction(action);
                }
            }

            EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
            newEvent.type = EntityEventManager.EntityEventType.OnBaseEntityDeleted;
            newEvent.timestamp = DateTime.Now;
            newEvent.entity = this;
            newEvent.priority = 1;
            EntityEventManager.Instance.AddEvent(newEvent);
        }
		internal void InternalSaveWorld()
		{
			try
			{
				DateTime saveStartTime = DateTime.Now;

				Type type = BackingObject.GetType();
				Type[] argTypes = new Type[1];
				argTypes[0] = typeof(string);

				m_isSaving = true;
				bool result = (bool)BaseObject.InvokeEntityMethod(BackingObject, WorldManagerSaveWorldMethod, new object[] { null }, argTypes);
				m_isSaving = false;

				if (result)
				{
					TimeSpan timeToSave = DateTime.Now - saveStartTime;
					LogManager.APILog.WriteLineAndConsole("Save complete and took " + timeToSave.TotalSeconds + " seconds");

					EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
					newEvent.type = EntityEventManager.EntityEventType.OnSectorSaved;
					newEvent.timestamp = DateTime.Now;
					newEvent.entity = null;
					newEvent.priority = 0;
					EntityEventManager.Instance.AddEvent(newEvent);
				}
				else
				{
					LogManager.APILog.WriteLineAndConsole("Save failed!");
				}
			}
			catch (Exception ex)
			{
				m_isSaving = false;
				LogManager.ErrorLog.WriteLine(ex);
			}
		}
Пример #22
0
		public CubeBlockEntity( CubeGridEntity parent, MyObjectBuilder_CubeBlock definition, Object backingObject )
			: base( definition, backingObject )
		{
			m_parent = parent;

			EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent( );
			newEvent.type = EntityEventManager.EntityEventType.OnCubeBlockCreated;
			newEvent.timestamp = DateTime.Now;
			newEvent.entity = this;
			if ( m_parent.IsLoading )
			{
				newEvent.priority = 10;
			}
			else if ( EntityId != 0 )
			{
				newEvent.priority = 1;
			}
			else
			{
				newEvent.priority = 2;
			}
			EntityEventManager.Instance.AddEvent( newEvent );

			if ( EntityId != 0 )
			{
				GameEntityManager.AddEntity( EntityId, this );
			}

			m_buildPercent = definition.BuildPercent;
			m_integrityPercent = definition.IntegrityPercent;
			m_owner = definition.Owner;
			m_shareMode = definition.ShareMode;
		}
Пример #23
0
        public void Update( )
        {
            if ( !Loaded )
                return;
            if ( !Initialized )
                return;
            if ( !MySandboxGameWrapper.IsGameStarted )
                return;

            _lastUpdateTime = DateTime.Now - _lastUpdate;
            _averageUpdateInterval = ( _averageUpdateTime + _lastUpdateTime.TotalMilliseconds ) / 2;
            _lastUpdate = DateTime.Now;

            EntityEventManager.Instance.ResourceLocked = true;

            List<EntityEventManager.EntityEvent> events = EntityEventManager.Instance.EntityEvents;
            List<ChatManager.ChatEvent> chatEvents = ChatManager.Instance.ChatEvents;

            //Generate the player join/leave events here
            List<ulong> connectedPlayers = PlayerManager.Instance.ConnectedPlayers;
            try
            {
                foreach ( ulong steamId in connectedPlayers )
                {
                    if ( !_lastConnectedPlayerList.Contains( steamId ) )
                    {
                        EntityEventManager.EntityEvent playerEvent = new EntityEventManager.EntityEvent
                                                                     {
                                                                         priority = 1,
                                                                         timestamp = DateTime.Now,
                                                                         type = EntityEventManager.EntityEventType.OnPlayerJoined,
                                                                         entity = steamId
                                                                     };
                        //TODO - Find a way to stall the event long enough for a linked character entity to exist - this is impossible because of cockpits and respawnships
                        //For now, create a dummy entity just for passing the player's steam id along
                        events.Add( playerEvent );
                    }
                }
                foreach ( ulong steamId in _lastConnectedPlayerList )
                {
                    if ( !connectedPlayers.Contains( steamId ) )
                    {
                        EntityEventManager.EntityEvent playerEvent = new EntityEventManager.EntityEvent
                                                                     {
                                                                         priority = 1,
                                                                         timestamp = DateTime.Now,
                                                                         type = EntityEventManager.EntityEventType.OnPlayerLeft,
                                                                         entity = steamId
                                                                     };
                        //TODO - Find a way to stall the event long enough for a linked character entity to exist - this is impossible because of cockpits and respawnships
                        //For now, create a dummy entity just for passing the player's steam id along
                        events.Add( playerEvent );
                    }
                }
            }
            catch ( Exception ex )
            {
                ApplicationLog.BaseLog.Error( ex );
            }
            _lastConnectedPlayerList = new List<ulong>( connectedPlayers );

            //Run the update threads on the plugins
            foreach ( Guid key in Plugins.Keys )
            {
                object plugin = Plugins[ key ];

                if ( !PluginStates.ContainsKey( key ) )
                    continue;

                PluginManagerThreadParams parameters = new PluginManagerThreadParams
                                                       {
                                                           Plugin = plugin,
                                                           Key = key,
                                                           Plugins = Plugins,
                                                           PluginState = PluginStates,
                                                           Events = new List<EntityEventManager.EntityEvent>( events ),
                                                           ChatEvents = new List<ChatManager.ChatEvent>( chatEvents )
                                                       };

                ThreadPool.QueueUserWorkItem( DoUpdate, parameters );
                //				Thread pluginThread = new Thread(DoUpdate);
                //				pluginThread.Start(parameters);
            }

            //Capture profiling info if debugging is on
            if ( ExtenderOptions.IsDebugging )
            {
                _averageEvents = ( _averageEvents + ( events.Count + chatEvents.Count ) ) / 2;

                TimeSpan updateTime = DateTime.Now - _lastUpdate;
                _averageUpdateTime = ( _averageUpdateTime + updateTime.TotalMilliseconds ) / 2;

                TimeSpan timeSinceAverageOutput = DateTime.Now - _lastAverageOutput;
                if ( timeSinceAverageOutput.TotalSeconds > 30 )
                {
                    _lastAverageOutput = DateTime.Now;

                    ApplicationLog.BaseLog.Debug( "PluginManager - Update interval = {0}ms", _averageUpdateInterval );
                    ApplicationLog.BaseLog.Debug( "PluginManager - Update time = {0}ms", _averageUpdateTime );
                    ApplicationLog.BaseLog.Debug( "PluginManager - Events per update = {0}", _averageEvents );
                }
            }

            //Clean up the event managers
            EntityEventManager.Instance.ClearEvents( );
            EntityEventManager.Instance.ResourceLocked = false;
            ChatManager.Instance.ClearEvents( );
        }
Пример #24
0
		protected override void LoadDynamic( )
		{
			try
			{
				HashSet<Object> rawEntities = GetBackingDataHashSet( );
				Dictionary<long, BaseObject> internalDataCopy = new Dictionary<long, BaseObject>( GetInternalData( ) );

				//Update the main data mapping
				foreach ( Object entity in rawEntities )
				{
					try
					{
						if ( !IsValidEntity( entity ) )
							continue;

						MyObjectBuilder_CubeBlock baseEntity = (MyObjectBuilder_CubeBlock)CubeBlockEntity.InvokeEntityMethod( entity, CubeBlockEntity.CubeBlockGetObjectBuilderMethod );
						if ( baseEntity == null )
							continue;

						Vector3I cubePosition = baseEntity.Min;
						long packedBlockCoordinates = (long)cubePosition.X + (long)cubePosition.Y * 10000 + (long)cubePosition.Z * 100000000;

						//If the original data already contains an entry for this, skip creation
						if ( internalDataCopy.ContainsKey( packedBlockCoordinates ) )
						{
							CubeBlockEntity matchingCubeBlock = (CubeBlockEntity)GetEntry( packedBlockCoordinates );
							if ( matchingCubeBlock.IsDisposed )
								continue;

							matchingCubeBlock.BackingObject = entity;
							matchingCubeBlock.ObjectBuilder = baseEntity;
						}
						else
						{
							CubeBlockEntity newCubeBlock = null;

							if ( BlockRegistry.Instance.ContainsGameType( baseEntity.TypeId ) )
							{
								//Get the matching API type from the registry
								Type apiType = BlockRegistry.Instance.GetAPIType( baseEntity.TypeId );

								//Create a new API cube block
								newCubeBlock = (CubeBlockEntity)Activator.CreateInstance( apiType, new object[ ] { m_parent, baseEntity, entity } );
							}

							if ( newCubeBlock == null )
								newCubeBlock = new CubeBlockEntity( m_parent, baseEntity, entity );

							AddEntry( packedBlockCoordinates, newCubeBlock );
						}
					}
					catch ( Exception ex )
					{
						LogManager.ErrorLog.WriteLine( ex );
					}
				}

				//Cleanup old entities
				foreach ( KeyValuePair<long, BaseObject> entry in internalDataCopy )
				{
					try
					{
						if ( !rawEntities.Contains( entry.Value.BackingObject ) )
							DeleteEntry( entry.Value );
					}
					catch ( Exception ex )
					{
						LogManager.ErrorLog.WriteLine( ex );
					}
				}

				if ( GetInternalData( ).Count > 0 && m_isLoading )
				{
					//Trigger an event now that this cube grid has finished loading
					EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent( );
					newEvent.type = EntityEventManager.EntityEventType.OnCubeGridLoaded;
					newEvent.timestamp = DateTime.Now;
					newEvent.entity = this.m_parent;
					newEvent.priority = 1;
					EntityEventManager.Instance.AddEvent( newEvent );

					m_isLoading = false;
				}
			}
			catch ( Exception ex )
			{
				LogManager.ErrorLog.WriteLine( ex );
			}
		}
		private static void TriggerWorldSendEvent(ulong steamId)
		{
			EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
			newEvent.type = EntityEventManager.EntityEventType.OnPlayerWorldSent;
			newEvent.timestamp = DateTime.Now;
			newEvent.entity = steamId;
			newEvent.priority = 0;
			EntityEventManager.Instance.AddEvent(newEvent);
		}
Пример #26
0
        public CubeBlockEntity(CubeGridEntity parent, MyObjectBuilder_CubeBlock definition, Object backingObject)
            : base(definition, backingObject)
        {
            m_parent = parent;

            //Only enable events for non-structural blocks, for now
            if (definition.EntityId != 0)
            {
                EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
                newEvent.type = EntityEventManager.EntityEventType.OnCubeBlockCreated;
                newEvent.timestamp = DateTime.Now;
                newEvent.entity = this;
                if (m_parent.IsLoading)
                    newEvent.priority = 10;
                else
                    newEvent.priority = 1;
                EntityEventManager.Instance.AddEvent(newEvent);
            }
        }
Пример #27
0
        public CubeGridEntity(MyObjectBuilder_CubeGrid definition, Object backingObject)
            : base(definition, backingObject)
        {
            m_cubeBlockManager = new CubeBlockManager(this, backingObject, CubeGridGetCubeBlocksHashSetMethod);
            m_cubeBlockManager.Refresh();

            m_networkManager = new CubeGridNetworkManager(this);

            Object powerManager = InvokeEntityMethod(BackingObject, CubeGridGetPowerManagerMethod);
            m_powerManager = new PowerManager(powerManager);

            EntityEventManager.EntityEvent newEvent = new EntityEventManager.EntityEvent();
            newEvent.type = EntityEventManager.EntityEventType.OnCubeGridCreated;
            newEvent.timestamp = DateTime.Now;
            newEvent.entity = this;
            newEvent.priority = 1;
            EntityEventManager.Instance.AddEvent(newEvent);

            m_lastNameRefresh = DateTime.Now;
            m_name = "Cube Grid";
        }