OSDN Git Service

敵艦のIDが古いテストを通すための細工を削除する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / Sniffer.cs
index 3f1c320..32ca509 100644 (file)
@@ -23,7 +23,7 @@ namespace KancolleSniffer
         private bool _start;\r
         private readonly ItemInfo _itemInfo = new ItemInfo();\r
         private readonly MaterialInfo _materialInfo = new MaterialInfo();\r
-        private readonly QuestInfo _questInfo = new QuestInfo();\r
+        private readonly QuestInfo _questInfo;\r
         private readonly MissionInfo _missionInfo = new MissionInfo();\r
         private readonly ShipInfo _shipInfo;\r
         private readonly ConditionTimer _conditionTimer;\r
@@ -33,12 +33,23 @@ namespace KancolleSniffer
         private readonly BattleInfo _battleInfo;\r
         private readonly Logger _logger;\r
         private readonly ExMapInfo _exMapInfo = new ExMapInfo();\r
-        private readonly MiscTextInfo _miscTextInfo = new MiscTextInfo();\r
+        private readonly MiscTextInfo _miscTextInfo;\r
         private readonly BaseAirCoprs _baseAirCoprs;\r
+        private readonly PresetDeck _presetDeck = new PresetDeck();\r
         private readonly Status _status = new Status();\r
         private bool _saveState;\r
         private readonly List<IHaveState> _haveState;\r
 \r
+        public interface IRepeatingTimerController\r
+        {\r
+            void Stop(string key);\r
+            void Stop(string key, int fleet);\r
+            void Suspend();\r
+            void Resume();\r
+        }\r
+\r
+        public IRepeatingTimerController RepeatingTimerController { get; set; }\r
+\r
         [Flags]\r
         public enum Update\r
         {\r
@@ -55,19 +66,22 @@ namespace KancolleSniffer
             All = (1 << 9) - 1\r
         }\r
 \r
-        public Sniffer()\r
+        public Sniffer(bool start = false)\r
         {\r
+            _start = start;\r
             _shipInfo = new ShipInfo(_itemInfo);\r
             _conditionTimer = new ConditionTimer(_shipInfo);\r
             _dockInfo = new DockInfo(_shipInfo, _materialInfo);\r
-            _akashiTimer = new AkashiTimer(_shipInfo, _dockInfo);\r
+            _akashiTimer = new AkashiTimer(_shipInfo, _dockInfo, _presetDeck);\r
             _battleInfo = new BattleInfo(_shipInfo, _itemInfo);\r
             _logger = new Logger(_shipInfo, _itemInfo, _battleInfo);\r
+            _questInfo = new QuestInfo(_itemInfo, _battleInfo);\r
             _baseAirCoprs = new BaseAirCoprs(_itemInfo);\r
-            _haveState = new List<IHaveState> {_achievement, _materialInfo, _conditionTimer, _exMapInfo};\r
+            _miscTextInfo = new MiscTextInfo(_shipInfo, _itemInfo);\r
+            _haveState = new List<IHaveState> {_achievement, _materialInfo, _conditionTimer, _exMapInfo, _questInfo};\r
         }\r
 \r
-        private void SaveState()\r
+        public void SaveState()\r
         {\r
             if (!_saveState)\r
                 return;\r
@@ -100,13 +114,14 @@ namespace KancolleSniffer
             }\r
             if (!_start)\r
                 return Update.None;\r
+\r
             if (url.EndsWith("api_port/port"))\r
                 return ApiPort(data);\r
             if (url.Contains("member"))\r
                 return ApiMember(url, json);\r
             if (url.Contains("kousyou"))\r
                 return ApiKousyou(url, request, data);\r
-            if (url.Contains("battle"))\r
+            if (url.Contains("battle") || url.Contains("sortie"))\r
                 return ApiBattle(url, request, data);\r
             return ApiOthers(url, request, data);\r
         }\r
@@ -117,6 +132,7 @@ namespace KancolleSniffer
             _missionInfo.InspectMaster(data.api_mst_mission);\r
             _itemInfo.InspectMaster(data);\r
             _exMapInfo.ResetIfNeeded();\r
+            _miscTextInfo.InspectMaster(data);\r
             _start = true;\r
             return Update.Start;\r
         }\r
