public override bool HandleCommand(ulong userId, string[] words)
        {
            var entities = MyEntities.GetEntities( ).ToArray( );
            var planets  = new HashSet <MyPlanet>( );
            int count    = 0;

            foreach (var entity in entities)
            {
                MyPlanet item = entity as MyPlanet;
                if (item != null)
                {
                    planets.Add(item);
                }
            }

            foreach (var planet in planets)
            {
                var sphere25 = new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MinimumRadius * 0.25);
                var sphere75 = new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MinimumRadius * 0.75);
                foreach (var entity in entities)
                {
                    if (entity.MarkedForClose || entity.Physics == null || entity is MyCharacter)
                    {
                        continue;
                    }

                    if (sphere25.Contains(entity.PositionComp.GetPosition()) != ContainmentType.Disjoint)
                    {
                        count++;
                        Wrapper.BeginGameAction(entity.Close, null, null);
                        continue;
                    }

                    if (Vector3.IsZero(entity.Physics.LinearVelocity))
                    {
                        continue;
                    }

                    if (sphere75.Contains(entity.PositionComp.GetPosition()) == ContainmentType.Disjoint)
                    {
                        continue;
                    }

                    count++;
                    Wrapper.BeginGameAction(entity.Close, null, null);
                }
            }

            Communication.SendPrivateInformation(userId, $"Deleted {count} entities trapped in planets.");
            return(true);
        }
