重构中,先删除多余代码和修改部分逻辑

simpledesign
nxiaoxiao 1 year ago
parent 0082549e0b
commit 2a0fa4e7a0

@ -1,140 +0,0 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace OMS.NET.Common
{
public class UserInfo
{
public string? Name { get; set; }
public string? Email { get; set; }
public string? Color { get; set; }
}
public class ActiveDataElement
{
public string EID { get; set; }
public UserInfo? Pick { get; set; }
public UserInfo? Select { get; set; }
public ActiveDataElement(string id)
{
EID = "E" + id;
}
}
public class ActiveDataElementConverter : JsonConverter<ActiveDataElement>
{
public override ActiveDataElement Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}
reader.Read();
string? eid = (reader.GetString()?[1..]) ?? throw new JsonException(); // Removing 'E' prefix to get the ID
var element = new ActiveDataElement(eid);
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
break;
}
if (reader.TokenType == JsonTokenType.StartObject)
{
continue;
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException();
}
string? propertyName = reader.GetString();
reader.Read();
switch (propertyName)
{
case "pick":
element.Pick = DeserializeUserInfo(ref reader);
break;
case "select":
element.Select = DeserializeUserInfo(ref reader);
break;
default:
reader.Skip(); // Skip unknown properties
break;
}
}
//reader.CurrentDepth = 0;
reader.Read();
//还需要读取一次因为之前有过一次读取跳过了一个token最后一个token也要读一次
return element;
}
public override void Write(Utf8JsonWriter writer, ActiveDataElement value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WritePropertyName(value.EID);
writer.WriteStartObject();
if (value.Pick != null) { WriteUserInfo(writer, "pick", value.Pick); }
if (value.Select != null) { WriteUserInfo(writer, "select", value.Select); }
writer.WriteEndObject();
writer.WriteEndObject();
}
private static void WriteUserInfo(Utf8JsonWriter writer, string propertyName, UserInfo userInfo)
{
writer.WriteStartObject(propertyName);
if (userInfo != null)
{
writer.WriteString("name", userInfo.Name);
writer.WriteString("email", userInfo.Email);
writer.WriteString("color", userInfo.Color);
}
writer.WriteEndObject();
}
private static UserInfo DeserializeUserInfo(ref Utf8JsonReader reader)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}
string? name = null;
string? email = null;
string? color = null;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
break;
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException();
}
string? propertyName = reader.GetString();
reader.Read();
switch (propertyName)
{
case "name":
name = reader.GetString();
break;
case "email":
email = reader.GetString();
break;
case "color":
color = reader.GetString();
break;
default:
reader.Skip(); // Skip unknown properties
break;
}
}
return new UserInfo { Name = name, Email = email, Color = color };
}
}
}

@ -1,11 +1,8 @@
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using OMS.NET.Common;
using OMS.NET.DbClass;
namespace OMS.NET
namespace OMS.NET.Common
{
class GlobalArea
{
@ -250,107 +247,5 @@ namespace OMS.NET
#endregion
#region 缓存与活动数据
private static readonly List<AccountData> _AccountDataList = new();
private static readonly object _AccountDataListLock = new();
/// <summary>
/// 缓存已查询用户数据,如果已存在则替换,需要在数据更新后调用
/// </summary>
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;
}
}
}
/// <summary>
/// 提供一个简单获取登录数据的方法,而不需要重复进行数据库查询
/// </summary>
public static AccountData? GetLoginAccountData(string? email)
{
if (email == null) return null;
lock (_AccountDataListLock)
{
return _AccountDataList.Find(u => u.UserEmail == email);
}
}
private static readonly List<LayerData> _LayerDataList = new();
private static readonly object _LayerDataListLock = new();
/// <summary>
/// 从数据库中构建layerid 和 templateid的对应关系
/// </summary>
public static void BuildLayerData()
{
List<MapLayer> mapLayer = MapLayer.GetMapLayerList();
lock (_LayerDataListLock)
{
foreach (MapLayer layer in mapLayer)
{
LayerData layerData = new(null, layer);
if (layerData.Type != "order")
{
string temId = layerData.Structure!.AsArray().ElementAt(1)!["template"]!["id"]!.GetValue<string>();
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;
}
}
}
#endregion
/// <summary>
/// 默认loglevel为3发布版本需要改成2
/// </summary>
private static 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);
}
}
}

