예제 #1
0
        public static void DeleteSmart(this IMyCubeGrid Grid)
        {
            if (!MyAPIGateway.Session.IsServer)
            {
                return;
            }
            List <IMyCubeGrid> Subgrids = Grid.GetAllSubgrids();

            foreach (IMyCubeGrid Subgrid in Subgrids)
            {
                Subgrid.Close();
            }
            Grid.Close();
        }
예제 #2
0
        ///  Closes this grid and all its subgrids (may include things docked on connectors!)
        public static void CloseAll(this IMyCubeGrid grid)
        {
            var slimBlocks = new List <IMySlimBlock>();

            grid.GetBlocks(slimBlocks, b => b.FatBlock is IMyMotorBase);
            foreach (var slim in slimBlocks)
            {
                var fat     = slim.FatBlock as IMyMotorBase;
                var subGrid = fat.TopGrid;
                if (subGrid != null)
                {
                    subGrid.Close();
                }
            }
            grid.Close();
        }
예제 #3
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;
            }
        }
예제 #4
0
        public void HandleChatCommand(ulong steamId, string command)
        {
            MyPromoteLevel level = MyAPIGateway.Session.GetUserPromoteLevel(steamId);

            Logging.Instance.WriteLine($"Got chat command from {steamId} : {command}");

            if (command.Equals("!join", StringComparison.CurrentCultureIgnoreCase))
            {
                if (!Settings.Instance.Hub)
                {
                    Communication.SendServerChat(steamId, "Join commands are not valid in battle servers!");
                    return;
                }
                Communication.SendServerChat(steamId, $"There are {Servers.Count} battle servers. Please select the one you want by sending '!join [number]'");
                List <int> availableServers = (from server in Servers.Values where server.CanJoin select server.Index + 1).ToList();

                if (availableServers.Count < Servers.Count)
                {
                    Communication.SendServerChat(steamId, $"These servers are ready for matches: {string.Join(", ", availableServers)}");
                }
                else
                {
                    Communication.SendServerChat(steamId, $"All {Servers.Count} servers are available for new matches!");
                }

                return;
            }

            if (command.StartsWith("!join", StringComparison.CurrentCultureIgnoreCase))
            {
                int ind = command.IndexOf(" ");
                if (ind == -1)
                {
                    Communication.SendServerChat(steamId, "Couldn't parse your server selection!");
                    return;
                }

                string     numtex = command.Substring(ind);
                ServerItem server;
                int        num;
                if (!int.TryParse(numtex, out num))
                {
                    Communication.SendServerChat(steamId, "Couldn't parse your server selection!");
                    return;
                }

                if (!Servers.TryGetValue(num - 1, out server))
                {
                    Communication.SendServerChat(steamId, $"Couldn't find server {num}");
                    return;
                }

                if (!server.CanJoin)
                {
                    Communication.SendServerChat(steamId, "Sorry, this server is not open to new members. Please try another.");
                    return;
                }

                IMyPlayer player = Utilities.GetPlayerBySteamId(steamId);

                var         block = player?.Controller?.ControlledEntity?.Entity as IMyCubeBlock;
                IMyCubeGrid grid  = block?.CubeGrid;
                if (grid == null)
                {
                    Communication.SendServerChat(steamId, "Can't find your ship. Make sure you're seated in the ship you want to take with you.");
                    return;
                }

                var blocks = new List <IMySlimBlock>();
                grid.GetBlocks(blocks);

                if (blocks.Count > Settings.Instance.MaxBlockCount)
                {
                    Communication.SendServerChat(steamId, $"Your ship has {blocks.Count} blocks. The limit for this server is {Settings.Instance.MaxBlockCount}");
                    return;
                }

                byte[] payload = Utilities.SerializeAndSign(grid, Utilities.GetPlayerBySteamId(steamId), block.Position);
                Communication.SegmentAndSend(Communication.MessageType.ClientGridPart, payload, MyAPIGateway.Multiplayer.ServerId, steamId);

                server.Join(steamId);

                var timer = new Timer(10000);
                timer.AutoReset = false;
                timer.Elapsed  += (a, b) => MyAPIGateway.Utilities.InvokeOnGameThread(() => grid.Close());
                timer.Start();
                return;
            }

            if (command.Equals("!hub", StringComparison.CurrentCultureIgnoreCase))
            {
                if (Settings.Instance.Hub)
                {
                    Communication.SendServerChat(steamId, "You're already in the hub!");
                    return;
                }
                Communication.RedirectClient(steamId, Settings.Instance.HubIP);
                return;
            }

            if (level >= MyPromoteLevel.Moderator)
            {
                if (command.StartsWith("!spectate", StringComparison.CurrentCultureIgnoreCase))
                {
                    int ind = command.IndexOf(" ");
                    if (ind == -1)
                    {
                        Communication.SendServerChat(steamId, "Couldn't parse your server selection!");
                        return;
                    }

                    string     numtex = command.Substring(ind);
                    ServerItem server;
                    int        num;
                    if (!int.TryParse(numtex, out num))
                    {
                        Communication.SendServerChat(steamId, "Couldn't parse your server selection!");
                        return;
                    }

                    if (!Servers.TryGetValue(num - 1, out server))
                    {
                        Communication.SendServerChat(steamId, $"Couldn't find server {num}");
                        return;
                    }

                    MyAPIGateway.Utilities.DeleteFileInLocalStorage("Ship.bin", typeof(LinkModCore));
                    Communication.RedirectClient(steamId, server.IP);
                    return;
                }
            }

            if (level >= MyPromoteLevel.Admin)
            {
                if (command.Equals("!endjoin", StringComparison.CurrentCultureIgnoreCase))
                {
                    _lobbyTimer.Stop();
                    _lobbyRunning = false;
                    _matchRunning = true;
                    Communication.SendNotification(0, "MATCH START!", MyFontEnum.Green);
                    Logging.Instance.WriteLine("Starting match");
                    _matchTimer.Start();
                    return;
                }

                if (command.Equals("!endmatch", StringComparison.CurrentCultureIgnoreCase))
                {
                    _matchTimer.Stop();
                    _matchRunning = false;
                    Communication.SendNotification(0, "MATCH OVER!", MyFontEnum.Red, 10000);
                    Logging.Instance.WriteLine("Ending match");
                    Utilities.ScrubServer();
                    return;
                }

                if (command.Equals("!reload", StringComparison.CurrentCultureIgnoreCase))
                {
                    Settings.LoadSettings();
                    Communication.SendServerChat(steamId, "Okay.");
                    return;
                }

                if (command.Equals("!save", StringComparison.CurrentCultureIgnoreCase))
                {
                    Settings.SaveSettings();
                    Communication.SendServerChat(steamId, "Okay.");
                    return;
                }

                if (command.StartsWith("!reset", StringComparison.CurrentCultureIgnoreCase))
                {
                    int ind = command.IndexOf(" ");
                    if (ind == -1)
                    {
                        foreach (var s in Servers.Values)
                        {
                            s.Reset();
                        }
                        Communication.SendServerChat(steamId, "Reset all servers");
                        return;
                    }

                    string     numtex = command.Substring(ind);
                    ServerItem server;
                    int        num;
                    if (!int.TryParse(numtex, out num))
                    {
                        Communication.SendServerChat(steamId, "Couldn't parse your server selection!");
                        return;
                    }

                    if (Servers.TryGetValue(num - 1, out server))
                    {
                        server.Reset();
                        Communication.SendServerChat(steamId, $"Reset server {num}");
                    }
                }
            }

            if (command.Equals("!help", StringComparison.CurrentCultureIgnoreCase))
            {
                if (level >= MyPromoteLevel.Admin)
                {
                    Communication.SendServerChat(steamId, ADMIN_HELP);
                }
                else
                {
                    if (level >= MyPromoteLevel.Moderator)
                    {
                        Communication.SendServerChat(steamId, MODERATOR_HELP);
                    }
                    else
                    {
                        Communication.SendServerChat(steamId, HELP_TEXT);
                    }
                }
            }
        }