Esempio n. 2
0
        public override bool HandleCommand(ulong userId, string[] words)
        {
            if (!PluginSettings.Instance.DockingEnabled)
            {
                return(false);
            }

            if (words.Length < 1)
            {
                Communication.SendPrivateInformation(userId, GetHelp());
                return(true);
            }

            if (m_docking)
            {
                Communication.SendPrivateInformation(userId, "Server is busy");
                return(true);
            }

            m_docking = true;
            try
            {
                string pylonName = string.Join(" ", words);

                /*
                 * int timeLeft;
                 * if (Entity.CheckCoolDown(pylonName, out timeLeft))
                 * {
                 *      Communication.Message(String.Format("The docking zone '{0}' is on cooldown.  Please wait a {1} seconds before trying to dock/undock again.", pylonName, Math.Max(0, timeLeft)));
                 *      return;
                 * }
                 */

                if (PlayerMap.Instance.GetPlayerIdsFromSteamId(userId).Count < 1)
                {
                    Communication.SendPrivateInformation(userId, $"Unable to find player Id: {userId}");
                    return(true);
                }

                long playerId = PlayerMap.Instance.GetPlayerIdsFromSteamId(userId).First();

                Dictionary <string, List <IMyCubeBlock> > testList;
                List <IMyCubeBlock> beaconList;
                DockingZone.FindByName(pylonName, out testList, out beaconList, playerId);
                if (beaconList.Count == 4)
                {
                    // Check ownership
                    foreach (IMyCubeBlock entityBlock in beaconList)
                    {
                        IMyTerminalBlock terminal = (IMyTerminalBlock)entityBlock;
                        if (!terminal.HasPlayerAccess(playerId))
                        {
                            Communication.SendPrivateInformation(userId, $"You do not have permission to use '{pylonName}'.  You must either own all the beacons or they must be shared with faction.");
                            return(true);
                        }
                    }

                    // Check for bounding box intsection of other docking zones
                    int intersectElement = 0;
                    if (Entity.CheckForIntersection(testList, beaconList, out intersectElement))
                    {
                        Communication.SendPrivateInformation(userId, $"The docking zone '{pylonName}' intersects with docking zone '{testList.ElementAt( intersectElement ).Key}'.  Make sure you place your docking zones so they don't overlap.");
                        return(true);
                    }

                    // Check if ship already docked in this zone
                    IMyCubeBlock       e             = beaconList[0];
                    IMyCubeGrid        parent        = (IMyCubeGrid)e.Parent;
                    long[]             beaconListIds = beaconList.Select(b => b.EntityId).ToArray();
                    long               ownerId       = beaconList.First().OwnerId;
                    List <DockingItem> checkItems    = Docking.Instance.Find(d => d.PlayerId == ownerId && d.TargetEntityId == parent.EntityId && d.DockingBeaconIds.Intersect(beaconListIds).Count() == 4);
                    if (checkItems.Count >= PluginSettings.Instance.DockingShipsPerZone)
                    {
                        Communication.SendPrivateInformation(userId, $"Docking zone '{pylonName}' already contains the maximum capacity of ships.");
                        return(true);
                    }

                    // Figure out center of docking area, and other distance information
                    double   maxDistance = 99;
                    Vector3D vPos        = new Vector3D(0, 0, 0);

                    foreach (IMyCubeBlock b in beaconList)
                    {
                        Vector3D beaconPos = Entity.GetBlockEntityPosition(b);
                        vPos += beaconPos;
                    }

                    vPos = vPos / 4;
                    foreach (IMyCubeBlock b in beaconList)
                    {
                        Vector3D beaconPos = Entity.GetBlockEntityPosition(b);
                        maxDistance = Math.Min(maxDistance, Vector3D.Distance(vPos, beaconPos));
                    }

                    // Find ship in docking area
                    IMyCubeGrid         dockingEntity = null;
                    HashSet <IMyEntity> cubeGrids     = new HashSet <IMyEntity>();
                    Wrapper.GameAction(() =>
                    {
                        MyAPIGateway.Entities.GetEntities(cubeGrids, f => f is IMyCubeGrid);
                    });
                    foreach (IMyCubeGrid gridCheck in cubeGrids)
                    {
                        if (gridCheck.IsStatic || gridCheck == parent)
                        {
                            continue;
                        }

                        double distance = Vector3D.Distance(gridCheck.GetPosition(), vPos);
                        if (distance < maxDistance)
                        {
                            dockingEntity = gridCheck;
                            break;
                        }
                    }

                    // Figure out if the ship fits in docking area, and then save ship
                    if (dockingEntity != null)
                    {
                        // Get bounding box of both the docking zone and docking ship
                        OrientedBoundingBoxD targetBounding  = Entity.GetBoundingBox(beaconList);
                        OrientedBoundingBoxD dockingBounding = Entity.GetBoundingBox(dockingEntity);

                        // Make sure the docking zone contains the docking ship.  If they intersect or are disjointed, then fail
                        if (!Entity.GreaterThan(dockingBounding.HalfExtent * 2, targetBounding.HalfExtent * 2))
                        {
                            Communication.SendPrivateInformation(userId, $"The ship '{dockingEntity.DisplayName}' is too large for it's carrier.  The ship's bounding box must fit inside the docking zone bounding box!");
                            return(true);
                        }

                        if (targetBounding.Contains(ref dockingBounding) != ContainmentType.Contains)
                        {
                            Communication.SendPrivateInformation(userId, $"The ship '{dockingEntity.DisplayName}' is not fully inside the docking zone '{pylonName}'.  Make sure the ship is fully contained inside the docking zone");
                            return(true);
                        }

                        // Calculate the mass and ensure the docking ship is less than half the mass of the dock
                        float parentMass  = Entity.CalculateMass(parent);
                        float dockingMass = Entity.CalculateMass(dockingEntity);
                        if (dockingMass > parentMass)
                        {
                            Communication.SendPrivateInformation(userId, $"The ship you're trying to dock is too heavy for it's carrier.  The ship mass must be less than half the large ship / stations mass! (DM={dockingMass}kg CM={parentMass}kg)");
                            return(true);
                        }

                        // Check to see if the ship is piloted, if it is, error out.
                        // TODO: Check to see if we can get a real time copy of this entity?
                        List <IMySlimBlock> blocks = new List <IMySlimBlock>();
                        dockingEntity.GetBlocks(blocks, x => x.FatBlock is MyCockpit);
                        foreach (IMySlimBlock slim in blocks)
                        {
                            //MyObjectBuilder_Cockpit c = (MyObjectBuilder_Cockpit)slim.FatBlock.GetObjectBuilderCubeBlock();
                            var c = (MyShipController)slim.FatBlock;
                            if (c.Pilot != null)
                            {
                                Communication.SendPrivateInformation(userId, $"Ship in docking zone '{pylonName}' has a pilot!  Please exit the ship before trying to dock.  (Sometimes this can lag a bit.  Wait 10 seconds and try again)");
                                return(true);
                            }
                        }

                        // Save position and rotation information.  Some fun stuff here.
                        // Get our dock rotation as a quaternion
                        Quaternion saveQuat = Quaternion.CreateFromRotationMatrix(parent.WorldMatrix.GetOrientation());
                        // Transform docked ship's local position by inverse of the the parent (unwinds parent) and save it for when we undock
                        Vector3D savePos = Vector3D.Transform(dockingEntity.GetPosition() - parent.GetPosition(), Quaternion.Inverse(saveQuat));
                        // Get local rotation of dock ship, and save it for when we undock
                        saveQuat = Quaternion.Inverse(saveQuat) * Quaternion.CreateFromRotationMatrix(dockingEntity.WorldMatrix.GetOrientation());

                        // Save ship to file and remove
                        FileInfo info = new FileInfo(Path.Combine(Essentials.PluginPath, "Docking", $"docked_{ownerId}_{parent.EntityId}_{dockingEntity.EntityId}.sbc"));
                        if (!Directory.Exists(info.DirectoryName))
                        {
                            Directory.CreateDirectory(info.DirectoryName);
                        }
                        //CubeGridEntity dockingGrid = new CubeGridEntity((MyObjectBuilder_CubeGrid)dockingEntity.GetObjectBuilder(), dockingEntity);
                        MyObjectBuilder_CubeGrid gridBuilder = CubeGrids.SafeGetObjectBuilder(dockingEntity);
                        if (gridBuilder == null)
                        {
                            Communication.SendPrivateInformation(userId, $"Failed to load entity for export: {dockingEntity.DisplayName}");
                            return(true);
                        }

                        // Save item
                        DockingItem dockItem = new DockingItem
                        {
                            DockedEntityId   = dockingEntity.EntityId,
                            TargetEntityId   = parent.EntityId,
                            PlayerId         = ownerId,
                            DockingBeaconIds = beaconList.Select(s => s.EntityId).ToArray( ),
                            DockedName       = dockingEntity.DisplayName,
                            SavePos          = savePos,
                            SaveQuat         = saveQuat
                        };
                        Docking.Instance.Add(dockItem);

                        // Serialize and save ship to file
                        MyObjectBuilderSerializer.SerializeXML(info.FullName, false, gridBuilder);
                        Wrapper.BeginGameAction(() => dockingEntity.Close( ));

                        Communication.SendPrivateInformation(userId, $"Docked ship '{dockItem.DockedName}' in docking zone '{pylonName}'.");
                        Log.Info("Docked ship \"{0}\" in docking zone \"{1}\". Saved to {2}", dockItem.DockedName, pylonName, info.FullName);

                        /*
                         * // Add a cool down
                         * DockingCooldownItem cItem = new DockingCooldownItem();
                         * cItem.name = pylonName;
                         * cItem.startTime = DateTime.Now;
                         * PluginDocking.CooldownList.Add(cItem);
                         */
                    }
                    else
                    {
                        Communication.SendPrivateInformation(userId, $"No ships in docking zone '{pylonName}'.");
                    }
                }
                else if (beaconList.Count > 4)
                {
                    Communication.SendPrivateInformation(userId, $"Too many beacons with the name or another zone with the name '{pylonName}'.  Place only 4 beacons to create a zone or try a different zone name.");
                }
                else
                {
                    Communication.SendPrivateInformation(userId, string.Format("Can not locate docking zone '{0}'.  There must be 4 beacons with the name '{0}' to create a docking zone.  Beacons must be fully built!", pylonName));
                }

                return(true);
            }
            catch (SecurityException ex)
            {
                Log.Error("Can't access docked ship file.", ex);
                return(false);
            }
            catch (UnauthorizedAccessException ex)
            {
                Log.Error("Can't access docked ship file.", ex);
                return(false);
            }
            catch (DirectoryNotFoundException ex)
            {
                Log.Error("Directory does not exist", ex);
                return(false);
            }
            catch (IOException ex)
            {
                Log.Error(ex);
                return(false);
            }
            finally
            {
                m_docking = false;
            }
        }
