using MongoDB.Bson; using MongoDB.Driver; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; namespace LolDataRequestLib { /// /// 데이터를 관리하기위한 매니저객체. /// /// 데이터 공유의 편의성을 위해 Singleton을 사용. /// /// 모든 데이터를 요청하고 관리한다. /// public class DataManager { #region 싱글턴&생성자 private static DataManager mInstance = null; private static object mSingletonLocker = new object(); internal MongoClient mDBClient = null; public bool isNewBanPick = false; public static DataManager getInstance() { lock (mSingletonLocker) { if (mInstance == null) { mInstance = new DataManager(); } } return mInstance; } private DataManager() { init(); } #endregion #region 라이브데이터변수 /// /// 실시간 업데이트 데이터 크리티컬세션 관리용 락커. /// private object mDataAccessObjectLocker = new object(); /// /// 벤픽에 관련된 데이터 /// private BsonValue m밴픽데이터 = null; /// /// 벤픽에 관련된 데이터 게터&세터 /// internal BsonValue 밴픽데이터 { get { lock (mDataAccessObjectLocker) { return m밴픽데이터; } } set { lock (mDataAccessObjectLocker) { m밴픽데이터 = value; } } } /// /// 경기데이터에 관련된 데이터 /// private BsonValue m경기데이터 = null; /// /// 경기데이터(status_update)에 관련된 데이터 게터&세터 /// internal BsonValue 경기데이터 { get { lock (mDataAccessObjectLocker) { return m경기데이터; } } set { lock (mDataAccessObjectLocker) { m경기데이터 = value; } } } /// /// 모든 오브젝트에 관련된 데이터 /// private BsonValue m오브젝트데이터 = null; /// /// 오브젝트데이터에 관련된 데이터 게터&세터 /// internal BsonValue 오브젝트데이터 { get { lock (mDataAccessObjectLocker) { return m오브젝트데이터; } } set { lock (mDataAccessObjectLocker) { m오브젝트데이터 = value; } } } /// /// 드래곤리스폰에 관련된 데이터 /// private BsonValue m드래곤리스폰 = null; /// /// 드래곤리스폰에 관련된 데이터 게터&세터 /// internal BsonValue 드래곤리스폰 { get { lock (mDataAccessObjectLocker) { return m드래곤리스폰; } } set { lock (mDataAccessObjectLocker) { m드래곤리스폰 = value; } } } /* private BsonValue m아타칸리스폰 = null; /// /// 드래곤리스폰에 관련된 데이터 게터&세터 /// internal BsonValue 아타칸리스폰 { get { lock (mDataAccessObjectLocker) { return m아타칸리스폰; } } set { lock (mDataAccessObjectLocker) { m아타칸리스폰= value; } } } */ /// /// 건물파괴에 관련된 데이터 /// private BsonValue m건물데이터 = null; /// /// 건물파괴에 관련된 데이터 게터&세터 /// internal BsonValue 건물데이터 { get { lock (mDataAccessObjectLocker) { return m건물데이터; } } set { lock (mDataAccessObjectLocker) { m건물데이터 = value; } } } /// /// 건물파괴에 관련된 골드 데이터 /// private BsonValue m타워골드데이터 = null; /// /// 건물파괴에 관련된 데이터 게터&세터 /// internal BsonValue 타워골드데이터 { get { lock (mDataAccessObjectLocker) { return m타워골드데이터; } } set { lock (mDataAccessObjectLocker) { m타워골드데이터 = value; } } } #endregion /// /// 라이브데이터를 업데이트하는 인스턴스 리스트 /// List mRequestDataList = null; /// /// 매니저 초기화. /// 필요한 Request들을 생성하고 RequestWorker를 실행한다.. /// private void init() { //라이브워커 준비 IsupdateWorkersWork = true; mRequestDataList = new List(); mRequestDataList.Add(ARequestData.createRequestFactory(DBDefine.RequestDataType.BAN_AND_PICK)); mRequestDataList.Add(ARequestData.createRequestFactory(DBDefine.RequestDataType.GAME_STATUS)); mRequestDataList.Add(ARequestData.createRequestFactory(DBDefine.RequestDataType.OBJECT_EVENT)); mRequestDataList.Add(ARequestData.createRequestFactory(DBDefine.RequestDataType.STRUCT_EVENT)); mRequestDataList.Add(ARequestData.createRequestFactory(DBDefine.RequestDataType.STRUCT_GOLD_EVENT)); mRequestDataList.Add(ARequestData.createRequestFactory(DBDefine.RequestDataType.DRAGON_RESPAWN)); mRequestDataList.Add(ARequestData.createRequestFactory(DBDefine.RequestDataType.ATAKHAN_RESPAWN)); //기초데이터(밴순서, 챔피언매핑, 룬매핑) 만들기. mDBClient = new MongoClient(DBDefine.MONGODB주소); 밴데이터만들기(false); setChampionDataMapping(); setRuneDataMapping(); } /// /// DB주소를 변경하고 MongodbClient를 초기화 /// /// public void resetDBAddress(string 가져온디비주소) { DBDefine.디비변경(가져온디비주소); lock (mDataAccessObjectLocker) { mDBClient = new MongoClient(DBDefine.MONGODB주소); foreach (ARequestData item in mRequestDataList) { item.resetDBAddress(); } } 밴픽데이터 = null; 오브젝트데이터 = null; 드래곤리스폰 = null; //아타칸리스폰 = null; 경기데이터 = null; 건물데이터 = null; 타워골드데이터 = null; } /// /// 챔피언ID-챔피언이름 영문 매핑 /// //public Dictionary mChampionTable = null; public Dictionary mChampionTable = null; public class ChampionInfoVO { public int ID; public string champNameKOR; public string champNameENG; } /// /// 챔피언매핑데이터를 가져와서 세팅한다. /// void setChampionDataMapping() { //IMongoDatabase eventDataBase = mDBClient.GetDatabase("basic_data_lol"); //var filter = Builders.Filter.Eq("type", "champion"); //var projection = Builders.Projection // .Exclude("_id"); //List documents = eventDataBase.GetCollection("campion_raw") // .Find(filter) // .Project(projection) // .ToList(); BsonDocument documents = null; if (!BsonDocument.TryParse((File.ReadAllText(DBDefine.챔피언데이터파일경로)), out documents)) { throw new Exception("챔피언 데이터 파일에서 데이터를 가져올 수 없습니다."); } BsonDocument bufChampionDataArray = documents["data"].AsBsonDocument; /* * 20230106 챔피언 정보 업데이트 수정 mChampionTable = new Dictionary(); foreach (BsonElement item in bufChampionDataArray) { mChampionTable.Add(Convert.ToInt32(item.Value["key"].AsString), item.Name.Replace(" ", "")); } */ mChampionTable = new Dictionary(); foreach (BsonElement item in bufChampionDataArray) { ChampionInfoVO bufChampionInfo = new ChampionInfoVO(); try { bufChampionInfo.ID = Convert.ToInt32(item.Value["key"].AsString); bufChampionInfo.champNameENG = item.Value["id"].AsString.Replace(" ", ""); bufChampionInfo.champNameKOR = item.Value["name"].AsString.Replace(" ", ""); } catch(Exception ex) { } finally { mChampionTable.Add(Convert.ToInt32(item.Value["key"].AsString), bufChampionInfo); } } } public Dictionary mRuneTable = null; void setRuneDataMapping() { BsonArray documents = null; //JObject ddd = JObject.Parse(File.ReadAllText(DBDefine.룬데이터파일경로)); try { documents = MongoDB.Bson.Serialization.BsonSerializer.Deserialize(File.ReadAllText(DBDefine.룬데이터파일경로)); } catch (Exception) { throw new Exception("룬데이터를 가져오는데 오류가 발생했습니다"); } //documents = BsonArray.Parse(); mRuneTable = new Dictionary(); foreach (BsonDocument item in documents) { mRuneTable.Add(item["id"].ToInt32(), item["name"].AsString); BsonArray innerRunes = item["slots"].AsBsonArray; foreach (BsonValue innerItem in innerRunes) { BsonArray innerSubRunes = innerItem["runes"].AsBsonArray; foreach (BsonValue innerSubItem in innerSubRunes) { mRuneTable.Add(innerSubItem["id"].ToInt32(), innerSubItem["name"].AsString.Replace(" ", "")); } } } } internal Dictionary 밴픽순서테이블 = new Dictionary(); public void 밴데이터만들기(bool isRedBan) { 밴픽순서테이블 = new Dictionary(); if (!isRedBan) { 밴픽순서테이블.Add(101, 1); 밴픽순서테이블.Add(202, 2); 밴픽순서테이블.Add(103, 3); 밴픽순서테이블.Add(204, 4); 밴픽순서테이블.Add(105, 5); 밴픽순서테이블.Add(206, 6); 밴픽순서테이블.Add(201, 7); 밴픽순서테이블.Add(102, 8); 밴픽순서테이블.Add(203, 9); 밴픽순서테이블.Add(104, 10); } else { 밴픽순서테이블.Add(201, 1); 밴픽순서테이블.Add(102, 2); 밴픽순서테이블.Add(203, 3); 밴픽순서테이블.Add(104, 4); 밴픽순서테이블.Add(205, 5); 밴픽순서테이블.Add(106, 6); 밴픽순서테이블.Add(101, 7); 밴픽순서테이블.Add(202, 8); 밴픽순서테이블.Add(103, 9); 밴픽순서테이블.Add(204, 10); } } public bool IsupdateWorkersWork = false; //public string mPlatformGameID = "ESPORTSTMNT06_1720762"; /// /// DB에서 라이브로 데이터를 가져올 게임의 PlatformID /// //public string mPlatformGameID = "ESPORTSTMNT02_1923726"; public string platformGameID = "sr fakegod's game"; //public string mPlatformGameID = "ESPORTSTMNT06_1721059"; public object platformIDLocker = new object(); /// /// 경기가 리게임 되었을때를 대비해 platformID가 바뀔경우 상시업데이트인덱스를 setter에서 초기화한다. /// public string mPlatformGameID { get { lock (mDataAccessObjectLocker) { return platformGameID; } } set { lock (mDataAccessObjectLocker) { foreach (ARequestData item in mRequestDataList) { item.initIndex(); } platformGameID = value; } } } public int 리퀘스트인터벌밀리초 = 400; /// /// 라이브로 연결해서 나갈 데이터를 파싱해서 리턴한다. /// /// /// public DataSet 라이브데이터요청(DBDefine.요청데이터분류 요청데이터타입) { IResponseData bufInstance = null; DataSet rtnValue = new DataSet(); try { switch (요청데이터타입) { case DBDefine.요청데이터분류.밴데이터: bufInstance = new ResponseData.밴데이터(); break; case DBDefine.요청데이터분류.팟지: bufInstance = new ResponseData.팟지선수(); break; case DBDefine.요청데이터분류.픽데이터: bufInstance = new ResponseData.픽데이터(); break; case DBDefine.요청데이터분류.현재골드량선수: bufInstance = new ResponseData.골드획득량선수(); break; case DBDefine.요청데이터분류.현재데미지량선수: bufInstance = new ResponseData.누적데미지선수(); break; case DBDefine.요청데이터분류.경험치레벨: bufInstance = new ResponseData.경험치레벨선수(); break; case DBDefine.요청데이터분류.룬데이터: bufInstance = new ResponseData.룬데이터(); break; case DBDefine.요청데이터분류.오브젝트킬: bufInstance = new ResponseData.오브젝트킬전체(false); break; case DBDefine.요청데이터분류.골드차이팀: bufInstance = new ResponseData.골드차이팀(); break; case DBDefine.요청데이터분류.타워철거전체: bufInstance = new ResponseData.타워파괴전체(); break; case DBDefine.요청데이터분류.타워골드데이터: bufInstance = new ResponseData.타워골드데이터(); break; case DBDefine.요청데이터분류.용리스폰: bufInstance = new ResponseData.용데이터(); break; //case DBDefine.요청데이터분류.아타칸리스폰: // bufInstance = new ResponseData.아타칸데이터(); // break; case DBDefine.요청데이터분류.퀘스트완료여부: bufInstance = new ResponseData.퀘스트완료여부(); break; case DBDefine.요청데이터분류.킬뎃어시: bufInstance = new ResponseData.KDA선수(); break; case DBDefine.요청데이터분류.경기종료정보: IResponseData bufGameEndData = new ResponseData.경기종료정보(); DataTable bufResult = bufGameEndData.디비데이터를데이터테이블로만듬(); if (bufResult == null || bufResult.Rows.Count == 0) { return rtnValue; } else { rtnValue.Tables.Add(bufResult); } IResponseData bufKDAData = new ResponseData.KDA선수(); rtnValue.Tables.Add(bufKDAData.디비데이터를데이터테이블로만듬()); IResponseData bufTowerData = new ResponseData.타워파괴전체(); rtnValue.Tables.Add(bufTowerData.디비데이터를데이터테이블로만듬()); IResponseData bufTowerGoldData = new ResponseData.타워골드데이터(); rtnValue.Tables.Add(bufTowerGoldData.디비데이터를데이터테이블로만듬()); IResponseData bufObjectData = new ResponseData.오브젝트킬전체(true); rtnValue.Tables.Add(bufObjectData.디비데이터를데이터테이블로만듬()); IResponseData bufBanData = new ResponseData.밴데이터(); rtnValue.Tables.Add(bufBanData.디비데이터를데이터테이블로만듬()); IResponseData bufDamageData = new ResponseData.누적데미지선수(); rtnValue.Tables.Add(bufDamageData.디비데이터를데이터테이블로만듬()); IResponseData bufGoldTeamData = new ResponseData.골드차이팀(); rtnValue.Tables.Add(bufGoldTeamData.디비데이터를데이터테이블로만듬()); return rtnValue; } rtnValue.Tables.Add(bufInstance.디비데이터를데이터테이블로만듬()); return rtnValue; } catch (Exception ex) { Console.WriteLine(ex.ToString()); DataSet ddd = new DataSet(); ddd.Tables.Add(new DataTable("데이터없음")); return ddd; } } public DataSet 한타딜량요청(int 시작초, int 종료초) { if (시작초 == 0) { return null; } IResponseData bufInstance = new ResponseData.한타딜량범위(시작초, 종료초); DataSet rtnValue = new DataSet(); rtnValue.Tables.Add(bufInstance.디비데이터를데이터테이블로만듬()); return rtnValue; } #region 서버와의통신부분 public void requestServerForUpdateRemoveAll(string serverIP) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create( "http://" + serverIP + ":60003/" + "RemoveAll"); request.Method = "GET"; request.Timeout = 30 * 1000; try { using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse()) { lock (mDataAccessObjectLocker) { foreach (ARequestData item in mRequestDataList) { item.initIndex(); } } HttpStatusCode status = resp.StatusCode; Stream respStream = resp.GetResponseStream(); using (StreamReader sr = new StreamReader(respStream)) { } } } catch (Exception) { } } public string requestServerForGameInfo(string serverIP) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create( "http://" + serverIP + ":60003/GameInfoGet"); request.Method = "GET"; request.Timeout = 30 * 1000; string responseText = ""; try { using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse()) { HttpStatusCode status = resp.StatusCode; //Console.WriteLine(status); // 정상이면 "OK" Stream respStream = resp.GetResponseStream(); using (StreamReader sr = new StreamReader(respStream)) { responseText = sr.ReadToEnd(); } } if (responseText.Contains(Environment.NewLine)) { return responseText; } } catch (Exception) { } return ""; } public DBDefine.서버의답변 requestServerForUpdateGameKey(string serverIP, string gameKey, bool isTest) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create( "http://" + serverIP + ":60003/" + (isTest ? "TEST" : "REAL") + ("/ConnectionGameKey") + ":" + gameKey); request.Method = "GET"; request.Timeout = 30 * 1000; string responseText = ""; try { using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse()) { lock (mDataAccessObjectLocker) { foreach (ARequestData item in mRequestDataList) { item.initIndex(); } } HttpStatusCode status = resp.StatusCode; //Console.WriteLine(status); // 정상이면 "OK" Stream respStream = resp.GetResponseStream(); using (StreamReader sr = new StreamReader(respStream)) { responseText = sr.ReadToEnd(); } } string[] responseServerData = responseText.Split('_'); string statusServer = responseServerData[0]; if (statusServer == "1") { mPlatformGameID = responseServerData[1] + "_" + responseServerData[2]; return DBDefine.서버의답변.방을찾았고업데이트를시작함; } else if (statusServer == "2") { mPlatformGameID = responseServerData[1] + "_" + responseServerData[2]; return DBDefine.서버의답변.이미방을업데이트중임; } else if (statusServer == "3") { return DBDefine.서버의답변.방을못찾아서업데이트를못함; } else if (statusServer == "4") { return DBDefine.서버의답변.명령이틀림; } return DBDefine.서버의답변.서버와의연결이이상함; } catch (Exception) { return DBDefine.서버의답변.서버와의연결이이상함; } } public DBDefine.서버의답변 requestServerForUpdate(string serverIP, string gameName, bool isTest) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create( "http://" + serverIP + ":60003/" + (isTest ? "TEST" : "REAL") + ":" + gameName); request.Method = "GET"; request.Timeout = 30 * 1000; string responseText = ""; try { using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse()) { lock (mDataAccessObjectLocker) { foreach (ARequestData item in mRequestDataList) { item.initIndex(); } } HttpStatusCode status = resp.StatusCode; //Console.WriteLine(status); // 정상이면 "OK" Stream respStream = resp.GetResponseStream(); using (StreamReader sr = new StreamReader(respStream)) { responseText = sr.ReadToEnd(); } } string[] responseServerData = responseText.Split('_'); string statusServer = responseServerData[0]; if (statusServer == "1") { mPlatformGameID = responseServerData[1] + "_" + responseServerData[2]; return DBDefine.서버의답변.방을찾았고업데이트를시작함; } else if (statusServer == "2") { mPlatformGameID = responseServerData[1] + "_" + responseServerData[2]; return DBDefine.서버의답변.이미방을업데이트중임; } else if (statusServer == "3") { return DBDefine.서버의답변.방을못찾아서업데이트를못함; } else if (statusServer == "4") { return DBDefine.서버의답변.명령이틀림; } return DBDefine.서버의답변.서버와의연결이이상함; } catch (Exception) { return DBDefine.서버의답변.서버와의연결이이상함; } } #endregion #region 게임타이머관련 /*0603 라이브게임 타이머 개발 * * Form Timer로 진행시에 UI스레드에서 밀리는 현상이 발생할때 대책이 없다. * * * 따라서 따로 SystemTimer를 사용해서 초가 바뀔경우에 Data를 Interface로 드롭하는 방식을 사용한다. * */ /// /// 경기시간을 스레드로 보호하기위한 Locker /// private static object gameTimeLocker = new object(); /// /// 경기시간(초) /// internal int mGameTime = 0; /// /// 경기시간(초) 게터세터 /// internal int 경기시간 { get { lock (gameTimeLocker) { return mGameTime; } } set { lock (gameTimeLocker) { mGameTime = value; } } } System.Timers.Timer m라이브시간계산용타이머 = new System.Timers.Timer(); /// /// 시간 이벤트 콜백 /// IGameTimeEventDrop mCallback = null; public void setCallback(IGameTimeEventDrop recvCallback) { this.mCallback = recvCallback; } DateTime lastUpdateTime = new DateTime(); public void timerStart() { if (m라이브시간계산용타이머.Enabled) { m라이브시간계산용타이머.Stop(); m라이브시간계산용타이머.Elapsed -= timerTick; } lastUpdateTime = DateTime.Now; m라이브시간계산용타이머 = new System.Timers.Timer(); m라이브시간계산용타이머.Interval = 300; m라이브시간계산용타이머.Elapsed += timerTick; m라이브시간계산용타이머.Start(); } public void timerStop() { if (m라이브시간계산용타이머.Enabled) { m라이브시간계산용타이머.Stop(); m라이브시간계산용타이머.Elapsed -= timerTick; } } public void setGameTime(int 초) { 경기시간 = 초; } void timerTick(object sender, System.Timers.ElapsedEventArgs e) { if (lastUpdateTime.AddSeconds(1) < DateTime.Now) { lastUpdateTime = lastUpdateTime.AddSeconds(1); 경기시간 += 1; eventTimerWork(); if (mCallback != null) { mCallback.현재게임시간(경기시간); } } } void eventTimerWork() { try { ThreadPool.QueueUserWorkItem(o => 오브젝트체크()); ThreadPool.QueueUserWorkItem(o => 드래곤체크()); //ThreadPool.QueueUserWorkItem(o => 아타칸체크()); ThreadPool.QueueUserWorkItem(o => 억제기체크()); ThreadPool.QueueUserWorkItem(o => 한타딜량()); ThreadPool.QueueUserWorkItem(o => 라인퀘스트체크()); } catch(Exception ex) { } } private readonly Dictionary _roleBoundQuestCompleteCache = new Dictionary(); void 라인퀘스트체크() { try { DataTable dataTable = 라이브데이터요청(DBDefine.요청데이터분류.퀘스트완료여부).Tables[DBDefine.요청데이터분류.퀘스트완료여부.GetStringValue()]; mCallback.라인퀘스트정보(dataTable); } catch(Exception ex) { } } public void 초당한타딜량리턴시작() { is한타딜량체크 = true; } public void 초당한타딜량리턴종료() { is한타딜량체크 = false; } private bool is한타딜량체크 = false; private DataTable 한타초기딜량 = null; int 엘더파워플레이시작차이 = 0; int 바론파워플레이시작차이 = 0; void 오브젝트체크() { DataTable 오브젝트데이터 = 라이브데이터요청(DBDefine.요청데이터분류.오브젝트킬).Tables[DBDefine.요청데이터분류.오브젝트킬.GetStringValue()]; IEnumerable 전령스폰데이터 = null; IEnumerable 바론스폰데이터 = null; IEnumerable 엘더드래곤데이터 = null; IEnumerable 공허유충데이터 = null; //IEnumerable 아타칸데이터 = null; if (오브젝트데이터 != null) { 전령스폰데이터 = 오브젝트데이터 .AsEnumerable().Where(r => r.Field("오브젝트타입").Contains("riftHerald")); 바론스폰데이터 = 오브젝트데이터 .AsEnumerable().Where(r => r.Field("오브젝트타입").Contains("baron")); 엘더드래곤데이터 = 오브젝트데이터 .AsEnumerable().Where(r => r.Field("오브젝트타입").Contains("dragon") && r.Field("드래곤종류").Contains("elder")); 공허유충데이터 = 오브젝트데이터 .AsEnumerable().Where(r => r.Field("오브젝트타입").Contains("VoidGrub")); //아타칸데이터 = 오브젝트데이터 //.AsEnumerable().Where(r => r.Field("오브젝트타입").Contains("Atakhan")); } if (엘더드래곤데이터.Count() != 0) { foreach (DataRow item in 엘더드래곤데이터) { int 젠타임 = (Convert.ToInt32(item["킬시간"]) / 1000) + 360 - 경기시간; if (젠타임 >= 210 && 젠타임 < 361) { if (젠타임 == 360) { 엘더파워플레이시작차이 = getGoldGapForPowerPlay((DBDefine.팀구분)((item["잡은팀"].ToString() == "블루") ? 100 : 200), 경기시간); } else if (젠타임 < 210) { 엘더파워플레이시작차이 = 0; } if (mCallback != null) { mCallback.오브젝트버프시간(item["잡은팀"].ToString(), "elder", 젠타임 - 210, getGoldGapForPowerPlay((DBDefine.팀구분)((item["잡은팀"].ToString() == "블루") ? 100 : 200), 경기시간) - 엘더파워플레이시작차이); } } } } //전령처리 if (900 - 경기시간 >= 0) { if (mCallback != null) { mCallback.오브젝트리스폰시간("첫전령", "riftHerald", 900 - 경기시간); } } ////아타칸 //if (1200 - 경기시간 >= 0) //{ // if (mCallback != null) // { // mCallback.오브젝트리스폰시간("아타칸", "atakhan", 1200 - 경기시간); // } //} ////아타칸 잡은 정보 //if (아타칸데이터.Count() > 0) //{ // foreach (DataRow item in 아타칸데이터) // { // if (mCallback != null) // { // int 킬시간 = Convert.ToInt32(item["킬시간"]) / 1000; // if (킬시간 - 경기시간 <=5 && 킬시간 - 경기시간 >= -5) // { // mCallback.오브젝트리스폰시간(item["잡은팀"].ToString(), item["오브젝트타입"].ToString(), 킬시간); // } // } // } //} /* if (전령스폰데이터.Count() == 0) { } else if (전령스폰데이터.Count() == 1) { foreach (DataRow item in 전령스폰데이터) { int 젠타임 = (Convert.ToInt32(item["킬시간"]) / 1000) + 360 - 경기시간; if (젠타임 >= 0 && 젠타임 < 361) { if (mCallback != null) { mCallback.오브젝트리스폰시간(item["잡은팀"].ToString(), "riftHerald", 젠타임); } } } } */ //바론처리 if (1200 - 경기시간 >= 0) { if (mCallback != null) { mCallback.오브젝트리스폰시간("첫바론", "baron", 1200 - 경기시간); } } else { foreach (DataRow item in 바론스폰데이터) { /* int 젠타임 = (Convert.ToInt32(item["킬시간"]) / 1000) + 360 - 경기시간; if (젠타임 >= 0 && 젠타임 < 361) { if (mCallback != null) { mCallback.오브젝트리스폰시간(item["잡은팀"].ToString(), item["오브젝트타입"].ToString(), 젠타임); } } if (젠타임 >= 180 && 젠타임 < 361) { if (젠타임 == 360) { 바론파워플레이시작차이 = getGoldGapForPowerPlay((DBDefine.팀구분)((item["잡은팀"].ToString() == "블루") ? 100 : 200), 경기시간); } else if (젠타임 < 180) { 바론파워플레이시작차이 = 0; } if (mCallback != null) { mCallback.오브젝트버프시간(item["잡은팀"].ToString(), "baron", 젠타임 - 180, getGoldGapForPowerPlay((DBDefine.팀구분)((item["잡은팀"].ToString() == "블루") ? 100 : 200), 경기시간) - 바론파워플레이시작차이); } } */ int 젠타임 = (Convert.ToInt32(item["킬시간"]) / 1000) + 360 - 경기시간; if (젠타임 >= 0 && 젠타임 < 361) { if (mCallback != null) { mCallback.오브젝트리스폰시간(item["잡은팀"].ToString(), item["오브젝트타입"].ToString(), 젠타임); } } if (젠타임 >= 180 && 젠타임 < 361) { if (젠타임 == 360) { 바론파워플레이시작차이 = getGoldGapForPowerPlay((DBDefine.팀구분)((item["잡은팀"].ToString() == "블루") ? 100 : 200), 경기시간); } else if (젠타임 < 180) { 바론파워플레이시작차이 = 0; } if (mCallback != null) { mCallback.오브젝트버프시간(item["잡은팀"].ToString(), "baron", 젠타임 - 180, getGoldGapForPowerPlay((DBDefine.팀구분)((item["잡은팀"].ToString() == "블루") ? 100 : 200), 경기시간, Convert.ToInt32(item["킬시간"]) / 1000)); } } } } //아타칸처리 /* if (아타칸데이터.Count() == 0) { } else { foreach (DataRow item in 아타칸데이터) { if (mCallback != null) { mCallback.오브젝트리스폰시간("아타칸", item["오브젝트타입"].ToString(), 360 - 경기시간); } } } */ //공허유충시간 if (공허유충데이터.Count() < 3) { if (480 - 경기시간 >= 0) { if (mCallback != null) { mCallback.오브젝트리스폰시간("첫유충", "horde", 480 - 경기시간); } } } if (공허유충데이터.Count() > 0) { int 블루팀공허유충 = 0; int 레드팀공허유충 = 0; if (공허유충데이터.Count() == 3) { /* int 젠타임 = -1; foreach (DataRow item in 공허유충데이터) { int 젠타임체크 = (Convert.ToInt32(item["킬시간"]) / 1000) + 240 - 경기시간; if (젠타임체크 > 젠타임) 젠타임 = 젠타임체크; } if (젠타임 >= 0 && 젠타임 < 241) { if (mCallback != null) { mCallback.오브젝트리스폰시간("", "horde", 젠타임); } } */ } foreach (DataRow item in 공허유충데이터) { if (item["잡은팀"].ToString() == "블루") 블루팀공허유충++; else 레드팀공허유충++; } if (mCallback != null) { mCallback.공허유충정보(블루팀공허유충, 레드팀공허유충); } } } void 드래곤체크() { DataTable dragonSpawnData = 라이브데이터요청(DBDefine.요청데이터분류.용리스폰).Tables[DBDefine.요청데이터분류.용리스폰.GetStringValue()]; foreach (DataRow item in dragonSpawnData.Rows) { int 젠타임 = Convert.ToInt32(item["리스폰타임"]) - 경기시간; int 오버되는젠타임 = (item["용정보"].ToString() == "elder" ? 361 : 301); if (젠타임 >= 0 && 젠타임 < 오버되는젠타임) { if (mCallback != null) { mCallback.드래곤리스폰시간(item["용정보"].ToString(), 젠타임); } } else if (젠타임 >= 0)//이상상황이므로 라이브로 추정 { if (mCallback != null) { mCallback.드래곤리스폰시간(item["용정보"].ToString(), 0); } } } } //void 아타칸체크() //{ // DataTable atakhanSpawnData = 라이브데이터요청(DBDefine.요청데이터분류.아타칸리스폰).Tables[DBDefine.요청데이터분류.아타칸리스폰.GetStringValue()]; // int 인덱스값 = 0; // string rtnValue = ""; // foreach (DataRow item in atakhanSpawnData.Rows) // { // if (인덱스값 < Convert.ToInt32(item["리스폰타임"])) // { // 인덱스값 = Convert.ToInt32(item["리스폰타임"]); // rtnValue = item["아타칸정보"].ToString(); // } // } // if (atakhanSpawnData.Rows.Count > 0) // { // if (mCallback != null) // { // mCallback.아타칸리스폰정보(rtnValue, 인덱스값); // } // } //} void 억제기체크() { try { IEnumerable 가져온정보 = 라이브데이터요청(DBDefine.요청데이터분류.타워철거전체).Tables[DBDefine.요청데이터분류.타워철거전체.GetStringValue()].AsEnumerable() .Where(r => r.Field("타워종류").Contains("inhibitor") || (r.Field("타워종류").Contains("turret") && r.Field("터렛티어").Contains("nexus"))); if (가져온정보.Count() == 0) { return; } DataTable 억제기데이터 = 가져온정보.CopyToDataTable(); DataTable 억제기리스폰정보 = new DataTable(); 억제기리스폰정보.Columns.Add("타워부서진팀"); 억제기리스폰정보.Columns.Add("파괴된라인"); 억제기리스폰정보.Columns.Add("넥서스타워"); 억제기리스폰정보.Columns.Add("타워위치"); 억제기리스폰정보.Columns.Add("남은시간(초)"); foreach (DataRow item in 억제기데이터.Rows) { int 젠타임 = Convert.ToInt32(item["경기시간(초)"]) + 300 - 경기시간; if (item["타워종류"].ToString() == "turret") { 젠타임 = Convert.ToInt32(item["경기시간(초)"]) + 180 - 경기시간; if (젠타임 >= 0 && 젠타임 < 181) { DataRow bufRow = 억제기리스폰정보.NewRow(); bufRow["타워부서진팀"] = item["타워부서진팀"].ToString(); bufRow["파괴된라인"] = item["파괴된라인"].ToString(); bufRow["남은시간(초)"] = 젠타임; bufRow["넥서스타워"] = item["넥서스타워"].ToString(); bufRow["타워위치"] = item["타워위치"].ToString(); 억제기리스폰정보.Rows.Add(bufRow); } } else { if (젠타임 >= 0 && 젠타임 < 301) { DataRow bufRow = 억제기리스폰정보.NewRow(); bufRow["타워부서진팀"] = item["타워부서진팀"].ToString(); bufRow["파괴된라인"] = item["파괴된라인"].ToString(); bufRow["남은시간(초)"] = 젠타임; bufRow["넥서스타워"] = ""; bufRow["타워위치"] = ""; 억제기리스폰정보.Rows.Add(bufRow); } } } if (mCallback != null && 억제기리스폰정보.Rows.Count != 0) { mCallback.억제기리스폰시간(억제기리스폰정보); } } catch (Exception ex) { } } void 한타딜량() { if (is한타딜량체크) { getDamageDealtForTeamFight(경기시간); if (mCallback != null) { mCallback.한타딜량실시간(한타초기딜량); } } else { 한타초기딜량 = null; } } int getGoldGapForPowerPlay(DBDefine.팀구분 오브젝트잡은팀, int 가져온초, int 킬시간) { int rtnValue = 0; //var subfilter1 = Builders.Filter.Eq("RequestGameID", DataManager.getInstance().mPlatformGameID); var subFilter2NowTime = MongoDB.Bson.Serialization.BsonSerializer.Deserialize("{'eventDocument.gameTime' : {$gt : " + (킬시간 - 1) * 1000 + ", $lt : " + 가져온초 * 1000 + "}}"); //var subFilter2KillTime = MongoDB.Bson.Serialization.BsonSerializer.Deserialize("{'eventDocument.gameTime' : {$lt : " + (킬시간 - 1) * 1000 + " }}"); //var filter1NowTime = Builders.Filter.And(subfilter1, subFilter2NowTime); var filter1NowTime = Builders.Filter.And(subFilter2NowTime); //var filter1KillTime = Builders.Filter.And(subfilter1, subFilter2KillTime); var projectionFilter = MongoDB.Bson.Serialization.BsonSerializer.Deserialize("{'eventDocument.teams' : 1 , 'eventDocument.gameTime' : 1 }"); /*List 바론킬시점documents = mDBClient.GetDatabase("datalol").GetCollection("stats_update") .Find(filter1KillTime) .Project(projectionFilter) .SortByDescending(x => x["sequenceIndex"]) .Limit(1) .ToList(); List 킬시점가져온팀데이터들 = 바론킬시점documents.Last()["eventDocument"].AsBsonDocument["teams"].AsBsonArray.ToList(); int 킬시점블루팀골드 = 킬시점가져온팀데이터들.Where(o => o["teamID"] == (int)DBDefine.팀구분.블루).ToList().Last()["totalGold"].ToInt32(); int 킬시점레드팀골드 = 킬시점가져온팀데이터들.Where(o => o["teamID"] == (int)DBDefine.팀구분.퍼플).ToList().Last()["totalGold"].ToInt32(); int 잡은시점골드차 = 0; if (오브젝트잡은팀 == DBDefine.팀구분.블루) { 잡은시점골드차 = 블루팀골드 - 레드팀골드; } else { 잡은시점골드차 = 레드팀골드 - 블루팀골드; } */ List 현재시점documents = mDBClient.GetDatabase("datalol").GetCollection("stats_update") .Find(filter1NowTime) .Project(projectionFilter) .SortByDescending(x => x["sequenceIndex"]) .ToList(); if (현재시점documents.Count > 2) { List 현재시점가져온팀데이터들 = 현재시점documents.First()["eventDocument"].AsBsonDocument["teams"].AsBsonArray.ToList(); List 바론킬가져온팀데이터들 = 현재시점documents.Last()["eventDocument"].AsBsonDocument["teams"].AsBsonArray.ToList(); int 현재블루팀골드 = 현재시점가져온팀데이터들.Where(o => o["teamID"] == (int)DBDefine.팀구분.블루).ToList().Last()["totalGold"].ToInt32(); int 현재레드팀골드 = 현재시점가져온팀데이터들.Where(o => o["teamID"] == (int)DBDefine.팀구분.퍼플).ToList().Last()["totalGold"].ToInt32(); int 바론킬블루팀골드 = 바론킬가져온팀데이터들.Where(o => o["teamID"] == (int)DBDefine.팀구분.블루).ToList().Last()["totalGold"].ToInt32(); int 바론킬레드팀골드 = 바론킬가져온팀데이터들.Where(o => o["teamID"] == (int)DBDefine.팀구분.퍼플).ToList().Last()["totalGold"].ToInt32(); int 현재골드차 = 0; int 킬시점골드차 = 0; if (오브젝트잡은팀 == DBDefine.팀구분.블루) { 현재골드차 = 현재블루팀골드 - 현재레드팀골드; 킬시점골드차 = 바론킬블루팀골드 - 바론킬레드팀골드; } else { 현재골드차 = 현재레드팀골드 - 현재블루팀골드; 킬시점골드차 = 바론킬레드팀골드 - 바론킬블루팀골드; } rtnValue = 현재골드차 - 킬시점골드차; } else if (현재시점documents.Count == 1) { } else { } return rtnValue; } int getGoldGapForPowerPlay(DBDefine.팀구분 오브젝트잡은팀, int 가져온초) { int rtnValue = 0; //var subfilter1 = Builders.Filter.Eq("RequestGameID", DataManager.getInstance().mPlatformGameID); var subFilter2 = MongoDB.Bson.Serialization.BsonSerializer.Deserialize("{'eventDocument.gameTime' : {$lt : " + 가져온초 * 1000 + " }}"); var filter1 = Builders.Filter.And(subFilter2); //var filter1 = Builders.Filter.And(subfilter1, subFilter2); var projectionFilter = MongoDB.Bson.Serialization.BsonSerializer.Deserialize("{'eventDocument.teams' : 1 , 'eventDocument.gameTime' : 1 }"); List documents = mDBClient.GetDatabase("datalol").GetCollection("stats_update") .Find(filter1) .Project(projectionFilter) .SortByDescending(x => x["sequenceIndex"]) .Limit(1) .ToList(); List 가져온팀데이터들 = documents.Last()["eventDocument"].AsBsonDocument["teams"].AsBsonArray.ToList(); int 블루팀골드 = 가져온팀데이터들.Where(o => o["teamID"] == (int)DBDefine.팀구분.블루).ToList().Last()["totalGold"].ToInt32(); int 레드팀골드 = 가져온팀데이터들.Where(o => o["teamID"] == (int)DBDefine.팀구분.퍼플).ToList().Last()["totalGold"].ToInt32(); if (오브젝트잡은팀 == DBDefine.팀구분.블루) { rtnValue = 블루팀골드 - 레드팀골드; } else { rtnValue = 레드팀골드 - 블루팀골드; } return rtnValue; } void getDamageDealtForTeamFight(int 가져온초) { //var subfilter1 = Builders.Filter.Eq("RequestGameID", DataManager.getInstance().mPlatformGameID); var subFilter2 = MongoDB.Bson.Serialization.BsonSerializer.Deserialize("{'eventDocument.gameTime' : {$lt : " + 가져온초 * 1000 + " }}"); var filter1 = Builders.Filter.And(subFilter2); //var filter1 = Builders.Filter.And(subfilter1, subFilter2); var projectionFilter = MongoDB.Bson.Serialization.BsonSerializer.Deserialize("{'eventDocument.participants' : 1 , 'eventDocument.gameTime' : 1 }"); List documents = mDBClient.GetDatabase("datalol").GetCollection("stats_update") .Find(filter1) .Project(projectionFilter) .SortByDescending(x => x["sequenceIndex"]) .Limit(1) .ToList(); List 가져온팀데이터들 = documents.Last()["eventDocument"].AsBsonDocument["participants"].AsBsonArray.ToList(); if (한타초기딜량 == null) { 한타초기딜량 = new DataTable(); 한타초기딜량.Columns.Add("팀"); 한타초기딜량.Columns.Add("아이디"); 한타초기딜량.Columns.Add("챔피언"); 한타초기딜량.Columns.Add("최초딜량"); 한타초기딜량.Columns.Add("현재딜량"); 한타초기딜량.Columns.Add("딜량차이"); 한타초기딜량.Columns.Add("딜량백분율"); 한타초기딜량.Columns.Add("생존여부"); foreach (BsonValue item in 가져온팀데이터들) { DataRow bufRow = 한타초기딜량.NewRow(); bufRow["팀"] = (DBDefine.팀구분)item["teamID"].ToInt32(); bufRow["아이디"] = item["playerName"].ToString(); bufRow["챔피언"] = item["championName"].ToString(); bufRow["생존여부"] = item["alive"].ToBoolean(); bufRow["딜량차이"] = 0; bufRow["딜량백분율"] = 0; bufRow["최초딜량"] = item["stats"].AsBsonArray.Where(r => r["name"] == "TOTAL_DAMAGE_DEALT_TO_CHAMPIONS").Last()["value"]; bufRow["현재딜량"] = item["stats"].AsBsonArray.Where(r => r["name"] == "TOTAL_DAMAGE_DEALT_TO_CHAMPIONS").Last()["value"]; 한타초기딜량.Rows.Add(bufRow); } } else { foreach (BsonValue item in 가져온팀데이터들) { DataRow bufRow = 한타초기딜량.AsEnumerable().Where(r => r.Field("아이디") == item["playerName"].ToString()).Last(); bufRow["현재딜량"] = item["stats"].AsBsonArray.Where(r => r["name"] == "TOTAL_DAMAGE_DEALT_TO_CHAMPIONS").Last()["value"]; bufRow["생존여부"] = item["alive"].ToBoolean(); bufRow["딜량차이"] = Convert.ToDouble(bufRow["현재딜량"]) - Convert.ToDouble(bufRow["최초딜량"]); } double 최대딜량 = Convert.ToDouble(한타초기딜량.AsEnumerable().OrderByDescending(r => Convert.ToDouble(r.Field("딜량차이"))).First()["딜량차이"]); foreach (DataRow item in 한타초기딜량.Rows) { double 딜량차이값 = Convert.ToDouble(item["딜량차이"]); if (딜량차이값 != 0) { item["딜량백분율"] = 딜량차이값 / 최대딜량 * 100.0; } else { item["딜량백분율"] = 0.0; } } } } #endregion } }