- improved _auto-connections_ for _podded_ pilots, closed #752, closed #355, closed #259, closed #235

This commit is contained in:
Mark Friedrich
2019-04-19 16:31:36 +02:00
parent 51b3fd41f0
commit e0fb6f19f5
8 changed files with 145 additions and 87 deletions

View File

@@ -35,7 +35,7 @@ CCP_SSO_DOWNTIME = 11:00
; CCP ESI API
CCP_ESI_URL = https://esi.evetech.net
CCP_ESI_DATASOURCE = singularity
CCP_ESI_SCOPES = esi-location.read_online.v1,esi-location.read_location.v1,esi-location.read_ship_type.v1,esi-ui.write_waypoint.v1,esi-ui.open_window.v1,esi-universe.read_structures.v1,esi-corporations.read_corporation_membership.v1
CCP_ESI_SCOPES = esi-location.read_online.v1,esi-location.read_location.v1,esi-location.read_ship_type.v1,esi-ui.write_waypoint.v1,esi-ui.open_window.v1,esi-universe.read_structures.v1,esi-corporations.read_corporation_membership.v1,esi-clones.read_clones.v1
CCP_ESI_SCOPES_ADMIN =
; SMTP settings (optional)
@@ -88,7 +88,7 @@ CCP_SSO_DOWNTIME = 11:00
; CCP ESI API
CCP_ESI_URL = https://esi.evetech.net
CCP_ESI_DATASOURCE = tranquility
CCP_ESI_SCOPES = esi-location.read_online.v1,esi-location.read_location.v1,esi-location.read_ship_type.v1,esi-ui.write_waypoint.v1,esi-ui.open_window.v1,esi-universe.read_structures.v1,esi-corporations.read_corporation_membership.v1
CCP_ESI_SCOPES = esi-location.read_online.v1,esi-location.read_location.v1,esi-location.read_ship_type.v1,esi-ui.write_waypoint.v1,esi-ui.open_window.v1,esi-universe.read_structures.v1,esi-corporations.read_corporation_membership.v1,esi-clones.read_clones.v1
CCP_ESI_SCOPES_ADMIN =
; SMTP settings (optional)

View File

