Issues (1369)

classes/Fleet/FleetDispatcher.php (3 issues)

1
<?php /** @noinspection PhpUnnecessaryCurlyVarSyntaxInspection */
2
/** @noinspection PhpDeprecationInspection */
3
4
/**
5
 * Created by Gorlum 15.06.2017 4:12
6
 */
7
8
namespace Fleet;
9
10
use Core\Scheduler\Lock;
11
use DBAL\db_mysql;
12
use SN;
13
use debug;
14
use classConfig;
15
use Core\GlobalContainer;
16
17
/**
18
 * Class Fleet\FleetDispatcher
19
 *
20
 */
21
class FleetDispatcher {
22
  const TASK_COMPLETE = 0;
23
//  const TASK_TERMINATED = 1;
24
25
//  const F_FLEET_EVENT = 'fleet_event';
26
  const F_FLEET_MISSION = 'fleet_mission';
27
//  /** @var array[] $fleet_list */
28
//  public static $fleet_list = [];
29
  /** @var FleetDispatchEvent[] $fleet_event_list */
30
  public static $fleet_event_list = [];
31
  /** @var int[] $missions_used */
32
  public $missions_used = [];
33
  /**
34
   * @var GlobalContainer $gc
35
   */
36
  protected $gc;
37
38
  /**
39
   * @var classConfig $gameConfig
40
   */
41
  protected $gameConfig;
42
43
  /**
44
   * @var debug $debug
45
   */
46
  protected $debug;
47
48
  public function __construct(GlobalContainer $gc) {
49
    $this->gc = $gc;
50
51
    $this->gameConfig = $gc->config;
52
    $this->debug      = $gc->debug;
53
  }
54
55
//  /**
56
//   * @deprecated
57
//   */
58
//  public function dispatch() {
59
//    if (
60
//      SN::$options[PAGE_OPTION_FLEET_UPDATE_SKIP]
61
//      ||
62
//      SN::gameIsDisabled()
63
//      ||
64
//      !$this->getLockOld()
65
//    ) {
66
//      return;
67
//    }
68
//
69
//    $this->flt_flying_fleet_handler();
70
//
71
//    $this->releaseLock();
72
//
73
//    set_time_limit(60);
74
//  }
75
76
77
  /**
78
   * @return bool
79
   * @deprecated
80
   */
81
  protected function getLockOld() {
82
    db_mysql::db_transaction_start();
83
84
    // Watchdog timer
85
    if ($this->gameConfig->db_loadItem('fleet_update_lock')) {
86
//      var_dump($this->gameConfig->db_loadItem('fleet_update_lock'));
87
//      var_dump(SN_TIME_NOW - strtotime($this->gameConfig->fleet_update_lock));
88
//      if (SN_TIME_NOW - strtotime($this->gameConfig->fleet_update_lock) <= mt_rand(90, 120)) {
89
      if (SN_TIME_NOW - strtotime($this->gameConfig->fleet_update_lock) <= mt_rand(20, 40)) {
90
        db_mysql::db_transaction_rollback();
91
92
        return false;
93
      } else {
94
        $this->debug->warning('Fleet dispatcher was locked too long - watchdog unlocked', 'FFH Error', 504);
95
      }
96
    }
97
98
    $this->gameConfig->db_saveItem('fleet_update_last', SN_TIME_SQL);
99
    $this->gameConfig->db_saveItem('fleet_update_lock', SN_TIME_SQL);
100
    db_mysql::db_transaction_commit();
101
102
    return true;
103
  }
104
105
  /**
106
   * @deprecated
107
   */
108
  protected function releaseLock() {
109
    db_mysql::db_transaction_start();
110
    $this->gameConfig->db_saveItem('fleet_update_lock', '');
111
    db_mysql::db_transaction_commit();
112
  }
113
114
115
  // ------------------------------------------------------------------
116
117
  /**
118
   * @return int|int[]
119
   */
120
  public function flt_flying_fleet_handler() {
121
//    $this->log_file('Dispatch started');
122
    $watchdog = new FleetWatchdog();
123
    if (($result = $watchdog->acquireLock()) == FleetWatchdog::TASK_ALREADY_LOCKED) {
124
      return $result;
125
    }
126
127
    $result = ['code' => self::TASK_COMPLETE];
128
129
    set_time_limit(max(3, SN::$gc->config->fleet_update_max_run_time - 3));
130
131
    //log_file('Начинаем обсчёт флотов');
132
133
//    $this->log_file('Обсчёт ракет');
134
    FleetDispatchEvent::$processedIPR = coe_o_missile_calculate();
135
136
    // Filling self::$fleet_event_list with FleetDispatchEvent
137
    self::$fleet_event_list = $this->getFleetEvents();
138
    $this->loadMissionFiles();
139
140
    $sn_groups_mission = sn_get_groups('missions');
0 ignored issues
show
The assignment to $sn_groups_mission is dead and can be removed.
Loading history...
141
    foreach (self::$fleet_event_list as $fleetEvent) {
142
      $result['code'] = $watchdog->begin($fleetEvent);
143
      if ($result['code'] === FleetWatchdog::TASK_TOO_LONG) {
144
        $result['message'] = $watchdog->getTerminationMessage();
145
        break;
146
      } elseif ($result['code'] === FleetWatchdog::FLEET_IS_EMPTY) {
147
        continue;
148
      }
149
150
      db_mysql::db_transaction_start();
151
      // Locking further fleet dispatcher tasks
152
      SN::$gc->config->pass()->fleet_update_last = date(FMT_DATE_TIME_SQL, time());
153
154
      // Locking all event-related records
155
      $fleetEvent->lockEventRecords();
156
157
      // Refreshing fleet record
158
      if (empty($fleetEvent->refreshFleet())) {
159
        // Fleet was destroyed in course of previous actions
160
        db_mysql::db_transaction_commit();
161
        continue;
162
      } elseif ($fleetEvent->event == EVENT_FLT_RETURN && $fleetEvent->fleet['fleet_mess'] == FLEET_STATUS_RETURNING) {
163
        // Fleet returns to planet
164
        RestoreFleetToPlanet($fleetEvent->fleet, true, false, true);
0 ignored issues
show
Deprecated Code introduced by
The function RestoreFleetToPlanet() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

164
        /** @scrutinizer ignore-deprecated */ RestoreFleetToPlanet($fleetEvent->fleet, true, false, true);
Loading history...
165
        db_mysql::db_transaction_commit();
166
        continue;
167
      } elseif ($fleetEvent->event == EVENT_FLT_ARRIVE && $fleetEvent->fleet['fleet_mess'] != FLEET_STATUS_FLYING) {
168
        // При событии EVENT_FLT_ARRIVE флот всегда должен иметь fleet_mess == 0 / FLEET_STATUS_FLYING
169
        // В противном случае это означает, что флот уже был обработан ранее - например, при САБе
170
        db_mysql::db_transaction_commit();
171
        continue;
172
      }
173
174
      // From now on we have only events of types [EVENT_FLT_ARRIVE, EVENT_FLT_ACCOMPLISH] and $fleet_row['fleet_mess'] == FLEET_STATUS_FLYING (0)
175
176
      // Here we refresh dstPlanetRow (by calling sys_o_get_updated() and using its result - so below this call we will have actual dst planet/dst user records
177
      // In same vein we refresh srcPlanetRow
178
      $fleetEvent->refreshMissionData();
179
180
      switch ($fleetEvent->missionId) {
181
        // Для боевых атак нужно обновлять по САБу и по холду - таки надо возвращать данные из обработчика миссий!
182
        case MT_ATTACK:
183
        case MT_AKS:
184
        case MT_DESTROY:
185
          flt_mission_attack($fleetEvent);
186
        break;
187
188
        case MT_TRANSPORT:
189
          flt_mission_transport($fleetEvent);
190
        break;
191
192
        case MT_HOLD:
193
          flt_mission_hold($fleetEvent);
194
        break;
195
196
        case MT_RELOCATE:
197
          flt_mission_relocate($fleetEvent);
198
        break;
199
200
        case MT_EXPLORE:
201
          $outcome = new MissionExploreResult();
202
          $outcome->flt_mission_explore($fleetEvent);
203
        break;
204
205
        case MT_RECYCLE:
206
          flt_mission_recycle($fleetEvent);
207
        break;
208
209
        case MT_COLONIZE:
210
          flt_mission_colonize($fleetEvent);
211
        break;
212
213
        case MT_SPY:
214
          require_once(SN_ROOT_PHYSICAL . 'includes/includes/coe_simulator_helpers.php');
215
216
          $theMission = MissionEspionage::buildFromArray($fleetEvent);
217
          $theMission->flt_mission_spy();
218
219
          unset($theMission);
220
        break;
221
222
        case MT_MISSILE:  // Missiles !!
223
        break;
224
225
//      default:
226
//        doquery("DELETE FROM `{{fleets}}` WHERE `fleet_id` = '{$fleet_row['fleet_id']}' LIMIT 1;");
227
//      break;
228
      }
229
      db_mysql::db_transaction_commit();
230
    }
231
232
    $watchdog->unlock();
233
234
//    $that->log_file('Dispatch finished - NORMAL SHUTDOWN');
235
236
    return $result;
237
  }
238
239
  /**
240
   * @param $workTime
241
   * @param $eventsProcessed
242
   * @param $lastMissionId
243
   * @param $lastEventId
244
   * @param $lastEventLength
245
   * @param $totalEvents
246
   */
247
  public function logTermination($workTime, $eventsProcessed, $lastMissionId, $lastEventId, $lastEventLength, $totalEvents) {
248
    SN::$debug->warning(sprintf(
0 ignored issues
show
The method warning() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

248
    SN::$debug->/** @scrutinizer ignore-call */ 
249
                warning(sprintf(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
249
      'Flying fleet handler works %1$s (> %2$s) seconds - skip rest. Processed %3$d / %7$d events. Last event: mission %4$s event %6$s (%5$ss)',
250
      number_format($workTime, 4),
251
      SN::$config->fleet_update_dispatch_time,
252
      $eventsProcessed,
253
      $lastMissionId ? SN::$lang['type_mission'][$lastMissionId] : '!TERMINATED BY TIMEOUT!',
254
      number_format($lastEventLength, 4),
255
      $lastEventId ? SN::$lang['fleet_events'][$lastEventId] : '!TERMINATED BY TIMEOUT!',
256
      $totalEvents
257
    ),
258
      'FFH Warning',
259
      504
260
    );
261
  }
262
263
  /**
264
   * @return Lock
265
   */
266
  public function buildLock() {
267
    return new Lock($this->gc, classConfig::FLEET_UPDATE_RUN_LOCK, SN::$gc->config->fleet_update_max_run_time, 1, classConfig::DATE_TYPE_UNIX);
268
  }
269
270
  public function getFleetEvents() {
271
    $fleet_event_list = [];
272
273
    // Gets active fleets on current tick for Flying Fleet Handler
274
    $fleet_list_current_tick = DbFleetStatic::db_fleet_list(
275
      "
276
        (`fleet_start_time` <= " . SN_TIME_NOW . " AND `fleet_mess` = 0)
277
        OR
278
        (`fleet_end_stay` <= " . SN_TIME_NOW . " AND `fleet_end_stay` > 0 AND `fleet_mess` = 0)
279
        OR
280
        (`fleet_end_time` <= " . SN_TIME_NOW . ")
281
      ", DB_SELECT_PLAIN
282
    );
283
284
    foreach ($fleet_list_current_tick as $fleet_row) {
285
      if ($fleet_row['fleet_start_time'] <= SN_TIME_NOW && $fleet_row['fleet_mess'] == 0) {
286
        $fleet_event_list[] = new FleetDispatchEvent($fleet_row, EVENT_FLT_ARRIVE);
287
      }
288
289
      if ($fleet_row['fleet_end_stay'] > 0 && $fleet_row['fleet_end_stay'] <= SN_TIME_NOW && $fleet_row['fleet_mess'] == 0) {
290
        $fleet_event_list[] = new FleetDispatchEvent($fleet_row, EVENT_FLT_ACCOMPLISH);
291
      }
292
293
      if ($fleet_row['fleet_end_time'] <= SN_TIME_NOW) {
294
        $fleet_event_list[] = new FleetDispatchEvent($fleet_row, EVENT_FLT_RETURN);
295
      }
296
297
      $this->missions_used[$fleet_row[self::F_FLEET_MISSION]] = 1;
298
    }
299
300
    FleetDispatchEvent::sortEvents($fleet_event_list);
301
302
    return $fleet_event_list;
303
  }
304
305
  /**
306
   * @return void
307
   */
308
  public function loadMissionFiles() {
309
    $mission_files = [
310
      MT_ATTACK  => 'flt_mission_attack',
311
      MT_AKS     => 'flt_mission_attack',
312
      MT_DESTROY => 'flt_mission_attack',
313
314
      MT_TRANSPORT => 'flt_mission_transport',
315
      MT_RELOCATE  => 'flt_mission_relocate',
316
      MT_HOLD      => 'flt_mission_hold',
317
      MT_SPY       => '',
318
      MT_COLONIZE  => 'flt_mission_colonize',
319
      MT_RECYCLE   => 'flt_mission_recycle',
320
      // MT_MISSILE => 'flt_mission_missile.php',
321
      // MT_EXPLORE   => 'flt_mission_explore',
322
    ];
323
    foreach ($this->missions_used as $mission_id => $cork) {
324
      if (!empty($mission_files[$mission_id])) {
325
        require_once(SN_ROOT_PHYSICAL . "includes/includes/{$mission_files[$mission_id]}" . DOT_PHP_EX);
326
      }
327
    }
328
  }
329
330
  /**
331
   * @param string $msg
332
   *
333
   * @noinspection PhpUnused
334
   */
335
  public function log_file($msg) {
336
    file_put_contents(__DIR__ . '/../../.ffh-event.log', date(FMT_DATE_TIME_SQL, time()) . ' ' . $msg . "\r\n", FILE_APPEND);
337
  }
338
339
}
340