/// <summary> /// Перехват события когда что-то было уничтожено, получило повреждения или только что создано /// </summary> public void UIEventChange(Thing thing, bool distroy = false, bool newSpawn = false) { Loger.Log("HostAttackUpdate UIEventChange " + thing.GetType().ToString() + " " + thing.Label + " id=" + thing.thingIDNumber + (distroy ? " distroy!" : "") + (newSpawn ? " newSpawn!" : "")); var tId = thing.thingIDNumber; lock (ToSendListsSync) { if (distroy) { if (!ToSendDeleteId.Contains(tId)) { ToSendDeleteId.Add(tId); } } else if (newSpawn) { ToSendThingAdd.Add(thing); } else { if (!ToUpdateStateId.Contains(tId)) { ToUpdateStateId.Add(tId); ToUpdateState.Add(thing); } } } }
/// <summary> /// Перехват события когда что-то было уничтожено, получило повреждения или только что создано /// </summary> public void UIEventChange(Thing thing, bool distroy = false, bool newSpawn = false) { Loger.Log("HostAttackUpdate UIEventChange " + thing.GetType().ToString() + " " + thing.Label + " id=" + thing.thingIDNumber + (distroy ? " distroy!" : "") + (newSpawn ? " newSpawn!" : "") + (thing is Corpse ? " Corpse" : "")); var tId = thing.thingIDNumber; lock (ToSendListsSync) { if (distroy) { if (!ToSendDeleteId.Contains(tId)) { ToSendDeleteId.Add(tId); } } else if (newSpawn) { if (thing is Corpse && (thing as Corpse).InnerPawn != null) { //трупы обрабатываем отдельно: передаем труп не как объект, а как редактирование состояния пешки - // она сама станет трупом + после изменеия состояния удалить из словарей, чтобы её не удалили // (да ID созданного трупа будет не синхронизированно, но считаем что с ними ничего не будут делать) //todo здесь, а также изменить у атакующего: когда пришла команда удалить пешку, то // задержать команду на 1 цикл (новый массив) var corpse = thing as Corpse; ToSendNewCorpse.Add(corpse.InnerPawn); } else { ToSendThingAdd.Add(thing); } } else { if (!ToUpdateStateId.Contains(tId)) { ToUpdateStateId.Add(tId); ToUpdateState.Add(thing); } } } }
private void AttackUpdate() { bool inTimerEvent = false; try { if (InTimer) { return; } InTimer = true; AttackUpdateTick++; // Loger.Log("Client HostAttackUpdate #" + AttackUpdateTick.ToString()); SessionClientController.Command((connect) => { try { List <Pawn> mapPawns; AttackHostFromSrv toClient; lock (ToSendListsSync) { // Loger.Log("Client HostAttackUpdate 1"); //обновляем списки mapPawns = GameMap.mapPawns.AllPawnsSpawned; var mapPawnsId = new HashSet <int>(mapPawns.Select(p => p.thingIDNumber)); mapPawnsId.SymmetricExceptWith(SendedPawnsId); //новые пешки + те что на сервере, но их уже нет на карте if (mapPawnsId.Count > 0) { var toSendAddId = new HashSet <int>(mapPawnsId); toSendAddId.ExceptWith(SendedPawnsId); //только новые пешки if (toSendAddId.Count > 0) { toSendAddId.ExceptWith(ToSendAddId); //исключаем те, которые уже есть в списке ToSendAddId.AddRange(toSendAddId); } var toSendDeleteId = new HashSet <int>(mapPawnsId); toSendDeleteId.IntersectWith(SendedPawnsId); //только те, что на сервере но их уже нет на карте if (toSendDeleteId.Count > 0) { toSendDeleteId.ExceptWith(ToSendDeleteId); //исключаем те, которые уже есть в списке ToSendDeleteId.AddRange(toSendDeleteId); } } //посылаем пакеты с данными // Loger.Log("Client HostAttackUpdate 2"); var newPawns = new List <ThingEntry>(); var newPawnsId = new List <int>(); int cnt = ToSendAddId.Count < 3 || ToSendAddId.Count > 6 || AttackUpdateTick == 0 ? ToSendAddId.Count : 3; int i = 0; int[] added = new int[cnt]; foreach (int id in ToSendAddId) { if (i >= cnt) { break; } added[i++] = id; var thing = mapPawns.Where(p => p.thingIDNumber == id).FirstOrDefault(); var tt = ThingEntry.CreateEntry(thing, 1); //передаем те, что были исходные у атакуемого (хотя там используется только как признак TransportID != 0 - значит те кто атакует) if (AttackingPawnDic.ContainsKey(tt.OriginalID)) { tt.TransportID = AttackingPawnDic[tt.OriginalID]; } newPawns.Add(tt); newPawnsId.Add(id); } for (i = 0; i < cnt; i++) { ToSendAddId.Remove(added[i]); SendedPawnsId.Add(added[i]); } foreach (int id in ToSendDeleteId) { SendedPawnsId.Remove(id); } //вещи var newThings = ToSendThingAdd .Where(thing => !ToSendDeleteId.Any(d => thing.thingIDNumber == d)) .Select(thing => ThingEntry.CreateEntry(thing, thing.stackCount)) .ToList(); //передаем изменение местоположения и пр. по ID хоста var toSendState = new List <AttackThingState>(); var toSendStateId = new List <int>(); for (int imp = 0; imp < mapPawns.Count; imp++) { var mp = mapPawns[imp]; var mpID = mp.thingIDNumber; if (ToUpdateStateId.Contains(mpID)) { continue; } var mpHash = AttackThingState.GetHash(mp); int mpHS; if (!SendedState.TryGetValue(mpID, out mpHS) || mpHS != mpHash) { SendedState[mpID] = mpHash; toSendState.Add(new AttackThingState(mp)); } } for (int imp = 0; imp < ToUpdateState.Count; imp++) { var mp = ToUpdateState[imp]; var mpID = mp.thingIDNumber; if (ToSendDeleteId.Contains(mpID)) { continue; } if (mp is Pawn) { var mpHash = AttackThingState.GetHash(mp); SendedState[mpID] = mpHash; //заносим только для проверки выше } toSendState.Add(new AttackThingState(mp)); } //обновляем поколения вещей учавствующих в Job и отправляем нужные foreach (var mp in ThingPrepareChange0) { var mpID = mp.thingIDNumber; if (ToSendDeleteId.Contains(mpID)) { continue; } toSendState.Add(new AttackThingState(mp)); } Loger.Log("HostAttackUpdate UpdateCommand FromJob Count=" + ThingPrepareChange0.Count.ToString()); ThingPrepareChange0 = ThingPrepareChange1; ThingPrepareChange1 = new HashSet <Thing>(); //Loger.Log("Client HostAttackUpdate 3"); toClient = connect.AttackOnlineHost(new AttackHostToSrv() { State = 10, NewPawns = newPawns, NewPawnsId = newPawnsId, NewThings = newThings, NewThingsId = newThings.Select(th => th.OriginalID).ToList(), Delete = ToSendDeleteId.ToList(), UpdateState = toSendState }); ToSendThingAdd.Clear(); ToSendDeleteId.Clear(); ToUpdateStateId.Clear(); ToUpdateState.Clear(); } //принимаем обновление команд атакующих if (toClient.UpdateCommand.Count > 0) { Loger.Log("HostAttackUpdate UpdateCommand Count=" + toClient.UpdateCommand.Count.ToString()); UIEventNewJobDisable = true; for (int ii = 0; ii < toClient.UpdateCommand.Count; ii++) { var comm = toClient.UpdateCommand[ii]; var pawn = mapPawns.Where(p => p.thingIDNumber == comm.HostPawnID).FirstOrDefault() as Pawn; if (pawn == null) { Loger.Log("HostAttackUpdate UpdateCommand pawn == null " + comm.HostPawnID.ToString()); continue; } AttackingPawnJobDic[comm.HostPawnID] = comm; ApplyAttackingPawnJob(pawn); } UIEventNewJobDisable = false; } // Loger.Log("Client HostAttackUpdate 4"); } catch (Exception ext) { InTimer = false; Loger.Log("HostAttackUpdate Event Exception " + ext.ToString()); } finally { InTimer = false; } }); } catch (Exception ext) { Loger.Log("HostAttackUpdate Exception " + ext.ToString()); } if (!inTimerEvent) { InTimer = false; } }