Files
2026-04-01 20:20:09 +09:00

257 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace updateServer
{
//롤 데이터코더로부터 경기요청 및 등록정보를 요청받는다.
public class NetManager
{
const string TAG = "NETMANAGER";
HttpListener listener = null;
bool doListen = false;
Thread mListenTaskWorker = null;
ManualResetEvent mThreadCloseObserver = new ManualResetEvent(false);
internal void stop()
{
doListen = false;
listener.Stop();
mThreadCloseObserver.WaitOne();
}
internal bool IsAlive()
{
if (mListenTaskWorker == null || !mListenTaskWorker.IsAlive)
{
return false;
}
else
{
return true;
}
}
internal void start()
{
doListen = true;
Program.mMainForm.lbServerStatus.Text = "OK";
mListenTaskWorker = new Thread(listenTask);
mListenTaskWorker.IsBackground = true;
mListenTaskWorker.Start();
}
private void listenTask()
{
listener = new HttpListener();
listener.Prefixes.Clear();
listener.Prefixes.Add("http://+:60003/");
listener.AuthenticationSchemes = AuthenticationSchemes.Basic | AuthenticationSchemes.Anonymous;
listener.Start();
while (doListen)
{
try
{
var context = listener.GetContext();
HandleRequest(context);
}
catch (Exception ex)
{
}
}
mThreadCloseObserver.Set();
Program.mMainForm.Invoke(new System.Windows.Forms.MethodInvoker(() => { Program.mMainForm.lbServerStatus.Text = "CLOSE"; }));
}
//기존에 저장한 값들을 배열로 저장하여 관리한다.
List<string> beforeKeys = new List<string>();
private void HandleRequest(object state)
{
HttpListenerContext context = (HttpListenerContext)state;
HttpListenerRequest request = context.Request;
string returnValue = "";
try
{
if (request.RawUrl != "/favicon.ico")
{
returnValue = request.RawUrl;
bool isTest = false;
var bytes = Encoding.UTF8.GetBytes(returnValue);
if (returnValue.Contains("/RemoveAll"))
{
UpdateManager.getInstance().RemoveAllEventRaw();
UpdateManager.getInstance().RemoveBackup();
}
else if (returnValue.Contains("/GameInfoGet"))
{
returnValue = UpdateManager.getInstance().GameKey + Environment.NewLine + UpdateManager.getInstance().GameName;
}
else if (returnValue.Contains("/ConnectionGameKey"))
{
string mPlatformKeyName = returnValue.Split(':')[1].Replace("%7C", "|").Replace("%20", " ");
lock (UpdateManager.getInstance().mWorkerTableLocker)
{
if (!UpdateManager.getInstance().mUpdateWorkerTable.ContainsKey(mPlatformKeyName))
{
UpdateManager.getInstance().startUpdateEventRaw(mPlatformKeyName, false);
returnValue = "1_" + mPlatformKeyName + "_REQUEST_START_OK_";
}
else
{
returnValue = "2_" + mPlatformKeyName + "_UPDATED_LAST";
}
}
}
////REQUEST:게임아이디
else if (returnValue.Contains("/REAL") || returnValue.Contains("/TEST"))
{
Dictionary<string, string> reqValue = null;
if (returnValue.Contains("/REAL"))
{
isTest = false;
}
else
{
isTest = true;
}
///라이엇에 진행중인 게임리스트를 요청
reqValue = UpdateManager.getInstance().GameListUpdateWorker(isTest);
string requestGameName = returnValue.Split(':')[1].Replace("%7C", "|").Replace("%20", " ");
if (reqValue.ContainsValue(requestGameName))
{
lock (UpdateManager.getInstance().mWorkerTableLocker)
{
string mPlatformKeyName = "";
//게임리스트에서 현재 요청받은 게임이름이 있는지 찾는다.
if (reqValue.Where(r => r.Value == requestGameName).Count() > 1)
{
//이미 기존에 저장된 값이 있는지 확인하는 절차
var target = reqValue.Where(r => r.Value == requestGameName);
List<string> noneSavedKey = new List<string>();
foreach (var v in target)
{
if (!beforeKeys.Contains(v.Key)) noneSavedKey.Add(v.Key);
}
if (noneSavedKey.Count == 1)
{
// 1개만 존재하면 해당 값으로 진행
mPlatformKeyName = noneSavedKey[0];
beforeKeys.Add(mPlatformKeyName);
}
else if (noneSavedKey.Count == 0)
{
//카운트가 0이면, target의 key 중에서 beforeKeys에 인덱스가 가장 높은 값으로 진행한다.
int maxIndex = -1;
foreach (var key in target.Select(x => x.Key))
{
int idx = beforeKeys.IndexOf(key);
if (idx > maxIndex)
{
maxIndex = idx;
mPlatformKeyName = key;
}
}
}
else
{
// 새로운 키가 2개 이상이면, 새로 발견된 키들을 모두 등록하고
// 마지막 키를 선택
foreach (var key in noneSavedKey)
{
beforeKeys.Add(key);
}
mPlatformKeyName = noneSavedKey.Last();
}
//기존 방식 : 가장 최근의 값으로 진행
//mPlatformKeyName = reqValue.LastOrDefault(x => x.Value == requestGameName).Key;
}
else if (reqValue.Where(r => r.Value == requestGameName).Count() == 1)
{
mPlatformKeyName = reqValue.FirstOrDefault(x => x.Value == requestGameName).Key;
if (!beforeKeys.Contains(mPlatformKeyName)) beforeKeys.Add(mPlatformKeyName);
}
//현재 받고있는 게임중에 클라이언트와 라이엇에서 요청받는게 중복되는지 확인한다.
if (!UpdateManager.getInstance().mUpdateWorkerTable.ContainsKey(mPlatformKeyName))
{
UpdateManager.getInstance().startUpdateEventRaw(mPlatformKeyName, false);
returnValue = "1_" + mPlatformKeyName + "_REQUEST_START_OK_";
}
else
{
returnValue = "2_" + mPlatformKeyName + "_UPDATED_LAST";
}
}
}
//라이엇에서 클라이언트가 요청한 게임아이디가 없는경우.
else
{
returnValue = "3_" + requestGameName + "_CANT_FIND_GAME";
}
}
//클라이언트의 요청 자체가 이상한 경우.
else
{
returnValue = "4_" + returnValue + "_ELIGAL_REQUEST";
}
}
}
catch (Exception ex)
{
//알수없는에러
Console.WriteLine(ex.ToString());
returnValue = "5_BAD_SERVER_STATS_" + ex.ToString();
}
var rtnbytes = Encoding.UTF8.GetBytes(returnValue);
context.Response.OutputStream.Write(rtnbytes, 0, rtnbytes.Length);
context.Response.OutputStream.Flush();
context.Response.OutputStream.Close();
}
}
}