thewar_server/Server/System/SystemMain.cs

155 lines
5.6 KiB
C#

using System.Reflection;
using NLog;
using Server.Git;
namespace Server.System {
public class ProtocolProcessor {
private static Dictionary<Protocol, AbstractService> SERVICE_DIC = new Dictionary<Protocol, AbstractService>();
private static readonly NLog.ILogger logger = LogManager.GetCurrentClassLogger();
public static string cryptoData = "";
public static string version = "";
public static void addProtocol(AbstractService abstractService) {
if (SERVICE_DIC.ContainsKey(abstractService.ProtocolValue())) {
logger.Error("중복된 프로토콜 : " + abstractService.ProtocolValue());
throw new Exception("중복된 프로토콜 : " + abstractService.ProtocolValue());
}
SERVICE_DIC.Add(abstractService.ProtocolValue(), abstractService);
}
public static void Init() {
// 현재 실행 중인 어셈블리를 가져옴
var assembly = Assembly.GetExecutingAssembly();
// 'AbstractService'의 하위 클래스를 모두 찾음
var serviceTypes = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(AbstractService)) && !t.IsAbstract);
// 각 클래스의 인스턴스를 생성합니다. 생성자에서 자동으로 등록됩니다.
foreach (var type in serviceTypes)
addProtocol((AbstractService)Activator.CreateInstance(type));
}
public static string Process(HttpContext context) {
AbstractService abstractService;
//TODO 좀더 딥한곳에 status를 수정하게 만들기.
string Response = "";
try {
Protocol cmd = (Protocol)int.Parse(context.Request.Headers["cmd"]);
SERVICE_DIC.TryGetValue(cmd, out abstractService);
if (abstractService == null)
throw new RuntimeException("Not Found", Error.NotFound);
string body = Request(context.Request).GetAwaiter().GetResult();
logger.Info("GetRequst : " + body);
Req req = abstractService.Requst(body);
if (req == null)
throw new RuntimeException("", Error.NoData);
else if (!req.IsReceivedAllField())
throw new RuntimeException("Internal Server Error", Error.Unknown);
else if (!req.GetRedis())
throw new RuntimeException("null session", Error.NullSession);
Response = abstractService.Process();
logger.Info("GetResponse : " + Response);
}
catch (RuntimeException ex) {
ErrorResp error = new ErrorResp(ex);
Response = error.ToJson();
logger.Error("GetErrorResponse : " + Response);
}
catch (Exception ex) {
ErrorResp error = new ErrorResp();
Response = error.ToJson();
logger.Error("GetErrorResponse : " + ex.ToString());
}
finally{}
return Response;
}
private static async Task<string> Request(HttpRequest request) {
using var reader = new StreamReader(request.Body);
return await reader.ReadToEndAsync();
}
}
public class GItWebhook
{
private static readonly NLog.ILogger logger = LogManager.GetCurrentClassLogger();
public static bool isUpdate = true;
public static Thread thread;
private static AbstractGit git;
public static ErrorResp successResp;
public static string Process(HttpContext context)
{
isUpdate = !isUpdate;
if (isUpdate)
{
return successResp.ToJson();
}
string Response;
try
{
string eaDelivery = context.Request.Headers["X-Gitea-Delivery"];
logger.Info($"SaveVersion : {eaDelivery}");
//task를 쓰면 멈출수가 없기에 thread를 사용
Response = successResp.ToJson();
//무작위 공격을 대비한 1차적인 방어조치
if (eaDelivery == "" || eaDelivery.Length < 15)
return Response;
ProtocolProcessor.version = eaDelivery;
if (thread.ThreadState == ThreadState.Stopped)
{
logger.Info("new excel update");
thread = new Thread(git.Init);
thread.Start();
}
else if (thread.ThreadState == ThreadState.WaitSleepJoin || thread.ThreadState == ThreadState.Running)
{
logger.Info("new excel restart");
git.isRestart = true;
}
}
catch (RuntimeException ex)
{
ErrorResp error = new ErrorResp(ex);
Response = error.ToJson();
logger.Error("GetErrorResponse : " + Response);
}
catch (Exception ex)
{
ErrorResp error = new ErrorResp();
Response = error.ToJson();
logger.Error("GetErrorResponse : " + ex.ToString());
}
return Response;
}
public static void Init()
{
git = new XlsxToJson();
thread = new Thread(git.Init);
successResp = new ErrorResp();
successResp.status = 200;
successResp.message = "Success";
thread.Start();
}
}
}