예제 #1
0
 /// <summary>
 /// Handles a console command.
 /// </summary>
 /// <param name="sender">The sending object.</param>
 /// <param name="e">The event data.</param>
 public void CommandInputHandle(object sender, ConsoleCommandEventArgs e)
 {
     Schedule.ScheduleSyncTask(() =>
     {
         Commands.ExecuteCommands(e.Command);
     });
 }
예제 #2
0
        /// <summary>
        /// Starts up and run the server.
        /// </summary>
        /// <param name="game">The game name.</param>
        /// <param name="loaded">The action to fire when the server is loaded.</param>
        public void StartUp(string game, Action loaded = null)
        {
            CurThread = Thread.CurrentThread;
            Files     = new FileHandler();
            GameName  = FileHandler.CleanFileName(game);
            Files.SetSaveDirEarly("server_" + GameName);
            SysConsole.Written += OnConsoleWritten;
            SysConsole.Output(OutputType.INIT, "Launching as new server, this is " + (this == Central ? "" : "NOT ") + "the Central server.");
            SysConsole.Output(OutputType.INIT, "Loading console input handler...");
            ConsoleHandler.Init();
            ConsoleHandler.OnCommandInput += CommandInputHandle;
            SysConsole.Output(OutputType.INIT, "Loading command engine...");
            Commands = new ServerCommands();
            Commands.Init(new ServerOutputter(this), this);
            SysConsole.Output(OutputType.INIT, "Loading CVar engine...");
            CVars = new ServerCVar();
            CVars.Init(this, Commands.Output);
            SysConsole.Output(OutputType.INIT, "Loading default settings...");
            Config   = new FDSSection(Files.ReadText("server_config.fds"));
            Settings = new ServerSettings(this, Config);
            if (Files.Exists("serverdefaultsettings.cfg"))
            {
                string contents = Files.ReadText("serverdefaultsettings.cfg");
                Commands.ExecuteCommands(contents);
            }
            if (Files.Exists("server_eid.txt"))
            {
                cID = long.Parse(Files.ReadText("server_eid.txt") ?? "1");
            }
            SysConsole.Output(OutputType.INIT, "Loading player command engine...");
            PCEngine = new PlayerCommandEngine();
            SysConsole.Output(OutputType.INIT, "Loading permissions engine...");
            PermGroups = new PermissionsGroupEngine()
            {
                TheServer = this
            };
            SysConsole.Output(OutputType.INIT, "Loading item registry...");
            ItemInfos = new ItemInfoRegistry();
            Items     = new ItemRegistry(this);
            Recipes   = new RecipeRegistry()
            {
                TheServer = this
            };
            SysConsole.Output(OutputType.INIT, "Loading model handler...");
            Models = new ModelEngine(this);
            SysConsole.Output(OutputType.INIT, "Loading animation handler...");
            Animations = new AnimationEngine();
            SysConsole.Output(OutputType.INIT, "Preparing networking...");
            Networking = new NetworkBase(this);
            Networking.Init();
            SysConsole.Output(OutputType.INIT, "Loading plugins...");
            Plugins = new PluginManager(this);
            Plugins.Init();
            SysConsole.Output(OutputType.INIT, "Loading scripts...");
            AutorunScripts();
            SysConsole.Output(OutputType.INIT, "Building initial world(s)...");
            foreach (string str in Settings.Worlds)
            {
                LoadWorld(str.ToLowerFast());
            }
            SysConsole.Output(OutputType.INIT, "Preparing block image system...");
            BlockImages = new BlockImageManager();
            BlockImages.Init(this);
            loaded?.Invoke();
            SysConsole.Output(OutputType.INIT, "Ticking...");
            // Tick
            double    TARGETFPS    = 30d;
            Stopwatch Counter      = new Stopwatch();
            Stopwatch DeltaCounter = new Stopwatch();

            DeltaCounter.Start();
            double TotalDelta   = 0;
            double CurrentDelta = 0d;
            double TargetDelta  = 0d;
            int    targettime   = 0;

            try
            {
                while (true)
                {
                    // Update the tick time usage counter
                    Counter.Reset();
                    Counter.Start();
                    // Update the tick delta counter
                    DeltaCounter.Stop();
                    // Delta time = Elapsed ticks * (ticks/second)
                    CurrentDelta = ((double)DeltaCounter.ElapsedTicks) / ((double)Stopwatch.Frequency);
                    // Begin the delta counter to find out how much time is /really/ slept+ticked for
                    DeltaCounter.Reset();
                    DeltaCounter.Start();
                    // How much time should pass between each tick ideally
                    TARGETFPS = Settings.FPS;
                    if (TARGETFPS < 1 || TARGETFPS > 600)
                    {
                        Settings.FPS = 30;
                        TARGETFPS    = 30;
                    }
                    TargetDelta = (1d / TARGETFPS);
                    // How much delta has been built up
                    TotalDelta += CurrentDelta;
                    while (TotalDelta > TargetDelta * 3)
                    {
                        // Lagging - cheat to catch up!
                        TargetDelta *= 2;
                    }
                    // As long as there's more delta built up than delta wanted, tick
                    while (TotalDelta > TargetDelta)
                    {
                        if (NeedShutdown.IsCancellationRequested)
                        {
                            CurThread = Thread.CurrentThread;
                            ShutDown(ShutdownCallback);
                            return;
                        }
                        else if (NeedsQuickShutdown.IsCancellationRequested)
                        {
                            CurThread = Thread.CurrentThread;
                            ShutDownQuickly();
                            return;
                        }
                        lock (TickLock)
                        {
                            Tick(TargetDelta);
                        }
                        TotalDelta -= TargetDelta;
                    }
                    // The tick is done, stop measuring it
                    Counter.Stop();
                    // Only sleep for target milliseconds/tick minus how long the tick took... this is imprecise but that's okay
                    targettime = (int)((1000d / TARGETFPS) - Counter.ElapsedMilliseconds);
                    // Only sleep at all if we're not lagging
                    if (targettime > 0)
                    {
                        // Try to sleep for the target time - very imprecise, thus we deal with precision inside the tick code
                        Thread.Sleep(targettime);
                    }
                }
            }
            catch (ThreadAbortException)
            {
                return;
            }
        }