- part 1/2 WIP added WebSocket extension, #420

- part 1/2 added "secure routes" to route finder module, #311
This commit is contained in:
Exodus4D
2017-01-05 22:15:12 +01:00
parent f927395484
commit 4e0533c7fe
12 changed files with 556 additions and 83 deletions

View File

@@ -86,6 +86,9 @@ class Connection extends Controller\AccessController {
$connection->save();
$newConnectionData = $connection->getData();
// broadcast map changes
$this->broadcastMapData($connection->mapId);
}
}
}
@@ -100,18 +103,31 @@ class Connection extends Controller\AccessController {
* @throws \Exception
*/
public function delete(\Base $f3){
$connectionIds = $f3->get('POST.connectionIds');
$activeCharacter = $this->getCharacter();
$mapId = (int)$f3->get('POST.mapId');
$connectionIds = (array)$f3->get('POST.connectionIds');
/**
* @var Model\ConnectionModel $connection
*/
$connection = Model\BasicModel::getNew('ConnectionModel');
foreach($connectionIds as $connectionId){
$connection->getById($connectionId);
$connection->delete( $activeCharacter );
if($mapId){
$activeCharacter = $this->getCharacter();
/**
* @var Model\MapModel $map
*/
$map = Model\BasicModel::getNew('MapModel');
$map->getById($mapId);
if( $map->hasAccess($activeCharacter) ){
foreach($connectionIds as $connectionId){
if( $connection = $map->getConnectionById($connectionId) ){
$connection->delete( $activeCharacter );
$connection->reset();
}
}
// broadcast map changes
$this->broadcastMapData($map);
}
$connection->reset();
}
echo json_encode([]);

View File

@@ -9,6 +9,7 @@
namespace Controller\Api;
use Controller;
use lib\Config;
use lib\Socket;
use Model;
/**
@@ -396,10 +397,10 @@ class Map extends Controller\AccessController {
$maxShared = max($f3->get('PATHFINDER.MAP.PRIVATE.MAX_SHARED') - 1, 0);
$accessCharacters = array_slice($accessCharacters, 0, $maxShared);
if($accessCharacters){
// clear map access. In case something has removed from access list
$map->clearAccess();
// clear map access. In case something has removed from access list
$map->clearAccess();
if($accessCharacters){
/**
* @var $tempCharacter Model\CharacterModel
*/
@@ -439,10 +440,10 @@ class Map extends Controller\AccessController {
$maxShared = max($f3->get('PATHFINDER.MAP.CORPORATION.MAX_SHARED') - 1, 0);
$accessCorporations = array_slice($accessCorporations, 0, $maxShared);
if($accessCorporations){
// clear map access. In case something has removed from access list
$map->clearAccess();
// clear map access. In case something has removed from access list
$map->clearAccess();
if($accessCorporations){
/**
* @var $tempCorporation Model\CorporationModel
*/
@@ -482,10 +483,10 @@ class Map extends Controller\AccessController {
$maxShared = max($f3->get('PATHFINDER.MAP.ALLIANCE.MAX_SHARED') - 1, 0);
$accessAlliances = array_slice($accessAlliances, 0, $maxShared);
if($accessAlliances){
// clear map access. In case something has removed from access list
$map->clearAccess();
// clear map access. In case something has removed from access list
$map->clearAccess();
if($accessAlliances){
/**
* @var $tempAlliance Model\AllianceModel
*/
@@ -512,7 +513,16 @@ class Map extends Controller\AccessController {
}
// reload the same map model (refresh)
// this makes sure all data is up2date
$map->getById( $map->id, 0 );
$map->getById( $map->_id, 0 );
$charactersData = $map->getCharactersData();
$characterIds = array_map(function ($data){
return $data->id;
}, $charactersData);
// broadcast map Access -> and send map Data
$this->broadcastMapAccess($map, $characterIds);
$return->mapData = $map->getData();
}else{
@@ -546,11 +556,79 @@ class Map extends Controller\AccessController {
*/
$map = Model\BasicModel::getNew('MapModel');
$map->getById($mapData['id']);
$map->delete( $activeCharacter );
$map->delete( $activeCharacter, function($mapId){
$this->broadcastMapDeleted($mapId);
});
echo json_encode([]);
}
/**
* broadcast characters with map access rights to WebSocket server
* -> if characters with map access found -> broadcast mapData to them
* @param Model\MapModel $map
* @param array $characterIds
* @return int
*/
protected function broadcastMapAccess($map, $characterIds){
$connectionCount = 0;
$mapAccess = [
'id' => $map->_id,
'characterIds' => $characterIds
];
$charCount = (int)(new Socket( Config::getSocketUri() ))->sendData('mapAccess', $mapAccess);
if($charCount > 0){
// map has active connections that should receive map Data
$connectionCount = $this->broadcastMapData($map);
}
return $connectionCount;
}
/**
* broadcast map delete information to clients
* @param int $mapId
* @return bool|string
*/
protected function broadcastMapDeleted($mapId){
return (new Socket( Config::getSocketUri() ))->sendData('mapDeleted', $mapId);
}
/**
* get map access tokens for current character
* -> send access tokens via TCP Socket for WebSocket auth
* @param \Base $f3
*/
public function getAccessData(\Base $f3){
$return = (object) [];
$activeCharacter = $this->getCharacter();
$maps = $activeCharacter->getMaps();
$return->data = [
'id' => $activeCharacter->_id,
'token' => bin2hex(random_bytes(16)), // token for character access
'mapData' => []
];
if($maps){
foreach($maps as $map){
$return->data['mapData'][] = [
'id' => $map->_id,
'token' => bin2hex(random_bytes(16)) // token for map access
];
}
}
// send Access Data to WebSocket Server and get response (status)
// if 'OK' -> Socket exists
$return->status = (new Socket( Config::getSocketUri() ))->sendData('mapConnectionAccess', $return->data);
echo json_encode( $return );
}
/**
* update map data
* -> function is called continuously (trigger) by any active client
@@ -603,6 +681,7 @@ class Map extends Controller\AccessController {
// loop current user maps and check for changes
foreach($maps as $map){
$mapChanged = false;
// update system data ---------------------------------------------------------------------
foreach($systems as $i => $systemData){
@@ -631,6 +710,8 @@ class Map extends Controller\AccessController {
$system->updatedCharacterId = $activeCharacter;
$system->save();
$mapChanged = true;
// a system belongs to ONE map -> speed up for multiple maps
unset($systemData[$i]);
}
@@ -663,17 +744,23 @@ class Map extends Controller\AccessController {
$connection->setData($connectionData);
$connection->save();
$mapChanged = true;
// a connection belongs to ONE map -> speed up for multiple maps
unset($connectionData[$i]);
}
}
}
if($mapChanged){
$this->broadcastMapData($map);
}
}
}
}
// format map Data for return
$return->mapData = self::getFormattedMapData($maps);
$return->mapData = $this->getFormattedMapsData($maps);
// cache time(s) per user should be equal or less than this function is called
// prevent request flooding
@@ -696,23 +783,13 @@ class Map extends Controller\AccessController {
/**
* get formatted map data
* @param $mapModels
* @param Model\MapModel[] $mapModels
* @return array
*/
public static function getFormattedMapData($mapModels){
protected function getFormattedMapsData($mapModels){
$mapData = [];
foreach($mapModels as &$mapModel){
/**
* @var $mapModel Model\MapModel
*/
$allMapData = $mapModel->getData();
$mapData[] = [
'config' => $allMapData->mapData,
'data' => [
'systems' => $allMapData->systems,
'connections' => $allMapData->connections,
]
];
foreach($mapModels as $mapModel){
$mapData[] = $this->getFormattedMapData($mapModel);
}
return $mapData;

View File

@@ -53,13 +53,17 @@ class Route extends Controller\AccessController {
* -> this function is required for route search! (Don´t forget)
* @param array $mapIds
* @param array $filterData
* @param array $keepSystems
*/
public function initJumpData($mapIds = [], $filterData = []){
public function initJumpData($mapIds = [], $filterData = [], $keepSystems = []){
// add static data (e.g. K-Space stargates,..)
$this->setStaticJumpData();
// add map specific data
$this->setDynamicJumpData($mapIds, $filterData);
// filter jump data (e.g. remove some systems (0.0, LS)
$this->filterJumpData($filterData, $keepSystems);
}
/**
@@ -256,6 +260,35 @@ class Route extends Controller\AccessController {
}
}
/**
* filter systems (remove some systems) e.g. WH,LS,0.0 for "safer search"
* @param array $filterData
* @param array $keepSystems
*/
private function filterJumpData($filterData = [], $keepSystems = []){
if($filterData['safer']){
// remove all systems (TrueSec < 0.5) from search arrays
$this->jumpArray = array_filter($this->jumpArray, function($jumpData) use($keepSystems) {
// systemId is always last entry
$systemId = end($jumpData);
$systemNameData = $this->nameArray[$systemId];
$systemSec = $systemNameData[3];
if($systemSec < 0.45 && !in_array($systemId, $keepSystems)){
// remove system from nameArray as well
unset($this->nameArray[$systemId]);
// remove system from idArray as well
$systemName = $systemNameData[0];
unset($this->idArray[$systemName]);
return false;
}else{
return true;
}
});
}
}
/**
* get system data by systemId and dataName
* @param $systemId
@@ -504,7 +537,7 @@ class Route extends Controller\AccessController {
array_walk($mapData, function(&$item, &$key, $data){
if( isset($data[1][$key]) ){
// character has mas access -> do not check again
// character has map access -> do not check again
$item = $data[1][$key];
}else{
// check map access for current character
@@ -534,7 +567,8 @@ class Route extends Controller\AccessController {
'wormholes' => (bool) $routeData['wormholes'],
'wormholesReduced' => (bool) $routeData['wormholesReduced'],
'wormholesCritical' => (bool) $routeData['wormholesCritical'],
'wormholesEOL' => (bool) $routeData['wormholesEOL']
'wormholesEOL' => (bool) $routeData['wormholesEOL'],
'safer' => (bool) $routeData['safer']
];
$returnRoutData = [
@@ -553,8 +587,9 @@ class Route extends Controller\AccessController {
count($mapIds) > 0
){
$systemFrom = $routeData['systemFromData']['name'];
$systemFromId = (int)$routeData['systemFromData']['systemId'];
$systemTo = $routeData['systemToData']['name'];
$systemToId = (int)$routeData['systemToData']['systemId'];
$cacheKey = $this->getRouteCacheKey(
$mapIds,
@@ -571,7 +606,9 @@ class Route extends Controller\AccessController {
$searchDepth = $f3->get('PATHFINDER.ROUTE.SEARCH_DEPTH');
// set jump data for following route search
$this->initJumpData($mapIds, $filterData);
// --> don´t filter some systems (e.g. systemFrom, systemTo) even if they are are WH,LS,0.0
$keepSystems = [$systemFromId, $systemToId];
$this->initJumpData($mapIds, $filterData, $keepSystems);
// no cached route data found
$foundRoutData = $this->findRoute($systemFrom, $systemTo, $searchDepth);

View File

@@ -273,6 +273,9 @@ class System extends Controller\AccessController {
$newSystemModel->getById( $systemModel->id, 0);
$newSystemModel->clearCacheData();
$newSystemData = $newSystemModel->getData();
// broadcast map changes
$this->broadcastMapData($newSystemModel->mapId);
}
}
@@ -408,29 +411,41 @@ class System extends Controller\AccessController {
* @param \Base $f3
*/
public function delete(\Base $f3){
$mapId = (int)$f3->get('POST.mapId');
$systemIds = (array)$f3->get('POST.systemIds');
$activeCharacter = $this->getCharacter();
/**
* @var Model\SystemModel $system
*/
$system = Model\BasicModel::getNew('SystemModel');
foreach($systemIds as $systemId){
$system->getById($systemId);
if( $system->hasAccess($activeCharacter) ){
// check whether system should be deleted OR set "inactive"
if(
empty($system->alias) &&
empty($system->description)
){
$system->erase();
}else{
// keep data -> set "inactive"
$system->setActive(false);
$system->save();
if($mapId){
$activeCharacter = $this->getCharacter();
/**
* @var Model\MapModel $map
*/
$map = Model\BasicModel::getNew('MapModel');
$map->getById($mapId);
if( $map->hasAccess($activeCharacter) ){
foreach($systemIds as $systemId){
if( $system = $map->getSystemById($systemId) ){
// check whether system should be deleted OR set "inactive"
if(
empty($system->alias) &&
empty($system->description)
){
$system->erase();
}else{
// keep data -> set "inactive"
$system->setActive(false);
$system->save();
}
$system->reset();
}
}
$system->reset();
// broadcast map changes
$this->broadcastMapData($map);
}
}
echo json_encode([]);