protected void Command_Delete( ChatEvent chatEvent ) { ulong remoteUserId = chatEvent.RemoteUserId; List<string> commandParts = CommandParser.GetCommandParts( chatEvent.Message ); int paramCount = commandParts.Count - 1; MyEntity[] entities = new MyEntity[0]; SandboxGameAssemblyWrapper.Instance.GameAction(() => entities = MyEntities.GetEntities().ToArray()); var toRemove = new HashSet<MyEntity>(); //All entities if ( paramCount > 1 && commandParts[ 1 ].ToLower( ).Equals( "all" ) ) { //All cube grids that have no beacon or only a beacon with no name if ( commandParts[ 2 ].ToLower( ).Equals( "nobeacon" ) ) { int removeCount = 0; Parallel.ForEach(MyCubeGridGroups.Static.Logical.Groups, group => { bool found = false; foreach (var node in group.Nodes) { var grid = node.NodeData; if (grid.MarkedForClose || grid.Closed) continue; if (grid.CubeBlocks.OfType<MyBeacon>().Any()) { found = true; break; } } if (!found) return; removeCount++; foreach (var closeNode in group.Nodes) { SandboxGameAssemblyWrapper.Instance.BeginGameAction(()=>closeNode.NodeData.Close(), null, null); } }); SendPrivateChatMessage(remoteUserId, $"{removeCount} cube grids have been removed"); } //All cube grids that have no power else if ( commandParts[ 2 ].ToLower( ).Equals( "nopower" ) ) { //List<CubeGridEntity> entities = SectorObjectManager.Instance.GetTypedInternalData<CubeGridEntity>( ); //List<CubeGridEntity> entitiesToDispose = entities.Where( entity => entity.TotalPower <= 0 ).ToList( ); //foreach ( CubeGridEntity entity in entitiesToDispose ) //{ // entity.Dispose( ); //} //SendPrivateChatMessage( remoteUserId, string.Format( "{0} cube grids have been removed", entitiesToDispose.Count ) ); SendPrivateChatMessage( remoteUserId, "Unpowered grids removal temporarily unavailable in this version." ); } else if ( commandParts[ 2 ].ToLower( ).Equals( "floatingobjects" ) ) //All floating objects { int count = 0; foreach (var floating in entities.Where(e => e is MyFloatingObject)) { count++; SandboxGameAssemblyWrapper.Instance.BeginGameAction(() => floating.Close(), null, null); } SendPrivateChatMessage(remoteUserId, $"Removed {count} floating objects"); } else { string entityName = commandParts[ 2 ]; if ( commandParts.Count > 3 ) { for ( int i = 3; i < commandParts.Count; i++ ) { entityName += " " + commandParts[ i ]; } } int matchingEntitiesCount = 0; foreach ( var entity in entities ) { if (entity.MarkedForClose || entity.Closed) continue; bool isMatch = Regex.IsMatch( entity.Name, entityName, RegexOptions.IgnoreCase ); if ( !isMatch ) continue; SandboxGameAssemblyWrapper.Instance.BeginGameAction(() => entity.Close(), null, null); matchingEntitiesCount++; } SendPrivateChatMessage( remoteUserId, $"{matchingEntitiesCount} objects have been removed"); } } //All non-static cube grids if ( paramCount > 1 && commandParts[ 1 ].ToLower( ).Equals( "ship" ) ) { //That have no beacon or only a beacon with no name if ( commandParts[ 2 ].ToLower( ).Equals( "nobeacon" ) ) { int removeCount = 0; Parallel.ForEach(MyCubeGridGroups.Static.Logical.Groups, group => { bool found = false; foreach (var node in group.Nodes) { var grid = node.NodeData; if (grid.MarkedForClose || grid.Closed) continue; if (grid.IsStatic) continue; if (grid.CubeBlocks.OfType<MyBeacon>().Any()) { found = true; break; } } if (!found) return; removeCount++; foreach (var closeNode in group.Nodes) { SandboxGameAssemblyWrapper.Instance.BeginGameAction(() => closeNode.NodeData.Close(), null, null); } }); SendPrivateChatMessage(remoteUserId, $"{removeCount} cube grids have been removed"); } //All static cube grids if ( paramCount > 1 && commandParts[ 1 ].ToLower( ).Equals( "station" ) ) { int removeCount = 0; Parallel.ForEach(MyCubeGridGroups.Static.Logical.Groups, group => { bool found = false; foreach (var node in group.Nodes) { var grid = node.NodeData; if (grid.MarkedForClose || grid.Closed) continue; if(!grid.IsStatic) if (grid.CubeBlocks.OfType<MyBeacon>().Any()) { found = true; break; } } if (!found) return; removeCount++; foreach (var closeNode in group.Nodes) { SandboxGameAssemblyWrapper.Instance.BeginGameAction(() => closeNode.NodeData.Close(), null, null); } }); SendPrivateChatMessage(remoteUserId, $"{removeCount} cube grids have been removed"); } } //Prunes defunct player entries in the faction data /* if (paramCount > 1 && commandParts[1].ToLower().Equals("player")) { List<MyObjectBuilder_Checkpoint.PlayerItem> playersToRemove = new List<MyObjectBuilder_Checkpoint.PlayerItem>(); int playersRemovedCount = 0; if (commandParts[2].ToLower().Equals("dead")) { List<long> playerIds = PlayerMap.Instance.GetPlayerIds(); foreach (long playerId in playerIds) { MyObjectBuilder_Checkpoint.PlayerItem item = PlayerMap.Instance.GetPlayerItemFromPlayerId(playerId); if (item.IsDead) playersToRemove.Add(item); } //TODO - This is VERY slow. Need to find a much faster way to do this //TODO - Need to find a way to remove the player entries from the main list, not just from the blocks and factions foreach (var item in playersToRemove) { bool playerRemoved = false; //Check if any of the players we're about to remove own blocks //If so, set the owner to 0 and set the share mode to None foreach (var cubeGrid in SectorObjectManager.Instance.GetTypedInternalData<CubeGridEntity>()) { foreach (var cubeBlock in cubeGrid.CubeBlocks) { if (cubeBlock.Owner == item.PlayerId) { cubeBlock.Owner = 0; cubeBlock.ShareMode = MyOwnershipShareModeEnum.None; playerRemoved = true; } } } foreach (var entry in FactionsManager.Instance.Factions) { foreach (var member in entry.Members) { if (member.PlayerId == item.PlayerId) { entry.RemoveMember(member.PlayerId); playerRemoved = true; } } } if (playerRemoved) playersRemovedCount++; } } SendPrivateChatMessage(remoteUserId, "Deleted " + playersRemovedCount.ToString() + " player entries"); } */ //Prunes defunct faction entries in the faction data if ( paramCount > 1 && commandParts[ 1 ].ToLower( ).Equals( "faction" ) ) { List<MyFaction> factionsToRemove = new List<MyFaction>( ); if ( commandParts[ 2 ].ToLower( ).Equals( "empty" ) ) { factionsToRemove.AddRange( MySession.Static.Factions.Select( x => x.Value ).Where( v => !v.Members.Any() ) ); } if ( commandParts[ 2 ].ToLower( ).Equals( "nofounder" ) ) { foreach ( var entry in MySession.Static.Factions.Select( x => x.Value ) ) { bool founderMatch = entry.Members.Any( m => m.Value.IsFounder ); if ( !founderMatch ) factionsToRemove.Add( entry ); } } if ( commandParts[ 2 ].ToLower( ).Equals( "noleader" ) ) { foreach (var entry in MySession.Static.Factions.Select(x => x.Value)) { bool founderMatch = entry.Members.Any( member => member.Value.IsFounder || member.Value.IsLeader ); if ( !founderMatch ) factionsToRemove.Add( entry ); } } foreach ( var entry in factionsToRemove ) { MyFactionCollection.RemoveFaction( entry.FactionId ); } SendPrivateChatMessage( remoteUserId, string.Format( "Deleted {0} factions", factionsToRemove.Count ) ); } //Single entity if ( paramCount == 1 ) { string rawEntityId = commandParts[ 1 ]; try { long entityId = long.Parse( rawEntityId ); foreach ( var entity in entities ) { if ( entity.EntityId != entityId ) continue; SandboxGameAssemblyWrapper.Instance.BeginGameAction(() => entity.Close(), null, null); } } catch ( Exception ex ) { ApplicationLog.BaseLog.Error( ex ); } } }