Beispiel #1
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;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Starts up the server.
        /// </summary>
        public static void Init()
        {
            SysConsole.Output(OutputType.INIT, "Loading server...");
            SysConsole.Output(OutputType.INIT, "Loading command engine (Frenetic)...");
            Outputter op = new ServerOutputter();

            ServerCommands.Init(op);
            ServerCVar.Init(op);
            SysConsole.Output(OutputType.INIT, "Loading console reader...");
            ConsoleHandler.Init();
            SysConsole.Output(OutputType.INIT, "Preparing world system...");
            Worlds = new List <World>();
            SysConsole.Output(OutputType.INIT, "Loading networking engine...");
            NetworkBase.Init(true);
            SysConsole.Output(OutputType.INIT, "Loading player command engine...");
            PlayerCommandEngine.Init();
            SysConsole.Output(OutputType.INIT, "Preparing default worlds...");
            // TEMPORARY; TODO: Read settings / command line / anything
            CreateWorld("world");
            SysConsole.Output(OutputType.INIT, "Preparing to tick...");
            // Tick
            double    TARGETFPS    = 40d;
            Stopwatch Counter      = new Stopwatch();
            Stopwatch DeltaCounter = new Stopwatch();

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

            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);
                // How much time should pass between each tick ideally
                TARGETFPS = ServerCVar.g_fps.ValueD;
                if (TARGETFPS < 1 || TARGETFPS > 100)
                {
                    ServerCVar.g_fps.Set("40");
                    TARGETFPS = 40;
                }
                TargetDelta = (1d / TARGETFPS);
                // How much delta has been built up
                TotalDelta += CurrentDelta;
                if (TotalDelta > TargetDelta * 10)
                {
                    // Lagging - cheat to catch up!
                    TargetDelta *= 3;
                }
                if (TotalDelta > TargetDelta * 10)
                {
                    // Lagging a /lot/ - cheat /extra/ to catch up!
                    TargetDelta *= 3;
                }
                if (TotalDelta > TargetDelta * 10)
                {
                    // At this point, the server's practically dead.
                    TargetDelta *= 3;
                }
                // Give up on acceleration at this point. 50 * 27 = 1.35 seconds / tick under a default tickrate.
                // As long as there's more delta built up than delta wanted, tick
                while (TotalDelta > TargetDelta)
                {
                    Tick(TargetDelta);
                    TotalDelta -= TargetDelta;
                }
                // Begin the delta counter to find out how much time is /really/ slept for
                DeltaCounter.Reset();
                DeltaCounter.Start();
                // 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);
                }
            }
        }
Beispiel #3
0
 public override void Apply()
 {
     PlayerCommandEngine.Execute(Sender, command);
 }