1
0
Fork 0
mirror of https://codeberg.org/demostf/api.git synced 2026-06-03 09:54:17 +02:00

store kills directly with players

This commit is contained in:
Robin Appelman 2021-05-24 14:34:43 +02:00
commit 6d01061c58
11 changed files with 83 additions and 84 deletions

View file

@ -14,7 +14,6 @@ use Demostf\API\Providers\ChatProvider;
use Demostf\API\Providers\DemoListProvider;
use Demostf\API\Providers\DemoProvider;
use Demostf\API\Providers\InfoProvider;
use Demostf\API\Providers\KillProvider;
use Demostf\API\Providers\PlayerProvider;
use Demostf\API\Providers\UploadProvider;
use Demostf\API\Providers\UserProvider;
@ -82,10 +81,6 @@ class Container {
return new InfoProvider($this->connection);
}
public function getKillProvider(): KillProvider {
return new KillProvider($this->connection);
}
public function getPlayerProvider(): PlayerProvider {
return new PlayerProvider($this->connection);
}
@ -104,7 +99,6 @@ class Container {
$this->getUserProvider(),
$this->getDemoProvider(),
new DemoSaver(
$this->getKillProvider(),
$this->getPlayerProvider(),
$this->getChatProvider(),
$this->getUserProvider(),

View file

@ -12,8 +12,22 @@ class Player {
private string $name;
private string $team;
private string $class;
private int $kills;
private int $assists;
private int $deaths;
public function __construct(int $id, int $demoId, int $demoUserId, int $userId, string $name, string $team, string $class) {
public function __construct(
int $id,
int $demoId,
int $demoUserId,
int $userId,
string $name,
string $team,
string $class,
int $kills,
int $assists,
int $deaths
) {
$this->id = $id;
$this->demoId = $demoId;
$this->demoUserId = $demoUserId;
@ -21,6 +35,9 @@ class Player {
$this->name = $name;
$this->team = $team;
$this->class = $class;
$this->kills = $kills;
$this->assists = $assists;
$this->deaths = $deaths;
}
public function getId(): int {
@ -50,4 +67,16 @@ class Player {
public function getClass(): string {
return $this->class;
}
public function getKills(): int {
return $this->kills;
}
public function getAssists(): int {
return $this->assists;
}
public function getDeaths(): int {
return $this->deaths;
}
}

View file

@ -5,20 +5,17 @@ declare(strict_types=1);
namespace Demostf\API\Demo;
use DateTime;
use Demostf\API\Data\Kill;
use Demostf\API\Data\ParsedDemo;
use Demostf\API\Data\Player;
use Demostf\API\Data\StoredDemo;
use Demostf\API\Data\Upload;
use Demostf\API\Providers\ChatProvider;
use Demostf\API\Providers\DemoProvider;
use Demostf\API\Providers\KillProvider;
use Demostf\API\Providers\PlayerProvider;
use Demostf\API\Providers\UserProvider;
use Doctrine\DBAL\Connection;
class DemoSaver {
private KillProvider $killProvider;
private PlayerProvider $playerProvider;
private ChatProvider $chatProvider;
private UserProvider $userProvider;
@ -26,14 +23,12 @@ class DemoSaver {
private Connection $connection;
public function __construct(
KillProvider $killProvider,
PlayerProvider $playerProvider,
ChatProvider $chatProvider,
UserProvider $userProvider,
DemoProvider $demoProvider,
Connection $connection
) {
$this->killProvider = $killProvider;
$this->playerProvider = $playerProvider;
$this->chatProvider = $chatProvider;
$this->userProvider = $userProvider;
@ -42,9 +37,6 @@ class DemoSaver {
}
public function saveDemo(ParsedDemo $demo, Header $header, StoredDemo $storedDemo, Upload $upload): int {
/** @var int[] $userMap [$demoUserId => $dbUserId] */
$userMap = [0 => 0];
$this->connection->beginTransaction();
$demoId = $this->demoProvider->storeDemo(new Demo(
@ -67,9 +59,30 @@ class DemoSaver {
$storedDemo->getPath()
), $storedDemo->getBackend(), $storedDemo->getPath());
$kills = [];
$assists = [];
$deaths = [];
foreach ($demo->getPlayers() as $player) {
$kills[$player->getDemoUserId()] = 0;
$assists[$player->getDemoUserId()] = 0;
$deaths[$player->getDemoUserId()] = 0;
}
foreach ($demo->getKills() as $kill) {
if ($kill->getAttackerDemoId()) {
$kills[$kill->getAttackerDemoId()]++;
}
if ($kill->getAssisterDemoId()) {
$assists[$kill->getAssisterDemoId()]++;
}
if ($kill->getVictimDemoId()) {
$deaths[$kill->getVictimDemoId()]++;
}
}
foreach ($demo->getPlayers() as $player) {
$userId = $this->userProvider->getUserId($player->getSteamId(), $player->getName());
$userMap[$player->getDemoUserId()] = $userId;
$this->playerProvider->store(new Player(
0,
@ -78,17 +91,10 @@ class DemoSaver {
$userId,
$player->getName(),
$player->getTeam(),
$player->getClass()
));
}
foreach ($demo->getKills() as $kill) {
$this->killProvider->store(new Kill(
0,
$demoId,
$userMap[$kill->getAttackerDemoId()] ?? 0,
$userMap[$kill->getAssisterDemoId()] ?? 0,
$userMap[$kill->getVictimDemoId()] ?? 0
$player->getClass(),
$kills[$player->getDemoUserId()],
$assists[$player->getDemoUserId()],
$deaths[$player->getDemoUserId()]
));
}

View file

@ -33,11 +33,8 @@ class DemoProvider extends BaseProvider {
public function get(int $id, bool $fetchDetails = true): ?Demo {
// sql magic
$sql = 'WITH demokills AS (SELECT attacker_id, assister_id, victim_id FROM kills WHERE demo_id = ?)
SELECT players.id, user_id, players.name, team, class, users.steamid, users.avatar,
(SELECT COUNT(*) FROM demokills WHERE attacker_id=players.user_id) AS kills,
(SELECT COUNT(*) FROM demokills WHERE assister_id=players.user_id) AS assists,
(SELECT COUNT(*) FROM demokills WHERE victim_id=players.user_id) AS deaths
$sql = '
SELECT players.id, user_id, players.name, team, class, users.steamid, users.avatar, players.kills, players.assists, players.deaths
FROM players
INNER JOIN users ON players.user_id = users.id
WHERE demo_id = ?';
@ -49,7 +46,7 @@ class DemoProvider extends BaseProvider {
if ($fetchDetails) {
$uploader = $this->userProvider->getById($demo->getUploader());
$playerQuery = $this->connection->executeQuery($sql, [$demo->getId(), $demo->getId()]);
$playerQuery = $this->connection->executeQuery($sql, [$demo->getId()]);
$players = $playerQuery->fetchAll(PDO::FETCH_ASSOC);
$demo->setUploaderUser($uploader);

View file

@ -1,23 +0,0 @@
<?php
declare(strict_types=1);
namespace Demostf\API\Providers;
use Demostf\API\Data\Kill;
class KillProvider extends BaseProvider {
public function store(Kill $kill): int {
$query = $this->getQueryBuilder();
$query->insert('kills')
->values([
'demo_id' => $query->createNamedParameter($kill->getDemoId()),
'attacker_id' => $query->createNamedParameter($kill->getAttackerId()),
'assister_id' => $query->createNamedParameter($kill->getAssisterId()),
'victim_id' => $query->createNamedParameter($kill->getVictimId()),
]);
$query->execute();
return (int) $this->connection->lastInsertId();
}
}

View file

@ -17,6 +17,9 @@ class PlayerProvider extends BaseProvider {
'name' => $query->createNamedParameter($player->getName()),
'team' => $query->createNamedParameter($player->getTeam()),
'class' => $query->createNamedParameter($player->getClass()),
'kills' => $query->createNamedParameter($player->getKills()),
'assists' => $query->createNamedParameter($player->getAssists()),
'deaths' => $query->createNamedParameter($player->getDeaths()),
]);
$query->execute();

View file

@ -15,7 +15,6 @@ use Demostf\API\Demo\DemoSaver;
use Demostf\API\Demo\Header;
use Demostf\API\Providers\ChatProvider;
use Demostf\API\Providers\DemoProvider;
use Demostf\API\Providers\KillProvider;
use Demostf\API\Providers\PlayerProvider;
use Demostf\API\Providers\UserProvider;
use Demostf\API\Test\TestCase;
@ -74,7 +73,6 @@ class DemoSaverTest extends TestCase {
);
$saver = new DemoSaver(
new KillProvider($this->getDatabaseConnection()),
new PlayerProvider($this->getDatabaseConnection()),
$chatProvider,
$userProvider,

View file

@ -138,7 +138,7 @@ class DemoListProviderTest extends TestCase {
}
private function addPlayer($demoId, $userId) {
$player = new Player(0, $demoId, 0, $userId, 'foo', 'red', 'scout');
$player = new Player(0, $demoId, 0, $userId, 'foo', 'red', 'scout', 1, 2, 3);
$this->playerProvider->store($player);
}

View file

@ -5,11 +5,9 @@ declare(strict_types=1);
namespace Demostf\API\Test\Providers;
use Demostf\API\Data\DemoPlayer;
use Demostf\API\Data\Kill;
use Demostf\API\Data\Player;
use Demostf\API\Demo\Demo;
use Demostf\API\Providers\DemoProvider;
use Demostf\API\Providers\KillProvider;
use Demostf\API\Providers\PlayerProvider;
use Demostf\API\Providers\UserProvider;
use Demostf\API\Test\TestCase;
@ -24,16 +22,12 @@ class DemoProviderTest extends TestCase {
/** @var PlayerProvider */
private $playerProvider;
/** @var KillProvider */
private $killProvider;
public function setUp(): void {
parent::setUp();
$this->userProvider = new UserProvider($this->getDatabaseConnection(), $this->getRandomGenerator());
$this->provider = new DemoProvider($this->getDatabaseConnection(), $this->userProvider);
$this->playerProvider = new PlayerProvider($this->getDatabaseConnection());
$this->killProvider = new KillProvider($this->getDatabaseConnection());
}
public function testGetNonExisting() {
@ -124,14 +118,10 @@ class DemoProviderTest extends TestCase {
);
$id = $this->provider->storeDemo($demo, 'dummy', 'path');
$player1 = $this->addPlayer($id, 101, $user1->getId(), 'red', 'scout');
$player2 = $this->addPlayer($id, 102, $user2->getId(), 'red', 'soldier');
$player3 = $this->addPlayer($id, 103, $user3->getId(), 'blue', 'engineer');
$player4 = $this->addPlayer($id, 104, $user4->getId(), 'blue', 'spy');
$this->addKill($id, $user1->getId(), 0, $user3->getId());
$this->addKill($id, $user1->getId(), $user2->getId(), $user3->getId());
$this->addKill($id, $user4->getId(), 0, $user1->getId());
$player1 = $this->addPlayer($id, 101, $user1->getId(), 'red', 'scout', 2, 0, 1);
$player2 = $this->addPlayer($id, 102, $user2->getId(), 'red', 'soldier', 0, 1, 0);
$player3 = $this->addPlayer($id, 103, $user3->getId(), 'blue', 'engineer', 0, 0, 2);
$player4 = $this->addPlayer($id, 104, $user4->getId(), 'blue', 'spy', 1, 0, 0);
$retrieved = $this->provider->get($id, true);
$this->assertInstanceOf(Demo::class, $retrieved);
@ -149,18 +139,22 @@ class DemoProviderTest extends TestCase {
], $players);
}
private function addPlayer(int $demoId, int $demoUserId, int $userId, string $team, string $class): int {
$player = new Player(0, $demoId, $demoUserId, $userId, 'user_' . $userId, $team, $class);
private function addPlayer(
int $demoId,
int $demoUserId,
int $userId,
string $team,
string $class,
int $kills,
int $assist,
int $deaths
): int {
$player = new Player(0, $demoId, $demoUserId, $userId, 'user_' . $userId, $team, $class, $kills, $assist,
$deaths);
return $this->playerProvider->store($player);
}
private function addKill(int $demoId, int $attackerId, int $assisterId, int $victimId): int {
$kill = new Kill(0, $demoId, $attackerId, $assisterId, $victimId);
return $this->killProvider->store($kill);
}
public function testSetDemoUrl() {
$uploaderSteamId = $this->getSteamId('12345', 'test');
$this->userProvider->store($uploaderSteamId, 'test');

View file

@ -16,7 +16,6 @@ use Demostf\API\Demo\RawParser;
use Demostf\API\Error\InvalidKeyException;
use Demostf\API\Providers\ChatProvider;
use Demostf\API\Providers\DemoProvider;
use Demostf\API\Providers\KillProvider;
use Demostf\API\Providers\PlayerProvider;
use Demostf\API\Providers\UploadProvider;
use Demostf\API\Providers\UserProvider;
@ -76,7 +75,6 @@ class UploadProviderTest extends TestCase {
$this->userProvider = new UserProvider($this->getDatabaseConnection(), $this->getRandomGenerator());
$this->demoProvider = new DemoProvider($this->getDatabaseConnection(), $this->userProvider);
$this->demoSaver = new DemoSaver(
new KillProvider($this->getDatabaseConnection()),
new PlayerProvider($this->getDatabaseConnection()),
new ChatProvider($this->getDatabaseConnection()),
$this->userProvider,

View file

@ -75,7 +75,10 @@ class UserProviderTest extends TestCase {
$user->getId(),
$user->getName(),
'red',
'scout'
'scout',
1,
1,
1
));
$this->getDatabaseConnection()->query('REFRESH MATERIALIZED VIEW name_list');