using MongoDB.Bson; using MongoDB.Driver; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LolDataRequestLib.ResponseData { internal class 골드차이팀 : AResponseData { protected override DataTable buildDataForResponse(BsonDocument recvDocument) { List bufPlayerDataList = null; if (recvDocument != null) { bufPlayerDataList = recvDocument.Elements.ToList(); } DataTable goldData = new DataTable(); goldData.TableName = DBDefine.요청데이터분류.골드차이팀.ToString(); goldData.Columns.Add("블루팀골드량"); goldData.Columns.Add("레드팀골드량"); goldData.Columns.Add("골드차"); goldData.Columns.Add("골드차블루최대"); goldData.Columns.Add("골드차레드최대"); goldData.Columns.Add("초"); int 골드차블루최대값 = 0; int 골드차레드최대값 = 0; foreach (BsonElement item in bufPlayerDataList) { DataRow bufRow = goldData.NewRow(); BsonArray itemValue = item.Value.ToBsonDocument()["teams"].AsBsonArray; int 블루팀골드 = 0; int 레드팀골드 = 0; foreach (BsonValue itemTeam in itemValue) { if (itemTeam["teamID"].ToInt32() == (int)DBDefine.팀구분.블루) { 블루팀골드 = itemTeam["totalGold"].ToInt32(); } else { 레드팀골드 = itemTeam["totalGold"].ToInt32(); } } bufRow["블루팀골드량"] = 블루팀골드; bufRow["레드팀골드량"] = 레드팀골드; bufRow["골드차"] = 블루팀골드 - 레드팀골드; if (골드차블루최대값 < (블루팀골드 - 레드팀골드)) { 골드차블루최대값 = (블루팀골드 - 레드팀골드); } if (골드차레드최대값 < (레드팀골드 - 블루팀골드)) { 골드차레드최대값 = (레드팀골드 - 블루팀골드); } bufRow["골드차블루최대"] = 골드차블루최대값; bufRow["골드차레드최대"] = 골드차레드최대값 * -1; bufRow["초"] = item.Value["gameTime"].ToInt32() / 1000; goldData.Rows.Add(bufRow); } return goldData; } protected override BsonDocument getDataFromMongo() { // 필요한 필드만 포함하는 필터 문서를 생성합니다. var subFilter = MongoDB.Bson.Serialization.BsonSerializer.Deserialize("{'eventDocument.playbackID' : 1, 'eventDocument.teams.totalGold' : 1, 'eventDocument.teams.teamID' : 1, 'eventDocument.sequenceIndex' : 1, " + "'eventDocument.gameTime' : 1, 'eventDocument.parentGameID': 1, 'eventDocument.repeater_timestamp': 1}"); //var subFilter = MongoDB.Bson.Serialization.BsonSerializer.Deserialize("{'eventDocument.playbackID' : 1, 'eventDocument.teams.totalGold' : 1, 'eventDocument.teams.teamID' : 1,'eventDocument.sequenceIndex' : 1, 'eventDocument.gameTime' : 1}"); // MongoDB 컬렉션 "stats_update"에서 전체 문서를 가져오고 필요한 필드만 Projection합니다. List documents = mEventDataBase.GetCollection("stats_update") .Find(new BsonDocument()) .Project(subFilter) .ToList(); //documents = documents.OrderBy(r => r["eventDocument"]["sequenceIndex"].ToInt32()).ToList(); documents = documents.OrderBy(r => DateTime.Parse(r["eventDocument"]["repeater_timestamp"].AsString)).ToList(); BsonDocument rtnValue = new BsonDocument(); // 이전 이벤트의 RequestGameID를 저장할 변수입니다. string previousRequestGameID = null; foreach (BsonDocument item in documents) { try { // 현재 이벤트의 RequestGameID 값을 추출합니다. string currentRequestGameID = item["eventDocument"]["parentGameID"].ToString(); // 롤백 상황 감지: // 이전 이벤트의 RequestGameID가 존재하고, 현재 이벤트의 값과 다르다면 // 이는 롤백 후 새로운 게임 데이터가 들어왔음을 의미합니다. if (previousRequestGameID != null && !currentRequestGameID.Equals(previousRequestGameID)) { // 현재 이벤트의 gameTime을 롤백 기준으로 설정합니다. int rollbackThreshold = item["eventDocument"]["gameTime"].ToInt32(); // 지금까지 모아둔 데이터(rtnValue) 중 gameTime이 rollbackThreshold 미만인 이벤트만 유지합니다. List filteredElements = rtnValue.ToList() .Where(d => d.Value["gameTime"].ToInt32() < rollbackThreshold) .ToList(); rtnValue = new BsonDocument(filteredElements); } // 현재 이벤트 정보를 새 BsonDocument로 준비합니다. BsonDocument bufDocument = new BsonDocument(); bufDocument.Add("gameTime", item["eventDocument"]["gameTime"].ToInt32()); bufDocument.Add("teams", item["eventDocument"]["teams"].AsBsonArray); bufDocument.Add("playback", item["eventDocument"]["playbackID"].ToString()); bufDocument.Add("parentGameID", item["eventDocument"]["parentGameID"]); // sequenceIndex 값을 Key로 하여 해당 이벤트를 rtnValue에 추가합니다. rtnValue.Add(item["eventDocument"]["sequenceIndex"].ToString(), bufDocument); // 다음 반복을 위해 이전 RequestGameID를 업데이트합니다. previousRequestGameID = currentRequestGameID; } catch(Exception ex) { Console.WriteLine(ex.Message); } } return rtnValue; } } }