@@ -124,25 +140,31 @@ namespace KancolleSniffer
         private Update ApiPort(dynamic data)\r
         {\r
             _itemInfo.InspectBasic(data.api_basic);\r
-            _materialInfo.InspectMaterial(data.api_material, true);\r
+            _materialInfo.InspectMaterialPort(data.api_material);\r
             _logger.InspectBasic(data.api_basic);\r
             _logger.InspectMaterial(data.api_material);\r
             _shipInfo.InspectShip(data);\r
             _shipInfo.ClearBadlyDamagedShips();\r
             _conditionTimer.CalcRegenTime();\r
             _missionInfo.InspectDeck(data.api_deck_port);\r
+            _questInfo.InspectDeck(data.api_deck_port);\r
             _dockInfo.InspectNDock(data.api_ndock);\r
             _akashiTimer.Port();\r
             _achievement.InspectBasic(data.api_basic);\r
             if (data.api_parallel_quest_count()) // 昔のログにはないので\r
-                _questInfo.QuestCount = (int)data.api_parallel_quest_count;\r
+                _questInfo.AcceptMax = (int)data.api_parallel_quest_count;\r
             if (data.api_event_object())\r
                 _baseAirCoprs.InspectEventObject(data.api_event_object);\r
+            if (data.api_plane_info())\r
+                _baseAirCoprs.InspectPlaneInfo(data.api_plane_info);\r
             _battleInfo.CleanupResult();\r
-            _battleInfo.InBattle = false;\r
+            _battleInfo.BattleState = BattleState.None;\r
             _shipInfo.ClearEscapedShips();\r
-            _miscTextInfo.ClearIfNeeded();\r
+            _miscTextInfo.Port();\r
             SaveState();\r
+            RepeatingTimerController?.Resume();\r
+            foreach (var s in new[] {"遠征終了", "入渠終了", "疲労回復", "泊地修理"})\r
+                RepeatingTimerController?.Stop(s);\r
             return Update.All;\r
         }\r
 \r
@@ -154,7 +176,7 @@ namespace KancolleSniffer
             {\r
                 _itemInfo.InspectSlotItem(data.api_slot_item, true);\r
                 _dockInfo.InspectKDock(data.api_kdock);\r
-                return Update.Timer;\r
+                return Update.None;\r
             }\r
             if (url.EndsWith("api_get_member/basic"))\r
             {\r
@@ -178,6 +200,7 @@ namespace KancolleSniffer
                 _dockInfo.InspectNDock(data);\r
                 _conditionTimer.CheckCond();\r
                 _akashiTimer.CheckFleet();\r
+                RepeatingTimerController?.Stop("入渠終了");\r
                 return Update.NDock | Update.Timer | Update.Ship;\r
             }\r
             if (url.EndsWith("api_get_member/questlist"))\r
@@ -190,6 +213,7 @@ namespace KancolleSniffer
                 _shipInfo.InspectDeck(data);\r
                 _missionInfo.InspectDeck(data);\r
                 _akashiTimer.CheckFleet();\r
+                _questInfo.InspectDeck(data);\r
                 return Update.Mission | Update.Timer;\r
             }\r
             if (url.EndsWith("api_get_member/ship2"))\r
@@ -197,14 +221,14 @@ namespace KancolleSniffer
                 // ここだけjsonなので注意\r
                 _shipInfo.InspectShip(json);\r
                 _akashiTimer.CheckFleet();\r
-                _battleInfo.InBattle = false;\r
+                _battleInfo.BattleState = BattleState.None;\r
                 return Update.Item | Update.Ship | Update.Battle;\r
             }\r
             if (url.EndsWith("api_get_member/ship_deck"))\r
             {\r
                 _shipInfo.InspectShip(data);\r
                 _akashiTimer.CheckFleet();\r
-                _battleInfo.InBattle = false;\r
+                _battleInfo.BattleState = BattleState.None;\r
                 return Update.Ship | Update.Battle;\r
             }\r
             if (url.EndsWith("api_get_member/ship3"))\r
@@ -223,6 +247,8 @@ namespace KancolleSniffer
             {\r
                 _exMapInfo.InspectMapInfo(data);\r
                 _miscTextInfo.InspectMapInfo(data);\r
+                if (data.api_air_base())\r
+                    _baseAirCoprs.Inspect(data.api_air_base);\r
                 return Update.Item;\r
             }\r
             if (url.EndsWith("api_req_member/get_practice_enemyinfo"))\r
@@ -232,7 +258,7 @@ namespace KancolleSniffer
             }\r
             if (url.EndsWith("api_get_member/preset_deck"))\r
             {\r
-                _shipInfo.InspectPresetDeck(data);\r
+                _presetDeck.Inspect(data);\r
                 return Update.None;\r
             }\r
             if (url.EndsWith("api_get_member/base_air_corps"))\r