@ -1,63 +0,0 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using OMS.NET.DbClass;
namespace OMS.NET.Common
{
public class LayerData
{
public string? TemplateId { get; set; }
public long LayerId { get; set; }
public bool HasChange { get; set; } = false;
public string Type { get; set; }
public JsonNode? Members { get; set; }
public JsonNode? Structure { get; set; }
public int Phase { get; set; } = 1;
public LayerData(long layerId, string type)
{
LayerId = layerId;
Type = type;
}
public LayerData(string? templateId, MapLayer layer)
{
TemplateId = templateId;
LayerId = layer.Id;
Type = layer.Type;
Members = (layer.Type == "order") ? JsonNode.Parse(layer.Members) : JsonNode.Parse(Util.Base64ToJson(layer.Members));
Structure = string.IsNullOrEmpty(layer.Structure) ? null : JsonNode.Parse(Util.Base64ToJson(layer.Structure));
Phase = layer.Phase;
}
public void AppendElement(long itemId, string ItemType)
{
if (this.Type == "order")
{
GlobalArea.Log.Error($"order图层不能添加{ItemType}元素");
return;
}
if (this.Members![itemId.ToString()] == null)
{
this.Members![itemId.ToString()] = ItemType;
this.Structure!.AsArray().Add(itemId);
this.HasChange = true;
//上传图层到数据库
MapLayer mapLayer = ConvertToMapLayer();
MapLayer.Update(mapLayer);
}
}
public MapLayer ConvertToMapLayer()
{
return new MapLayer()
{
Id = this.LayerId,
Type = this.Type,
Members = (this.Type == "order") ? this.Members!.ToString() : Util.JsonToBase64(this.Members!.ToString()),
Structure = (this.Structure == null) ? "" : Util.JsonToBase64(this.Structure!.ToString()),
Phase = this.Phase
};
}
}
}

