예제 #1
0
 public MonitorPlayer(MonitorPlayerConfig config)
 {
     State             = States.Initializing;
     Config            = config != null ? config : throw new ArgumentNullException(nameof(config));
     MainPlayerManager = new PlayerManager(config);
     //注册玩家上下线的事件
     if (!string.IsNullOrWhiteSpace(Config.RunCommandForPlayerJoin))
     {
         MainPlayerManager.Joined += player =>
         {
             const string     reg       = @"^(\S+)( (.*))?$";
             ProcessStartInfo StartInfo = new ProcessStartInfo();
             StartInfo.FileName = Regex.Replace(Config.RunCommandForPlayerJoin, reg, "$1");
             if (Config.RunCommandForPlayerJoin.Contains(" "))
             {
                 StartInfo.Arguments = Regex
                                       .Replace(Config.RunCommandForPlayerJoin, reg, "$3")
                                       .Replace("$PLAYER_NAME", player.Name)
                                       .Replace("$PLAYER_UUID", player.Uuid.ToString());
             }
             Process.Start(StartInfo);
         };
     }
     if (!string.IsNullOrWhiteSpace(Config.RunCommandForPlayerDisconnected))
     {
         MainPlayerManager.Disconnected += player =>
         {
             const string     reg       = @"^(\S+)( (.*))?$";
             ProcessStartInfo StartInfo = new ProcessStartInfo();
             StartInfo.FileName = Regex.Replace(Config.RunCommandForPlayerDisconnected, reg, "$1");
             if (Config.RunCommandForPlayerDisconnected.Contains(" "))
             {
                 StartInfo.Arguments = Regex
                                       .Replace(Config.RunCommandForPlayerDisconnected, reg, "$3")
                                       .Replace("$PLAYER_NAME", player.Name)
                                       .Replace("$PLAYER_UUID", player.Uuid.ToString());
             }
             Process.Start(StartInfo);
         };
     }
     //解析服务器地址(如果是域名的话)
     try
     {
         SLP = new Ping(Config.ServerHost, Config.ServerPort);
     }
     catch (SocketException se)
     {
         if (se.SocketErrorCode == SocketError.HostNotFound)
         {
             Screen.Clear();
             ColorfullyConsole.WriteLine("&c错误&r:&f你输入的服务器地址不存在");
             ColorfullyConsole.WriteLine($"&e详细信息&r:&4{se}");
             Program.Exit(-1);
         }
     }
     State = States.Initialized;
 }
예제 #2
0
 //虽然名字这样叫吧,但是其实只是在打印名字而已
 private void StandardExceptionHandler(Exception e, string consoleTitle, DateTime?firstTime, int retryTime, int tryTick, int maxTryTick)
 {
     Console.Title = consoleTitle;
     Screen.Clear();
     IsFirstPrint = true;
     //Print Info
     PrintTime(ref firstTime);
     ColorfullyConsole.WriteLine($"&e详细信息&r:&c{e}");
     RetryHandler(ref retryTime, ref tryTick, maxTryTick);
 }
예제 #3
0
 private void PrintTime(ref DateTime?firstTime)
 {
     if (firstTime == null)
     {
         firstTime = DateTime.Now;
         ColorfullyConsole.WriteLine($"&f发生时间&r:&e{firstTime}");
     }
     else
     {
         ColorfullyConsole.WriteLine($"&f发生时间(首次)&r:&e{firstTime}");
         ColorfullyConsole.WriteLine($"&f发生时间(本次)&r:&e{DateTime.Now}");
     }
 }
예제 #4
0
 public static void Exit(string info, bool hasPause, int exitCode)
 {
     //因为在修改控制台中的文字时会暂时隐藏光标
     //所以有概率在还没有改回来的状态下就被用户按下Ctrl+c然后光标就没了所以这边需要恢复一下
     Console.CursorVisible = true;
     if (!string.IsNullOrEmpty(info))
     {
         ColorfullyConsole.WriteLine(info);
     }
     if (hasPause)
     {
         Console.WriteLine("按任意键关闭程序...");
         Console.ReadKey();
     }
     Environment.Exit(exitCode);
 }
