public void Restore(GameBackupModel backup) { if (GameStatus != GameStatusType.Created) { throw new Exception("Нельзя восстановить игру, так как она уже была запущена."); } StoredEvents.AddRange(backup.StoredEvents); GameStatus = backup.GameStatus; LaunchTime = backup.LaunchTime; EndTime = backup.EndTime; foreach (var td in backup.TeamProgress) { LocalTeam team = Teams.Single(x => x.Id == td.Key); team.Progress = new TeamGameProgress( Config.Grid[Teams.IndexOf(team)], td.Value.LastHintTime, td.Value.LastTaskCompleteTime, td.Value.CurrentTaskIndex ); } NewEvents.Add(new GameRestored(DateTime.Now)); SendBroadcastMessage("Игра была восстановлена после перезапуска"); }
private void GetEvents(ref MySqlCommand cmd) { try { if (ServerMajorVersion >= 5.1) { // Edited by Niemand //cmd.commandText = "SHOW EVENTS WHERE Db LIKE '" + DatabaseName + "';"; cmd.CommandText = "SHOW EVENTS WHERE UPPER(TRIM(Db))=UPPER(TRIM('" + DatabaseName + "'));"; DataTable dtEvents = new DataTable(); MySqlDataAdapter daEvents = new MySqlDataAdapter(cmd); daEvents.Fill(dtEvents); daEvents = null; foreach (DataRow dr in dtEvents.Rows) { cmd.CommandText = "SHOW CREATE EVENT `" + dr[1].ToString() + "`;"; MySqlDataAdapter daEventCur = new MySqlDataAdapter(cmd); DataTable dtEventCur = new DataTable(); daEventCur.Fill(dtEventCur); daEventCur = null; string createSql = ""; object ob = dtEventCur.Rows[0][3]; if (ob is String) { createSql = ob + ""; } // It has been reported that, in some unknown cases, the query will return // byte array. // Report: http://www.codeproject.com/Messages/4450086/Small-changes-in-Code.aspx else if (ob is Byte[]) { var enc = new UTF8Encoding(); createSql = enc.GetString((byte[])ob); } createSql = createSql.Replace("\r\n", "^^^^").Replace("\n", "\r\n").Replace("^^^^", "\r\n"); StoredEvents.Add(dr[1].ToString(), createSql); } } } catch { // Purposely do nothing. // Trap exception that raised due to restriction of user privilege // The MySQL User used in this connection is not allowed to access Events // Clear and Reset Collection StoredEvents.Clear(); } }
/// <summary> /// Обрабатывает один фрейм игры, на текущий момент времени. /// </summary> public void Iterate() { if (GameStatus != GameStatusType.InProgress && GameStatus != GameStatusType.Stopped) { return; } lock (_locker) { // Запоминаем время начала итерации DateTime curTime = DateTime.Now; int eventsCount = NewEvents.Count; // STEP 1: Обрабатываем все ивенты (если они есть) if (eventsCount > 0) { // Получаем список ивентов, обрабатываемый на текущей итерации List <GameEvent> processedEvents = NewEvents.GetRange(0, eventsCount).OrderBy(x => x.AddDate).ToList(); NewEvents.RemoveRange(0, eventsCount); // Выполняем каждый ивент foreach (GameEvent currentEvent in processedEvents) { currentEvent.Run(this); } // Добавляем все обработанные ивенты в список StoredEvents.AddRange(processedEvents); } // STEP 2: Добавляем новые ивенты, если прошло необходимое время (подсказка, слив адреса, слив задания) if (GameStatus != GameStatusType.Stopped) { foreach (LocalTeam t in Teams) { // Получение первого задания, если прошло достаточно времени и команда еще не начала играть. if (t.Progress == null) { if (curTime > ((DateTime)LaunchTime).AddSeconds(Setting.SecondsDelayStart * Teams.IndexOf(t))) { NewEvents.Add(new TeamStartsPlay(curTime, t.Id)); } continue; } if (t.Progress.IsAllTaskCompleted()) { continue; } // Кол-во секунд, прошедшее со сдачи последнего задания double lastCompleteTaskSec = curTime.Subtract(t.Progress.LastTaskCompleteTime).TotalSeconds; // Кол-во секунд, прошедшее с получения последней подсказки double lastHintSec = curTime.Subtract(t.Progress.LastHintTime).TotalSeconds; // ... сливаем задание if (lastCompleteTaskSec > (Setting.TaskDropDelaySec + Setting.Hint2DelaySec + Setting.Hint1DelaySec)) { NewEvents.Add(new TeamDropTask(curTime, t.Id, t.Progress.CurrentTaskIndex)); } // ... сливаем адрес else if (lastCompleteTaskSec > (Setting.Hint2DelaySec + Setting.Hint1DelaySec) && lastHintSec > Setting.Hint2DelaySec) { NewEvents.Add(new TeamGetAddress(curTime, t.Id, t.Progress.CurrentTaskIndex)); } // ... сливаем подсказку else if (lastCompleteTaskSec > (Setting.Hint1DelaySec) && lastHintSec > Setting.Hint1DelaySec) { NewEvents.Add(new TeamGetHint(curTime, t.Id, t.Progress.CurrentTaskIndex)); } } } // STEP 3: Анализируем пришедшие сообщения от пользователей и добавляем новые ивенты List <Message> inputMessages = Noticer.PullInput(); foreach (Message m in inputMessages) { LocalTeam playerTeam = Teams.First(x => x.Id == m.Player.TeamId); if (playerTeam.Progress == null) { m.Player.SendMessage(Noticer, $"Ваша команда еще не получила первое задание."); continue; } if (playerTeam.Progress.GetCurrentTask() == null) { m.Player.SendMessage(Noticer, $"Ваша команда уже выполнила все задания."); continue; } switch (m.Text) { case "задание": m.Player.SendMessage(Noticer, $"Какая-то подсказка."); continue; } if (playerTeam.Progress.GetCurrentTask().Code == m.Text) { NewEvents.Add(new PlayerCompletedTask(curTime, playerTeam.Id, m.Player.Id, playerTeam.Progress.CurrentTaskIndex)); } else { NewEvents.Add(new PlayerFailedTask(curTime, playerTeam.Id, m.Player.Id, playerTeam.Progress.CurrentTaskIndex)); } } // STEP 4: Завершение игры // Переводим игру в статус "останавливается", если пришло время конца игры. if (GameStatus == GameStatusType.InProgress && curTime.Subtract((DateTime)LaunchTime).TotalMinutes > Setting.GameDurationMin) { NewEvents.Add(new GameStopped(DateTime.Now)); } // Если после остановки игры прошло необходимое кол-во минут - завершаем игру. if (GameStatus == GameStatusType.Stopped && EndTime != null && curTime > EndTime?.AddMinutes(Setting.GameClosingDurationMin)) { GameStatus = GameStatusType.Ended; SendBroadcastMessage("Приём кодов завершён."); } } }
public void Save(StoredEvents theEvent) { _dbSet.InsertOne(theEvent); }