@@ -250,7 +276,8 @@ namespace KancolleSniffer
                 _itemInfo.InspectCreateItem(data);\r
                 _materialInfo.InspectCreateIem(data);\r
                 _logger.InspectCreateItem(request, data);\r
-                return Update.Item;\r
+                _questInfo.CountCreateItem();\r
+                return Update.Item | Update.QuestList;\r
             }\r
             if (url.EndsWith("api_req_kousyou/getship"))\r
             {\r
@@ -258,6 +285,7 @@ namespace KancolleSniffer
                 _shipInfo.InspectShip(data);\r
                 _dockInfo.InspectKDock(data.api_kdock);\r
                 _conditionTimer.CheckCond();\r
+                RepeatingTimerController?.Stop("建造完了");\r
                 return Update.Item | Update.Timer;\r
             }\r
             if (url.EndsWith("api_req_kousyou/destroyship"))\r
@@ -266,13 +294,15 @@ namespace KancolleSniffer
                 _materialInfo.InspectDestroyShip(data);\r
                 _conditionTimer.CheckCond();\r
                 _akashiTimer.CheckFleet();\r
-                return Update.Item | Update.Ship;\r
+                _questInfo.InspectDestroyShip(request);\r
+                return Update.Item | Update.Ship | Update.QuestList;\r
             }\r
             if (url.EndsWith("api_req_kousyou/destroyitem2"))\r
             {\r
+                _questInfo.InspectDestroyItem(request, data); // 本当に削除される前\r
                 _itemInfo.InspectDestroyItem(request, data);\r
                 _materialInfo.InspectDestroyItem(data);\r
-                return Update.Item;\r
+                return Update.Item | Update.QuestList;\r
             }\r
             if (url.EndsWith("api_req_kousyou/remodel_slot"))\r
             {\r
@@ -280,12 +310,14 @@ namespace KancolleSniffer
                 _logger.InspectRemodelSlot(request, data); // 資材の差が必要なので_materialInfoより前\r
                 _itemInfo.InspectRemodelSlot(data);\r
                 _materialInfo.InspectRemodelSlot(data);\r
-                return Update.Item;\r
+                _questInfo.CountRemodelSlot();\r
+                return Update.Item | Update.QuestList;\r
             }\r
             if (url.EndsWith("api_req_kousyou/createship"))\r
             {\r
                 _logger.InspectCreateShip(request);\r
-                return Update.None;\r
+                _questInfo.CountCreateShip();\r
+                return Update.QuestList;\r
             }\r
             if (url.EndsWith("api_req_kousyou/createship_speedchange"))\r
             {\r
@@ -297,9 +329,9 @@ namespace KancolleSniffer
 \r
         private Update ApiBattle(string url, string request, dynamic data)\r
         {\r
-            if (IsNormalBattleAPI(url))\r
+            if (IsNormalBattleAPI(url) || IsCombinedBattleAPI(url))\r
             {\r
-                _battleInfo.InspectBattle(data, url);\r
+                _battleInfo.InspectBattle(url, request, data);\r
                 _logger.InspectBattle(data);\r
                 return Update.Ship | Update.Battle;\r
             }\r
@@ -309,40 +341,32 @@ namespace KancolleSniffer
                 {\r
                     _shipInfo.InspectMapStart(request); // 演習を出撃中とみなす\r
                     _conditionTimer.InvalidateCond();\r
-                    _miscTextInfo.ClearFlag = true;\r
+                    RepeatingTimerController?.Suspend();\r
                 }\r
-                _battleInfo.InspectBattle(data, url);\r
+                _battleInfo.InspectBattle(url, request, data);\r
                 return Update.Ship | Update.Battle | Update.Timer;\r
             }\r
-            if (url.EndsWith("api_req_sortie/battleresult"))\r
+            if (url.EndsWith("api_req_sortie/battleresult") || url.EndsWith("api_req_combined_battle/battleresult"))\r
             {\r
                 _battleInfo.InspectBattleResult(data);\r
                 _exMapInfo.InspectBattleResult(data);\r
                 _logger.InspectBattleResult(data);\r
-                return Update.Ship;\r
+                _questInfo.InspectBattleResult(data);\r
+                _miscTextInfo.InspectBattleResult(data);\r
+                return Update.Ship | Update.QuestList;\r
             }\r
             if (url.EndsWith("api_req_practice/battle_result"))\r
             {\r
                 _battleInfo.InspectPracticeResult(data);\r
-                return Update.Ship;\r
+                _questInfo.InspectPracticeResult(data);\r
+                return Update.Ship | Update.QuestList;\r
             }\r
-            if (IsCombinedBattleAPI(url))\r
+            if (url.EndsWith("/goback_port"))\r
             {\r
-                _battleInfo.InspectCombinedBattle(data, url);\r
-                _logger.InspectBattle(data);\r
-                return Update.Ship | Update.Battle;\r
-            }\r
-            if (url.EndsWith("api_req_combined_battle/battleresult"))\r
-            {\r
-                _battleInfo.InspectCombinedBattleResult(data);\r
-                _logger.InspectBattleResult(data);\r
-                return Update.Ship;\r
-            }\r
-            if (url.EndsWith("api_req_combined_battle/goback_port"))\r
-            {\r
-                _battleInfo.CauseCombinedBattleEscape();\r
+                _battleInfo.CauseEscape();\r
                 return Update.Ship;\r
             }\r
+            _battleInfo.BattleState = BattleState.Unknown;\r
             return Update.None;\r
         }\r
 \r
