서버 기본시스템 커밋

This commit is contained in:
김민서 2023-11-22 10:49:38 +09:00
parent 3ec8800dc5
commit b78da63856
21 changed files with 1165 additions and 0 deletions

66
.gitignore vendored Normal file
View File

@ -0,0 +1,66 @@
# Created by https://www.toptal.com/developers/gitignore/api/unity
# Edit at https://www.toptal.com/developers/gitignore?templates=unity
### Unity ###
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
/Client/[Ll]ibrary/
/Client/[Tt]emp/
/Client/[Oo]bj/
/Client/[Bb]uild/
/Client/[Ll]ogs/
/Client/[Uu]ser[Ss]ettings/
# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/Client/[Mm]emoryCaptures/
# Recordings can get excessive in size
/Client/[Rr]ecordings/
# Autogenerated Jetbrains Rider plugin
/Client/[Aa]ssets/Plugins/Editor/JetBrains*
# Visual Studio cache directory
.vs/
.obj/
# Visual Code directory
.vscode/
# Gradle cache directory
.gradle/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
sysinfo.txt
# Builds
*.apk
*.aab
*.unitypackage
*.app

66
server/.gitignore vendored Normal file
View File

@ -0,0 +1,66 @@
# Created by https://www.toptal.com/developers/gitignore/api/unity
# Edit at https://www.toptal.com/developers/gitignore?templates=unity
### Unity ###
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
/Server/[Ll]ibrary/
/Server/[Tt]emp/
/Server/[Oo]bj/
/Server/[Bb]uild/
/Server/[Ll]ogs/
/Server/[Uu]ser[Ss]ettings/
# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/Server/[Mm]emoryCaptures/
# Recordings can get excessive in size
/Server/[Rr]ecordings/
# Autogenerated Jetbrains Rider plugin
/Server/[Aa]ssets/Plugins/Editor/JetBrains*
# Visual Studio cache directory
.vs/
.obj/
# Visual Code directory
.vscode/
# Gradle cache directory
.gradle/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
sysinfo.txt
# Builds
*.apk
*.aab
*.unitypackage
*.app

View File

@ -0,0 +1,150 @@
using LibGit2Sharp;
using NLog;
using Server.System;
using System.Diagnostics;
namespace Server.Git
{
public abstract class AbstractGit
{
private static readonly NLog.ILogger logger = LogManager.GetCurrentClassLogger();
public bool isRestart;
string _repositoryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "excel");
public string excel = "";
public string repositoryPath { get { return _repositoryPath; } }
/// <summary>
/// 가장먼저 시작해야 하는 스크립트
/// </summary>
public void Init()
{
restart:
isRestart = false;
Pull();
if (isRestart)
goto restart;
ChangeScript();
if (isRestart)
goto restart;
Push();
if (isRestart)
goto restart;
}
/// <summary>
/// 엑셀 불러오기, 저장, 혹은 배포 까지 작업해야하는 함수
/// </summary>
public abstract void ChangeScript();
private void Pull()
{
if (!Directory.Exists(_repositoryPath))
{
Directory.CreateDirectory(_repositoryPath);
RepositorySet($"clone {STATICS.remoteUrl} {_repositoryPath}", null);
//main브렌치로 세팅
RepositorySet("branch -m main", _repositoryPath);
RepositorySet("branch --set-upstream-to=origin/main main", _repositoryPath);
}
// pull 명령어 실행
RepositorySet("pull", _repositoryPath);
}
private static void RepositorySet(string command, string workingDirectory)
{
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "git",
Arguments = command,
WorkingDirectory = workingDirectory,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using (Process process = new Process { StartInfo = psi })
{
process.Start();
process.WaitForExit();
// Git 명령 실행 결과 출력
Console.WriteLine(process.StandardOutput.ReadToEnd());
// 오류 메시지 출력
Console.WriteLine(process.StandardError.ReadToEnd());
}
}
private void Push()
{
if(excel == "")
{
return;
}
//json 저장
using (StreamWriter writer = new StreamWriter(repositoryPath + "\\excel.json"))
{
writer.Write(excel);
Console.WriteLine($"파일이 저장되었습니다 : {repositoryPath + "\\excel.json"}");
}
// 스테이징
RepositorySet("add .", repositoryPath);
// 커밋
RepositorySet($"commit -m \"update excel data\"", repositoryPath);
// 푸시
RepositorySet("push origin main", repositoryPath);
}
/// <summary>
/// 모든 파일리스트 반환
/// </summary>
/// <param name="directoryPath">검색할 폴더 경로</param>
/// <param name="extension">확장자</param>
/// <returns></returns>
public List<string> GetFiles(string directoryPath, string extension)
{
List<string> xlsxFileList = new List<string>();
try
{
string[] files = Directory.GetFiles(directoryPath);
foreach (string file in files)
{
if (Path.GetExtension(file).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
{
xlsxFileList.Add(file);
}
}
string[] subdirectories = Directory.GetDirectories(directoryPath);
foreach (string subdirectory in subdirectories)
{
//git시스템 파일은 뛰어넘기
if (subdirectory == directoryPath + "\\.git")
continue;
//제귀
xlsxFileList.AddRange(GetFiles(subdirectory, extension));
}
}
catch (Exception ex)
{
logger.Error(ex);
}
return xlsxFileList;
}
}
}