예제 #5
0
        private void RetryHandler(ref int retryTime, ref int tick, int maxTick)
        {
            if (tick == 0)
            {
                ColorfullyConsole.WriteLine($"将在&f{(retryTime / 1000.0f):F2}&r秒后尝试重新连接服务器");
            }
            else if (tick < maxTick)
            {
                ColorfullyConsole.WriteLine($"&e已重试&r:&f{tick}次,{(retryTime / 1000.0f):F2}秒后将继续尝试去重新连接服务器");
            }
            else
            {
                Console.WriteLine($"已到达最大重试次数({maxTick})");
                if (Platform.IsWindows)
                {
                    Console.ReadKey(true);
                }
                Environment.Exit(-1);
            }

            //随机重试时间(随便写的)
            if (tick > maxTick / 2)
            {
                retryTime += new Random().Next(233 * 2, 33333 * 3);
                retryTime -= new Random().Next(2, 33333 * 3);
            }
            else
            {
                retryTime += new Random().Next(233, 2333 * 3);
                retryTime -= new Random().Next(23, 2333 * 3);
            }
            if (retryTime <= 1000)
            {
                retryTime = 1000 * 6;
            }
            Thread.Sleep(retryTime);
            tick++;
            Console.WriteLine("时间到,正在重试...");
        }
        string GetColorCode(string arg)
        {
            if (string.IsNullOrWhiteSpace(arg))
            {
                ColorfullyConsole.Write($"&c错误: \r\n &r选项 \"&e--highlight-color&r\" 没有值");
                Program.Exit(false, -1); return("");
            }

            try
            {
                int ColorCode = Convert.ToInt32(arg, 16);
                if (ColorCode >= 0 && ColorCode <= 0xf)
                {
                    return(ColorfullyConsole.DefaultColorCodeMark + ColorCode.ToString("x"));
                }
            }
            catch (FormatException)
            {
                string ColorText = arg.ToLowerInvariant();
                foreach (var name in typeof(ConsoleColor).GetEnumNames())
                {
                    if (name.ToLowerInvariant() == ColorText && Enum.TryParse(name, out ConsoleColor color))
                    {
                        return(ColorfullyConsole.DefaultColorCodeMark + ((int)color).ToString("x"));
                    }
                }
            }

            ColorfullyConsole.WriteLine($"&c错误&r: 颜色 \"{arg}\" 不存在,可用的颜色:");
            foreach (var name in typeof(ConsoleColor).GetEnumNames())
            {
                ConsoleColor CurrentColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), name);
                ColorfullyConsole.WriteLine($"0x{((int)CurrentColor):x}: {name}", CurrentColor);
            }
            Program.Exit(false, -1); return("");
        }
        protected override void LoadByConsoleOptions(ReadOnlySpan <string> args)
        {
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            for (int i = 0; i < args.Length; i++)
            {
                try
                {
                    //这边我有点想改成大小写敏感..
                    switch (args[i].ToLowerInvariant())
                    {
                    case "-h":
                    case "-help":
                    case "--help":
                        (this as IConsoleHelp).Show(); break;

                    case "-i":
                    case "-ip":
                    case "-host":
                        this.ServerHost = args[++i]; break;

                    case "-p":
                    case "-port":
                        this.ServerPort = ushort.Parse(args[++i]); break;

                    case "-s":
                    case "-sleep":
                        this.SleepTime = int.Parse(args[++i]); break;

                    case "-b":
                    case "-blood":
                        this.Blood = int.Parse(args[++i]); break;

                    case "--highlight":
                        this.HighlightList.AddRange(args[++i].Replace(',', ',').Split(',')); break;

                    case "--highlight-color":
                        this.HighlightColor = GetColorCode(args[++i]); break;

                    case "--color-minecraft":
                        this.SwitchColorScheme(new ConsolePlus.ColorSchemes.MinecraftColorScheme()); break;

                    case "--watchcat":
                        Watchcat.Instance.Start(1000 * 26, 8, 100.0 / (Environment.ProcessorCount + 0.3)); break;

                    case "--script-logged":
                        this.RunCommandForPlayerJoin = args.Length >= i + 1 ? args[++i] : throw new Exception($"option {args[i]} it value is empty"); break;

                    case "--script-loggedout":
                        this.RunCommandForPlayerDisconnected = args.Length >= i + 1 ? args[++i] : throw new Exception($"option {args[i]} it value is empty"); break;

                    default:
                        ColorfullyConsole.WriteLine($"&c错误:\r\n &r未知命令行选项:{args[i]}\r\n");
                        Program.Exit(false, -1);
                        break;
                    }
                }
                catch (IndexOutOfRangeException)
                {
                    //这边坐标可能有问题
                    if (args.Length <= i + 1)
                    {
                        ColorfullyConsole.WriteLine($"&c错误:\r\n &r命令行选项 \"&e{args[i-1]}&r\" 需要一个参数.\r\n");
                        Program.Exit(false, -1);
                    }
                    else
                    {
                        throw;
                    }
                }
                catch (FormatException)
                {
                    ColorfullyConsole.Write($"&c错误:\r\n &r命令行选项 \"&e{args[i-1]}&r\" 的值无法被转换,");
                    switch (args[i - 1].ToLowerInvariant())
                    {
                    case "-p":
                    case "-port":
                        Console.WriteLine("请输入一个有效的端口号(1-65535)");
                        break;

                    case "-s":
                    case "-b":
                    case "-sleep":
                    case "-blood":
                        Console.WriteLine("它不是一个有效的32位带符号整数。");
                        break;

                    default:
                        Console.WriteLine("超出范围。");
                        break;
                    }
                    Console.WriteLine();
                    Program.Exit(false, -1);
                }
            }
            //这里我当初是怎么想的???
            //if (!string.IsNullOrWhiteSpace(this.ServerHost))
            //    this.ServerPort = Minecraft.DefaultPortOfServer;
        }