@@ -362,7 +386,12 @@ namespace KancolleSniffer
                    url.EndsWith("api_req_combined_battle/ld_airbattle") ||\r
                    url.EndsWith("api_req_combined_battle/battle_water") ||\r
                    url.EndsWith("api_req_combined_battle/midnight_battle") ||\r
-                   url.EndsWith("api_req_combined_battle/sp_midnight");\r
+                   url.EndsWith("api_req_combined_battle/sp_midnight") ||\r
+                   url.EndsWith("api_req_combined_battle/ec_battle") ||\r
+                   url.EndsWith("api_req_combined_battle/ec_midnight_battle") ||\r
+                   url.EndsWith("api_req_combined_battle/ec_night_to_day") ||\r
+                   url.EndsWith("api_req_combined_battle/each_battle") ||\r
+                   url.EndsWith("api_req_combined_battle/each_battle_water");\r
         }\r
 \r
         private Update ApiOthers(string url, string request, dynamic data)\r
@@ -381,12 +410,12 @@ namespace KancolleSniffer
             }\r
             if (url.EndsWith("api_req_hensei/preset_register"))\r
             {\r
-                _shipInfo.InspectPresetRegister(data);\r
+                _presetDeck.InspectRegister(data);\r
                 return Update.None;\r
             }\r
             if (url.EndsWith("api_req_hensei/preset_delete"))\r
             {\r
-                _shipInfo.InspectPresetDelete(request);\r
+                _presetDeck.InspectDelete(request);\r
                 return Update.Timer;\r
             }\r
             if (url.EndsWith("api_req_hensei/combined"))\r
