Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Failed Conditions
Push — main ( d9cfb9...10f5c7 )
by Dan
32s queued 21s
created

Bounty::getClaimableByPlayer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 10
nc 2
nop 2
dl 0
loc 13
rs 9.9332
c 1
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Smr;
4
5
use AbstractSmrPlayer;
6
use Exception;
7
use SmrPlayer;
8
9
class Bounty {
10
11
	/**
12
	 * Returns a list of all active (not claimable) bounties for given location $type.
13
	 *
14
	 * @return array<self>
15
	 */
16
	public static function getMostWanted(BountyType $type, int $gameID): array {
17
		$db = Database::getInstance();
18
		$dbResult = $db->read('SELECT * FROM bounty WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND type =' . $db->escapeString($type->value) . ' AND claimer_id = 0 ORDER BY amount DESC');
19
		$bounties = [];
20
		foreach ($dbResult->records() as $dbRecord) {
21
			$bounties[] = self::getFromRecord($dbRecord);
22
		}
23
		return $bounties;
24
	}
25
26
	/**
27
	 * Get bounties that have been placed on this player.
28
	 *
29
	 * @return array<int, self>
30
	 */
31
	public static function getPlacedOnPlayer(AbstractSmrPlayer $player): array {
32
		$db = Database::getInstance();
33
		$dbResult = $db->read('SELECT * FROM bounty WHERE ' . $player->getSQL());
34
		$bounties = [];
35
		foreach ($dbResult->records() as $dbRecord) {
36
			// Recall that bounty_id is only unique to a given player
37
			$bounties[$dbRecord->getInt('bounty_id')] = self::getFromRecord($dbRecord);
38
		}
39
		return $bounties;
40
	}
41
42
	/**
43
	 * Get bounties that can be claimed by this player.
44
	 *
45
	 * @return array<self>
46
	 */
47
	public static function getClaimableByPlayer(AbstractSmrPlayer $player, ?BountyType $type = null): array {
48
		$db = Database::getInstance();
49
		$query = 'SELECT * FROM bounty WHERE claimer_id=' . $db->escapeNumber($player->getAccountID()) . ' AND game_id=' . $db->escapeNumber($player->getGameID());
50
		$query .= match ($type) {
51
			null => '',
52
			default => ' AND type=' . $db->escapeString($type->value),
53
		};
54
		$dbResult = $db->read($query);
55
		$bounties = [];
56
		foreach ($dbResult->records() as $dbRecord) {
57
			$bounties[] = self::getFromRecord($dbRecord);
58
		}
59
		return $bounties;
60
	}
61
62
	public static function getFromRecord(DatabaseRecord $record): self {
63
		return new self(
64
			targetID: $record->getInt('account_id'),
65
			bountyID: $record->getInt('bounty_id'),
66
			gameID: $record->getInt('game_id'),
67
			type: BountyType::from($record->getString('type')),
68
			time: $record->getInt('time'),
69
			claimerID: $record->getInt('claimer_id'),
70
			credits: $record->getInt('amount'),
71
			smrCredits: $record->getInt('smr_credits'),
72
			hasChanged: false,
73
		);
74
	}
75
76
	public function __construct(
77
		public readonly int $targetID, // target account ID
78
		public readonly int $bountyID, // only unique to the target
79
		public readonly int $gameID,
80
		public readonly BountyType $type,
81
		public readonly int $time,
82
		private int $claimerID = 0, // claimer account ID (or 0)
83
		private int $credits = 0,
84
		private int $smrCredits = 0,
85
		private bool $hasChanged = true,
86
	) {}
87
88
	public function getCredits(): int {
89
		return $this->credits;
90
	}
91
92
	public function getSmrCredits(): int {
93
		return $this->smrCredits;
94
	}
95
96
	public function isActive(): bool {
97
		return $this->claimerID == 0;
98
	}
99
100
	public function setClaimable(int $claimerID): void {
101
		if (!$this->isActive()) {
102
			throw new Exception('This bounty has already been claimed!');
103
		}
104
		$this->claimerID = $claimerID;
105
		$this->hasChanged = true;
106
	}
107
108
	public function setClaimed(): void {
109
		$this->setCredits(0);
110
		$this->setSmrCredits(0);
111
	}
112
113
	private function setCredits(int $credits): void {
114
		if ($this->credits == $credits) {
115
			return;
116
		}
117
		$this->credits = $credits;
118
		$this->hasChanged = true;
119
	}
120
121
	private function setSmrCredits(int $smrCredits): void {
122
		if ($this->smrCredits == $smrCredits) {
123
			return;
124
		}
125
		$this->smrCredits = $smrCredits;
126
		$this->hasChanged = true;
127
	}
128
129
	public function increaseCredits(int $credits): void {
130
		if ($credits < 0) {
131
			throw new Exception('Cannot increase by a negative amount');
132
		}
133
		$this->setCredits($this->credits + $credits);
134
	}
135
136
	public function increaseSmrCredits(int $smrCredits): void {
137
		if ($smrCredits < 0) {
138
			throw new Exception('Cannot increase by a negative amount');
139
		}
140
		$this->setSmrCredits($this->smrCredits + $smrCredits);
141
	}
142
143
	public function getTargetPlayer(): AbstractSmrPlayer {
144
		return SmrPlayer::getPlayer($this->targetID, $this->gameID);
145
	}
146
147
	/**
148
	 * @return bool Whether or not the database was updated
149
	 */
150
	public function update(): bool {
151
		if (!$this->hasChanged) {
152
			return false;
153
		}
154
		$db = Database::getInstance();
155
		if ($this->credits > 0 || $this->smrCredits > 0) {
156
			$db->replace('bounty', [
157
				'account_id' => $db->escapeNumber($this->targetID),
158
				'bounty_id' => $db->escapeNumber($this->bountyID),
159
				'game_id' => $db->escapeNumber($this->gameID),
160
				'type' => $db->escapeString($this->type->value),
161
				'time' => $db->escapeNumber($this->time),
162
				'claimer_id' => $db->escapeNumber($this->claimerID),
163
				'amount' => $db->escapeNumber($this->credits),
164
				'smr_credits' => $db->escapeNumber($this->smrCredits),
165
			]);
166
		} else {
167
			$db->write('DELETE FROM bounty WHERE bounty_id=' . $db->escapeNumber($this->bountyID) . ' AND account_id=' . $db->escapeNumber($this->targetID) . ' AND game_id=' . $db->escapeNumber($this->gameID));
168
		}
169
		$this->hasChanged = false;
170
		return true;
171
	}
172
173
}
174