@ -1,30 +1,24 @@
namespace OMS.NET.Common
{
public class Logger
public class Log
{
private readonly int _logLevel;
private int logCount;
private string logPath;
private static readonly int _logLevel = 3; //debug
private static int logCount = 0;
private static string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log", $"{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.log");
private static readonly object LogLock = new();
private void WriteLog(string message)
private static void WriteLogToFile(string message)
{
lock (LogLock)
{
using var writer = new StreamWriter(this.logPath, true);
using var writer = new StreamWriter(logPath, true);
writer.WriteLine(message);
}
}
public Logger(int level)
private static string GetNewLogFile()
{
_logLevel = level;
this.logPath = GetNewLogFile();
}
private string GetNewLogFile()
{
this.logCount = 0;
logCount = 0;
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log", $"{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.log");
if (!Directory.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log")))
{
@ -34,16 +28,16 @@ namespace OMS.NET.Common
return path;
}
private void Log(string message, int level)
private static void Go(string message, int level)
{
if (level <= this._logLevel)
if (level <= _logLevel)
{
string logtime = DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss]");
string leveltext = level switch
{
0 => "[ERROR]",
1 => "[WARN]",
2 => "[INFO]",
1 => "[WARN] ",
2 => "[INFO] ",
3 => "[DEBUG]",
_ => level.ToString(),
};
@ -51,31 +45,32 @@ namespace OMS.NET.Common
Console.WriteLine(logtext);
if (logCount > 100000)
{
this.logPath = GetNewLogFile();
logPath = GetNewLogFile();
}
//File.AppendAllTextAsync(this.logPath, logtext);
WriteLog(logtext);
WriteLogToFile(logtext);
logCount++;
}
}
public void Error(string message)
public static void Error(string message)
{
Log(message, 0);
Go(message, 0);
}
public void Warn(string message)
public static void Warn(string message)
{
Log(message, 1);
Go(message, 1);
}
public void Info(string message)
public static void Info(string message)
{
Log(message, 2);
Go(message, 2);
}
public void Debug(string message)
public static void Debug(string message)
{
Log(message, 3);
Go(message, 3);
}
}
}

@ -1,6 +1,4 @@
using System.Reflection;
using System.Text;
using System.Text.Json;
namespace OMS.NET.Common
{
@ -36,38 +34,6 @@ namespace OMS.NET.Common
? value
: "false";
/// <summary>
/// 地图的背景图片位置图像尺寸为220px * 165px 最大为60kb 支持PNG和jpg类型的图片格式
/// default ./map_img.png
/// </summary>
public string Img => _config.TryGetValue("ServerConfigImg", out string? value)
? value
: "./map_img.png";
/// <summary>
/// key是唯一的,长度不限格式k[a-Z0-9]是客户端采用https://name.com/ + m/key 的方式快捷访问地图服务器的
/// default k0
/// </summary>
public string Key => _config.TryGetValue("ServerConfigKey", out string? value)
? value
: "k0";
/// <summary>
/// 服务器websocket链接的地址
/// default 'ws://0.0.0.0:8080'
/// </summary>
public string Url => _config.TryGetValue("ServerConfigUrl", out string? value)
? value
: "ws://0.0.0.0:8080";
/// <summary>
/// 服务器名称
/// default 地图名称
/// </summary>
public string Name => _config.TryGetValue("ServerConfigName", out string? value)
? value
: "地图名称";
/// <summary>
/// 服务器最大在线人数
/// default 20
@ -76,172 +42,6 @@ namespace OMS.NET.Common
? value
: "20";
/// <summary>
/// 最大高度
/// default 10000
/// </summary>
public string MaxHeight => _config.TryGetValue("ServerConfigMaxHeight", out string? value)
? value
: "10000";
/// <summary>
/// 最小高度
/// default -10000
/// </summary>
public string MinHeight => _config.TryGetValue("ServerConfigMinHeight", out string? value)
? value
: "-10000";
/// <summary>
/// 最大宽度
/// default 10000
/// </summary>
public string MaxWidth => _config.TryGetValue("ServerConfigMaxWidth", out string? value)
? value
: "10000";
/// <summary>
/// 最小宽度
/// default -10000
/// </summary>
public string MinWidth => _config.TryGetValue("ServerConfigMinWidth", out string? value)
? value
: "-10000";
/// <summary>
/// 区域内横轴和纵轴的最小层级下layer0每像素移动量单位 纵轴单位
/// default 1
/// </summary>
public string Unit1Y => _config.TryGetValue("ServerConfigUnit1Y", out string? value)
? value
: "1";
/// <summary>
/// 区域内横轴和纵轴的最小层级下layer0每像素移动量单位 横轴单位
/// default 1
/// </summary>
public string Unit1X => _config.TryGetValue("ServerConfigUnit1X", out string? value)
? value
: "1";
/// <summary>
/// 打开地图时的默认中心点 x
/// default 0
/// </summary>
public string P0X => _config.TryGetValue("ServerConfigP0X", out string? value)
? value
: "0";
/// <summary>
/// 打开地图时的默认中心点 y
/// default 0
/// </summary>
public string P0Y => _config.TryGetValue("ServerConfigP0Y", out string? value)
? value
: "0";
/// <summary>
/// 最大层级
/// default 5
/// </summary>
public string MaxLayer => _config.TryGetValue("ServerConfigMaxLayer", out string? value)
? value
: "default";
/// <summary>
/// 最小层级
/// default 0
/// </summary>
public string MinLayer => _config.TryGetValue("ServerConfigMinLayer", out string? value)
? value
: "default";
/// <summary>
/// 默认层级
/// default 0
/// </summary>
public string DefaultLayer => _config.TryGetValue("ServerConfigDefaultLayer", out string? value)
? value
: "0";
/// <summary>
/// 默认缩放比例
/// default 1
/// </summary>
public string ZoomAdd => _config.TryGetValue("ServerConfigZoomAdd", out string? value)
? value
: "1";
/// <summary>
/// 表示是否启用额外的底图服务
/// default false
/// </summary>
public string EnableBase => _config.TryGetValue("ServerConfigEnableBase", out string? value)
? value
: "false";
/// <summary>
/// 默认x
/// default 0
/// </summary>
public string DefaultX => _config.TryGetValue("ServerConfigDefaultX", out string? value)
? value
: "0";
/// <summary>
/// 默认y
/// default 0
/// </summary>
public string DefaultY => _config.TryGetValue("ServerConfigDefaultY", out string? value)
? value
: "0";
/// <summary>
/// 屏幕默认分辨率x
/// default 1920
/// </summary>
public string ResolutionX => _config.TryGetValue("ServerConfigResolutionX", out string? value)
? value
: "1920";
/// <summary>
/// 屏幕默认分辨率y
/// default 980
/// </summary>
public string ResolutionY => _config.TryGetValue("ServerConfigResolutionY", out string? value)
? value
: "980";
/// <summary>
/// 最大底图缩放等级
/// default 0
/// </summary>
public string MaxZoom => _config.TryGetValue("ServerConfigMaxZoom", out string? value)
? value
: "0";
/// <summary>
/// 最小底图缩放等级
/// default 0
/// </summary>
public string MinZoom => _config.TryGetValue("ServerConfigMinZoom", out string? value)
? value
: "0";
/// <summary>
/// 默认底图缩放等级
/// default 0
/// </summary>
public string DefaultZoom => _config.TryGetValue("ServerConfigDefaultZoom", out string? value)
? value
: "0";
/// <summary>
/// 底图服务的服务器URL
/// default empty
/// </summary>
public string BaseMapUrl => _config.TryGetValue("ServerConfigBaseMapUrl", out string? value)
? value
: "";
public ServerConfig()
{
//do nothing,everything default

@ -22,11 +22,4 @@ namespace OMS.NET.Common
this.UserEndPoint = UserEndPoint;
}
}
// public class UserData
// {
// public string UserEmail { get; set; }
// public string UserName { get; set; }
// public int Map_Layer { get; set; }
// }
}

@ -1,71 +0,0 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace OMS.NET.Common
{
public class Point
{
public double X { get; set; }
public double Y { get; set; }
}
public class Util
{
public static readonly JsonSerializerOptions options = new()
{
ReadCommentHandling = JsonCommentHandling.Skip, //允许注释
AllowTrailingCommas = true,//允许尾随逗号
//PropertyNamingPolicy = new InstructNamingPolicy(), // 属性名为定制转换
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, // 忽略 null 值
WriteIndented = true, // 美化输出
PropertyNameCaseInsensitive = true,//属性名忽略大小写
};
public static string ObjToBase64(object obj)
{
string utf8 = JsonSerializer.Serialize(obj, options);
return Convert.ToBase64String(Encoding.UTF8.GetBytes(utf8));
}
public static string JsonToBase64(string json)
{
return Convert.ToBase64String(Encoding.UTF8.GetBytes(json));
}
public static string Base64ToJson(string base64)
{
return Encoding.UTF8.GetString(Convert.FromBase64String(base64));
}
// public static JsonNode? JsonNodeFromJson(string json)
// {
// return JsonNode.Parse(json);
// }
//===========================================================
public static List<Point> PointsFromBase64(string base64)
{
string utf8 = Base64ToJson(base64);
return PointsFromJson(utf8);
}
public static List<Point> PointsFromJson(string json)
{
return JsonSerializer.Deserialize<List<Point>>(json, options) ?? new List<Point>();
}
public static Point PointFromBase64(string base64)
{
string utf8 = Base64ToJson(base64);
return PointFromJson(utf8);
}
public static Point PointFromJson(string json)
{
return JsonSerializer.Deserialize<Point>(json, options) ?? throw new Exception("转化point类型失败:" + json);
}
}
}

@ -1,19 +0,0 @@
using System.Text.RegularExpressions;
namespace OMS.NET.Common
{
public static class Validations
{
/// <summary>
/// 验证颜色值是否有效
/// </summary>
/// <param name="color"></param>
/// <returns></returns>
public static bool IsHexColor(string color)
{
// Regex for hex color code (with or without #)
var hexColorRegex = new Regex(@"^#?[0-9A-Fa-f]{6}$");
return hexColorRegex.IsMatch(color);
}
}
}

@ -1,134 +0,0 @@
using System.Text;
using System.Text.Json;
using OMS.NET.Common;
using OMS.NET.DbClass;
namespace OMS.NET.Instructs
{
public class AddElementBroadcastInstruct : BroadcastInstuct
{
public AddElementBroadcastInstruct()
{
Type = "broadcast";
}
public override Task Handler(string wsid)
{
return Task.Run(() =>
{
if (GlobalArea.LoginCheckByID(wsid))
{
//从Data中解析数据收到的是json文本类型
if (Data?.GetType() == typeof(JsonElement))
{
try
{
long id = Data.GetProperty("id").GetInt64();
string type = Data.GetProperty("type").GetString();
string points = Data.GetProperty("points").GetString();
string point = Data.GetProperty("point").GetString();
string? color = Data.GetProperty("color").GetString();
int? width = Data.GetProperty("width").GetInt32();
string? childRelations = Data.GetProperty("childRelations").GetString();
string? fatherRelations = Data.GetProperty("fatherRelations").GetString();
string? childNodes = Data.GetProperty("childNodes").GetString();
string? fatherNode = Data.GetProperty("fatherNode").GetString();
string? details = Data.GetProperty("details").GetString();
string? custom = Data.GetProperty("custom").GetString();
//validations todo
//假设所有数据均合法
MapData mapData = new()
{
Type = type,
Points = Util.JsonToBase64(points),
Point = Util.JsonToBase64(point),
Color = color,
Width = width,
ChildRelations = childRelations,
FatherRelations = fatherRelations,
ChildNodes = childNodes,
FatherNode = fatherNode,
Details = Util.JsonToBase64(details),
Custom = Util.JsonToBase64(custom)
};
//保存点到数据库
MapData.Add(mapData);
//获取图层id
if (Data.GetProperty("custom").TryGetProperty("tmpId", out JsonElement tmpIdNode))
{
string tmpId = tmpIdNode.GetString() ?? throw new Exception("tmpId不能为空");
LayerData? layer = GlobalArea.GetLayerDataByTemplateId(tmpId);
if (layer != null && mapData.Id != -1)
{
layer.AppendElement(mapData.Id, mapData.Type);//包括数据库操作
//准备回复广播
string conveyor = GlobalArea.GetLoginEmailByID(wsid);
string time = GlobalArea.GetCurrentTime();
ResponseOrBroadcastInstructs.Add(new BroadcastInstuct()
{
IsBroadcast = true,
Class = this.Class,
Conveyor = conveyor,
Time = time,
Data = mapData,
});
ResponseOrBroadcastInstructs.Add(new BroadcastInstuct()
{
IsBroadcast = true,
Class = "updateLayerData",
Conveyor = conveyor,
Time = time,
Data = new
{
id = layer.LayerId,
members = layer.Members!.ToString(),
structure = layer.Structure!.ToString(),
}
});
ResponseOrBroadcastInstructs.Add(new SendErrorInstuct()
{
IsResponse = true,
Class = "upload",
Conveyor = conveyor,
Time = time,
Data = new Dictionary<string, object>()
{
{"vid",id},
{"rid",mapData.Id}
},
});
}
}
else
{
throw new Exception("未找到 tmpId");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
ResponseOrBroadcastInstructs.Add(new SendErrorInstuct()
{
IsResponse = true,
Class = "upload",
Conveyor = GlobalArea.GetLoginEmailByID(wsid),
Time = GlobalArea.GetCurrentTime(),
Data = new
{
source = Data,
message = ex.Message,
},
});
}
}
}
});
}
}
}

@ -1,31 +0,0 @@
using System.Text.Json;
namespace OMS.NET.Instructs
{
/// <summary>
/// 广播指令的基类
/// </summary>
public class BroadcastInstuct : Instruct
{
public BroadcastInstuct()
{
this.Type = "broadcast";
}
}
public class SendCorrectInstuct : Instruct
{
public SendCorrectInstuct()
{
this.Type = "send_error";
}
}
public class SendErrorInstuct : Instruct
{
public SendErrorInstuct()
{
this.Type = "send_correct";
}
}
}

@ -1,52 +0,0 @@
using OMS.NET.DbClass;
namespace OMS.NET.Instructs
{
public class GetPresenceInstruct : Instruct
{
public GetPresenceInstruct()
{
this.Type = "get_presence";
}
public override Task Handler(string wsid)
{
return Task.Run(() =>
{
if (GlobalArea.LoginCheckByID(wsid))
{
//获取所有在线用户,移除重复
List<string?> emails = GlobalArea.UserConnects.Where(u => u.UserEmail != null)
.Select(u => u.UserEmail).Distinct().ToList();
List<dynamic> allLoginUsers = new();
emails.ForEach(email =>
{
AccountData accountData = GlobalArea.GetLoginAccountData(email)!;
//由于是已登录用户,默认都能查询到值
allLoginUsers.Add(new
{
userEmail = accountData.UserEmail,
userQq = accountData.UserQQ,
userName = accountData.UserName,
headColor = accountData.HeadColor,
});
});
this.ResponseOrBroadcastInstructs.Add(new SendPresenceInstruct()
{
IsResponse = true,
Data = allLoginUsers,
});
}
});
}
}
public class SendPresenceInstruct : Instruct
{
public SendPresenceInstruct()
{
this.Type = "send_presence";
}
}
}

@ -1,47 +0,0 @@
namespace OMS.NET.Instructs
{
public class GetServerConfigInstruct : Instruct
{
public GetServerConfigInstruct()
{
this.Type = "get_serverConfig";
}
public override Task Handler(string wsid)
{
return Task.Run(() =>
{
this.ResponseOrBroadcastInstructs.Add(new SendServerConfigInstruct
{
IsResponse = true,
Data = new
{
anonymous_login = bool.TryParse(GlobalArea.ServerConfig.AnonymousLogin, out bool booleanValue) && booleanValue,
key = GlobalArea.ServerConfig.Key,
url = GlobalArea.ServerConfig.Url,
name = GlobalArea.ServerConfig.Name,
online_number = GlobalArea.ConnectClientsCount,
max_online = GlobalArea.ServerConfig.MaxUser,
default_x = GlobalArea.ServerConfig.DefaultX,
default_y = GlobalArea.ServerConfig.DefaultY,
//以下在0.7会删除
enable_base_map = GlobalArea.ServerConfig.EnableBase,
//base_map_type= GlobalArea.ServerConfig.ServerConfigEnableBase,
max_zoom = GlobalArea.ServerConfig.MaxZoom,
min_zoom = GlobalArea.ServerConfig.MinZoom,
default_zoom = GlobalArea.ServerConfig.DefaultZoom,
base_map_url = GlobalArea.ServerConfig.BaseMapUrl
}
});
});
}
}
public class SendServerConfigInstruct : Instruct
{
public SendServerConfigInstruct()
{
this.Type = "send_serverConfig";
}
}
}

@ -1,84 +0,0 @@
using System.Globalization;
using WebSocketSharp;
namespace OMS.NET.Instructs
{
public class GetServerImgInstruct : Instruct
{
public GetServerImgInstruct()
{
this.Type = "get_serverImg";
}
public override Task Handler(string wsid)
{
return Task.Run(() =>
{
if (this.Time != null)
{
//时间解析
string format = "yyyy-MM-dd HH:mm:ss";
DateTime clientDateTime = DateTime.ParseExact(this.Time, format, CultureInfo.InvariantCulture);
//Console.WriteLine("Converted DateTime: " + clientDateTime);
string serverImgPath = GlobalArea.ServerConfig.Img;
if (File.Exists(serverImgPath))
{
DateTime serverImgLastModified = File.GetLastWriteTime(serverImgPath);
Instruct res = new SendServerConfigInstruct
{
IsResponse = true
};
if (serverImgLastModified > clientDateTime)
{
byte[] imageBytes = File.ReadAllBytes(serverImgPath);
string imageFileType = GetImageFileType(imageBytes);
string base64String = $"data:image/{imageFileType};base64," + Convert.ToBase64String(imageBytes);
//Console.WriteLine("Base64 Encoded Image: " + base64String);
res.Data = new
{
@string = base64String,
time = serverImgLastModified.ToString(format),
};
}
else
{
res.Data = new
{
@string = ""
};
}
this.ResponseOrBroadcastInstructs.Add(res);
}
}
});
}
static string GetImageFileType(byte[] imageBytes)
{
byte[] fileHeader = imageBytes.SubArray(0, 8);
// PNG 文件的文件头字节为 89 50 4E 47 0D 0A 1A 0A
if (fileHeader[0] == 0x89 && fileHeader[1] == 0x50 && fileHeader[2] == 0x4E && fileHeader[3] == 0x47 &&
fileHeader[4] == 0x0D && fileHeader[5] == 0x0A && fileHeader[6] == 0x1A && fileHeader[7] == 0x0A)
{
return "png";
}
// JPEG 文件的文件头字节为 FF D8 FF
if (fileHeader[0] == 0xFF && fileHeader[1] == 0xD8 && fileHeader[2] == 0xFF)
{
return "jpeg";
}
return "unknown";
}
}
public class SendServerImgInstruct : Instruct
{
public SendServerImgInstruct()
{
this.Type = "send_serverImg";
}
}
}

@ -1,5 +1,4 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text.Json;
using System.Text.Json.Serialization;

@ -1,32 +0,0 @@
namespace OMS.NET.Instructs
{
/// <summary>
/// 用于测试和代码复制
/// </summary>
public class PingInstuct : Instruct
{
public PingInstuct()
{
this.Type = "ping";
}
public override Task Handler(string wsid)
{
return Task.Run(() =>
{
this.ResponseOrBroadcastInstructs.Add(new PongInstuct()
{
IsResponse = true
});
});
}
}
public class PongInstuct : Instruct
{
public PongInstuct()
{
this.Type = "pong";
}
}
}

@ -1,6 +1,5 @@
using System.Net;
using System.Text;
using System.Text.Unicode;
using OMS.NET.Common;
using OMS.NET.Instructs;
using WebSocketSharp;
using WebSocketSharp.Server;
@ -12,11 +11,11 @@ namespace OMS.NET
private IPEndPoint iPEndPoint = new(IPAddress.Any, 0);
protected override async void OnMessage(MessageEventArgs e)
{
GlobalArea.Log.Debug(this.ID + " " + this.Context.UserEndPoint.ToString() + ":" + e.Data);
Log.Debug(this.ID + " " + this.Context.UserEndPoint.ToString() + ":" + e.Data);
Instruct? instruct = Instruct.JsonStringParse(e.Data);
if (instruct != null)
{
await instruct.HandlerAndMeasure(this.ID);//传递ws连接的id为某些需要判断ws连接状态的处理逻辑准备
await instruct.HandlerAndMeasure(this.ID);
if (instruct.ResponseOrBroadcastInstructs.Count > 0)
{
instruct.ResponseOrBroadcastInstructs.ForEach(res =>
@ -25,7 +24,6 @@ namespace OMS.NET
{
string str = res.ToJsonString();
Send(str);
//GlobalArea.Log.Debug("已发送回复 " + str);
}
if (res.IsBroadcast)
{
@ -38,7 +36,6 @@ namespace OMS.NET
session.Context.WebSocket.Send(str);
}
}
//GlobalArea.Log.Debug("已发送广播 " + str);
}
});
}
@ -49,22 +46,22 @@ namespace OMS.NET
{
this.iPEndPoint = this.Context.UserEndPoint;
GlobalArea.AddUserConnect(this.ID, this.iPEndPoint);
Console.WriteLine(this.ID + " " + this.iPEndPoint.ToString() + " Conection Open");
Console.WriteLine($"当前连接客户端数量: {GlobalArea.ConnectClientsCount}");
// Console.WriteLine(this.ID + " " + this.iPEndPoint.ToString() + " Conection Open");
// Console.WriteLine($"当前连接客户端数量: {GlobalArea.ConnectClientsCount}");
}
protected override void OnClose(CloseEventArgs e)
{
GlobalArea.RemoveUserConnectByID(this.ID);
Console.WriteLine(this.ID + " " + this.iPEndPoint.ToString() + " Conection Close" + e.Reason);
Console.WriteLine($"当前连接客户端数量: {GlobalArea.ConnectClientsCount}");
// Console.WriteLine(this.ID + " " + this.iPEndPoint.ToString() + " Conection Close" + e.Reason);
// Console.WriteLine($"当前连接客户端数量: {GlobalArea.ConnectClientsCount}");
}
protected override void OnError(ErrorEventArgs e)
{
GlobalArea.RemoveUserConnectByID(this.ID);
Console.WriteLine(this.ID + " " + this.iPEndPoint.ToString() + " Conection Error Close" + e.Message);
Console.WriteLine($"当前连接客户端数量: {GlobalArea.ConnectClientsCount}");
// Console.WriteLine(this.ID + " " + this.iPEndPoint.ToString() + " Conection Error Close" + e.Message);
// Console.WriteLine($"当前连接客户端数量: {GlobalArea.ConnectClientsCount}");
}
}
}