@@ -398,14 +427,16 @@ namespace KancolleSniffer
             {\r
                 _shipInfo.InspectCharge(data);\r
                 _materialInfo.InspectCharge(data);\r
-                return Update.Item | Update.Ship;\r
+                _questInfo.CountCharge();\r
+                return Update.Item | Update.Ship | Update.QuestList;\r
             }\r
             if (url.EndsWith("api_req_kaisou/powerup"))\r
             {\r
                 _shipInfo.InspectPowerup(request, data);\r
                 _conditionTimer.CheckCond();\r
                 _akashiTimer.CheckFleet();\r
-                return Update.Item | Update.Ship;\r
+                _questInfo.InspectPowerup(data);\r
+                return Update.Item | Update.Ship | Update.QuestList;\r
             }\r
             if (url.EndsWith("api_req_kaisou/slot_exchange_index"))\r
             {\r
@@ -422,34 +453,51 @@ namespace KancolleSniffer
                 _dockInfo.InspectNyukyo(request);\r
                 _conditionTimer.CheckCond();\r
                 _akashiTimer.CheckFleet();\r
-                return Update.Item | Update.Ship;\r
+                _questInfo.CountNyukyo();\r
+                var ndock = HttpUtility.ParseQueryString(request)["api_ndock_id"];\r
+                if (ndock != null && int.TryParse(ndock, out int id))\r
+                    RepeatingTimerController?.Stop("入渠終了", id - 1);\r
+                return Update.Item | Update.Ship | Update.QuestList;\r
             }\r
             if (url.EndsWith("api_req_nyukyo/speedchange"))\r
             {\r
                 _dockInfo.InspectSpeedChange(request);\r
                 _conditionTimer.CheckCond();\r
-                return Update.NDock | Update.Timer | Update.Ship;\r
+                return Update.NDock | Update.Timer | Update.Item | Update.Ship;\r
             }\r
             if (url.EndsWith("api_req_map/start"))\r
             {\r
                 _shipInfo.InspectMapStart(request); // 出撃中判定が必要なので_conditionTimerより前\r
                 _conditionTimer.InvalidateCond();\r
                 _exMapInfo.InspectMapStart(data);\r
+                _battleInfo.InspectMapStart(data);\r
                 _logger.InspectMapStart(data);\r
-                _miscTextInfo.ClearFlag = true;\r
+                _miscTextInfo.SortieStarted = true;\r
+                _questInfo.InspectMapStart(data);\r
+                RepeatingTimerController?.Suspend();\r
                 return Update.Timer | Update.Ship;\r
             }\r
             if (url.EndsWith("api_req_map/next"))\r
             {\r
-                _battleInfo.InspectMapNext(request);\r
                 _exMapInfo.InspectMapNext(data);\r
+                _battleInfo.InspectMapNext(data);\r
                 _logger.InspectMapNext(data);\r
+                _questInfo.InspectMapNext(data);\r
+                _miscTextInfo.InspectMapNext(data);\r
+                return Update.None;\r
+            }\r
+            if (url.EndsWith("api_req_mission/start"))\r
+            {\r
+                var deck = HttpUtility.ParseQueryString(request)["api_deck_id"];\r
+                if (deck != null && int.TryParse(deck, out int id))\r
+                    RepeatingTimerController?.Stop("遠征終了", id - 1);\r
                 return Update.None;\r
             }\r
             if (url.EndsWith("api_req_mission/result"))\r
             {\r
                 _materialInfo.InspectMissionResult(data);\r
                 _logger.InspectMissionResult(data);\r
+                _questInfo.InspectMissionResult(request, data);\r
                 return Update.Item;\r
             }\r
             if (url.EndsWith("api_req_quest/stop"))\r
@@ -460,6 +508,7 @@ namespace KancolleSniffer
             if (url.EndsWith("api_req_quest/clearitemget"))\r
             {\r
                 _questInfo.InspectClearItemGet(request);\r
+                _logger.InspectClearItemGet(data);\r
                 return Update.QuestList;\r
             }\r
             if (url.EndsWith("api_req_air_corps/supply"))\r
@@ -479,12 +528,17 @@ namespace KancolleSniffer
                 _baseAirCoprs.InspectSetAction(request);\r
                 return Update.Ship;\r
             }\r
+            if (url.EndsWith("api_req_air_corps/expand_base"))\r
+            {\r
+                _baseAirCoprs.InspectExpandBase(request, data);\r
+                return Update.Ship;\r
+            }\r
             return Update.None;\r
         }\r
 \r
         public NameAndTimer[] NDock => _dockInfo.NDock;\r
 \r
-        public RingTimer[] KDock => _dockInfo.KDock;\r
+        public AlarmTimer[] KDock => _dockInfo.KDock;\r
 \r
         public ItemInfo Item => _itemInfo;\r
 \r
@@ -492,16 +546,26 @@ namespace KancolleSniffer
 \r
         public QuestStatus[] Quests => _questInfo.Quests;\r
 \r
+        public void ClearQuests() => _questInfo.ClearQuests();\r
+\r
         public NameAndTimer[] Missions => _missionInfo.Missions;\r
 \r
         public DateTime GetConditionTimer(int fleet) => _conditionTimer.GetTimer(fleet);\r
 \r
-        public int[] GetConditionNotice() => _conditionTimer.GetNotice();\r
+        public int[] GetConditionNotice(DateTime prev, DateTime now) => _conditionTimer.GetNotice(prev, now);\r
 \r
         public ShipStatus[] GetShipStatuses(int fleet) => _shipInfo.GetShipStatuses(fleet);\r
 \r
         public int[] GetDeck(int fleet) => _shipInfo.GetDeck(fleet);\r
 \r
+        public bool[] InSortie => _shipInfo.InSortie;\r
+\r
+        public ShipInfo.ShipStatusPair[] BattleResultStatusDiff => _shipInfo.BattleResultDiff;\r
+\r
+        public bool IsBattleResultStatusError => _shipInfo.IsBattleResultError;\r
+\r
+        public ShipStatus[] BattleStartStatus => _shipInfo.BattleStartStatus;\r
+\r
         public int CombinedFleetType => _shipInfo.CombinedFleetType;\r
 \r
         public ChargeStatus[] ChargeStatuses => _shipInfo.ChargeStatuses;\r
