using System.Net; using System.Security.Cryptography; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; using K4os.Compression.LZ4.Internal; using OMS.NET.Common; using OMS.NET.DbClass; using OMS.NET.Instructs; namespace OMS.NET { class GlobalArea { #region 用户登录列表相关 private static readonly List _UserConnectList = new(); private static readonly object _UserConnectListLock = new(); /// /// 连接客户端数量 /// public static int ConnectClientsCount { get { lock (_UserConnectListLock) { return _UserConnectList.Count; } } } public static int LoginUserCount { get { lock (_UserConnectListLock) { return _UserConnectList .Where(u => u.UserEmail != null) // 过滤出UserEmail不为空的项 .Select(u => u.UserEmail) // 选择UserEmail .Distinct().Count(); // 去重且计算数量 } } } public static List UserConnects { get { lock (_UserConnectListLock) { return _UserConnectList; } } } /// /// 添加ws连接记录 /// public static void AddUserConnect(string wsid, IPEndPoint iPEndPoint) { lock (_UserConnectListLock) { UserConnect userConnect = new(wsid, iPEndPoint); _UserConnectList.Add(userConnect); } } public static void RemoveUserConnectByID(string wsid) { lock (_UserConnectListLock) { UserConnect? userConnect = _UserConnectList.Find(u => u.ID == wsid); if (userConnect != null) { _UserConnectList.Remove(userConnect); } } } public static bool LoginCheckByID(string wsid) { lock (_UserConnectListLock) { return _UserConnectList.Exists(u => u.ID == wsid && u.UserEmail != null); } } /// /// 通过wsid查询连接的Email信息 /// /// Email信息,可能是空字符串 public static string GetLoginEmailByID(string wsid) { lock (_UserConnectListLock) { return _UserConnectList.First(u => u.ID == wsid).UserEmail!; } } public static bool LoginCheckByEmail(string email) { lock (_UserConnectListLock) { return _UserConnectList.Exists(u => u.UserEmail == email); } } /// /// 添加登录记录 /// public static void Login(string wsid, string email) { lock (_UserConnectListLock) { UserConnect? userConnect = _UserConnectList.Find(u => u.ID == wsid); if (userConnect != null) { userConnect.UserEmail = email; } } } #endregion #region 服务器配置相关 private static ServerConfig _ServerConfig = new(); private static readonly object _ServerConfigLock = new(); /// /// 提供只读服务器配置访问 /// public static ServerConfig ServerConfig { get { lock (_ServerConfigLock) { return _ServerConfig; } } } /// /// 提供完整的数据库连接字符串,带数据库名称 /// public static string ConnectionStringWithDbName { get { lock (_ServerConfigLock) { return _ServerConfig.ConnectionString + ";database=" + _ServerConfig.DataBaseName; } } } public static void LoadServerConfig() { lock (_ServerConfigLock) { string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"server.yaml"); //读取配置文件 _ServerConfig = new(configPath); Console.WriteLine("已读取到配置文件..." + Environment.NewLine + _ServerConfig.ToString()); } } #endregion #region RSA加解密相关 private static readonly RSA _Rsa = RSA.Create(); private static readonly object _RsaLock = new(); public static RSA Rsa { get { lock (_RsaLock) { return _Rsa; } } } /// /// 导入指定私钥,如果不存在则创建并保存 /// public static void LoadRsaPkey() { lock (_RsaLock) { string pkeyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @".pkey"); if (File.Exists(pkeyPath)) { DateTime lastModifyTime = File.GetLastWriteTime(pkeyPath); bool isOneYearApart = Math.Abs((DateTime.Now - lastModifyTime).TotalDays) >= 365; if (isOneYearApart) { File.WriteAllText(pkeyPath, Convert.ToBase64String(_Rsa.ExportPkcs8PrivateKey())); } else { string pkey = File.ReadAllText(pkeyPath); Console.WriteLine("继续使用现有pkey: " + pkey); _Rsa.ImportPkcs8PrivateKey(Convert.FromBase64String(pkey), out _); } } else { File.WriteAllText(pkeyPath, Convert.ToBase64String(_Rsa.ExportPkcs8PrivateKey())); Console.WriteLine("创建pkey:" + File.ReadAllText(pkeyPath)); } } } /// /// 以base64格式导出公钥字符串 /// /// 公钥字符串,base64格式 public static string GetRsaPublickKey() { lock (_RsaLock) { return Convert.ToBase64String(_Rsa.ExportRSAPublicKey()); } } /// /// 解密 /// /// base64编码的密文 /// 原文字符串 utf-8编码 public static string DecryptFromBase64String(string base64) { lock (_RsaLock) { byte[] decrypt = _Rsa.Decrypt(Convert.FromBase64String(base64), RSAEncryptionPadding.Pkcs1); return Encoding.UTF8.GetString(decrypt); } } /// /// 加密 /// /// 原文字符串 utf-8编码 /// base64编码的密文 public static string EncryptToBase64String(string src) { lock (_RsaLock) { byte[] encrypt = _Rsa.Encrypt(Encoding.UTF8.GetBytes(src), RSAEncryptionPadding.Pkcs1); return Convert.ToBase64String(encrypt); } } #endregion #region 缓存与活动数据 private static readonly List _AccountDataList = new(); private static readonly object _AccountDataListLock = new(); /// /// 缓存已查询用户数据,如果已存在则替换,需要在数据更新后调用 /// public static void AddLoginAccountData(AccountData? accountData) { if (accountData == null) return; lock (_AccountDataListLock) { int index = _AccountDataList.FindIndex(u => u.UserEmail == accountData.UserEmail); if (index == -1) { _AccountDataList.Add(accountData); } else { _AccountDataList[index] = accountData; } } } /// /// 提供一个简单获取登录数据的方法,而不需要重复进行数据库查询 /// public static AccountData? GetLoginAccountData(string? email) { if (email == null) return null; lock (_AccountDataListLock) { return _AccountDataList.Find(u => u.UserEmail == email); } } private static List _LayerDataList = new(); private static readonly object _LayerDataListLock = new(); private static readonly List _ActiveDataList = new(); private static readonly object _ActiveDataListLock = new(); public static List GetActiveDataList { get { lock (_ActiveDataListLock) { return _ActiveDataList.Where(x => x.Pick != null || x.Select != null).ToList(); } } } public static bool IsElementExit(long elementId) { lock (_ActiveDataListLock) { ActiveDataElement? ad = _ActiveDataList.Find(u => u.EID == ("E" + elementId)); return ad != null; } } public static ActiveDataElement? GetActiveDataElement(long elementId) { lock (_ActiveDataListLock) { return _ActiveDataList.Find(u => u.EID == ("E" + elementId)); } } public static void AddActiveDataElement(ActiveDataElement activeDataElement) { lock (_ActiveDataListLock) { _ActiveDataList.Add(activeDataElement); } } /// /// 移除活动数据,调用前必需确保对象已存在 /// public static void RemoveActiveDataElement(long elementId) { lock (_ActiveDataListLock) { _ActiveDataList.Remove(GetActiveDataElement(elementId)!); } } /// /// 从数据库中构建layerid 和 templateid的对应关系 /// public static void BuildLayerData() { List mapLayer = MapLayer.GetMapLayerList(); lock (_LayerDataListLock) { foreach (MapLayer layer in mapLayer.Where(x => x.Phase == 1)) { LayerData layerData = new(null, layer); if (layerData.Type != "order") { string temId = layerData.Structure!.AsArray().ElementAt(1)!["template"]!["id"]!.GetValue(); layerData.TemplateId = temId; } _LayerDataList.Add(layerData); Console.WriteLine($"{layerData.TemplateId}--{layerData.LayerId}"); } } } public static LayerData? GetLayerDataByTemplateId(string templateId) { lock (_LayerDataListLock) { try { return _LayerDataList.Where(x => x.TemplateId == templateId).First(); } catch { Log.Warn("通过模板id未获取到图层数据"); return null; } } } public static LayerData? GetLayerDataByLayerId(long layerId) { lock (_LayerDataListLock) { try { return _LayerDataList.Where(x => x.LayerId == layerId).First(); } catch { Log.Warn("通过图层id未获取到图层数据"); return null; } } } public static LayerData GetOrderLayerData() { lock (_LayerDataListLock) { return _LayerDataList.Where(x => x.Type == "order").First()!; } } /// /// 移除已经标记删除的图层模板映射 /// public static void RemoveDeletedLayerData() { lock (_LayerDataListLock) { _LayerDataList = _LayerDataList.Where(x => x.Phase == 1).ToList(); } } public static dynamic AdjustElementOrder(long elementAId, long elementBId, string templateA, string templateB, string method) { lock (_LayerDataListLock) { dynamic result = new object(); List layers = new(); result.layers = layers; LayerData layerA = GetLayerDataByTemplateId(templateA)!; LayerData layerB = GetLayerDataByTemplateId(templateB)!; if (layerA.LayerId == layerB.LayerId) { layerA.AdjustABOrder(elementAId, elementBId, method); layers.Add(layerA); } else { MapData mapDataA = MapData.Get(elementAId)!; JsonNode bTemplateData = layerB.Structure!.AsArray().ElementAt(1)!["template"]!; if (bTemplateData["typeRule"]![mapDataA.Type]!.GetValue() == true) { JsonArray aDetail = JsonObject.Parse(Util.Base64ToJson(mapDataA.Details!))!.AsArray(); JsonNode aCustom = JsonObject.Parse(Util.Base64ToJson(mapDataA.Custom!))!; Util.DetailsTransform(aDetail, bTemplateData.AsArray()); aCustom["tmpId"] = templateB; mapDataA.Details = Util.JsonToBase64(aDetail.ToString()); mapDataA.Custom = Util.JsonToBase64(aCustom.ToString()); if (MapData.Update(mapDataA) == -1) throw new Exception("数据库修改失败"); result.element = mapDataA; } layerA.DeleteElement(elementAId); layerB.AppendElement(elementAId, mapDataA.Type); layerB.AdjustABOrder(elementAId, elementBId, method);//丢在一起,再调整顺序 layers.Add(layerA); layers.Add(layerB); } return result; } } public static LayerData CreateGroupLayer(string creator) { lock (_LayerDataListLock) { //int max = _LayerDataList.Count; LayerData layer = new(-1, "group") { Members = new JsonObject(), TemplateId = CreateGroupLayerTemplateId() }; layer.Members.AsObject()["0"] = 0; string time = GetCurrentTime(); layer.Structure = new JsonArray(); layer.Structure.AsArray().Add(CreateGroupLayerName()); layer.Structure.AsArray().Add(new { template = new { id = layer.TemplateId, name = "template", creator = creator, modify = time, locked = false, explain = "none", typeRule = new { point = true, line = true, area = true, curve = true }, detailsRule = new List { new { set = false, name = "name", @default = "default", type = "text" } }, colorRule = new { basis = "", type = "", condition = new List() }, widthRule = new { basis = "", type = "", condition = new List() } } }); MapLayer mapLayer = layer.ConvertToMapLayer(); MapLayer.Add(mapLayer); if (mapLayer.Id != -1) { LayerData order = GetOrderLayerData(); order.OrderAddGroupLayer(mapLayer.Id); layer.HasChange = true; layer.LayerId = mapLayer.Id; _LayerDataList.Add(layer); } return layer; } } private static string CreateGroupLayerName() { lock (_LayerDataListLock) { string name = "layer " + Util.GetRandomNumber6(); while (_LayerDataList.Any(x => x.Name == name)) { name = "layer " + Util.GetRandomNumber6(); } return name; } } private static string CreateGroupLayerTemplateId() { lock (_LayerDataListLock) { string tmpId = Util.CreateTemplateId(); while (_LayerDataList.Any(x => x.TemplateId == tmpId)) { tmpId = Util.CreateTemplateId(); } return tmpId; } } #endregion /// /// 默认loglevel为3,发布版本需要改成2 /// private static readonly Logger _Logger = new(3); private static readonly object _LoggerLock = new(); public static Logger Log { get { lock (_LoggerLock) { return _Logger; } } } public static string GetCurrentTime() { string format = "yyyy-MM-dd HH:mm:ss"; return DateTime.Now.ToString(format); } } }