예제 #5
0
 private void DeleteGrid(IMyCubeGrid cubeGrid, string reason)
 {
     MyLog.Default.WriteLineAndConsole($"DELETED GRID: {cubeGrid.DisplayName}. Reason: {reason}.");
     cubeGrid.Delete();
     cubeGrid.Close();
 }
예제 #6
0
        private void CheckBeforeJump(Vector3D gridpos, ulong steamId, IMyCubeGrid gridtotp)
        {
            ServerJumpClass.Instance.SomeLog("CheckBeforeJump() start");
            bool   HyperDrive = false;
            bool   GateLink   = false;
            string IP         = "0.0.0.0:27016";

            Communication.SendServerChat(steamId, "CheckBeforeJump start!" + gridpos);
            List <IMyEntity> allentities = new List <IMyEntity>();
            var tmpsphere = new BoundingSphereD(gridpos, 5100);

            allentities = MyAPIGateway.Entities.GetEntitiesInSphere(ref tmpsphere);
            Communication.SendServerChat(steamId, "GetTopMostEntitiesInSphere :" + allentities.Count);
            List <IMyCubeGrid> allentitieslist = allentities.OfType <IMyCubeGrid>().ToList();

            Communication.SendServerChat(steamId, ".OfType<IMyCubeGrid>() :" + allentitieslist.Count);
            if (allentitieslist.Count >= 2)
            {
                foreach (IMyCubeGrid grid in allentitieslist)
                {
                    if (grid?.GridSizeEnum == MyCubeSize.Small || grid.Physics == null || grid.MarkedForClose || grid.Closed)
                    {
                        continue;
                    }
                    // Logging.Instance.WriteLine($"grid.Name = " + grid.Name);
                    Communication.SendServerChat(steamId, "before GetBlocks :");
                    var blocks = new List <IMySlimBlock>();

                    var tmpspher2e = new BoundingSphereD(grid.GetPosition(), 1000);
                    blocks = grid.GetBlocksInsideSphere(ref tmpspher2e);

                    Communication.SendServerChat(steamId, " GetBlocks :" + blocks.Count);

                    foreach (IMySlimBlock block in blocks)
                    {
                        try
                        {
                            // Communication.SendServerChat(steamId, " block :" + block.GetObjectBuilderCubeBlock().SubtypeName);
                            if (block.FatBlock == null)
                            {
                                continue;
                            }
                            if (block?.FatBlock?.BlockDefinition.SubtypeId == "HyperDrive" &&
                                ((block.FatBlock.GetObjectBuilderCubeBlock() as MyObjectBuilder_JumpDrive).StoredPower >= (block.FatBlock as MyJumpDrive).BlockDefinition.PowerNeededForJump))
                            {
                                HyperDrive = true;
                                Communication.SendServerChat(steamId, "  HyperDrive = true; :");
                                //   Logging.Instance.WriteLine($"found HyperDrive !" + tmp2);
                            }
                            if (block.FatBlock.BlockDefinition.SubtypeId == "JumpGateLink")
                            {
                                GateLink = true;
                                IP       = (block.FatBlock as IMyTerminalBlock)?.CustomData.ToString();
                                Communication.SendServerChat(steamId, "  GateLink = true; :");
                            }
                            if (HyperDrive && GateLink)
                            {
                                //  MyAPIGateway.Utilities.InvokeOnGameThread(() => {
                                byte[] payload = Utilities.SerializeAndSign(gridtotp,
                                                                            Utilities.GetPlayerBySteamId(steamId),
                                                                            (Utilities.GetPlayerBySteamId(steamId)?.Controller?.ControlledEntity?.Entity as IMyCubeBlock).Position);

                                Communication.SegmentAndSend(Communication.MessageType.ClientGridPart, payload, MyAPIGateway.Multiplayer.ServerId, steamId);
                                //Communication.SendServerChat(steamId, "redirect to 178.210.32.201:27016!");
                                Communication.RedirectClient(steamId, IP);//"178.210.32.201:27016"
                                ServerJumpClass.Instance.SomeLog("[Jump] Client: " + Utilities.GetPlayerBySteamId(steamId).DisplayName + " steamId: " + steamId + " Grid: " + grid.DisplayName + " To: " + IP);
                                var timer = new Timer(10000);
                                timer.AutoReset = false;
                                timer.Elapsed  += (a, b) => MyAPIGateway.Utilities.InvokeOnGameThread(() => gridtotp.Close());
                                timer.Start();
                                //});
                                return;
                            }
                        }
                        catch { Communication.SendServerChat(steamId, "  catch foreach (IMySlimBlock block in blocks) "); }
                    }
                }
                Communication.SendServerChat(steamId, "HyperDrive = " + HyperDrive + "GateLink = " + GateLink);
                return;
            }
            else
            {
                Communication.SendServerChat(steamId, "allentitieslist.Count >=2!");
            }

            return;
        }