@@ -510,7 +574,7 @@ namespace KancolleSniffer
 \r
         public double GetContactTriggerRate(int fleet) => _shipInfo.GetContactTriggerRate(fleet);\r
 \r
-        public double GetFleetLineOfSights(int fleet) => _shipInfo.GetLineOfSights(fleet);\r
+        public double GetFleetLineOfSights(int fleet, int factor) => _shipInfo.GetLineOfSights(fleet, factor);\r
 \r
         public ShipStatus[] RepairList => _shipInfo.GetRepairList(_dockInfo);\r
 \r
@@ -518,6 +582,10 @@ namespace KancolleSniffer
 \r
         public string[] BadlyDamagedShips => _shipInfo.BadlyDamagedShips;\r
 \r
+        public double GetDaihatsuBonus(int fleet) => _shipInfo.GetDaihatsuBonus(fleet);\r
+\r
+        public double GetTransportPoint(int fleet) => _shipInfo.GetTransportPoint(fleet);\r
+\r
         public ItemStatus[] ItemList\r
         {\r
             get\r
@@ -539,7 +607,7 @@ namespace KancolleSniffer
 \r
         public string MiscText => _miscTextInfo.Text;\r
 \r
-        public BaseAirCoprs.AirCorpsInfo[] BaseAirCorps => _baseAirCoprs.AirCorps;\r
+        public BaseAirCoprs.BaseInfo[] BaseAirCorps => _baseAirCoprs.AllAirCorps;\r
 \r
         public void SetLogWriter(Action<string, string, string> writer, Func<DateTime> nowFunc)\r
         {\r
@@ -558,73 +626,17 @@ namespace KancolleSniffer
 \r
         public int MaterialLogInterval\r
         {\r
-            set { _logger.MaterialLogInterval = value; }\r
+            set => _logger.MaterialLogInterval = value;\r
         }\r
 \r
         public string LogOutputDir\r
         {\r
-            set { _logger.OutputDir = value; }\r
+            set => _logger.OutputDir = value;\r
         }\r
-    }\r
 \r
-    public class NameAndTimer\r
-    {\r
-        public string Name { get; set; }\r
-        public RingTimer Timer { get; set; }\r
-\r
-        public NameAndTimer()\r
+        public void FlashLog()\r
         {\r
-            Timer = new RingTimer();\r
+            _logger.FlashLog();\r
         }\r
     }\r
-\r
-    public class RingTimer\r
-    {\r
-        private readonly TimeSpan _spare;\r
-\r
-        public TimeSpan Rest { get; private set; }\r
-\r
-        public bool IsFinished => EndTime != DateTime.MinValue && Rest <= _spare;\r
-\r
-        public DateTime EndTime { get; private set; }\r
-\r
-        public bool NeedRing { get; set; }\r
-\r
-        public RingTimer(int spare = 60)\r
-        {\r
-            _spare = TimeSpan.FromSeconds(spare);\r
-        }\r
-\r
-        public void SetEndTime(double time)\r
-        {\r
-            SetEndTime((int)time == 0\r
-                ? DateTime.MinValue\r
-                : new DateTime(1970, 1, 1).ToLocalTime().AddSeconds(time / 1000));\r
-        }\r
-\r
-        public void SetEndTime(DateTime time)\r
-        {\r
-            EndTime = time;\r
-        }\r
-\r
-        public void Update()\r
-        {\r
-            if (EndTime == DateTime.MinValue)\r
-            {\r
-                Rest = TimeSpan.Zero;\r
-                return;\r
-            }\r
-            var prev = Rest;\r
-            Rest = EndTime - DateTime.Now;\r
-            if (Rest < TimeSpan.Zero)\r
-                Rest = TimeSpan.Zero;\r
-            if (prev > _spare && _spare >= Rest)\r
-                NeedRing = true;\r
-        }\r
-\r
-        public string ToString(bool finish = false)\r
-            => EndTime == DateTime.MinValue\r
-                ? ""\r
-                : finish ? EndTime.ToString(@"dd\ HH\:mm") : $@"{(int)Rest.TotalHours:d2}:{Rest:mm\:ss}";\r
-    }\r
 }
\ No newline at end of file