Issues (1369)

classes/Fleet/FleetDispatchEvent.php (6 issues)

1
<?php /** @noinspection PhpUnnecessaryCurlyVarSyntaxInspection, PhpCastIsUnnecessaryInspection, PhpDeprecationInspection */
2
3
/** Created by Gorlum 27.10.2024 18:42 */
4
5
namespace Fleet;
6
7
use mysqli_result;
8
use Planet\DBStaticPlanet;
9
use SN;
10
11
/**
12
 * @property array      $fleet          Fleet on which event time happens
13
 * @property string     $eventTimeStamp When event happened in timeline
14
 * @property string     $event          Event type
15
 *
16
 * @property int        $fleetId
17
 * @property ?int       $srcPlanetId
18
 * @property bool|array $srcPlanetRow
19
 * @property ?int       $fleetOwnerId
20
 * @property ?int       $dstPlanetId
21
 * @property bool|array $dstPlanetRow
22
 * @property ?int       $dstPlanetOwnerId
23
 *
24
 * @property array      $missionInfoNew
25
 * @property int        $missionId
26
 */
27
class FleetDispatchEvent {
28
  const IS_ATTACK = 'isAttack';
29
  const IS_TRANSPORT = 'isTransport';
30
31
  const F_FLEET_ID = 'fleet_id';
32
  const F_FLEET_OWNER_ID = 'fleet_owner';
33
  const F_PLANET_ID = 'id';
34
  const F_PLANET_OWNER_ID = 'id_owner';
35
  const IS_LOCK_SOURCE = 'isLockSource';
36
37
  /** @var array[] $sn_groups_mission */
38
  public static $sn_groups_mission = [];
39
  /** @var int[] $userIdsToLock */
40
  public $userIdsToLock = [];
41
  /** @var int[] $planetIdsToLock */
42
  public $planetIdsToLock = [];
43
  /** @var int[] $fleetIdsToLock */
44
  public $fleetIdsToLock = [];
45
  /** @var int $processedIPR Processed IPR on this run */
46
  public static $processedIPR = -1;
47
48
  public static $MISSIONS = [
49
    MT_ATTACK    => [self::IS_TRANSPORT => false, self::IS_ATTACK => true,],
50
    MT_AKS       => [self::IS_TRANSPORT => false, self::IS_ATTACK => true,],
51
    MT_DESTROY   => [self::IS_TRANSPORT => false, self::IS_ATTACK => true,],
52
    MT_HOLD      => [self::IS_TRANSPORT => false,],
53
    MT_SPY       => [self::IS_TRANSPORT => false, self::IS_LOCK_SOURCE => true, 'AJAX' => true,],
54
    MT_TRANSPORT => [self::IS_TRANSPORT => true, self::IS_LOCK_SOURCE => true,],
55
    MT_RELOCATE  => [self::IS_TRANSPORT => true, self::IS_LOCK_SOURCE => true,],
56
    MT_RECYCLE   => [self::IS_TRANSPORT => false, 'AJAX' => true,],
57
    MT_EXPLORE   => [self::IS_TRANSPORT => false,],
58
    MT_COLONIZE  => [self::IS_TRANSPORT => true,],
59
    MT_MISSILE   => [self::IS_TRANSPORT => false, 'AJAX' => true,],
60
  ];
61
62
  public function __construct($fleetRow, $eventType) {
63
    if (empty(self::$sn_groups_mission)) {
64
      self::$sn_groups_mission = sn_get_groups('missions');
65
    }
66
67
    $this->event = $eventType;
68
    $this->fleet = $fleetRow;
69
70
    $this->fleetId = $fleetRow[self::F_FLEET_ID];
71
72
    $this->fleetOwnerId = $fleetRow[self::F_FLEET_OWNER_ID];
73
74
    $this->missionId      = (int)$this->fleet[FleetDispatcher::F_FLEET_MISSION];
75
    $this->missionInfoNew = self::$MISSIONS[$this->missionId];
76
77
    $this->eventTimeStamp = (int)$this->fleet[$this->event === EVENT_FLT_ARRIVE ? 'fleet_start_time' :
78
      ($this->event === EVENT_FLT_ACCOMPLISH ? 'fleet_end_stay' : /* EVENT_FLT_RETURN */
79
        'fleet_end_time')];
80
81
    /** @var Fleet $fleetObject */
82
    $fleetObject = (object)$this->fleet;
83
84
    // Always locking flying fleet and fleet owner
85
    $this->userIdsToLock   = [(int)$fleetObject->fleet_owner ?: 0 => true,];
0 ignored issues
show
Documentation Bug introduced by
It seems like array((int)$fleetObject-...eet_owner ?: 0 => true) of type array<integer,true> is incompatible with the declared type integer[] of property $userIdsToLock.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
86
    $this->fleetIdsToLock  = [(int)$fleetObject->fleet_id => true,];
0 ignored issues
show
Documentation Bug introduced by
It seems like array((int)$fleetObject->fleet_id => true) of type array<integer,true> is incompatible with the declared type integer[] of property $fleetIdsToLock.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
87
    $this->planetIdsToLock = [];
88
89
    // Some locks make sense only on specific event types
90
    if ($this->event === EVENT_FLT_RETURN) {
91
      // There is no means or ways how returning fleet can influence other planet(s) then starting one
92
      $isLockSource = true;
93
    } else {
94
      // Locking destination planet always
95
      // There are no means or sense to make a mission which does not affect destination planet
96
      $this->getDstPlanetRowFromFleet();
97
      // Locking dest planet
98
      $this->planetIdsToLock[$this->dstPlanetId] = true;
99
      // Locking destination planet always implies locking destination user
100
      // Locking planet owner ID
101
      $this->userIdsToLock[$this->dstPlanetOwnerId] = true;
102
103
      // If the fleet is a part of existing fleet group - locking also fleets in group and their respected owners
104
      // Only doing it for EVENT_FLT_ARRIVE - currently no other event types does trigger fleet group actions
105
      if (!empty($fleetObject->fleet_group) && $this->event === EVENT_FLT_ARRIVE) {
106
        $fleetGroupId = (int)$fleetObject->fleet_group;
107
        foreach (DbFleetStatic::db_fleet_list("`fleet_group` = {$fleetGroupId}") as $fleetInGroup) {
108
          $this->userIdsToLock[(int)$fleetInGroup[self::F_FLEET_OWNER_ID] ?: 0] = true;
109
          $this->fleetIdsToLock[(int)$fleetInGroup[self::F_FLEET_ID] ?: 0]      = true;
110
        }
111
      }
112
113
      // We may need to lock source planet/user for some extra info such as planet name/username, coordinates etc
114
      $isLockSource = !empty($this->missionInfoNew[self::IS_LOCK_SOURCE]);
115
    }
116
117
    if ($isLockSource) {
118
      $this->getSrcPlanetRowFromFleet();
119
      $this->planetIdsToLock[$this->srcPlanetId] = true;
120
      $this->userIdsToLock[$this->fleetOwnerId]  = true;
121
    }
122
123
    if (!empty($this->missionInfoNew[self::IS_ATTACK])) {
124
      $fleetsOnHold = DbFleetStatic::fleet_list_on_hold(
125
        $fleetObject->fleet_end_galaxy,
126
        $fleetObject->fleet_end_system,
127
        $fleetObject->fleet_end_planet,
128
        $fleetObject->fleet_end_type,
129
        $this->eventTimeStamp
130
      );
131
      foreach ($fleetsOnHold as $aFleet) {
132
        $this->userIdsToLock[(int)$aFleet[self::F_FLEET_OWNER_ID] ?: 0] = true;
133
        $this->fleetIdsToLock[(int)$aFleet[self::F_FLEET_ID] ?: 0]      = true;
134
      }
135
    }
136
137
    unset($this->userIdsToLock[0]);
138
    unset($this->planetIdsToLock[0]);
139
    unset($this->fleetIdsToLock[0]);
140
141
    $this->userIdsToLock   = array_keys($this->userIdsToLock);
142
    $this->planetIdsToLock = array_keys($this->planetIdsToLock);
143
    $this->fleetIdsToLock  = array_keys($this->fleetIdsToLock);
144
  }
145
146
  /**
147
   * LOCK - Lock all records which can be used with mission
148
   *
149
   * @return array|bool|mysqli_result|null
150
   */
151
  public function lockEventRecords() {
152
    $locks = [];
153
154
    if (!empty($this->userIdsToLock)) {
155
      $locks['users'] = $this->userIdsToLock;
156
    }
157
    if (!empty($this->planetIdsToLock)) {
158
      $locks['planets'] = $this->planetIdsToLock;
159
    }
160
    if (!empty($this->fleetIdsToLock)) {
161
      $locks['fleets'] = $this->fleetIdsToLock;
162
    }
163
    return SN::$gc->db->lockRecords($locks);
164
  }
165
166
  public static function sortEvents(&$eventList) {
167
    uasort($eventList, function (FleetDispatchEvent $a, FleetDispatchEvent $b) {
168
      return
169
        // Сравниваем время флотов - кто раньше, тот и первый обрабатывается
170
          $a->eventTimeStamp > $b->eventTimeStamp ? 1 : ($a->eventTimeStamp < $b->eventTimeStamp ? -1 :
171
          // Если время - одинаковое, сравниваем события флотов
172
          // Если события - одинаковые, то флоты равны
173
          ($a->event == $b->event ? 0 :
174
            // Если события разные - первыми считаем прибывающие флоты
175
            ($a->event == EVENT_FLT_ARRIVE ? 1 : ($b->event == EVENT_FLT_ARRIVE ? -1 :
176
              // Если нет прибывающих флотов - дальше считаем флоты, которые закончили миссию
177
              ($a->event == EVENT_FLT_ACCOMPLISH ? 1 : ($b->event == EVENT_FLT_ACCOMPLISH ? -1 :
178
                // Если нет флотов, закончивших задание - остались возвращающиеся флоты, которые равны между собой
179
                // TODO: Добавить еще проверку по ID флота и/или времени запуска - что бы обсчитывать их в порядке запуска
180
                (
181
                0 // Вообще сюда доходить не должно - будет отсекаться на равенстве событий
182
                )
183
              ))
184
            ))
185
          )
186
        );
187
    });
188
  }
189
190
  /**
191
   */
192
  public function refreshMissionData() {
193
    if (!empty($this->srcPlanetId) && !empty($this->fleetOwnerId)) {
194
//       $this->srcPlanetRow = DBStaticPlanet::db_planet_by_vector($this->fleet, 'fleet_start_');
195
      $updateResult = sys_o_get_updated($this->fleetOwnerId, $this->srcPlanetId, $this->eventTimeStamp);
0 ignored issues
show
$this->eventTimeStamp of type string is incompatible with the type integer expected by parameter $UpdateTime of sys_o_get_updated(). ( Ignorable by Annotation )

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

195
      $updateResult = sys_o_get_updated($this->fleetOwnerId, $this->srcPlanetId, /** @scrutinizer ignore-type */ $this->eventTimeStamp);
Loading history...
196
197
      $this->updateSrcPlanetRow($updateResult['planet']);
198
    }
199
200
    if (!empty($this->dstPlanetId) && !empty($this->dstPlanetOwnerId)) {
201
      $updateResult = sys_o_get_updated($this->dstPlanetOwnerId, $this->dstPlanetId, $this->eventTimeStamp);
202
203
      $this->updateDstPlanetRow($updateResult['planet']);
204
    }
205
  }
206
207
  /**
208
   * @return array|false
209
   */
210
  public function refreshFleet() {
211
    return $this->fleet = DbFleetStatic::db_fleet_get($this->fleetId);
0 ignored issues
show
Documentation Bug introduced by
It seems like Fleet\DbFleetStatic::db_fleet_get($this->fleetId) can also be of type false. However, the property $fleet is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
212
  }
213
214
  public function getSrcPlanetRowFromFleet() {
215
    $this->srcPlanetRow = DBStaticPlanet::db_planet_by_vector($this->fleet, 'fleet_start_');
216
217
    $this->updateSrcPlanetRow($this->srcPlanetRow);
0 ignored issues
show
It seems like $this->srcPlanetRow can also be of type boolean; however, parameter $srcPlanetRow of Fleet\FleetDispatchEvent::updateSrcPlanetRow() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

217
    $this->updateSrcPlanetRow(/** @scrutinizer ignore-type */ $this->srcPlanetRow);
Loading history...
218
219
    return $this->srcPlanetRow;
220
  }
221
222
  /**
223
   * @param array $srcPlanetRow
224
   *
225
   * @return array|bool
226
   */
227
  public function updateSrcPlanetRow($srcPlanetRow) {
228
//    $this->srcPlanetRow = is_array($srcPlanetRow) ? $srcPlanetRow : DBStaticPlanet::db_planet_by_vector($this->fleet, 'fleet_start_');
229
    $this->srcPlanetRow = $srcPlanetRow;
230
231
    $this->srcPlanetId = !empty($this->srcPlanetRow[self::F_PLANET_ID]) ? (int)$this->srcPlanetRow[self::F_PLANET_ID] : 0;
232
    // Starting planet can change owner while fleet mission - and even change planet ID
233
    // It can happen due to teleport shenanigans or because of planet capturing (in certain game modes)
234
    $this->fleetOwnerId = !empty($this->srcPlanetRow[self::F_PLANET_OWNER_ID]) ? (int)$this->srcPlanetRow[self::F_PLANET_OWNER_ID] : $this->fleetOwnerId;
235
236
    return $this->srcPlanetRow;
237
  }
238
239
240
  public function getDstPlanetRowFromFleet() {
241
    $this->dstPlanetRow = DBStaticPlanet::db_planet_by_vector($this->fleet, 'fleet_end_');
242
243
    $this->updateDstPlanetRow($this->dstPlanetRow);
0 ignored issues
show
It seems like $this->dstPlanetRow can also be of type boolean; however, parameter $dstPlanetRow of Fleet\FleetDispatchEvent::updateDstPlanetRow() does only seem to accept array|null, maybe add an additional type check? ( Ignorable by Annotation )

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

243
    $this->updateDstPlanetRow(/** @scrutinizer ignore-type */ $this->dstPlanetRow);
Loading history...
244
245
    return $this->dstPlanetRow;
246
  }
247
248
  /**
249
   * @param ?array $dstPlanetRow
250
   *
251
   * @return array|bool|null
252
   */
253
  public function updateDstPlanetRow($dstPlanetRow = null) {
254
    $this->dstPlanetRow = $dstPlanetRow;
255
256
    $this->dstPlanetId = !empty($this->dstPlanetRow[self::F_PLANET_ID]) ? (int)$this->dstPlanetRow[self::F_PLANET_ID] : 0;
257
    // Retrieving destination owner ID
258
    $this->dstPlanetOwnerId = !empty($this->dstPlanetRow[self::F_PLANET_OWNER_ID]) ? (int)$this->dstPlanetRow[self::F_PLANET_OWNER_ID] : 0;
259
260
    return $this->dstPlanetRow;
261
  }
262
263
}
264