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 beforeKeys = new List(); 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 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 noneSavedKey = new List(); 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(); } } }