Esempio n. 3
0
        public override bool Handle(ulong remoteUserId, CallSite site, BitStream stream, object obj)
        {
            if (!PluginSettings.Instance.LimitPasteSize)
            {
                return(false);
            }

            if (PluginSettings.Instance.AdminPasteExempt && PlayerManager.Instance.IsUserAdmin(remoteUserId))
            {
                return(false);
            }

            if (PluginSettings.Instance.SpaceMasterPasteExempt && PlayerManager.Instance.IsUserPromoted(remoteUserId))
            {
                return(false);
            }

            var     gridsList         = new List <MyObjectBuilder_CubeGrid>();
            bool    detectDisconects  = false;
            long    inventoryEntityId = 0;
            Vector3 objectVelocity    = Vector3.Zero;
            bool    multiBlock        = false;
            bool    instantBuild      = false;

            base.Serialize(site.MethodInfo, stream, ref gridsList, ref detectDisconects, ref inventoryEntityId, ref objectVelocity, ref multiBlock, ref instantBuild);

            int blockCount = 0;

            //foreach (var gridOb in gridsList)
            //{
            //    blockCount += gridOb.CubeBlocks.Count;
            //}

            for (int i = 0; i < gridsList.Count; i++)
            {
                blockCount += gridsList[i].CubeBlocks.Count;
            }

            if (blockCount < PluginSettings.Instance.PasteBlockCount)
            {
                return(false);
            }

            NoGrief.Log.Info($"Intercepted grid paste request from {PlayerMap.Instance.GetFastPlayerNameFromSteamId(remoteUserId)} for {blockCount} blocks.");

            if (!string.IsNullOrEmpty(PluginSettings.Instance.PasteLimitMessagePrivate))
            {
                Communication.Notification(remoteUserId, MyFontEnum.Red, 10000, PluginSettings.Instance.PasteLimitMessagePrivate);
            }

            if (!string.IsNullOrEmpty(PluginSettings.Instance.PasteLimitMessagePublic))
            {
                Communication.SendPublicInformation(PluginSettings.Instance.PasteLimitMessagePublic.Replace("%player%", PlayerMap.Instance.GetFastPlayerNameFromSteamId(remoteUserId)).Replace("%count%", blockCount.ToString()));
            }

            if (PluginSettings.Instance.PasteLimitBan)
            {
                _kickTimer.Elapsed += (sender, args) =>
                {
                    Wrapper.BeginGameAction(() => MyMultiplayer.Static.BanClient(remoteUserId, true));
                    NoGrief.Log.Info($"Auto-banned player {PlayerMap.Instance.GetFastPlayerNameFromSteamId(remoteUserId)}:{remoteUserId} for violating paste limits");
                };
                _kickTimer.AutoReset = false;
                _kickTimer.Start();
            }
            else if (PluginSettings.Instance.PasteLimitKick)
            {
                _kickTimer.Elapsed += (sender, args) =>
                {
                    Wrapper.BeginGameAction(() => MyMultiplayer.Static.KickClient(remoteUserId));
                    NoGrief.Log.Info($"Auto-kicked player {PlayerMap.Instance.GetFastPlayerNameFromSteamId(remoteUserId)}:{remoteUserId} for violating paste limits");
                };
                _kickTimer.AutoReset = false;
                _kickTimer.Start();
            }

            //send the fail message to make the client play the paste fail sound
            //just because we can
            var inf = typeof(MyCubeBuilder).GetMethod("SpawnGridReply", BindingFlags.NonPublic | BindingFlags.Static);

            ServerNetworkManager.Instance.RaiseStaticEvent(inf, remoteUserId, false);

            return(true);
        }