예제 #8
0
        private PingReply ExceptionHandler(Ping slp)
        {
            DateTime?FirstTime  = null;
            int      RetryTime  = 1000 * 6;
            int      TryTick    = 0;
            int      MaxTryTick = ushort.MaxValue;

            while (State != States.Abort)
            {
                PingReply SLPResult = null;
                try
                {
                    SLPResult = slp.Send();
                    if (SLPResult != null)
                    {
                        FirstTime = null;
                        TryTick   = 0;
                        return(SLPResult);
                    }
                    else
                    {
                        throw new NullReferenceException("Reply is null");
                    }
                }
                catch (SocketException e)
                {
                    //恢复连接后有两种可能性:
                    //1.服务器崩溃
                    //2.客户端网络异常
                    //这边将来我可能会写更好的处理方法,现在只要崩溃了就无脑清空屏幕和玩家列表(玩家列表在FristPrint那边清理)
                    Screen.Clear();
                    IsFirstPrint = true;
                    if (e.SocketErrorCode == SocketError.HostNotFound)
                    {
                        //我没找到linux上这个错误的错误代码...
                        //这边好像不需要处理了?大概是不会到这边才出现错误的吧?
                        Console.BackgroundColor = ConsoleColor.Red;
                        Console.WriteLine("服务器地址错误(找不到这个地址)");
                        if (Platform.IsWindows)
                        {
                            Console.ReadKey(true);
                        }
                        Environment.Exit(-1);
                    }
                    else
                    {
                        PrintTime(ref FirstTime);
                        if (Platform.IsWindows)
                        {
                            Console.Title = $"网络发生了一点错误(qwq不要怕!可能过一会就可以恢复啦)";
                            ColorfullyConsole.WriteLine($"&c错误信息&r:&c{e.Message}&e(&c错误代码&f:&c{e.ErrorCode}&e)");
                        }
                        else
                        {
                            Console.Title = $"发生了网络异常";
                            ColorfullyConsole.WriteLine($"&e详细信息&r:&c{e}");
                        }
                        RetryHandler(ref RetryTime, ref TryTick, MaxTryTick);
                        continue;
                    }
                }
                catch (JsonException)
                {
                    try
                    {
                        return(JsonConvert.DeserializeObject <PingReply>(slp.ToString()));
                    }
                    catch (JsonException je)
                    {
                        IsFirstPrint  = true;
                        Console.Title = string.Empty;
                        Screen.Clear();
                        if (je is JsonSerializationException)
                        {
                            string ErrorJson = SLPResult?.ToString();
                            if (!string.IsNullOrWhiteSpace(ErrorJson) &&
                                ErrorJson.Contains("Server is still starting! Please wait before reconnecting"))
                            {
                                if (TryTick > short.MaxValue)
                                {
                                    Console.WriteLine("这服务器怎么一直在开启中的,怕是出了什么bug了...");
                                    Console.WriteLine($"请把这些信息复制给作者来修bug:{je}");
                                }
                                else
                                {
                                    Console.WriteLine("服务器正在开启中,程序将暂时16秒等待服务器开启...");
                                    Thread.Sleep(1000 * 16);
                                }
                                TryTick++;
                                continue;
                            }
                        }
                        PrintTime(ref FirstTime);
                        ColorfullyConsole.WriteLine("&cjson解析错误&f:&r服务器返回了一个无法被解析的json");
                        if (SLPResult != null)
                        {
                            ColorfullyConsole.WriteLine($"&e无法被解析的json&f:");
                            ColorfullyConsole.WriteLine($"{SLPResult.ToString()}");
                        }
                        ColorfullyConsole.WriteLine($"&e详细信息&r:&c{je}");
                        RetryHandler(ref RetryTime, ref TryTick, MaxTryTick);
                        continue;
                    }
                }
                catch (NullReferenceException nre)
                {
                    StandardExceptionHandler(nre, "发生了异常", FirstTime, RetryTime, TryTick, MaxTryTick);
                    continue;
                }
                catch (Exception)
                {
                    Console.Clear();
                    Console.WriteLine($"Time:{DateTime.Now}");
                    throw;
                }
            }
            return(null);
        }