@@ -317,7 +317,7 @@ class Map extends Controller\AccessController {
$mapDataSystems = (array)$mapDataData['systems'];
$mapDataConnections = (array)$mapDataData['connections'];
$systemCount = count($mapDataSystems);
if( $systemCount <= $defaultConfig['max_systems']){
if($systemCount <= $defaultConfig['max_systems']){
$map->copyfrom($mapDataConfig, ['name', 'icon', 'position', 'locked', 'rallyUpdated', 'rallyPoke']);
$map->typeId = $mapType;
@@ -583,7 +583,7 @@ 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);
// broadcast map Access -> and send map Data
$this->broadcastMapAccess($map);
@@ -717,7 +717,7 @@ class Map extends Controller\AccessController {
$return->status = $status;
echo json_encode( $return );
echo json_encode($return);
}
/**
@@ -817,7 +817,7 @@ class Map extends Controller\AccessController {
$return->userData = $activeCharacter->getUser()->getData();
}
echo json_encode( $return );
echo json_encode($return);
}
/**
@@ -901,7 +901,7 @@ class Map extends Controller\AccessController {
// add error (if exists)
$return->error = [];
echo json_encode( $return );
echo json_encode($return);
}
@@ -987,6 +987,7 @@ class Map extends Controller\AccessController {
$addSourceSystem = false;
$addTargetSystem = false;
$addConnection = false;
$route = [];
switch($mapScope->name){
case 'all':
@@ -1031,10 +1032,9 @@ class Map extends Controller\AccessController {
){
// check distance between systems (in jumps)
// -> if > 1 it is !very likely! a wormhole
$routeController = new Route();
$route = $routeController->searchRoute($sourceSystem->systemId, $targetSystem->systemId, 1);
$route = (new Route())->searchRoute($sourceSystem->systemId, $targetSystem->systemId, 1);
if( !$route['routePossible'] ){
if(!$route['routePossible']){
$addSourceSystem = true;
$addTargetSystem = true;
$addConnection = true;
@@ -1043,7 +1043,7 @@ class Map extends Controller\AccessController {
break;
}
// save source system ---------------------------------------------------------------------------------
// save source system =============================================================================
if(
$addSourceSystem &&
$sourceSystem &&
@@ -1061,7 +1061,7 @@ class Map extends Controller\AccessController {
}
}
// save target system ---------------------------------------------------------------------------------
// save target system =============================================================================
if(
$addTargetSystem &&
$targetSystem &&
@@ -1082,23 +1082,52 @@ class Map extends Controller\AccessController {
$sourceSystem &&
$targetSystem
){
$connection = $map->searchConnection( $sourceSystem, $targetSystem);
$connection = $map->searchConnection($sourceSystem, $targetSystem);
// save connection --------------------------------------------------------------------------------
// save connection ============================================================================
if(
$addConnection &&
!$connection
){
$connection = $map->getNewConnection($sourceSystem, $targetSystem);
$connection = $map->saveConnection($connection, $character);
// get updated maps object
if($connection){
$map = $connection->mapId;
$mapDataChanged = true;
// .. do not add connection if character got "podded" -------------------------------------
if(
$log->shipTypeId == 670 &&
$character->cloneLocationId
){
// .. current character location must be clone location
if(
(
'station' == $character->cloneLocationType &&
$character->cloneLocationId == $log->stationId
) || (
'structure' == $character->cloneLocationType &&
$character->cloneLocationId == $log->structureId
)
){
// .. now we need to check jump distance between systems
// -> if > 1 it is !very likely! podded jump
if(empty($route)){
$route = (new Route())->searchRoute($sourceSystem->systemId, $targetSystem->systemId, 1);
}
if(!$route['routePossible']){
$addConnection = false;
}
}
}
if($addConnection){
$connection = $map->getNewConnection($sourceSystem, $targetSystem);
$connection = $map->saveConnection($connection, $character);
// get updated maps object
if($connection){
$map = $connection->mapId;
$mapDataChanged = true;
}
}
}
// log jump mass ----------------------------------------------------------------------------------
// log jump mass ==============================================================================
if(
$connection &&
$connection->isWormhole()
@@ -1122,7 +1151,7 @@ class Map extends Controller\AccessController {
* @param \Base $f3
* @throws Exception
*/
public function getConnectionData (\Base $f3){
public function getConnectionData(\Base $f3){
$postData = (array)$f3->get('POST');
$addData = (array)$postData['addData'];
@@ -1217,16 +1246,3 @@ class Map extends Controller\AccessController {
}
}

View File

@@ -37,7 +37,7 @@ class User extends Controller\Controller{
/**
* valid reasons for captcha images
* @var string array
* @var array
*/
private static $captchaReason = [self::SESSION_CAPTCHA_ACCOUNT_UPDATE, self::SESSION_CAPTCHA_ACCOUNT_DELETE];
@@ -68,25 +68,27 @@ class User extends Controller\Controller{
is_null($currentUser) ||
$currentUser->_id !== $user->_id
){
// user has changed OR new user ---------------------------------------------------
// user has changed OR new user -----------------------------------------------------------------------
//-> set user/character data to session
$this->getF3()->set(self::SESSION_KEY_USER, [
'ID' => $user->_id,
'NAME' => $user->name
]);
}else{
// user has NOT changed -----------------------------------------------------------
// user has NOT changed -------------------------------------------------------------------------------
$sessionCharacters = $character::mergeSessionCharacterData($sessionCharacters);
}
$this->getF3()->set(self::SESSION_KEY_CHARACTERS, $sessionCharacters);
// save user login information --------------------------------------------------------
$character->roleId = $character->requestRole();
$character->updateCloneData();
$character->updateRoleData();
// save user login information ----------------------------------------------------------------------------
$character->touch('lastLogin');
$character->save();
// write login log --------------------------------------------------------------------
// write login log ----------------------------------------------------------------------------------------
self::getLogger('CHARACTER_LOGIN')->write(
sprintf(self::LOG_LOGGED_IN,
$user->_id,
@@ -96,7 +98,7 @@ class User extends Controller\Controller{
)
);
// set temp character data ------------------------------------------------------------
// set temp character data --------------------------------------------------------------------------------
// -> pass character data over for next http request (reroute())
$this->setTempCharacterData($character->_id);
@@ -263,7 +265,7 @@ class User extends Controller\Controller{
if($activeCharacter = $this->getCharacter()){
$user = $activeCharacter->getUser();
// captcha is send -> check captcha -------------------------------------------
// captcha is send -> check captcha ---------------------------------------------------------------
if(
isset($formData['captcha']) &&
!empty($formData['captcha'])
@@ -303,7 +305,7 @@ class User extends Controller\Controller{
}
}
// sharing config -------------------------------------------------------------
// sharing config ---------------------------------------------------------------------------------
if(isset($formData['share'])){
$privateSharing = (int)$formData['privateSharing'];
$corporationSharing = (int)$formData['corporationSharing'];
@@ -327,7 +329,7 @@ class User extends Controller\Controller{
$activeCharacter->save();
}
// character config -----------------------------------------------------------
// character config -------------------------------------------------------------------------------
if(isset($formData['character'])){
$activeCharacter->copyfrom($formData, ['logLocation', 'selectLocation']);

View File

@@ -69,7 +69,7 @@ class Sso extends Api\User{
isset($params['characterId']) &&
( $activeCharacter = $this->getCharacter() )
){
// authentication restricted to a characterId -----------------------------------------------
// authentication restricted to a characterId -------------------------------------------------------------
// restrict login to this characterId e.g. for character switch on map page
$characterId = (int)trim((string)$params['characterId']);
@@ -114,7 +114,7 @@ class Sso extends Api\User{
$f3->set(self::SESSION_KEY_SSO_FROM, 'map');
}
// redirect to CCP SSO ----------------------------------------------------------------------
// redirect to CCP SSO ----------------------------------------------------------------------------------------
$scopes = self::getScopesByAuthType();
$this->rerouteAuthorization($f3, $scopes);
}

View File

@@ -384,13 +384,11 @@ class Controller {
* @return array
* @throws \Exception
*/
public function getSessionCharacterData(){
public function getSessionCharacterData() : array {
$data = [];
if($user = $this->getUser()){
$header = self::getRequestHeaders();
$requestedCharacterId = (int)$header['Pf-Character'];
if( !$this->getF3()->get('AJAX') ){
$requestedCharacterId = (int)$_COOKIE['old_char_id'];
if(!$requestedCharacterId){
@@ -398,7 +396,6 @@ class Controller {
if((int)$tempCharacterData['ID'] > 0){
$requestedCharacterId = (int)$tempCharacterData['ID'];
}
}
}

View File

@@ -1376,7 +1376,6 @@ class Setup extends Controller {
ksort($requiredTables);
$this->databases[$dbAlias]['info'] = [
// 'db' => $db,
'label' => $dbLabel,
'host' => $dbConfigValues['SOCKET'] ? : $dbConfigValues['HOST'],
'port' => $dbConfigValues['PORT'] && !$dbConfigValues['SOCKET'] ? $dbConfigValues['PORT'] : '',

View File

@@ -16,6 +16,9 @@ use Model\Universe;
class CharacterModel extends AbstractPathfinderModel {
/**
* @var string
*/
protected $table = 'character';
/**
@@ -23,6 +26,9 @@ class CharacterModel extends AbstractPathfinderModel {
*/
const DATA_CACHE_KEY_LOG = 'LOG';
/**
* log message for character access
*/
const LOG_ACCESS = 'charId: [%20s], status: %s, charName: %s';
/**
@@ -52,8 +58,10 @@ class CharacterModel extends AbstractPathfinderModel {
* @var bool
*/
private $allowBanChange = false;
/**
* @var array
*/
protected $fieldConf = [
'lastLogin' => [
'type' => Schema::DT_TIMESTAMP,
@@ -124,6 +132,16 @@ class CharacterModel extends AbstractPathfinderModel {
]
],
],
'cloneLocationId' => [
'type' => Schema::DT_BIGINT,
'index' => true,
'activity-log' => true
],
'cloneLocationType' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
'default' => ''
],
'kicked' => [
'type' => Schema::DT_TIMESTAMP,
'index' => true
@@ -490,39 +508,42 @@ class CharacterModel extends AbstractPathfinderModel {
/**
* get ESI API "access_token" from OAuth
* @return bool|mixed
* @throws \Exception
*/
public function getAccessToken(){
$accessToken = false;
$refreshToken = true;
$timezone = self::getF3()->get('getTimeZone')();
$now = new \DateTime('now', $timezone);
try{
$timezone = self::getF3()->get('getTimeZone')();
$now = new \DateTime('now', $timezone);
if(
!empty($this->esiAccessToken) &&
!empty($this->esiAccessTokenExpires)
){
$expireTime = \DateTime::createFromFormat(
'Y-m-d H:i:s',
$this->esiAccessTokenExpires,
$timezone
);
// check if token is not expired
if($expireTime->getTimestamp() > $now->getTimestamp()){
// token still valid
$accessToken = $this->esiAccessToken;
// check if token should be renewed (close to expire)
$timeBuffer = 2 * 60;
$expireTime->sub(new \DateInterval('PT' . $timeBuffer . 'S'));
if(
!empty($this->esiAccessToken) &&
!empty($this->esiAccessTokenExpires)
){
$expireTime = \DateTime::createFromFormat(
'Y-m-d H:i:s',
$this->esiAccessTokenExpires,
$timezone
);
// check if token is not expired
if($expireTime->getTimestamp() > $now->getTimestamp()){
// token NOT close to expire
$refreshToken = false;
// token still valid
$accessToken = $this->esiAccessToken;
// check if token should be renewed (close to expire)
$timeBuffer = 2 * 60;
$expireTime->sub(new \DateInterval('PT' . $timeBuffer . 'S'));
if($expireTime->getTimestamp() > $now->getTimestamp()){
// token NOT close to expire
$refreshToken = false;
}
}
}
}catch(\Exception $e){
self::getF3()->error(500, $e->getMessage(), $e->getTrace());
}
// no valid "accessToken" found OR
@@ -673,7 +694,7 @@ class CharacterModel extends AbstractPathfinderModel {
* @return RoleModel
* @throws \Exception
*/
public function requestRole() : RoleModel{
protected function requestRole() : RoleModel {
$role = null;
// check config files for hardcoded character roles
@@ -718,7 +739,7 @@ class CharacterModel extends AbstractPathfinderModel {
* @return array
* @throws \Exception
*/
protected function requestRoles(){
protected function requestRoles() : array {
$rolesData = [];
// check if character has accepted all admin scopes (one of them is required for "role" request)
@@ -741,16 +762,39 @@ class CharacterModel extends AbstractPathfinderModel {
* check whether this char has accepted all "basic" api scopes
* @return bool
*/
public function hasBasicScopes(){
return empty( array_diff(Sso::getScopesByAuthType(), $this->esiScopes) );
public function hasBasicScopes() : bool {
return empty(array_diff(Sso::getScopesByAuthType(), $this->esiScopes));
}
/**
* check whether this char has accepted all admin api scopes
* @return bool
*/
public function hasAdminScopes(){
return empty( array_diff(Sso::getScopesByAuthType('admin'), $this->esiScopes) );
public function hasAdminScopes() : bool {
return empty(array_diff(Sso::getScopesByAuthType('admin'), $this->esiScopes));
}
/**
* update clone data
*/
public function updateCloneData(){
if($accessToken = $this->getAccessToken()){
$clonesData = self::getF3()->ccpClient()->getCharacterClonesData($this->_id, $accessToken);
if(!isset($clonesData['error'])){
if(!empty($homeLocationData = $clonesData['home']['location'])){
// clone home location data
$this->cloneLocationId = (int)$homeLocationData['id'];
$this->cloneLocationType = (string)$homeLocationData['type'];
}
}
}
}
/**
* @throws \Exception
*/
public function updateRoleData(){
$this->roleId = $this->requestRole();
}
/**
@@ -760,7 +804,7 @@ class CharacterModel extends AbstractPathfinderModel {
* @return CharacterModel
* @throws \Exception
*/
public function updateLog($additionalOptions = []){
public function updateLog($additionalOptions = []) : self {
$deleteLog = false;
$invalidResponse = false;
@@ -966,7 +1010,7 @@ class CharacterModel extends AbstractPathfinderModel {
* @return array (some status messages)
* @throws \Exception
*/
public function updateFromESI(){
public function updateFromESI() : array {
$status = [];
if( $accessToken = $this->getAccessToken() ){
@@ -1005,7 +1049,7 @@ class CharacterModel extends AbstractPathfinderModel {
* -> but is should be unique
* @return string
*/
public function getCookieName(){
public function getCookieName() : string {
return md5($this->name);
}

View File

@@ -209,7 +209,7 @@ class UserModel extends AbstractPathfinderModel {
* @return array
* @throws Exception
*/
public function getSessionCharacterData($characterId = 0, $objectCheck = true){
public function getSessionCharacterData($characterId = 0, $objectCheck = true) : array {
$data = [];
$characterId = (int)$characterId;
$currentSessionUser = (array)$this->getF3()->get(User::SESSION_KEY_USER);
@@ -254,7 +254,7 @@ class UserModel extends AbstractPathfinderModel {
* @param int $characterId
* @return array
*/
public function findSessionCharacterData(int $characterId): array{
public function findSessionCharacterData(int $characterId): array {
$data = [];
if($characterId){
$sessionCharacters = (array)$this->getF3()->get(User::SESSION_KEY_CHARACTERS);