Esempio n. 4
0
        public override void Handle()
        {
            if (!PluginSettings.Instance.ExclusionZonesEnabled)
            {
                return;
            }

            MyEntity[] entities = MyEntities.GetEntities().ToArray();
            if (entities.Length == 0)
            {
                NoGrief.Log.Info("Failed to get entity list in exclusion zone update. Skipping update.");
                return;
            }

            foreach (SettingsExclusionItem item in PluginSettings.Instance.ExclusionItems)
            {
                if (!item.Enabled)
                {
                    continue;
                }

                if (!_redirectedEntites.ContainsKey(item.EntityId))
                {
                    _redirectedEntites.Add(item.EntityId, new HashSet <long>());
                }

                MyEntity grid;
                if (!MyEntities.TryGetEntityById(item.EntityId, out grid))
                {
                    continue;
                }

                bool init = item.ContainsEntities.Count == 0;

                //zones don't work on moving entities
                if (!Vector3.IsZero(grid.Physics.LinearVelocity) || !Vector3.IsZero(grid.Physics.AngularVelocity))
                {
                    continue;
                }

                var sphere = new BoundingSphereD(grid.Center(), item.Radius);

                if (init)
                {
                    foreach (MyEntity entity in entities)
                    {
                        if (sphere.Contains(entity.PositionComp.WorldVolume) == ContainmentType.Contains)
                        {
                            item.ContainsEntities.Add(entity.EntityId);
                        }
                    }
                    if (item.TransportAdd)
                    {
                        item.AllowedEntities = item.ContainsEntities.ToList();
                    }
                }

                var outerSphere = new BoundingSphereD(sphere.Center, sphere.Radius + 50);

                var approaching = new HashSet <long>();
                foreach (MyEntity entity in entities)
                {
                    if (entity?.Physics == null)
                    {
                        continue;
                    }

                    if (entity.Closed || entity.MarkedForClose)
                    {
                        continue;
                    }

                    if (entity is MyVoxelBase)
                    {
                        continue;
                    }

                    if (entity is MyAmmoBase)
                    {
                        continue;
                    }

                    //entity is trying to enter the exclusion zone. push them away
                    if (outerSphere.Contains(entity.Center()) != ContainmentType.Disjoint && !item.ContainsEntities.Contains(entity.EntityId))
                    {
                        approaching.Add(entity.EntityId);
                        MyPlayer controller = MySession.Static.Players.GetControllingPlayer(entity);
                        try
                        {
                            if (controller?.Client != null)
                            {
                                if (!string.IsNullOrEmpty(item.FactionTag) && MySession.Static.Factions.GetPlayerFaction(controller.Identity.IdentityId).Tag == item.FactionTag)
                                {
                                    ExcludeEntities(entity, item);
                                    if (item.TransportAdd && !item.AllowedPlayers.Contains(controller.Client.SteamUserId))
                                    {
                                        item.AllowedPlayers.Add(controller.Client.SteamUserId);
                                    }
                                    continue;
                                }

                                if (item.AllowAdmins && controller.IsAdmin)
                                {
                                    ExcludeEntities(entity, item);
                                    continue;
                                }

                                if (item.AllowedPlayers.Contains(controller.Client.SteamUserId))
                                {
                                    ExcludeEntities(entity, item);
                                    continue;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            NoGrief.Log.Error(ex);
                        }

                        if (item.AllowedEntities.Contains(entity.EntityId))
                        {
                            ExcludeEntities(entity, item);
                            continue;
                        }

                        Vector3D direction = Vector3D.Normalize(entity.Center() - sphere.Center);
                        Vector3D velocity  = entity.Physics.LinearVelocity;
                        if (Vector3D.IsZero(velocity))
                        {
                            velocity += direction;
                        }

                        if (!_redirectedEntites[item.EntityId].Contains(entity.EntityId))
                        {
                            _redirectedEntites[item.EntityId].Add(entity.EntityId);

                            Vector3D forceDir = Vector3D.Reflect(Vector3D.Normalize(velocity), direction);
                            //Vector3D force = forceDir * (velocity.Length()+10) * entity.Physics.Mass * 5 + -entity.Physics.LinearAcceleration * entity.Physics.Mass;
                            //if (!force.IsValid())
                            //{
                            //    NoGrief.Log.Error("Invalid Force");
                            //    continue;
                            //}
                            if (controller?.Client != null && !string.IsNullOrEmpty(item.ExclusionMessage))
                            {
                                Communication.Notification(controller.Client.SteamUserId, MyFontEnum.White, 10000, item.ExclusionMessage);
                            }
                            if (!(entity is MyCharacter))
                            {
                                Vector3 force = forceDir * velocity.Length() * entity.Physics.Mass * 60 * 1.5;
                                force += entity.Physics.LinearAcceleration.Length() * entity.Physics.Mass * 60;
                                Wrapper.BeginGameAction(() => entity.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, force, entity.Physics.CenterOfMassWorld, Vector3.Zero));
                            }
                            else
                            {
                                //characres require a different method
                                var      character     = (MyCharacter)entity;
                                Vector3D bodyDirection = -Vector3D.Normalize(Vector3D.Transform(direction, character.PositionComp.WorldMatrixInvScaled));
                                Vector3D bodyForce     = bodyDirection * character.Physics.LinearVelocity.Length() * character.Physics.Mass * 60 * 1.5;
                                bodyForce += character.Physics.LinearAcceleration.Length() * character.Physics.Mass * 60;
                                Wrapper.BeginGameAction(() => character.Physics.AddForce(MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, bodyForce, character.Center(), Vector3.Zero));
                            }
                        }
                        if (sphere.Contains(entity.Center()) != ContainmentType.Disjoint)
                        {
                            if (!(entity is MyCharacter))
                            {
                                Vector3D force = direction * (velocity.Length() + 5) * entity.Physics.Mass * 60 * 2;
                                force += entity.Physics.LinearAcceleration.Length() * entity.Physics.Mass * 60;
                                Wrapper.BeginGameAction(() => entity.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, force, entity.Physics.CenterOfMassWorld, Vector3.Zero));
                            }
                            else
                            {
                                var      character     = (MyCharacter)entity;
                                Vector3D bodyDirection = -Vector3D.Normalize(Vector3D.Transform(direction, character.PositionComp.WorldMatrixInvScaled));
                                Vector3D bodyForce     = bodyDirection * (character.Physics.LinearVelocity.Length() + 5) * character.Physics.Mass * 60 * 2;
                                bodyForce += character.Physics.LinearAcceleration.Length() * character.Physics.Mass * 60;
                                Wrapper.BeginGameAction(() => character.Physics.AddForce(MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, bodyForce, character.Center(), Vector3.Zero));
                            }
                        }
                    }
                }

                var toRemove = new List <long>();
                //TODO: We're searching the dictionary way too much. Do something about it later
                foreach (long id in _redirectedEntites[item.EntityId])
                {
                    if (!approaching.Contains(id))
                    {
                        toRemove.Add(id);
                    }
                }
                foreach (long rem in toRemove)
                {
                    _redirectedEntites[item.EntityId].Remove(rem);
                }
            }
        }
