Esempio n. 1
0
        static Config()
        {
            try
            {
                if (!MiNetServer.IsRunningOnMono())                 //Fix issue on linux/mono.
                {
                    var assembly = Assembly.GetExecutingAssembly().GetName().CodeBase;
                    var path     = new Uri(Path.GetDirectoryName(assembly)).LocalPath;

                    var configFilePath = Path.Combine(path, ConfigFileName);

                    if (File.Exists(configFilePath))
                    {
                        FileContents = File.ReadAllText(configFilePath);
                    }
                }
                else
                {
                    if (File.Exists(ConfigFileName))
                    {
                        FileContents = File.ReadAllText(ConfigFileName);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Warn("Error configuring parser", e);
            }
        }
Esempio n. 2
0
        static Config()
        {
            try
            {
                string username = Environment.UserName;

                string fileContents = string.Empty;
                if (!MiNetServer.IsRunningOnMono())                 //Fix issue on linux/mono.
                {
                    var    assembly = Assembly.GetExecutingAssembly().GetName().CodeBase;
                    string rawPath  = Path.GetDirectoryName(assembly);
                    if (rawPath != null)
                    {
                        var path = new Uri(rawPath).LocalPath;

                        var configFilePath = Path.Combine(path, $"server.{username}.conf");
                        Log.Info($"Trying to load config-file {configFilePath}");
                        if (File.Exists(configFilePath))
                        {
                            fileContents = File.ReadAllText(configFilePath);
                        }
                        else
                        {
                            configFilePath = Path.Combine(path, ConfigFileName);

                            Log.Info($"Trying to load config-file {configFilePath}");

                            if (File.Exists(configFilePath))
                            {
                                fileContents = File.ReadAllText(configFilePath);
                            }
                        }
                        Log.Info($"Loading config-file {configFilePath}");
                    }
                }
                else
                {
                    if (File.Exists(ConfigFileName))
                    {
                        fileContents = File.ReadAllText(ConfigFileName);
                    }
                }

                LoadValues(fileContents);
            }
            catch (Exception e)
            {
                Log.Warn("Error configuring parser", e);
            }
        }
Esempio n. 3
0
        public HighPrecisionTimer(int interval, Action <object> action, bool useSignaling = false, bool skipTicks = true)
        {
            // The following is dangerous code. It will increase windows timer frequence to interrupt
            // every 1ms instead of default 15ms. It is the same tech that games use to increase FPS and
            // media decoders to increase precision of movies (chrome does this).
            // We use this here to increase the precision of our thread scheduling, since this will have a big
            // impact on overall performance of the server. DO note that changing this is a global setting in
            // Windows and will affect every running process. It will automatically disable itself and reset
            // to default after closing the process.
            // It will have a major impact bettery and energy consumption in general. So don't go tell GreenPeace about
            // this, thanks.
            //
            // HERE BE DRAGONS!
            if (!MiNetServer.IsRunningOnMono())
            {
                WinApi.TimeBeginPeriod(1);
            }
            // END IS HERE. SAFE AGAIN ...

            Avarage = interval;
            Action  = action;

            if (interval < 1)
            {
                throw new ArgumentOutOfRangeException();
            }

            CancelSource = new CancellationTokenSource();

            var  watch    = Stopwatch.StartNew();
            long nextStop = interval;

            var task = new Task(() =>
            {
                Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;

                while (!CancelSource.IsCancellationRequested)
                {
                    long msLeft = nextStop - watch.ElapsedMilliseconds;
                    if (msLeft <= 0)
                    {
                        if (msLeft < -1)
                        {
                            Misses++;
                        }
                        //if (!skipTicks && msLeft < -4) Log.Warn($"We are {msLeft}ms late for action execution");

                        long execTime = watch.ElapsedMilliseconds;
                        Action(this);
                        AutoReset.Reset();
                        execTime = watch.ElapsedMilliseconds - execTime;
                        Avarage  = (Avarage * 9 + execTime) / 10L;

                        if (skipTicks)
                        {
                            // Calculate when the next stop is. If we're too slow on the trigger then we'll skip ticks
                            nextStop = (long)(interval * (Math.Floor(watch.ElapsedMilliseconds / (float)interval /*+ 1f*/) + 1));
                        }
                        else
                        {
                            long calculatedNextStop = (long)(interval * (Math.Floor(watch.ElapsedMilliseconds / (float)interval /*+ 1f*/) + 1));
                            nextStop += interval;

                            // Calculate when the next stop is. If we're very behind on ticks then we'll skip ticks
                            if (calculatedNextStop - nextStop > 2 * interval)
                            {
                                //Log.Warn($"Skipping ticks because behind {calculatedNextStop - nextStop}ms. Too much");
                                nextStop = calculatedNextStop;
                            }
                        }

                        // If we can't keep up on execution time, we start skipping ticks until we catch up again.
                        if (Avarage > interval)
                        {
                            nextStop += interval;
                        }

                        continue;
                    }
                    if (msLeft < 5)
                    {
                        Spins++;

                        if (useSignaling)
                        {
                            AutoReset.WaitOne(50);
                        }

                        var stop = nextStop;
                        if (watch.ElapsedMilliseconds < stop)
                        {
                            SpinWait.SpinUntil(() => watch.ElapsedMilliseconds >= stop);
                        }

                        continue;
                    }

                    if (msLeft < 16)
                    {
                        if (Thread.Yield())
                        {
                            Yields++;
                            continue;
                        }

                        Sleeps++;
                        Thread.Sleep(1);
                        if (!skipTicks)
                        {
                            long t = nextStop - watch.ElapsedMilliseconds;
                            if (t < -5)
                            {
                                Log.Warn($"We overslept {t}ms in thread yield/sleep");
                            }
                        }
                        continue;
                    }

                    Sleeps++;
                    Thread.Sleep(Math.Max(1, (int)(msLeft - 16)));
                    if (!skipTicks)
                    {
                        long t = nextStop - watch.ElapsedMilliseconds;
                        if (t < -5)
                        {
                            Log.Warn($"We overslept {t}ms in thread sleep");
                        }
                    }
                }

                CancelSource.Dispose();
                CancelSource = null;

                AutoReset.Dispose();
                AutoReset = null;
            }, CancelSource.Token, TaskCreationOptions.LongRunning);

            task.Start();
        }