using System.Collections; using System.Net.NetworkInformation; using System.Security.Cryptography; using System.Text.Json; using System.Text.RegularExpressions; using Milimoe.FunGame.Core.Library.Common.Architecture; using Milimoe.FunGame.Core.Library.Constant; // 通用工具类,客户端和服务器端都可以直接调用的工具方法都可以写在这里 namespace Milimoe.FunGame.Core.Api.Utility { #region 网络服务 /// /// 网络服务工具箱 /// public class NetworkUtility { /// /// 判断字符串是否是IP地址 /// /// /// public static bool IsIP(string str) => Regex.IsMatch(str, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"); /// /// 判断字符串是否为邮箱地址 /// /// /// public static bool IsEmail(string str) => Regex.IsMatch(str, @"^(\w)+(\.\w)*@(\w)+((\.\w+)+)$"); /// /// 判断字符串是否是正常的用户名(只有中英文和数字) /// /// /// public static bool IsUserName(string str) => Regex.IsMatch(str, @"^[\u4e00-\u9fa5A-Za-z0-9]+$"); /// /// 获取用户名长度 /// /// /// public static int GetUserNameLength(string str) { int length = 0; for (int i = 0; i < str.Length; i++) { char c = str[i]; if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9') length++; else length += 2; } return length; } /// /// 判断字符串是否是一个FunGame可接受的服务器地址 /// /// /// public static ErrorIPAddressType IsServerAddress(string str) { string[] strs = str.Split(':'); string ip; int port; if (strs.Length < 2) { ip = strs[0]; port = 22222; } else if (strs.Length < 3) { ip = strs[0]; port = Convert.ToInt32(strs[1]); } else return ErrorIPAddressType.WrongFormat; if (IsIP(ip) && port > 0 && port < 65536) return ErrorIPAddressType.None; else if (!IsIP(ip) && port > 0 && port < 65536) return ErrorIPAddressType.IsNotIP; else if (IsIP(ip) && (port <= 0 || port >= 65536)) return ErrorIPAddressType.IsNotPort; else return ErrorIPAddressType.WrongFormat; } /// /// 判断参数是否是一个FunGame可接受的服务器地址 /// /// /// /// public static ErrorIPAddressType IsServerAddress(string ip, int port) { if (IsIP(ip) && port > 0 && port < 65536) return ErrorIPAddressType.None; else if (!IsIP(ip) && port > 0 && port < 65536) return ErrorIPAddressType.IsNotIP; else if (IsIP(ip) && (port <= 0 || port >= 65536)) return ErrorIPAddressType.IsNotPort; else return ErrorIPAddressType.WrongFormat; } /// /// 获取服务器的延迟 /// /// 服务器IP地址 /// public static int GetServerPing(string addr) { Ping pingSender = new(); PingOptions options = new() { DontFragment = true }; string data = "getserverping"; byte[] buffer = General.DefaultEncoding.GetBytes(data); int timeout = 120; PingReply reply = pingSender.Send(addr, timeout, buffer, options); if (reply.Status == IPStatus.Success) { return Convert.ToInt32(reply.RoundtripTime); } return -1; } /// /// 返回目标对象的Json字符串 /// /// /// /// public static string JsonSerialize(T obj) { return Service.JsonManager.GetString(obj); } /// /// 返回目标对象的Json字符串 可指定反序列化选项 /// /// /// /// /// public static string JsonSerialize(T obj, JsonSerializerOptions options) { return Service.JsonManager.GetString(obj, options); } /// /// 反序列化Json对象 /// /// /// /// public static T? JsonDeserialize(string json) { return Service.JsonManager.GetObject(json); } /// /// 反序列化Json对象 可指定反序列化选项 /// /// /// /// /// public static T? JsonDeserialize(string json, JsonSerializerOptions options) { return Service.JsonManager.GetObject(json, options); } /// /// 反序列化Hashtable中的Json对象 /// /// /// /// /// public static T? JsonDeserializeFromHashtable(Hashtable hashtable, string key) { return Service.JsonManager.GetObject(hashtable, key); } /// /// 反序列化Hashtable中的Json对象 可指定反序列化选项 /// /// /// /// /// /// public static T? JsonDeserializeFromHashtable(Hashtable hashtable, string key, JsonSerializerOptions options) { return Service.JsonManager.GetObject(hashtable, key, options); } } #endregion #region 时间服务 /// /// 时间服务工具箱 /// public class DateTimeUtility { /// /// 获取系统时间 /// /// 格式化类型 /// public static DateTime GetDateTime(TimeType type) { DateTime now = DateTime.Now; if (type == TimeType.DateOnly) return now.Date; else return now; } /// /// 通过字符串转换为DateTime对象 /// /// 时间字符串 /// 转换失败返回当前时间 public static DateTime GetDateTime(string format) { DateTime dt = default; if (DateTime.TryParse(format, out dt)) { return dt; } else { return DateTime.Now; } } /// /// 获取系统时间并转为字符串 /// /// 格式化类型 /// public static string GetDateTimeToString(TimeType type) { DateTime now = DateTime.Now; return type switch { TimeType.DateOnly => now.Date.ToString("D"), TimeType.TimeOnly => now.ToString("T"), TimeType.Year4 => now.Year.ToString(), TimeType.Year2 => "'" + now.ToString("yy"), TimeType.Month => now.Month.ToString(), TimeType.Day => now.Day.ToString(), TimeType.Hour => now.Hour.ToString(), TimeType.Minute => now.Minute.ToString(), TimeType.Second => now.Second.ToString(), _ => now.ToString("yyyy/MM/dd HH:mm:ss") }; } /// /// 获取系统短日期 /// /// public static string GetNowShortTime() { DateTime now = DateTime.Now; return now.AddMilliseconds(-now.Millisecond).ToString("T"); } /// /// 获取系统日期 /// /// public static string GetNowTime() { DateTime now = DateTime.Now; return now.AddMilliseconds(-now.Millisecond).ToString(); } } #endregion #region 加密服务 /// /// 使用HMACSHA512算法加密 /// internal class Encryption { /// /// 使用HMACSHA512算法加密 /// /// 需要加密的值 /// 秘钥 /// internal static string HmacSha512(string Message, string Key) { byte[] MessageBytes = General.DefaultEncoding.GetBytes(Message); Key = Convert.ToBase64String(General.DefaultEncoding.GetBytes(Key)); byte[] KeyBytes = General.DefaultEncoding.GetBytes(Key); HMACSHA512 Hmacsha512 = new(KeyBytes); byte[] Hash = Hmacsha512.ComputeHash(MessageBytes); string Hmac = BitConverter.ToString(Hash).Replace("-", ""); return Hmac.ToLower(); } } public static class StringExtension { /// /// 使用HMACSHA512算法加密 /// /// 需要加密的值 /// 秘钥 /// public static string Encrypt(this string msg, string key) { return Encryption.HmacSha512(msg, Encryption.HmacSha512(msg, key.ToLower())); } } #endregion #region 验证服务 public class Verification { /// /// 生成验证码 /// /// 类型 /// 长度 /// public static string CreateVerifyCode(VerifyCodeType type, int length) { return type switch { VerifyCodeType.MixVerifyCode => MixVerifyCode(length), VerifyCodeType.LetterVerifyCode => LetterVerifyCode(length), _ => NumberVerifyCode(length), }; } /// /// 数字验证码 /// /// /// private static string NumberVerifyCode(int length) { int[] RandMembers = new int[length]; int[] GetNumbers = new int[length]; string VerifyCode = ""; //生成起始序列值 int seekSeek = unchecked((int)DateTime.Now.Ticks); Random seekRand = new(seekSeek); int beginSeek = seekRand.Next(0, int.MaxValue - length * 10000); int[] seeks = new int[length]; for (int i = 0; i < length; i++) { beginSeek += 10000; seeks[i] = beginSeek; } //生成随机数字 for (int i = 0; i < length; i++) { Random rand = new(seeks[i]); int pownum = 1 * (int)Math.Pow(10, length); RandMembers[i] = rand.Next(pownum, int.MaxValue); } //抽取随机数字 for (int i = 0; i < length; i++) { string numStr = RandMembers[i].ToString(); int numLength = numStr.Length; Random rand = new(); int numPosition = rand.Next(0, numLength - 1); GetNumbers[i] = int.Parse(numStr.Substring(numPosition, 1)); } //生成验证码 for (int i = 0; i < length; i++) { VerifyCode += GetNumbers[i].ToString(); } return VerifyCode; } /// /// 字母验证码 /// /// /// private static string LetterVerifyCode(int length) { char[] Verification = new char[length]; char[] Dictionary = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; Random random = new(); for (int i = 0; i < length; i++) { Verification[i] = Dictionary[random.Next(Dictionary.Length - 1)]; } return new string(Verification); } /// /// 混合验证码 /// /// /// private static string MixVerifyCode(int length) { char[] Verification = new char[length]; char[] Dictionary = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; Random random = new(); for (int i = 0; i < length; i++) { Verification[i] = Dictionary[random.Next(Dictionary.Length - 1)]; } return new string(Verification); } } #endregion #region 多线程服务 public class TaskUtility { /// /// 开启一个任务:调用返回对象的OnCompleted()方法可以执行后续操作,支持异步 /// /// public static TaskAwaiter StartAndAwaitTask(Action action) => new(Service.TaskManager.StartAndAwaitTask(action)); /// /// 开启一个任务:调用返回对象的OnCompleted()方法可以执行后续操作,支持异步 /// /// public static TaskAwaiter StartAndAwaitTask(Func task) => new(Service.TaskManager.StartAndAwaitTask(task)); /// /// 开启一个计时器任务 /// /// /// public static void RunTimer(Action action, int milliseconds) { Service.TaskManager.StartAndAwaitTask(async () => { await Task.Delay(milliseconds); }).OnCompleted(action); } } #endregion }