Skip to content

Commit

Permalink
#95 Importing enemies now works from MDT (when MDT enemies are couple…
Browse files Browse the repository at this point in the history
…d, for now only in Atal'Dazar). Fixed enemies not loading. Thumbnails are now generated upon creating a new route.
  • Loading branch information
Wotuu committed Jan 16, 2019
1 parent 33bb3e0 commit abfef3f
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 57 deletions.
2 changes: 1 addition & 1 deletion app/Http/Controllers/APIEnemyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function list(Request $request)
$mdtEnemies = [];
if ($showMdtEnemies) {
/** @var Floor $floor */
$floor = Floor::where('id', $floorId)->first();
$floor = Floor::find($floorId);

$mdtEnemies = (new \App\Logic\MDT\Data\MDTDungeon($floor->dungeon->name))->getClonesAsEnemies($floor);
}
Expand Down
4 changes: 2 additions & 2 deletions app/Logic/MDT/Data/MDTDungeon.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ private function _getMDTEnemy($npcId)

/**
* Get all clones of this dungeon in the format of enemies (Keystone.guru style).
* @param $floors Collection The floors that you want to get the clones for.
* @param $floors Floor|Collection The floors that you want to get the clones for.
* @return Enemy[]
*/
public function getClonesAsEnemies($floors)
{
// Ensure floors is a collection
if (!($floors instanceof Collection)) {
$floors = new Collection($floors);
$floors = [$floors];
}

$mdtNpcs = $this->_getMDTNPCs();
Expand Down
110 changes: 67 additions & 43 deletions app/Logic/MDT/IO/ImportString.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use App\Models\DungeonRoute;
use App\Models\Enemy;
use App\Models\KillZone;
use App\Models\Npc;
use App\Models\KillZoneEnemy;
use Illuminate\Support\Facades\Auth;

/**
Expand Down Expand Up @@ -96,7 +96,7 @@ public function getDungeonRoute()
$dungeonRoute->difficulty = 'Casual';

// Pre-emptively save the route
// $dungeonRoute->save();
$dungeonRoute->save();

// Create killzones and attach enemies
/**
Expand All @@ -120,60 +120,84 @@ public function getDungeonRoute()
// Fetch all enemies of this
$mdtEnemies = (new \App\Logic\MDT\Data\MDTDungeon($dungeonRoute->dungeon->name))->getClonesAsEnemies($floors);

foreach ($decoded['value']['pulls'] as $pull) {
foreach ($pull as $key => $stringMdtEnemies) {
$killZone = new KillZone();
// $killZone->save();
$kzLat = 0;
$kzLng = 0;
foreach ($stringMdtEnemies as $npcIndex => $clones) {
foreach ($clones as $index => $cloneIndex) {
// Find the matching enemy of the clones
/** @var Enemy $mdtEnemy */
$mdtEnemy = null;
foreach ($mdtEnemies as $mdtEnemyCandidate) {
// NPC and clone index make for unique ID
if ($mdtEnemyCandidate->mdt_npc_index === $npcIndex && $mdtEnemyCandidate->mdt_id === $cloneIndex) {
// Found it
$mdtEnemy = $mdtEnemyCandidate;
break;
}
// For each pull the user created
foreach ($decoded['value']['pulls'] as $pullIndex => $pull) {
// Create a killzone
$killZone = new KillZone();
$killZone->dungeon_route_id = $dungeonRoute->id;
// Save it so we have an ID that we can use later on
$killZone->save();

// Init some variables
$totalEnemiesKilled = 0;
$kzLat = 0;
$kzLng = 0;
$floorId = -1;

// For each NPC that is killed in this pull (and their clones)
foreach ($pull as $npcIndex => $mdtClones) {
// Only if filled
$enemyCount = count($mdtClones);
foreach ($mdtClones as $index => $cloneIndex) {
// This comes in through as a double, cast to int
$cloneIndex = (int)$cloneIndex;

// Find the matching enemy of the clones
/** @var Enemy $mdtEnemy */
$mdtEnemy = null;
foreach ($mdtEnemies as $mdtEnemyCandidate) {
// NPC and clone index make for unique ID
if ($mdtEnemyCandidate->mdt_npc_index === $npcIndex && $mdtEnemyCandidate->mdt_id === $cloneIndex) {
// Found it
$mdtEnemy = $mdtEnemyCandidate;
break;
}
}

if ($mdtEnemy === null) {
echo "Unable to find MDT enemy!";
dd($stringMdtEnemies);
}
if ($mdtEnemy === null) {
throw new \Exception("Unable to find MDT enemy for index {$cloneIndex}!");
}

// We now know the MDT enemy that the user was trying to import. However, we need to know
// our own enemy. Thus, try to find the enemy in our list which has the same npc_id and mdt_id.
/** @var Enemy $enemy */
$enemy = null;
foreach ($enemies as $enemyCandidate) {
if ($enemyCandidate->mdt_id === $mdtEnemy->mdt_id && $enemyCandidate->npc_id === $mdtEnemy->npc_id) {
$enemy = $enemyCandidate;
break;
}
// We now know the MDT enemy that the user was trying to import. However, we need to know
// our own enemy. Thus, try to find the enemy in our list which has the same npc_id and mdt_id.
/** @var Enemy $enemy */
$enemy = null;
foreach ($enemies as $enemyCandidate) {
if ($enemyCandidate->mdt_id === $mdtEnemy->mdt_id && $enemyCandidate->npc_id === $mdtEnemy->npc_id) {
$enemy = $enemyCandidate;
break;
}
}

if ($enemy === null) {
echo "Unable to find enemy!";
dd($stringMdtEnemies);
}
if ($enemy === null) {
throw new \Exception("Unable to find enemy for mdt_id {$mdtEnemy->mdt_id}, npc_id {$mdtEnemy->npc_id}!");
}

$kzLat += $enemy->lat;
$kzLng += $enemy->lng;
$kzLat += $enemy->lat;
$kzLng += $enemy->lng;

dd($enemy);
// Couple the KillZoneEnemy to its KillZone
$kzEnemy = new KillZoneEnemy();
$kzEnemy->kill_zone_id = $killZone->id;
$kzEnemy->enemy_id = $enemy->id;
$kzEnemy->save();

$kzEnemy = new KillZoneEnemy();
// $kzEnemy->kill
}
// Should be the same floor_id all the time, but we need it anyways
$floorId = $enemy->floor_id;
}

$totalEnemiesKilled += $enemyCount;
}

// KillZones at the average position of all killed enemies
$killZone->floor_id = $floorId;
$killZone->lat = $kzLat / $totalEnemiesKilled;
$killZone->lng = $kzLng / $totalEnemiesKilled;
$killZone->save();
}
}

echo "Finished importing!";
dd($decoded);


Expand Down
35 changes: 24 additions & 11 deletions app/Logic/Scheduler/FindOutdatedThumbnails.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
use App\Jobs\ProcessRouteFloorThumbnail;
use App\Models\DungeonRoute;
use App\Models\Floor;
use Illuminate\Queue\Jobs\Job;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class FindOutdatedThumbnails
Expand All @@ -28,27 +30,38 @@ function __invoke()
Log::channel('scheduler')->debug(sprintf('Checking %s routes for thumbnails', $routes->count()));

$processed = 0;

$currentJobCount = DB::table('jobs')->count();
foreach ($routes as $dungeonRoute) {
/** @var DungeonRoute $dungeonRoute */
$updatedAt = Carbon::createFromTimeString($dungeonRoute->updated_at);
$thumbnailUpdatedAt = Carbon::createFromTimeString($dungeonRoute->thumbnail_updated_at);

if ((// Updated at is greater than the thumbnail updated at (don't keep updating thumbnails..)
$updatedAt->greaterThan($thumbnailUpdatedAt) &&
// If the route has been updated in the past x minutes...
$updatedAt->addMinute(config('keystoneguru.thumbnail_refresh_min'))->isPast())
||
// Update every month regardless
$thumbnailUpdatedAt->addMonth(1)->isPast()
||
// Thumbnail does not exist in the folder it should
!ProcessRouteFloorThumbnail::thumbnailsExistsForRoute($dungeonRoute)
) {
// Add a limit to the amount of jobs that can be queued at once. When we have 100 jobs, the server is busy
// enough as-is and we don't need to queue more jobs. Mostly this is done because
// ProcessRouteFloorThumbnail::thumbnailsExistsForRoute() gets more expensive the more jobs there are
// It has to deserialize the job's payload for each attempt to queue more jobs. If this goes to the 100s
// it will cause the server to come to a crawl for no real reason. Thus, this magic 100 is introduced.
if ($currentJobCount < 100 &&
((// Updated at is greater than the thumbnail updated at (don't keep updating thumbnails..)
$updatedAt->greaterThan($thumbnailUpdatedAt) &&
// If the route has been updated in the past x minutes...
$updatedAt->addMinute(config('keystoneguru.thumbnail_refresh_min'))->isPast())
||
// Update every month regardless
$thumbnailUpdatedAt->addMonth(1)->isPast()
||
// Thumbnail does not exist in the folder it should
!ProcessRouteFloorThumbnail::thumbnailsExistsForRoute($dungeonRoute)
)) {

if (!$this->isJobQueuedForModel(\App\Jobs\ProcessRouteFloorThumbnail::class, $dungeonRoute)) {
Log::channel('scheduler')->debug(sprintf('Queueing job for route %s (%s floors)', $dungeonRoute->public_key, $dungeonRoute->dungeon->floors->count()));

$dungeonRoute->queueRefreshThumbnails();

// Refresh the current job count, it should be increased now
$currentJobCount = DB::table('jobs')->count();
$processed++;
}
}
Expand Down

0 comments on commit abfef3f

Please sign in to comment.