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
Pull Request — main (#1508)
by Dan
04:48
created

Bounty   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 162
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 74
dl 0
loc 162
rs 10
c 1
b 0
f 0
wmc 27

16 Methods

Rating   Name   Duplication   Size   Complexity  
A getTargetPlayer() 0 2 1
A increaseCredits() 0 5 2
A increaseSmrCredits() 0 5 2
A setCredits() 0 6 2
A getCredits() 0 2 1
A update() 0 21 4
A isActive() 0 2 1
A setSmrCredits() 0 6 2
A setClaimed() 0 3 1
A getSmrCredits() 0 2 1
A getFromRecord() 0 11 1
A getPlacedOnPlayer() 0 9 2
A __construct() 0 11 1
A setClaimable() 0 6 2
A getMostWanted() 0 8 2
A getClaimableByPlayer() 0 13 2
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