Esempio n. 5
0
        public override bool HandleCommand(ulong userId, string[] words)
        {
            if (words.Length < 1)
            {
                return(true);
            }

            switch (words[0].ToLower( ))
            {
            case "reconnect":
            {
                var inf = typeof(MyCampaignSessionComponent).GetMethod("Reconnect", BindingFlags.NonPublic | BindingFlags.Static);
                if (words.Length < 1 && words[1].ToLower( ) == "all")
                {
                    ServerNetworkManager.Instance.RaiseStaticEvent(inf);
                }
                else
                {
                    ServerNetworkManager.Instance.RaiseStaticEvent(inf, new EndpointId(userId));
                }
                break;
            }

            case "close":
            {
                var inf = typeof(MyCampaignSessionComponent).GetMethod("CloseGame", BindingFlags.NonPublic | BindingFlags.Static);
                if (words.Length < 1 && words[1].ToLower( ) == "all")
                {
                    ServerNetworkManager.Instance.RaiseStaticEvent(inf);
                }
                else
                {
                    ServerNetworkManager.Instance.RaiseStaticEvent(inf, new EndpointId(userId));
                }
                break;
            }

            case "jump":
            {
                var        inf  = typeof(MyCharacter).GetMethod("Jump", BindingFlags.Public | BindingFlags.Instance);
                MyEntity[] ents = new MyEntity[0];
                Wrapper.GameAction(() => ents = MyEntities.GetEntities( ).ToArray( ));
                foreach (var entity in ents)
                {
                    var character = entity as MyCharacter;
                    if (character == null)
                    {
                        continue;
                    }

                    Wrapper.BeginGameAction(() => ServerNetworkManager.Instance.RaiseEvent(inf, character), null, null);
                }
                break;
            }

            case "character":
            {
                var        inf  = typeof(MyCharacter).GetMethod(words[1], BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
                MyEntity[] ents = new MyEntity[0];
                Wrapper.GameAction(() => ents = MyEntities.GetEntities( ).ToArray( ));
                foreach (var entity in ents)
                {
                    var character = entity as MyCharacter;
                    if (character == null)
                    {
                        continue;
                    }

                    if (words.Length == 2)
                    {
                        Wrapper.BeginGameAction(() => ServerNetworkManager.Instance.RaiseEvent(inf, character), null, null);
                    }
                    else
                    {
                        Wrapper.BeginGameAction(() => ServerNetworkManager.Instance.RaiseEvent(inf, character, words[2]), null, null);
                    }
                }
                break;
            }

            case "report":
            {
                var        inf  = typeof(MyProgrammableBlock).GetMethod("OpenEditorSucess", BindingFlags.NonPublic | BindingFlags.Instance);
                MyEntity[] ents = new MyEntity[0];
                Wrapper.GameAction(() => ents = MyEntities.GetEntities( ).ToArray( ));
                foreach (var ent in ents)
                {
                    var grid = ent as MyCubeGrid;
                    if (grid == null)
                    {
                        continue;
                    }

                    if (!grid.DisplayName.Contains("Essentials"))
                    {
                        continue;
                    }

                    var slim = grid.CubeBlocks.FirstOrDefault(s => s.FatBlock is MyProgrammableBlock);
                    if (slim == null)
                    {
                        Communication.SendPrivateInformation(userId, "fail");
                        return(true);
                    }
                    var    pb   = slim.FatBlock as MyProgrammableBlock;
                    string prog = $"Admin report ticket number: {pb.EntityId} \r\n" +
                                  "This report will be logged sent to the administrator. \r\n" +
                                  "The past 30 minutes of server activity will automatically be appended to the end of your report.\r\n\r\n" +
                                  "When you are done, click 'Remember and exit'. Do not click 'Check Code'\r\n\r\n";
                    pb.UpdateProgram(prog);

                    Wrapper.BeginGameAction(() =>
                        {
                            try
                            {
                                typeof(MyProgrammableBlock).GetMethod("SendUpdateProgramRequest", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(pb, new[] { prog });
                                ServerNetworkManager.Instance.RaiseEvent(inf, pb, new EndpointId(userId));
                            }
                            catch (Exception ex)
                            {
                                Essentials.Log.Error(ex);
                            }
                        }, null, null);
                }
                break;
            }

            case "ragdoll":
            {
                MyEntity[] ents = new MyEntity[0];
                Wrapper.GameAction(() => ents = MyEntities.GetEntities( ).ToArray( ));
                foreach (var ent in ents)
                {
                    var character = ent as MyCharacter;

                    character?.Components.Remove <MyCharacterRagdollComponent>( );
                }
                break;
            }

            case "respawn":
            {
                var inf = typeof(MySpaceRespawnComponent).GetMethod("ShowMedicalScreen_Implementation", BindingFlags.NonPublic | BindingFlags.Static);
                Wrapper.GameAction(() => ServerNetworkManager.Instance.RaiseStaticEvent(inf, userId));
                break;
            }

            case "update":
            {
                bool       set  = words.Length > 1 && words[1].ToLower( ).Equals("on");
                MyEntity[] ents = new MyEntity[0];
                Wrapper.GameAction(() => ents = MyEntities.GetEntities( ).ToArray( ));
                foreach (var ent in ents)
                {
                    var character = ent as MyCharacter;
                    if (character == null)
                    {
                        continue;
                    }

                    if (set)
                    {
                        MyEntities.RegisterForUpdate(ent);
                    }
                    else
                    {
                        MyEntities.UnregisterForUpdate(ent);
                    }
                }
                break;
            }

            case "seated":
            {
                bool       set  = words.Length > 1 && words[1].ToLower( ).Equals("on");
                MyEntity[] ents = new MyEntity[0];
                Wrapper.GameAction(() => ents = MyEntities.GetEntities( ).ToArray( ));

                foreach (var ent in ents)
                {
                    var grid = ent as MyCubeGrid;
                    if (grid == null)
                    {
                        continue;
                    }

                    var blocks = grid.GetBlocks( );

                    foreach (var block in blocks)
                    {
                        var cockpit = block?.FatBlock as MyCockpit;
                        if (cockpit?.Pilot == null)
                        {
                            continue;
                        }

                        Essentials.Log.Info(cockpit.Pilot.DisplayName);

                        if (set)
                        {
                            MyEntities.RegisterForUpdate(cockpit.Pilot);
                        }
                        else
                        {
                            MyEntities.UnregisterForUpdate(cockpit.Pilot);
                        }
                    }
                }
                break;
            }

            case "component":
            {
                MyEntity[] ents = new MyEntity[0];
                Wrapper.GameAction(() => ents = MyEntities.GetEntities( ).ToArray( ));
                foreach (var ent in ents)
                {
                    var character = ent as MyCharacter;

                    character?.Components.Clear( );
                }
                break;
            }
            }

            return(true);
        }
Esempio n. 6
0
        public override void Handle()
        {
            if (!PluginSettings.Instance.ProtectionZonesEnabled && !PluginSettings.Instance.ExclusionZonesEnabled)
            {
                return;
            }

            //the type is MyHashSetReader<MyProjectile>, but MyProjectile is private
            //cast to generic IEnumberable so we can get around this
            var projectiles = projPool.GetType().GetProperty("Active", BindingFlags.Instance | BindingFlags.Public).GetValue(projPool) as IEnumerable;

            //thread safety
            var projArray = projectiles.Cast <object>().ToArray();

            if (projArray == null)
            {
                throw new Exception("Try the other one");
            }

            var entities = MyEntities.GetEntities().ToArray();

            if (entities.Length == 0)
            {
                NoGrief.Log.Info("Failed to get entities in zone boundary update. Skipping update");
                return;
            }

            if (PluginSettings.Instance.ProtectionZonesEnabled)
            {
                foreach (var item in PluginSettings.Instance.ProtectionItems)
                {
                    if (!item.Enabled)
                    {
                        continue;
                    }

                    MyEntity ent;
                    if (!MyEntities.TryGetEntityById(item.EntityId, out ent))
                    {
                        continue;
                    }

                    if (ent.Closed || ent.MarkedForClose || ent.Physics == null)
                    {
                        continue;
                    }

                    if (!Vector3.IsZero(ent.Physics.LinearVelocity) || !Vector3.IsZero(ent.Physics.AngularVelocity))
                    {
                        continue;
                    }

                    var sphere      = new BoundingSphereD(ent.Center(), item.Radius);
                    var outerSphere = new BoundingSphereD(ent.Center(), item.Radius + 50);

                    //destroy any missiles crossing the zone boundary
                    foreach (var entity in entities)
                    {
                        if (entity.Closed || entity.MarkedForClose || entity.Physics == null)
                        {
                            continue;
                        }

                        if (!(entity is MyAmmoBase))
                        {
                            continue;
                        }

                        if (outerSphere.Contains(entity.Center()) != ContainmentType.Disjoint && sphere.Contains(entity.Center()) == ContainmentType.Disjoint)
                        {
                            Wrapper.BeginGameAction(() => ((IMyDestroyableObject)entity).DoDamage(100, MyStringHash.GetOrCompute("Explosion"), true));
                        }
                    }

                    //delete any bullets that are crossing the zone boundary
                    foreach (object obj in projArray)
                    {
                        FieldInfo posField = obj.GetType().GetField("m_position", BindingFlags.NonPublic | BindingFlags.Instance);

                        var pos = (Vector3D)posField.GetValue(obj);
                        if (outerSphere.Contains(pos) != ContainmentType.Disjoint && sphere.Contains(pos) == ContainmentType.Disjoint)
                        {
                            //obj.GetType().GetMethod("Close", BindingFlags.Public | BindingFlags.Instance).Invoke(obj, null);
                            FieldInfo state = obj.GetType().GetField("m_state", BindingFlags.NonPublic | BindingFlags.Instance);

                            //set state to KILLED_AND_DRAWN(2) to trick the game into removing the bullet on the next update
                            //this doesn't sync :(
                            state.SetValue(obj, (byte)2);
                        }
                    }
                }
            }
            if (PluginSettings.Instance.ExclusionZonesEnabled)
            {
                foreach (var item in PluginSettings.Instance.ExclusionItems)
                {
                    if (!item.Enabled)
                    {
                        continue;
                    }

                    MyEntity ent;
                    if (!MyEntities.TryGetEntityById(item.EntityId, out ent))
                    {
                        continue;
                    }

                    if (ent.Closed || ent.MarkedForClose || ent.Physics == null)
                    {
                        continue;
                    }

                    if (!Vector3.IsZero(ent.Physics.LinearVelocity) || !Vector3.IsZero(ent.Physics.AngularVelocity))
                    {
                        continue;
                    }

                    var sphere      = new BoundingSphereD(ent.Center(), item.Radius);
                    var outerSphere = new BoundingSphereD(ent.Center(), item.Radius + 50);

                    //destroy any missiles crossing the zone boundary
                    foreach (var entity in entities)
                    {
                        if (entity.Closed || entity.MarkedForClose || entity.Physics == null)
                        {
                            continue;
                        }

                        if (!(entity is MyAmmoBase))
                        {
                            continue;
                        }

                        if (outerSphere.Contains(entity.Center()) != ContainmentType.Disjoint && sphere.Contains(entity.Center()) == ContainmentType.Disjoint)
                        {
                            Wrapper.BeginGameAction(() => ((IMyDestroyableObject)entity).DoDamage(100, MyStringHash.GetOrCompute("Explosion"), true));
                        }
                    }

                    //delete any bullets that are crossing the zone boundary
                    foreach (object obj in projArray)
                    {
                        FieldInfo posField = obj.GetType().GetField("m_position", BindingFlags.NonPublic | BindingFlags.Instance);

                        var pos = (Vector3D)posField.GetValue(obj);
                        if (outerSphere.Contains(pos) != ContainmentType.Disjoint && sphere.Contains(pos) == ContainmentType.Disjoint)
                        {
                            //obj.GetType().GetMethod("Close", BindingFlags.Public | BindingFlags.Instance).Invoke(obj, null);
                            FieldInfo state = obj.GetType().GetField("m_state", BindingFlags.NonPublic | BindingFlags.Instance);

                            //set state to KILLED_AND_DRAWN(2) to trick the game into removing the bullet on the next update
                            //this doesn't sync :(
                            state.SetValue(obj, (byte)2);
                        }
                    }
                }
            }
        }
        public override bool HandleCommand(ulong userId, string[] words)
        {
            if (words.Length != 1)
            {
                Communication.SendPrivateInformation(userId, GetHelp( ));
                return(false);
            }
            bool small;
            bool large;

            switch (words[0].ToLower( ))
            {
            case "small":
                small = true;
                large = false;
                break;

            case "large":
                small = false;
                large = true;
                break;

            case "all":
                small = true;
                large = true;
                break;

            default:
                Communication.SendPrivateInformation(userId, GetHelp( ));
                return(false);
            }

            var ents  = MyEntities.GetEntities( ).ToArray( );
            int count = 0;

            foreach (var ent in ents)
            {
                var grid = ent as MyCubeGrid;
                if (grid == null)
                {
                    continue;
                }

                if (grid.Physics == null || grid.IsStatic)
                {
                    continue;
                }

                if ((grid.GridSizeEnum == MyCubeSize.Large && large) || (grid.GridSizeEnum == MyCubeSize.Small && small))
                {
                    Wrapper.BeginGameAction(() =>
                    {
                        grid.Physics.ClearSpeed( );
                        grid.RequestConversionToStation( );
                    });
                    Essentials.Log.Info($"Converted {grid.DisplayName} to static");
                    count++;
                }
            }
            Communication.SendPrivateInformation(userId, $"Converted {count} grids to static");
            return(true);
        }