|
|
using System.Net;
|
|
|
using System.Security.Cryptography;
|
|
|
using System.Text;
|
|
|
|
|
|
namespace OMS.NET.Common
|
|
|
{
|
|
|
class GlobalArea
|
|
|
{
|
|
|
#region 用户登录列表相关
|
|
|
private static readonly List<UserConnect> _UserConnectList = new();
|
|
|
private static readonly object _UserConnectListLock = new();
|
|
|
/// <summary>
|
|
|
/// 连接客户端数量
|
|
|
/// </summary>
|
|
|
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<UserConnect> UserConnects
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
lock (_UserConnectListLock)
|
|
|
{
|
|
|
return _UserConnectList;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 添加ws连接记录
|
|
|
/// </summary>
|
|
|
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);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 通过wsid查询连接的Email信息
|
|
|
/// </summary>
|
|
|
/// <returns>Email信息,可能是空字符串</returns>
|
|
|
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);
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 添加登录记录
|
|
|
/// </summary>
|
|
|
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();
|
|
|
|
|
|
/// <summary>
|
|
|
/// 提供只读服务器配置访问
|
|
|
/// </summary>
|
|
|
public static ServerConfig ServerConfig
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
lock (_ServerConfigLock)
|
|
|
{
|
|
|
return _ServerConfig;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 提供完整的数据库连接字符串,带数据库名称
|
|
|
/// </summary>
|
|
|
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;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 导入指定私钥,如果不存在则创建并保存
|
|
|
/// </summary>
|
|
|
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));
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 以base64格式导出公钥字符串
|
|
|
/// </summary>
|
|
|
/// <returns>公钥字符串,base64格式</returns>
|
|
|
public static string GetRsaPublickKey()
|
|
|
{
|
|
|
lock (_RsaLock)
|
|
|
{
|
|
|
return Convert.ToBase64String(_Rsa.ExportRSAPublicKey());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 解密
|
|
|
/// </summary>
|
|
|
/// <param name="base64">base64编码的密文</param>
|
|
|
/// <returns>原文字符串 utf-8编码</returns>
|
|
|
public static string DecryptFromBase64String(string base64)
|
|
|
{
|
|
|
lock (_RsaLock)
|
|
|
{
|
|
|
byte[] decrypt = _Rsa.Decrypt(Convert.FromBase64String(base64),
|
|
|
RSAEncryptionPadding.Pkcs1);
|
|
|
return Encoding.UTF8.GetString(decrypt);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 加密
|
|
|
/// </summary>
|
|
|
/// <param name="src">原文字符串 utf-8编码</param>
|
|
|
/// <returns>base64编码的密文</returns>
|
|
|
public static string EncryptToBase64String(string src)
|
|
|
{
|
|
|
lock (_RsaLock)
|
|
|
{
|
|
|
byte[] encrypt = _Rsa.Encrypt(Encoding.UTF8.GetBytes(src),
|
|
|
RSAEncryptionPadding.Pkcs1);
|
|
|
return Convert.ToBase64String(encrypt);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
} |