@ -1,10 +1,6 @@
using WebSocketSharp.Server;
using MySql.Data.MySqlClient;
using System.Text;
using System.Security.Cryptography;
using OMS.NET.Instructs;
using System.Dynamic;
using System.Security.Cryptography.X509Certificates;
using OMS.NET.Common;
namespace OMS.NET
{
@ -17,8 +13,6 @@ namespace OMS.NET
GlobalArea.LoadServerConfig();//加载服务器配置 默认server.yaml
GlobalArea.LoadRsaPkey();//加载rsa私钥 默认.pkey
DbCheck();
//预加载一些数据以方便后面的处理
GlobalArea.BuildLayerData();
//开启ws监听
var wssv = new WebSocketServer(Convert.ToInt16(GlobalArea.ServerConfig.ListenPort), false);
@ -27,6 +21,7 @@ namespace OMS.NET
wssv.Start();
Console.WriteLine("已开启ws监听, 端口: " + GlobalArea.ServerConfig.ListenPort);
Console.WriteLine("输入exit退出程序");
bool loopFlag = true;
while (loopFlag)
{
@ -47,7 +42,7 @@ namespace OMS.NET
}
catch (Exception e)
{
GlobalArea.Log.Error(e.Message);
Log.Error(e.Message);
}
}
@ -63,7 +58,7 @@ namespace OMS.NET
{
using MySqlConnection connection = new(GlobalArea.ServerConfig.ConnectionString);
connection.Open();
GlobalArea.Log.Info("dblock不存在连接到数据库服务进行检查");
Log.Info("dblock不存在连接到数据库服务进行检查");
//检查数据库是否存在,检查数据表是否
// 检查数据库是否存在
string dbName = GlobalArea.ServerConfig.DataBaseName;
@ -77,7 +72,7 @@ namespace OMS.NET
string createDatabaseQuery = $"CREATE DATABASE {dbName} CHARACTER SET utf8mb4";
MySqlCommand createDatabaseCmd = new(createDatabaseQuery, connection);
createDatabaseCmd.ExecuteNonQuery();
GlobalArea.Log.Info($"已创建数据库 {dbName}");
Log.Info($"已创建数据库 {dbName}");
}
//创建默认数据表实现通用逻辑从init.sql读取创建相关表的sql语句,默认以分号结尾,忽略空行和换行
@ -95,14 +90,14 @@ namespace OMS.NET
{
MySqlCommand createDatabaseCmd = new(sql, connection);
createDatabaseCmd.ExecuteNonQuery();
GlobalArea.Log.Info($"执行SQL成功 {sql}");
Log.Info($"执行SQL成功 {sql}");
});
}
File.WriteAllText(dblockPath, "");
}
else
{
GlobalArea.Log.Info("满足预设条件,跳过数据库检查");
Log.Info("满足预设条件,跳过数据库检查");
}
}
}