예제 #7
0
        public void HandleChatCommand(ulong steamId, string command)
        {
            MyPromoteLevel level = MyAPIGateway.Session.GetUserPromoteLevel(steamId);

            ServerJumpClass.Instance.SomeLog($"Got chat command from {steamId} : {command}");

            if (command.Equals("!join", StringComparison.CurrentCultureIgnoreCase))
            {
                InitJump(steamId);

                return;
            }

            if (command.StartsWith("!join", StringComparison.CurrentCultureIgnoreCase))
            {
                int ind = command.IndexOf(" ");
                if (ind == -1)
                {
                    Communication.SendServerChat(steamId, "Couldn't parse your server selection!");
                    return;
                }

                string     numtex = command.Substring(ind);
                ServerItem server;
                int        num;
                if (!int.TryParse(numtex, out num))
                {
                    Communication.SendServerChat(steamId, "Couldn't parse your server selection!");
                    return;
                }

                if (!Servers.TryGetValue(num - 1, out server))
                {
                    Communication.SendServerChat(steamId, $"Couldn't find server {num}");
                    return;
                }

                if (!server.CanJoin)
                {
                    Communication.SendServerChat(steamId, "Sorry, this server is not open to new members. Please try another.");
                    return;
                }

                IMyPlayer player = Utilities.GetPlayerBySteamId(steamId);

                var         block = player?.Controller?.ControlledEntity?.Entity as IMyCubeBlock;
                IMyCubeGrid grid  = block?.CubeGrid;
                if (grid == null)
                {
                    Communication.SendServerChat(steamId, "Can't find your ship. Make sure you're seated in the ship you want to take with you.");
                    return;
                }

                var blocks = new List <IMySlimBlock>();
                grid.GetBlocks(blocks);

                if (blocks.Count > Settings.MaxBlockCount)
                {
                    Communication.SendServerChat(steamId, $"Your ship has {blocks.Count} blocks. The limit for this server is {Settings.MaxBlockCount}");
                    return;
                }

                byte[] payload = Utilities.SerializeAndSign(grid, Utilities.GetPlayerBySteamId(steamId), block.Position);
                Communication.SegmentAndSend(Communication.MessageType.ClientGridPart, payload, MyAPIGateway.Multiplayer.ServerId, steamId);

                server.Join(steamId);

                var timer = new Timer(10000);
                timer.AutoReset = false;
                timer.Elapsed  += (a, b) => MyAPIGateway.Utilities.InvokeOnGameThread(() => grid.Close());
                timer.Start();
                return;
            }

            if (command.Equals("!hub", StringComparison.CurrentCultureIgnoreCase))
            {
                if (Settings.Hub)
                {
                    Communication.SendServerChat(steamId, "You're already in the hub!");
                    return;
                }
                Communication.RedirectClient(steamId, Settings.HubIP);
                return;
            }

            if (level >= MyPromoteLevel.Moderator)
            {
                if (command.StartsWith("!spectate", StringComparison.CurrentCultureIgnoreCase))
                {
                    int ind = command.IndexOf(" ");
                    if (ind == -1)
                    {
                        Communication.SendServerChat(steamId, "Couldn't parse your server selection!");
                        return;
                    }

                    string     numtex = command.Substring(ind);
                    ServerItem server;
                    int        num;
                    if (!int.TryParse(numtex, out num))
                    {
                        Communication.SendServerChat(steamId, "Couldn't parse your server selection!");
                        return;
                    }

                    if (!Servers.TryGetValue(num - 1, out server))
                    {
                        Communication.SendServerChat(steamId, $"Couldn't find server {num}");
                        return;
                    }

                    ServerJumpClass.Instance.SomeLog("DeleteFileInLocalStorage");
                    //  MyAPIGateway.Utilities.DeleteFileInLocalStorage("Ship.bin", typeof(ServerJump));
                    Communication.RedirectClient(steamId, server.IP);
                    return;
                }
            }

            if (level >= MyPromoteLevel.Admin)
            {
                if (command.Equals("!reload", StringComparison.CurrentCultureIgnoreCase))
                {
                    //Settings.LoadSettings();
                    Communication.SendServerChat(steamId, "Okay.");
                    return;
                }

                if (command.Equals("!save", StringComparison.CurrentCultureIgnoreCase))
                {
                    // Settings.SaveSettings();
                    Communication.SendServerChat(steamId, "Okay.");
                    return;
                }

                if (command.StartsWith("!reset", StringComparison.CurrentCultureIgnoreCase))
                {
                    int ind = command.IndexOf(" ");
                    if (ind == -1)
                    {
                        foreach (var s in Servers.Values)
                        {
                            s.Reset();
                        }
                        Communication.SendServerChat(steamId, "Reset all servers");
                        return;
                    }

                    string     numtex = command.Substring(ind);
                    ServerItem server;
                    int        num;
                    if (!int.TryParse(numtex, out num))
                    {
                        Communication.SendServerChat(steamId, "Couldn't parse your server selection!");
                        return;
                    }

                    if (Servers.TryGetValue(num - 1, out server))
                    {
                        server.Reset();
                        Communication.SendServerChat(steamId, $"Reset server {num}");
                    }
                }
            }

            if (command.Equals("!help", StringComparison.CurrentCultureIgnoreCase))
            {
                if (level >= MyPromoteLevel.Admin)
                {
                    Communication.SendServerChat(steamId, ADMIN_HELP);
                }
                else
                {
                    if (level >= MyPromoteLevel.Moderator)
                    {
                        Communication.SendServerChat(steamId, MODERATOR_HELP);
                    }
                    else
                    {
                        Communication.SendServerChat(steamId, HELP_TEXT);
                    }
                }
            }
        }
