From ac3077a6278df46b86c78916ad22883ac3e4bdbb Mon Sep 17 00:00:00 2001 From: Wouter Date: Sun, 6 Jan 2019 21:48:06 +0100 Subject: [PATCH] #95 Added conversions to load clones from MDT and plot them on the admin map. This seems to be working fine right now. Just the actual coupling needs to happen now. --- app/Http/Controllers/APIEnemyController.php | 29 ++- app/Http/Controllers/MDTImportController.php | 2 +- app/Logic/MDT/Data/MDTDungeon.php | 169 ++++++++++++++++++ app/Logic/MDT/{ => IO}/Deprecated.php | 0 app/Logic/MDT/{ => IO}/Huffman.php | 0 app/Logic/MDT/{ => IO}/ImportString.php | 10 +- app/Models/Enemy.php | 1 - resources/assets/css/map.css | 7 +- resources/assets/images/mapicon/flagged.png | Bin 354 -> 0 bytes resources/assets/images/mapicon/mdt.png | Bin 0 -> 5334 bytes .../enemyvisualmainaggressiveness.js | 31 ++-- .../mapobjectgroups/enemymapobjectgroup.js | 118 ++++++------ 12 files changed, 288 insertions(+), 79 deletions(-) create mode 100644 app/Logic/MDT/Data/MDTDungeon.php rename app/Logic/MDT/{ => IO}/Deprecated.php (100%) rename app/Logic/MDT/{ => IO}/Huffman.php (100%) rename app/Logic/MDT/{ => IO}/ImportString.php (84%) delete mode 100644 resources/assets/images/mapicon/flagged.png create mode 100644 resources/assets/images/mapicon/mdt.png diff --git a/app/Http/Controllers/APIEnemyController.php b/app/Http/Controllers/APIEnemyController.php index ab059c72a..5cd696720 100644 --- a/app/Http/Controllers/APIEnemyController.php +++ b/app/Http/Controllers/APIEnemyController.php @@ -4,9 +4,11 @@ use App\Http\Controllers\Traits\ChecksForDuplicates; use App\Http\Controllers\Traits\PublicKeyDungeonRoute; +use App\Logic\MDT\IO\MDTDungeon; use App\Models\DungeonRouteEnemyRaidMarker; use App\Models\Enemy; use App\Models\EnemyInfestedVote; +use App\Models\Floor; use App\Models\GameServerRegion; use App\Models\Npc; use App\Models\RaidMarker; @@ -25,12 +27,21 @@ function list(Request $request) { $floorId = $request->get('floor_id'); $dungeonRoutePublicKey = $request->get('dungeonroute', null); + $showMdtEnemies = false; - $routeId = -1; + // Only admins are allowed to see this + if (Auth::check()) { + if (Auth::user()->hasRole('admin')) { + // Only fetch it now + $showMdtEnemies = $request->get('show_mdt_enemies', false); + } + } + + $dungeonRoute = null; // If dungeon route was set, fetch the markers as well if ($dungeonRoutePublicKey !== null) { try { - $routeId = $this->_getDungeonRouteFromPublicKey($dungeonRoutePublicKey, false)->id; + $dungeonRoute = $this->_getDungeonRouteFromPublicKey($dungeonRoutePublicKey, false); } catch (\Exception $ex) { return response('Not found', Http::NOT_FOUND); } @@ -57,7 +68,7 @@ function list(Request $request) group by `enemies`.`id`; ', $params = [ 'userId' => Auth::check() ? Auth::user()->id : -1, - 'routeId' => $routeId, + 'routeId' => isset($dungeonRoute) ? $dungeonRoute->id : -1, 'affixGroupId' => $region->getCurrentAffixGroup()->id, 'minTime' => Carbon::now()->subMonth()->format('Y-m-d H:i:s'), 'floorId' => $floorId @@ -74,7 +85,17 @@ function list(Request $request) unset($enemy->npc_id); } - return $result; + $mdtEnemies = []; + + // Only if we should show MDT enemies + if ($showMdtEnemies) { + /** @var Floor $floor */ + $floor = Floor::where('id', $floorId)->first(); + + $mdtEnemies = (new \App\Logic\MDT\Data\MDTDungeon($floor->dungeon->name))->getClonesAsEnemies($floor); + } + + return ['enemies' => $result, 'mdt_enemies' => $mdtEnemies]; } /** diff --git a/app/Http/Controllers/MDTImportController.php b/app/Http/Controllers/MDTImportController.php index ff881edfc..4e4c2b109 100644 --- a/app/Http/Controllers/MDTImportController.php +++ b/app/Http/Controllers/MDTImportController.php @@ -2,7 +2,7 @@ namespace App\Http\Controllers; -use App\Logic\MDT\ImportString; +use App\Logic\MDT\IO\ImportString; use Illuminate\Http\Request; class MDTImportController extends Controller diff --git a/app/Logic/MDT/Data/MDTDungeon.php b/app/Logic/MDT/Data/MDTDungeon.php new file mode 100644 index 000000000..8ae4b1b1f --- /dev/null +++ b/app/Logic/MDT/Data/MDTDungeon.php @@ -0,0 +1,169 @@ + 'AtalDazar', + 'Freehold' => 'Freehold', + 'Kings\' Rest' => 'KingsRest', + 'Shrine of the Storm' => 'ShrineoftheStorm', + 'Siege of Boralus' => 'SiegeofBoralus', + 'Temple of Sethraliss' => 'TempleofSethraliss', + 'The MOTHERLODE!!' => 'TheMotherlode', + 'The Underrot' => 'TheUnderrot', + 'Tol Dagor' => 'TolDagor', + 'Waycrest Manor' => 'WaycrestManor' + ]; + + /** @var string The Dungeon's name (Keystone.guru style). Can be converted using self::$dungeonMapping */ + private $_dungeonName; + + + function __construct($dungeonName) + { + assert(array_key_exists($dungeonName, self::$dungeonNameMapping)); + $this->_dungeonName = $dungeonName; + } + + /** + * @return mixed Gets the MDT version of a dungeon name. + */ + private function _getMDTDungeonName() + { + return self::$dungeonNameMapping[$this->_dungeonName]; + } + + /** + * Get a list of NPCs + */ + private function _getMDTNPCs() + { + $lua = new \Lua(); + $lua->eval( + 'local MethodDungeonTools = {} + MethodDungeonTools.dungeonTotalCount = {} + MethodDungeonTools.mapPOIs = {} + MethodDungeonTools.dungeonEnemies = {} + MethodDungeonTools.scaleMultiplier = {} + ' . + file_get_contents( + base_path('vendor/nnogga/MethodDungeonTools/BattleForAzeroth/' . $this->_getMDTDungeonName() . '.lua') + ) . + // Insert dummy function to get what we need + ' + function GetDungeonEnemies() + return MethodDungeonTools.dungeonEnemies[dungeonIndex] + end + '); + return $lua->call('GetDungeonEnemies'); + } + + /** + * Get all clones of a specific NPC. + * @param $npcId int WoW's NPC id. + * @return array The enemy as an array. + */ + private function _getMDTEnemy($npcId) + { + $enemies = $this->_getMDTNPCs(); + + $result = null; + // Find the enemy in a list of enemies + foreach ($enemies as $enemy) { + // Id is classed as a double, some lua -> php conversion issue/choice. + if ((int)$enemy->id === $npcId) { + $result = $enemy; + break; + } + } + + return $result; + } + + + /** + * Get all clones of this dungeon in the format of enemies (Keystone.guru style). + * @param $floor Floor The floor you're looking for. + * @return array + */ + public function getClonesAsEnemies($floor) + { + $mdtNpcs = $this->_getMDTNPCs(); + + // Find the enemy in a list of enemies + $clones = []; + foreach ($mdtNpcs as $mdtNpc) { + foreach ($mdtNpc['clones'] as $mdtId => $clone) { + //Only clones that are on the same floor + if ((int)$clone['sublevel'] === $floor->index) { + // Set some additional props that come in handy when converting to an enemy + $clone['npcId'] = (int)$mdtNpc['id']; + $clone['mdtId'] = (int)$mdtId; + $clones[] = $clone; + } + } + } + + // We now know a list of clones that we want to display, convert those clones to TEMP enemies + $enemies = []; + /** @var Collection $npcs */ + $npcs = Npc::where('dungeon_id', $floor->dungeon->id)->get(); + foreach ($clones as $npcId => $clone) { + $enemy = new Enemy(); + // Dummy so we can ID them later on + $enemy->is_mdt = true; + $enemy->floor_id = $floor->id; + $enemy->enemy_pack_id = -1; + $enemy->npc_id = (int)$clone['npcId']; + $enemy->mdt_id = (int)$clone['mdtId']; + $enemy->is_infested = false; + $enemy->teeming = isset($clone['teeming']) && $clone['teeming'] ? 'visible' : null; + $enemy->faction = isset($clone['faction']) ? ($clone['faction'] === 1 ? 'alliance' : 'horde') : 'any'; + $enemy->enemy_forces_override = -1; + // This seems to match my coordinate system for about 99%. Sometimes it's a bit off but I can work around that. + $enemy->lat = ($clone['y'] / 2.2); + $enemy->lng = ($clone['x'] / 2.2); + $enemy->npc = $npcs->firstWhere('id', $enemy->npc_id); + + // Some properties which are dynamic on a normal enemy but static here + $enemy->raid_marker_name = null; + $enemy->infested_yes_votes = 0; + $enemy->infested_no_votes = 0; + $enemy->infested_user_vote = null; + + $enemies[] = $enemy; + } + + return $enemies; + } + + /** + * Get all enemies of this dungeon (Keystone.guru style). + */ + public function getEnemies() + { + + } +} \ No newline at end of file diff --git a/app/Logic/MDT/Deprecated.php b/app/Logic/MDT/IO/Deprecated.php similarity index 100% rename from app/Logic/MDT/Deprecated.php rename to app/Logic/MDT/IO/Deprecated.php diff --git a/app/Logic/MDT/Huffman.php b/app/Logic/MDT/IO/Huffman.php similarity index 100% rename from app/Logic/MDT/Huffman.php rename to app/Logic/MDT/IO/Huffman.php diff --git a/app/Logic/MDT/ImportString.php b/app/Logic/MDT/IO/ImportString.php similarity index 84% rename from app/Logic/MDT/ImportString.php rename to app/Logic/MDT/IO/ImportString.php index f1ea09594..23b3067a4 100644 --- a/app/Logic/MDT/ImportString.php +++ b/app/Logic/MDT/IO/ImportString.php @@ -6,16 +6,13 @@ * Time: 20:49 */ -namespace App\Logic\MDT; +namespace App\Logic\MDT\IO; -use App\Huffman; use App\Models\DungeonRoute; /** - * Class ImportString. This file was created as a sort of copy of https://github.com/nnogga/MethodDungeonTools/blob/master/Transmission.lua - * All rights belong to their respective owners, I did write this but I did not make this up. I merely translated the LUA - * to PHP to allow for importing of the exported strings. + * This file handles any and all conversion from DungeonRoutes to MDT Export strings and vice versa. * @package App\Logic\MDT * @author Wouter * @since 05/01/2019 @@ -45,7 +42,8 @@ function __construct() private function _getLua() { $lua = new \Lua(); - // $lua->assign("php_var", array(1=>1, 2, 3)); //lua table index begin with 1 + + // Load libraries (yeah can do this with ->library function as well) $lua->eval(file_get_contents(base_path('app/Logic/MDT/Lua/LibStub.lua'))); $lua->eval(file_get_contents(base_path('app/Logic/MDT/Lua/LibCompress.lua'))); $lua->eval(file_get_contents(base_path('app/Logic/MDT/Lua/AceSerializer.lua'))); diff --git a/app/Models/Enemy.php b/app/Models/Enemy.php index 263032b01..cbe292ebc 100644 --- a/app/Models/Enemy.php +++ b/app/Models/Enemy.php @@ -20,7 +20,6 @@ * @property \App\Models\EnemyPack $enemyPack * @property \App\Models\Npc $npc * @property \App\Models\Floor $floor - * @property \Illuminate\Support\Collection $vertices * @property \Illuminate\Support\Collection $thisweeksinfestedvotes */ class Enemy extends Model diff --git a/resources/assets/css/map.css b/resources/assets/css/map.css index 6ebe5b702..54b8c0b4b 100644 --- a/resources/assets/css/map.css +++ b/resources/assets/css/map.css @@ -233,7 +233,8 @@ html, body, #map, #app, .wrapper { .unfriendly_enemy_icon, .friendly_enemy_icon, .unset_enemy_icon, -.flagged_enemy_icon { +.flagged_enemy_icon, +.mdt_enemy_icon { width: 11px; height: 11px; } @@ -350,6 +351,10 @@ html, body, #map, #app, .wrapper { background: url("/images/mapicon/neutral.png") no-repeat center !important; } +.mdt_enemy_icon { + background: url("/images/mapicon/mdt.png") no-repeat center !important; +} + .door_icon { background: url("/images/mapicon/door.png") no-repeat center !important; } diff --git a/resources/assets/images/mapicon/flagged.png b/resources/assets/images/mapicon/flagged.png deleted file mode 100644 index cd49ec0da6b7fdfe5abdac28777cd75b648d5c7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 354 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhY)RhkE)4%caKYZ?lYt_f1s;*b zKvlvZ%*Zfnjs#GUy~NYkmHiPXH$Mya*467?0EOOrx;TbNT%LMS-`kl{g!RMye+nmN zJcy1q$S^vikQ8C$b1-K^m+w)P8-JLZ5)&hMnC+V!0}^XrbltdfDB)u3UV{skytnU} z8NO)b{$9lQJ?31mq(XD(lL=;S9qCs-m=T_V0XE%kdUV8iOt|*&%w@jzH tW&YGiO0#EM_Iv$Njo$j_f1dN#F;|uQm%X~ECI|F7gQu&X%Q~loCIE_Hj>7-| diff --git a/resources/assets/images/mapicon/mdt.png b/resources/assets/images/mapicon/mdt.png new file mode 100644 index 0000000000000000000000000000000000000000..8d2600723c380ca0c5cfb7512cf4a7a8c481833a GIT binary patch literal 5334 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 literal 0 HcmV?d00001 diff --git a/resources/assets/js/custom/enemyvisuals/enemyvisualmainaggressiveness.js b/resources/assets/js/custom/enemyvisuals/enemyvisualmainaggressiveness.js index a289f9c44..ddec5718f 100644 --- a/resources/assets/js/custom/enemyvisuals/enemyvisualmainaggressiveness.js +++ b/resources/assets/js/custom/enemyvisuals/enemyvisualmainaggressiveness.js @@ -18,7 +18,8 @@ class EnemyVisualMainAggressiveness extends EnemyVisualMain { 'friendly', 'unset', 'flagged', - 'boss' + 'boss', + 'mdt' ]; } @@ -41,21 +42,25 @@ class EnemyVisualMainAggressiveness extends EnemyVisualMain { * @private */ _updateIcon() { - let npc = this.enemyvisual.enemy.npc; + if( this.enemyvisual.enemy.is_mdt ){ + this.iconName = 'mdt'; + } else { + let npc = this.enemyvisual.enemy.npc; - // May be null if not set at all (yet) - if (npc !== null) { - if (npc.enemy_forces === -1) { - this.iconName = 'flagged'; - } - // @TODO Hard coded 3 = boss - else if (npc.classification_id === 3) { - this.iconName = 'boss'; + // May be null if not set at all (yet) + if (npc !== null) { + if (npc.enemy_forces === -1) { + this.iconName = 'flagged'; + } + // @TODO Hard coded 3 = boss + else if (npc.classification_id === 3) { + this.iconName = 'boss'; + } else { + this.iconName = npc.aggressiveness; + } } else { - this.iconName = npc.aggressiveness; + this.iconName = 'unset'; } - } else { - this.iconName = 'unset'; } } diff --git a/resources/assets/js/custom/mapobjectgroups/enemymapobjectgroup.js b/resources/assets/js/custom/mapobjectgroups/enemymapobjectgroup.js index 1a171f256..698d46b91 100644 --- a/resources/assets/js/custom/mapobjectgroups/enemymapobjectgroup.js +++ b/resources/assets/js/custom/mapobjectgroups/enemymapobjectgroup.js @@ -30,64 +30,76 @@ class EnemyMapObjectGroup extends MapObjectGroup { dataType: 'json', data: { dungeonroute: this.map.getDungeonRoute().publicKey, - floor_id: floor.id + floor_id: floor.id, + // Admin = show mdt enemies, otherwise don't + show_mdt_enemies: this.classname === 'AdminEnemy' }, success: function (json) { - // Now draw the enemies on the map - for (let index in json) { - if (json.hasOwnProperty(index)) { - let remoteEnemy = json[index]; - - let faction = self.map.getDungeonRoute().faction; - - if (remoteEnemy.faction !== 'any' && faction !== 'any' && faction !== remoteEnemy.faction) { - console.log('Skipping enemy that does not belong to the requested faction ', remoteEnemy, faction); - continue; - } - - // If the map isn't teeming, but the enemy is teeming.. - if (!self.map.teeming && remoteEnemy.teeming === 'visible') { - console.log('Skipping teeming enemy ' + remoteEnemy.id); - continue; - } - // If the map is teeming, but the enemy shouldn't be there for teeming maps.. - else if (self.map.teeming && remoteEnemy.teeming === 'invisible') { - console.log('Skipping teeming-filtered enemy ' + remoteEnemy.id); - continue; - } - - let layer = new LeafletEnemyMarker(); - layer.setLatLng(L.latLng(remoteEnemy.lat, remoteEnemy.lng)); - - let enemy = self.createNew(layer); - enemy.id = remoteEnemy.id; - enemy.enemy_pack_id = remoteEnemy.enemy_pack_id; - enemy.floor_id = remoteEnemy.floor_id; - enemy.teeming = remoteEnemy.teeming; - enemy.faction = remoteEnemy.faction; - enemy.enemy_forces_override = remoteEnemy.enemy_forces_override; - enemy.raid_marker_name = remoteEnemy.raid_marker_name; - enemy.infested_yes_votes = remoteEnemy.infested_yes_votes; - enemy.infested_no_votes = remoteEnemy.infested_no_votes; - enemy.infested_user_vote = remoteEnemy.infested_user_vote; - enemy.is_infested = remoteEnemy.is_infested; - - enemy.setNpc(remoteEnemy.npc); - // If actually set.. - if (remoteEnemy.hasOwnProperty('raid_marker_name') && remoteEnemy.raid_marker_name !== null) { - enemy.setRaidMarkerName(remoteEnemy.raid_marker_name); + let enemies = [ + json.enemies, + json.mdt_enemies + ]; + // For each set of enemies.. + for (let i = 0; i < enemies.length; i++) { + let enemySet = enemies[i]; + // Now draw the enemies on the map, if any + for (let index in enemySet) { + // Only if actually set + if (enemySet.hasOwnProperty(index)) { + let remoteEnemy = enemySet[index]; + + let faction = self.map.getDungeonRoute().faction; + + if (remoteEnemy.faction !== 'any' && faction !== 'any' && faction !== remoteEnemy.faction) { + console.log('Skipping enemy that does not belong to the requested faction ', remoteEnemy, faction); + continue; + } + + // If the map isn't teeming, but the enemy is teeming.. + if (!self.map.teeming && remoteEnemy.teeming === 'visible') { + console.log('Skipping teeming enemy ' + remoteEnemy.id); + continue; + } + // If the map is teeming, but the enemy shouldn't be there for teeming maps.. + else if (self.map.teeming && remoteEnemy.teeming === 'invisible') { + console.log('Skipping teeming-filtered enemy ' + remoteEnemy.id); + continue; + } + + let layer = new LeafletEnemyMarker(); + layer.setLatLng(L.latLng(remoteEnemy.lat, remoteEnemy.lng)); + + let enemy = self.createNew(layer); + enemy.id = remoteEnemy.id; + enemy.enemy_pack_id = remoteEnemy.enemy_pack_id; + enemy.floor_id = remoteEnemy.floor_id; + enemy.teeming = remoteEnemy.teeming; + enemy.faction = remoteEnemy.faction; + enemy.enemy_forces_override = remoteEnemy.enemy_forces_override; + enemy.raid_marker_name = remoteEnemy.raid_marker_name; + enemy.infested_yes_votes = remoteEnemy.infested_yes_votes; + enemy.infested_no_votes = remoteEnemy.infested_no_votes; + enemy.infested_user_vote = remoteEnemy.infested_user_vote; + enemy.is_infested = remoteEnemy.is_infested; + // Exception for MDT enemies + enemy.is_mdt = remoteEnemy.hasOwnProperty('is_mdt') ? remoteEnemy.is_mdt : false; + + enemy.setNpc(remoteEnemy.npc); + // If actually set.. + if (remoteEnemy.hasOwnProperty('raid_marker_name') && remoteEnemy.raid_marker_name !== null) { + enemy.setRaidMarkerName(remoteEnemy.raid_marker_name); + } + + // Is probably null if there's no patrol set + if (remoteEnemy.patrol !== null) { + + } + + // We just downloaded the enemy pack, it's synced alright! + enemy.setSynced(true); } - - // Is probably null if there's no patrol set - if (remoteEnemy.patrol !== null) { - - } - - // We just downloaded the enemy pack, it's synced alright! - enemy.setSynced(true); } } - callback(); } });