예제 #1
0
        private static void WriteAt(string str, int x, int y, bool controlCursor = true)
        {
            int buff_top  = Console.CursorTop;
            int buff_left = Console.CursorLeft;

            if (controlCursor)
            {
                Console.CursorVisible = false;
            }
            Console.SetCursorPosition(x, y);
            //颜色代码至少占2个字符,所以长度不满3的情况下可以直接用Console.Write提升一点点效率(大概可以?)
            if (str.Length > 2)
            {
                ColorfullyConsole.Write(str);
            }
            else
            {
                Console.Write(str);
            }
            Console.SetCursorPosition(buff_left, buff_top);
            if (controlCursor)
            {
                Console.CursorVisible = true;
            }
        }
예제 #2
0
        private static int GetStringLength(string str)
        {
            //这和string.Length有什么区别?
            //这边给的是输出到终端后占的长度
            //大概就是颜色代码不会被计算进去,然后中文是占两个字符的。
            int        length            = 0;
            const byte AsciiCharLength   = 1;
            const byte ChineseCharLength = 2;

            for (int i = 0; i < str.Length; i++)
            {
                int c;
                //样式代码会直接被跳过,不会被计算进去
                if (str[i] == '&' && i != str.Length - 1)
                {
                    c = str[i + 1];
                    //如果是样式代码就跳过,不算到长度里面去
                    if ((c >= 48 && c <= 57) || (c >= 97 && c <= 102) || ColorfullyConsole.IsFormatCodeSupport(str[i + 1]))
                    {
                        i++;
                        continue;
                    }
                }
                c       = str[i];
                length += (c >= 32 && c <= 126) ? AsciiCharLength : ChineseCharLength;
            }
            return(length);
        }
예제 #3
0
 /// <summary>清空屏幕后重新写入终端</summary>
 public static void Refurbih()
 {
     Console.CursorVisible = false;
     ColorfullyConsole.Clear();
     ReWrite(0, false);
     Console.CursorVisible = true;
 }
예제 #4
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;
 }
예제 #5
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);
 }
예제 #6
0
        private static void ConsoleInitializing()
        {
            //linux下设置终端标题感觉不太好的样子(虽然后面还是会设置
            if (Platform.IsWindows)
            {
                Console.Title = $"{Program.Name}({Program.Version})";
            }

            //Win10以下的Windows不知道为什么会有乱码或者字显示不全这样子的问题
            if (Platform.IsWindows && Environment.OSVersion.Version.Major >= 10)
            {
                Console.InputEncoding  = Encoding.UTF8;
                Console.OutputEncoding = Encoding.UTF8;
            }

            //设置默认字体颜色
            //(这行删了也可以正常运行,但是如果在使用ColorfullyConsole前使用Console类设置了字体颜色会导致ColorfullyConsole.ResetColor的颜色不对)
            ColorfullyConsole.Init();

            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs args) {
                //这边可能需要try一下,以前有一行注释说这里在bash下会报错
                if (args.SpecialKey == ConsoleSpecialKey.ControlC)
                {
                    Program.Exit(false);
                }
            };

            //Linux下窗口变动后会导致显示的位置不正常,而且我还弄不出刷新键
            //所以暂时先加个监视窗口变化的线程来解决这个问题
            if (!Platform.IsWindows)
            {
                Thread HeightWatching = new Thread(() =>
                {
                    int LastHeight = Console.WindowHeight;
                    while (true)
                    {
                        if (Screen.Count > 0)
                        {
                            int CurrentHeight = Console.WindowHeight;
                            if (CurrentHeight != LastHeight)
                            {
                                LastHeight = CurrentHeight;
                                Screen.Refurbih();
                            }
                        }
                        Thread.Sleep(2800);
                    }
                });
                HeightWatching.Name = nameof(HeightWatching);
                HeightWatching.Start();
            }
        }
예제 #7
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}");
     }
 }
예제 #8
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);
 }
예제 #9
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("时间到,正在重试...");
        }
        bool IConsoleGuide.OpenGuide()
        {
            string InputPrompt_Host = "服务器地址:";
            Random egg = new Random();

            while (string.IsNullOrWhiteSpace(this.ServerHost))
            {
                if (egg.Next(0, 233) == 23)
                {
                    ColorfullyConsole.WriteRainbow(InputPrompt_Host);
                }
                else
                {
                    ColorfullyConsole.Write(InputPrompt_Host, ConsoleColor.White);
                }
                string UserInput = Console.ReadLine();
                //我的解析写的有问题,可能有一些地址是可以用的但是我这边就是匹配不了,所以这边暂时加了一个强制使用符.
                if (UserInput.Length > 0 && UserInput[UserInput.Length - 1] == '!')
                {
                    this.ServerHost = UserInput;
                }
                else
                {
                    var BaseInfo = Minecraft.ServerAddressResolve(UserInput);
                    if (BaseInfo.HasValue)
                    {
                        this.ServerHost = BaseInfo.Value.Host;
                        this.ServerPort = BaseInfo.Value.Port;
                    }
                    else if (InputPrompt_Host[0] != '你')
                    {
                        InputPrompt_Host = "你输入的不是一个有效的服务器地址,请重新输入:";
                    }
                }
            }
            return(true);
        }
        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;
        }
예제 #13
0
 public static void Clear()
 {
     Lines.Clear();
     ColorfullyConsole.Clear();
 }
예제 #14
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);
        }