예제 #8
0
        public override void UpdateAfterSimulation100()
        {
            try
            {
                //if(!MyAPIGateway.Multiplayer.IsServer) // only server-side/SP
                if (!AiSessionCore.IsServer)
                {
                    return;
                }

                IMyRemoteControl rc   = (IMyRemoteControl)Entity;
                IMyCubeGrid      grid = rc.CubeGrid;

                if (grid.Physics == null || !rc.IsWorking || !Constants.NpcFactions.Contains(rc.GetOwnerFactionTag()))
                {
                    if (Constants.CleanupDebug)
                    {
                        AiSessionCore.GeneralLog.WriteToLog("CleanEemRc", grid.DisplayName + " (" + grid.EntityId + " @ " + grid.WorldMatrix.Translation + ") is not valid; " + (grid.Physics == null ? "Phys=null" : "Phys OK") + "; " + (rc.IsWorking ? "RC OK" : "RC Not working!") + "; " + (!Constants.NpcFactions.Contains(rc.GetOwnerFactionTag()) ? "Owner faction tag is not in NPC list (" + rc.GetOwnerFactionTag() + ")" : "Owner Faction OK"));
                    }

                    return;
                }

                if (!rc.CustomData.Contains(Constants.CleanupRcTag))
                {
                    if (Constants.CleanupDebug)
                    {
                        AiSessionCore.GeneralLog.WriteToLog("CleanEemRc", grid.DisplayName + " (" + grid.EntityId + " @ " + grid.WorldMatrix.Translation + ") RC does not contain the " + Constants.CleanupRcTag + "tag!");
                    }

                    return;
                }

                if (Constants.CleanupRcExtraTags.Length > 0)
                {
                    bool hasExtraTag = Constants.CleanupRcExtraTags.Any(tag => rc.CustomData.Contains(tag));

                    if (!hasExtraTag)
                    {
                        if (Constants.CleanupDebug)
                        {
                            AiSessionCore.GeneralLog.WriteToLog("CleanEemRc", grid.DisplayName + " (" + grid.EntityId + " @ " + grid.WorldMatrix.Translation + ") RC does not contain one of the extra tags!");
                        }

                        return;
                    }
                }

                if (Constants.CleanupDebug)
                {
                    AiSessionCore.GeneralLog.WriteToLog("CleanEemRc", "Checking RC '" + rc.CustomName + "' from grid '" + grid.DisplayName + "' (" + grid.EntityId + ") for any nearby players...");
                }

                int      rangeSq    = CleanEem.RangeSq;
                Vector3D gridCenter = grid.WorldAABB.Center;

                if (rangeSq <= 0)
                {
                    if (Constants.CleanupDebug)
                    {
                        AiSessionCore.GeneralLog.WriteToLog("CleanEemRc", "- WARNING: Range not assigned yet, ignoring grid for now.");
                    }

                    return;
                }

                //check if any player is within range of the ship
                foreach (IMyPlayer player in CleanEem.Players)
                {
                    if (Vector3D.DistanceSquared(player.GetPosition(), gridCenter) <= rangeSq)
                    {
                        if (Constants.CleanupDebug)
                        {
                            AiSessionCore.GeneralLog.WriteToLog("CleanEemRc", " - player '" + player.DisplayName + "' is within " + Math.Round(Math.Sqrt(rangeSq), 1) + "m of it, not removing.");
                        }

                        return;
                    }
                }

                if (Constants.CleanupDebug)
                {
                    AiSessionCore.GeneralLog.WriteToLog("CleanEemRc", " - no player is within " + Math.Round(Math.Sqrt(rangeSq), 1) + "m of it, removing...");
                }

                AiSessionCore.GeneralLog.WriteToLog("CleanEemRc", "NPC ship '" + grid.DisplayName + "' (" + grid.EntityId + ") removed.");

                CleanEem.GetAttachedGrids(grid); // this gets all connected grids and places them in Exploration.grids (it clears it first)

                foreach (IMyCubeGrid g in CleanEem.Grids)
                {
                    g.Close(); // this only works server-side
                    AiSessionCore.GeneralLog.WriteToLog("CleanEemRc", "  - subgrid '" + g.DisplayName + "' (" + g.EntityId + ") removed.");
                }

                grid.Close(); // this only works server-side
            }
            catch (Exception e)
            {
                AiSessionCore.GeneralLog.WriteToLog("CleanEemRc", $"Exception: {e}");
            }
        }