@ -1,6 +1,6 @@
# OMS.NET
OMS.NET为标准名称使用.NET 6开发语言使用C#。
一个跨平台的OME服务端的.NET实现。
# OMSS.NET
OMSS.NET为标准名称使用.NET 6开发语言使用C#。
对数据库结构进行重新设计,简化服务器指令操作
## 先决条件
### 确保.NET开发环境已安装
@ -8,7 +8,7 @@ OMS.NET为标准名称使用.NET 6开发语言使用C#。
### 创建server.yaml
模板如下按情况修改user、pas、port
需准备默认的map_img.png
```yaml
#连接字符串和默认监听端口
ConnectionString: server=localhost;port=3306;user=user;password=pas
@ -17,44 +17,7 @@ ListenPort: port
#匿名登录
AnonymousLogin: false
#服务器基础信息
#ServerConfigImg: ./map_img.png
#ServerConfigKey: k0
#ServerConfigUrl: ws://0.0.0.0:1080
#ServerConfigName: 地图名称
#ServerConfigMaxUser: 20
#以下四个常量规定了地图在什么区域内进行绘制
#ServerConfigMaxHeight: 10000
#ServerConfigMinHeight: -10000
#ServerConfigMaxWidth: 10000
#ServerConfigMinWidth: -10000
#以下两个常量决定了区域内横轴和纵轴的最小层级下layer0每像素移动量单位
#ServerConfigUnit1Y: 1
#ServerConfigUnit1X: 1
#打开地图时的默认中心点
#ServerConfigP0X: 0
#ServerConfigP0Y: 0
#层级为地图数据的缩放层级,可限制用户在高层级编辑地图导致严重误差
#ServerConfigMaxLayer: 5
#ServerConfigMinLayer: 0
#ServerConfigDefaultLayer: 0
#ServerConfigZoomAdd: 1
#底图配置
#缩放比为带有底图瓦图服务器的地图服务,可限制用户对底图缩放
#ServerConfigEnableBase: false
#ServerConfigDefaultX: 0
#ServerConfigDefaultY: 0
#ServerConfigResolutionX: 1920
#ServerConfigResolutionY: 980
#ServerConfigMaxZoom: 0
#ServerConfigMinZoom: 0
#ServerConfigDefaultZoom: 0
#ServerConfigBaseMapUrl: empty
ServerConfigMaxUser: 20
```

Loading…
Cancel
Save