View File

@ -0,0 +1,106 @@
using Aspose.Cells;
using Microsoft.AspNetCore.Http;
using NLog;
namespace Server.Git
{
public class sheet
{
string _name;
public string name { get { return _name; } }
List<string> _variable;
public List<string> variable { get { return _variable; } }
List<string> _type;
public List<string> type { get { return _type; } }
Dictionary<long, Dictionary<string, object>> _dicViewer;
public Dictionary<long, Dictionary<string, object>> dicViewer { get { return _dicViewer; } }
public sheet(string name, List<string> variable, List<string> type, Dictionary<long, Dictionary<string, object>> dicViewer)
{
this._name = name;
this._variable = variable;
this._type = type;
this._dicViewer = dicViewer;
}
}
class ExcelManager
{
private static readonly NLog.ILogger logger = LogManager.GetCurrentClassLogger();
List<sheet> _sheets;
public List<sheet> sheets { get { return _sheets; } }
string _pathFile;
public ExcelManager(string path, string file = "")
{
if (file == "")
_pathFile = path;
else
_pathFile = path + "\\" + file;
}
public bool Play()
{
return ExcelLoad(_pathFile);
}
public bool ExcelLoad(string path)//엑셀 로드
{
// 엑셀 파일 불러오기
Workbook wb = new Workbook(_pathFile);
// 모든 워크시트 가져오기
WorksheetCollection collection = wb.Worksheets;
_sheets = new List<sheet>();
// 모든 워크시트 반복
try
{
for (int worksheetIndex = 0; worksheetIndex < collection.Count; worksheetIndex++)
{
//변수이름
List<string> variable = new List<string>();
//변수 타입
List<string> type = new List<string>();
Dictionary<long, Dictionary<string, object>> dicViewer = new Dictionary<long, Dictionary<string, object>>();
// 인덱스를 사용하여 워크시트 가져오기
Worksheet worksheet = collection[worksheetIndex];
// 행과 열의 수 얻기
int vertical = worksheet.Cells.MaxDataRow;
int horizontal = worksheet.Cells.MaxDataColumn;
//변수 이름과 타입 삽입
for (int n = 0; n <= horizontal; n++)
{
variable.Add((string)worksheet.Cells[0, n].Value);
type.Add(((string)worksheet.Cells[2, n].Value).ToLower());
}
bool isIndex = variable[0] == "index";
for (int n = 3; n <= vertical; n++)
{
Dictionary<string, object> dataList = new Dictionary<string, object>();
for (int m = 0; m <= horizontal; m++)
{
dataList.Add(variable[m], worksheet.Cells[n, m].Value);
}
dicViewer.Add((int)(isIndex ? worksheet.Cells[n, 0].Value : n - 3), dataList);
}
sheet sheet = new sheet(worksheet.Name, variable, type, dicViewer);
_sheets.Add(sheet);
}
}
catch (Exception ex)
{
logger.Error(ex);
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,150 @@
using Microsoft.AspNetCore.Http;
using Npgsql;
using Server.SQL;
using Server.System;
using System.Globalization;
namespace Server.Git
{
public class ExcelSQL
{
List<sheet> sheets;
public ExcelSQL(List<sheet> sheets)
{
this.sheets = sheets;
}
public void DataUpdate()
{
using (NpgsqlConnection connection = new NpgsqlConnection(STATICS.EXCEL_SQL_URL))
{
try
{
// 데이터베이스 연결 열기
connection.Open();
// 쿼리 작성 및 실행
//모든 쿼리 삭제
string query;
string header1 = "CREATE TABLE IF NOT EXISTS excel.";
string header2 = "INSERT INTO excel.";
string newTableQuery;
string tableDatas;
#region
query = "DROP SCHEMA excel CASCADE;" +
"CREATE SCHEMA excel AUTHORIZATION manager;";
ExecuteNonQuery(connection, query);
#endregion
#region
query = "";
for (int n = 0; n < sheets.Count; n++)
{
//초기화
newTableQuery = "";
tableDatas = "(";
#region
newTableQuery += header1;
newTableQuery += sheets[n].name + "(";
for (int m = 0; m < sheets[n].variable.Count; m++)
{
if (sheets[n].type[m] == "long" && sheets[n].variable[m] == "index")
{
newTableQuery += "index SERIAL PRIMARY KEY";
tableDatas += "index";
continue;
}
if (m != 0)
{
newTableQuery += ",\n";
tableDatas += ", ";
}
switch (sheets[n].type[m])
{
case "int":
newTableQuery += $"{sheets[n].variable[m]} INT ";
break;
case "string":
newTableQuery += $"{sheets[n].variable[m]} VARCHAR(255) ";
break;
case "enum":
newTableQuery += $"{sheets[n].variable[m]} INT2 ";
break;
case "text":
newTableQuery += $"{sheets[n].variable[m]} TEXT ";
break;
case "time":
newTableQuery += $"{sheets[n].variable[m]} timestamp ";
break;
}
tableDatas += sheets[n].variable[m];
}
newTableQuery += ");\n";
tableDatas += ") VALUES ";
bool isStart = true;
query += newTableQuery;
#endregion
#region
query += header2;
query += sheets[n].name;
query += tableDatas;
foreach(KeyValuePair<long, Dictionary<string, object>> pair in sheets[n].dicViewer)
{
if (isStart)
{
isStart = !isStart;
}
else
{
query += ", ";
}
query += "(";
for (int m = 0; m < sheets[n].variable.Count; m++)
{
switch (sheets[n].type[m])
{
case "int":
case "enum":
query += $"{pair.Value[sheets[n].variable[m]]}";
break;
case "string":
case "text":
query += $"'{pair.Value[sheets[n].variable[m]]}'";
break;
case "time":
query += $"'{((DateTime)pair.Value[sheets[n].variable[m]]).ToString("yyyy-MM-dd HH:mm:ss")}'";
break;
}
if(m != sheets[n].variable.Count -1)
{
query += ", ";
}
}
query += ")";
}
#endregion
}
ExecuteNonQuery(connection, query);
#endregion
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
private void ExecuteNonQuery(NpgsqlConnection connection, string query)
{
using (NpgsqlCommand command = new NpgsqlCommand(query, connection))
{
Console.WriteLine(query);
command.ExecuteNonQuery();
}
}
}
}

View File

@ -0,0 +1,48 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
namespace Server.Git
{
public class XlsxToJson : AbstractGit
{
public override void ChangeScript()
{
//저장경로 : repositoryPath
//작업할것
//데이터 db에 업로드
List<string> fileList = GetFiles(repositoryPath, ".xlsx");
Dictionary<string, Dictionary<long, Dictionary<string, object>>> sheetList = new Dictionary<string, Dictionary<long, Dictionary<string, object>>>();
List<sheet> sheets = null;
for (int n = 0; n < fileList.Count; n++)
{
ExcelManager em = new ExcelManager(fileList[n]);
if (em.Play())
{
sheets = em.sheets;
for (int m = 0; m < sheets.Count; m++)
{
sheetList.Add(sheets[m].name, sheets[m].dicViewer);
}
}
else
{
Console.WriteLine("-1 : NotUpdate");
return;
}
}
excel = JsonConvert.SerializeObject(sheetList);
//현재 서버는 PostgreSQL기준으로 쿼리를 생성하는 코드와 패키지가 세팅되어 있습니다 이점 참고바랍니다
//추가로 해당 기능을 사용하려면 서버에 excel이라는 스키마가 존재하여야 합니다.
if (sheets != null)
{
ExcelSQL sql = new ExcelSQL(sheets);
sql.DataUpdate();
}
}
}
}

20
server/Server/NLog.config Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target
name="logfile"
xsi:type="File"
fileName="Log/${date:format=yyyy-MM-dd}.txt"
archiveAboveSize="10485760"
archiveNumbering="Sequence"
archiveEvery="Day"
maxArchiveFiles="1000"
/>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logfile" />
</rules>
</nlog>

19
server/Server/Program.cs Normal file
View File

@ -0,0 +1,19 @@
using Server.System;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
//웹서버 초기화
ProtocolProcessor.Init();
//깃 웹훅 초기화
GItWebhook.Init();
//http용 데이터
app.MapPost("/", ProtocolProcessor.Process);
//git 접근용 웹훅
app.MapPost("/git", GItWebhook.Process);
//app.MapPost("/update", GItWebhook.Process);
app.Run();

View File

@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "https://0.0.0.0:4861",
"sslPort": 4862
}
},
"profiles": {
"Server": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://0.0.0.0:4860",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

142
server/Server/SQL/SQL.cs Normal file
View File

@ -0,0 +1,142 @@
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Server.System;
namespace Server.SQL
{
public class SQL<T>
{
string className;
Regex regex = new Regex(STATICS.PATTERN);
public SQL()
{
className = typeof(T).Name;
}
public string sqlInsert(T instance)
{
List<string> names = new List<string>();
List<string> values = new List<string>();
foreach (FieldInfo field in typeof(T).GetFields())
{
object value = field.GetValue(instance);
if (value == null)
continue;
names.Add(field.Name);
values.Add(value.ToString());
}
StringBuilder qurry = new StringBuilder();
qurry.Append($"INSERT INTO {className} (");
int n = 0;
int count = names.Count;
for(; n < count; n++)
{
qurry.Append(names[n]);
if(n != count - 1)
{
qurry.Append(", ");
}
}
qurry.Append(") VALUES (");
n = 0;
for (; n < count; n++)
{
qurry.Append(values[n]);
if (n != count - 1)
{
qurry.Append(", ");
}
}
qurry.Append(");");
return qurry.ToString();
}
public string sqlUpdate(string[] names, object[] values, string[] wnames, object[] wvalues)
{
StringBuilder qurry = new StringBuilder();
qurry.Append($"UPDATE {className} SET ");
for(int n = 0; n < names.Length; n++)
{
qurry.Append($"{names[n]} = {values[n]}");
if(n < names.Length - 1)
{
qurry.Append(", ");
}
}
qurry.Append(" WHERE ");
for (int n = 0; n < wnames.Length; n++)
{
qurry.Append($"{wnames[n]} = {wvalues[n]}");
if (n < wnames.Length - 1)
{
qurry.Append(", ");
}
}
return qurry.ToString();
}
public string sqlSelect(string[] names, string[] wnames, object[] wvalues)
{
StringBuilder qurry = new StringBuilder();
if(names == null)
{
qurry.Append($"SELECT * FROM {className} ");
}
else
{
qurry.Append("SELECT ");
for(int n = 0; n < names.Length; n++)
{
qurry.Append(names[n]);
if (n < names.Length - 1)
{
qurry.Append(", ");
}
}
qurry.Append($" FROM {className} ");
}
qurry.Append(" WHERE ");
for (int n = 0; n < wnames.Length; n++)
{
qurry.Append($"{wnames[n]} = {wvalues[n]}");
if (n < wnames.Length - 1)
{
qurry.Append(", ");
}
}
return qurry.ToString();
}
public string sqlDelete(string[] wnames, object[] wvalues)
{
StringBuilder qurry = new StringBuilder();
qurry.Append($"DELETE FROM {className}");
qurry.Append(" WHERE ");
for (int n = 0; n < wnames.Length; n++)
{
qurry.Append($"{wnames[n]} = {wvalues[n]}");
if (n < wnames.Length - 1)
{
qurry.Append(", ");
}
}
return qurry.ToString();
}
public string Injection(string data)
{
return regex.Replace(data, "");
}
}
}

View File

@ -0,0 +1,18 @@
namespace Server.SQL
{
public class User
{
public int Id { get; set; }
public string NickName { get; set; }
public string count { get; set; }
}
public class UserSQL : SQL<User>
{
public void userInsert(User user)
{
string qurry = sqlInsert(user);
}
}
}
//쿼리 전송

View File

@ -0,0 +1,44 @@
using Server.System;
using Newtonsoft.Json;
namespace Server.Service
{
public class AddUser : AbstractService
{
private AddUserReq req;
public override string Process()
{
return makeResp();
}
public override Protocol ProtocolValue() => Protocol.AddUser;
public override Req Requst(string json)
{
req = JsonConvert.DeserializeObject<AddUserReq>(json);
return req;
}
private string makeResp()
{
AddUserResp resp = new AddUserResp();
resp.status = 200;
return resp.ToJson();
}
}
public class AddUserReq : Req
{
public override bool IsReceivedAllField()
{
return true;
}
}
public class AddUserResp : Resp
{
}
}

View File

@ -0,0 +1,44 @@
using Server.System;
using Newtonsoft.Json;
namespace Server.Service
{
public class awaketest : AbstractService
{
private awaketestReq req;
public override string Process()
{
return makeResp();
}
public override Protocol ProtocolValue() => Protocol.Test;
public override Req Requst(string json)
{
req = JsonConvert.DeserializeObject<awaketestReq>(json);
return req;
}
private string makeResp()
{
awaketestResp resp = new awaketestResp();
resp.status = 200;
return resp.ToJson();
}
}
public class awaketestReq : Req
{
public override bool IsReceivedAllField()
{
return true;
}
}
public class awaketestResp : Resp
{
}
}

View File

@ -0,0 +1,32 @@
using Newtonsoft.Json;
namespace Server.System
{
public abstract class AbstractService
{
public abstract Protocol ProtocolValue();
public abstract string Process();
public abstract Req Requst(string json);
}
public abstract class Req
{
public Protocol cmd;
public virtual bool IsReceivedAllField()
{
return true;
}
}
public abstract class Resp
{
public int status;
public virtual string ToJson()
{
return JsonConvert.SerializeObject(this);
}
}
}

View File

@ -0,0 +1,16 @@
public enum Protocol
{
Test = 0,
AddUser = 1,
}
public enum Error
{
RuntimeException = -1,//서버 오류
None = 0,//사용안함
success = 200,//성공
notFound = 404,//프로토콜 없음
unknown = 500,//파라미터 오류
crypto = 800,//암복호화 에러
nodata = 900,//데이터가 없음
}

View File

@ -0,0 +1,28 @@
namespace Server.System
{
public class ErrorResp : Resp
{
public string message;
public ErrorResp(RuntimeException ex)
{
this.status = (int)ex.status;
this.message = ex.Message;
}
public ErrorResp()
{
this.status = -1;
this.message = "Unknown Error";
}
}
public class RuntimeException : Exception
{
public Error status;
public RuntimeException(string message = "", Error status = Error.RuntimeException) : base(message)
{
this.status = status;
}
}
}

View File

@ -0,0 +1,73 @@
using NLog;
using Server.Git;
namespace Server.System
{
public class GItWebhook
{
private static readonly NLog.ILogger logger = LogManager.GetCurrentClassLogger();
public static Thread thread;
private static AbstractGit git;
public static string Process(HttpContext context)
{
//TODO 아무때나 호출되지 않게 만들기
string Response;
try
{
string eaDelivery = context.Request.Headers["X-Gitea-Delivery"];
string eaEvent = context.Request.Headers["X-Gitea-Event"];
string eaEventType = context.Request.Headers["X-Gitea-Event-Type"];
string eaSignature = context.Request.Headers["X-Gitea-Signature"];
Console.WriteLine($"X-Gitea-Delivery : {eaDelivery}");
Console.WriteLine($"X-Gitea-Event : {eaEvent}");
Console.WriteLine($"X-Gitea-Event-Type : {eaEventType}");
Console.WriteLine($"X-Gitea-Signature : {eaSignature}");
//task를 쓰면 멈출수가 없기에 thread를 사용
if (thread.ThreadState == ThreadState.Unstarted)
{
thread.Start();
}
else if (thread.ThreadState == ThreadState.Stopped)
{
thread = new Thread(git.Init);
thread.Start();
}
else if (thread.ThreadState == ThreadState.WaitSleepJoin || thread.ThreadState == ThreadState.Running)
{
git.isRestart = true;
}
ErrorResp error = new ErrorResp();
error.status = 200;
error.message = "Success";
Response = error.ToJson();
}
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);
}
}
}

View File

@ -0,0 +1,20 @@
namespace Server.System
{
public static class STATICS
{
#region Dev
#if DEBUG
public static readonly string SQL_URL = "Host=myHost;Port=myPort;Username=myUsername;Password=myPassword;Database=myDatabase;";
public static readonly string EXCEL_SQL_URL = "Host=myHost;Port=myPort;Username=myUsername;Password=myPassword;Database=myDatabase;";
#endif
#endregion
//비공계 프로젝트의 경우 아래와같이 작성해주세요
//"https://username:password@www.example.com/";
public static readonly string remoteUrl = "https://username:password@www.example.com/";
public static readonly string PATTERN = "[^a-zA-Z0-9가-힣 ]";
}
}

View File

@ -0,0 +1,78 @@
using System.Reflection;
using NLog;
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 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));
logger.Info("Server Start");
}
public static string Process(HttpContext context) {
AbstractService abstractService;
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);
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());
}
return Response;
}
private static async Task<string> Request(HttpRequest request) {
using var reader = new StreamReader(request.Body);
return await reader.ReadToEndAsync();
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Trace",
"Microsoft.AspNetCore": "Trace"
}
},
"AllowedHosts": "0.0.0.0;localhost"
}