- fixed multi character support location tracking, closed #314

This commit is contained in:
Exodus4D
2016-09-16 21:57:04 +02:00
parent 74faec37c9
commit 23eb032759
6 changed files with 121 additions and 85 deletions

View File

@@ -779,7 +779,8 @@ class Map extends Controller\AccessController {
$systemPosX = 0;
$systemPosY = 30;
$sourceSystemId = (int)$this->getF3()->get(User::SESSION_KEY_CHARACTERS_PREV_SYSTEM_ID);
$sessionCharacter = $this->getSessionCharacterData();
$sourceSystemId = (int)$sessionCharacter['PREV_SYSTEM_ID'];
$targetSystemId = (int)$log->systemId;
if($sourceSystemId){

View File

@@ -43,29 +43,6 @@ class User extends Controller\Controller{
*/
private static $captchaReason = [self::SESSION_CAPTCHA_ACCOUNT_UPDATE, self::SESSION_CAPTCHA_ACCOUNT_DELETE];
/**
* merges two multidimensional characterSession arrays by checking characterID
* @param array $characterDataBase
* @param array $characterData
* @return array
*/
private function mergeSessionCharacterData($characterDataBase = [], $characterData = []){
$addData = [];
foreach($characterDataBase as $i => $baseData){
foreach($characterData as $data){
if((int)$baseData['ID'] === (int)$data['ID']){
// overwrite changes
$characterDataBase[$i]['NAME'] = $data['NAME'];
$characterDataBase[$i]['TIME'] = $data['TIME'];
}else{
$addData[] = $data;
}
}
}
return array_merge($characterDataBase, $addData);
}
/**
* login a valid character
* @param Model\CharacterModel $characterModel
@@ -99,10 +76,7 @@ class User extends Controller\Controller{
]);
}else{
// user has NOT changed -----------------------------------------------------------
// -> get current session characters
$currentSessionCharacters = (array)$this->f3->get(self::SESSION_KEY_CHARACTERS);
$sessionCharacters = $this->mergeSessionCharacterData($sessionCharacters, $currentSessionCharacters);
$sessionCharacters = $characterModel::mergeSessionCharacterData($sessionCharacters);
}
$this->f3->set(self::SESSION_KEY_CHARACTERS, $sessionCharacters);

View File

@@ -319,62 +319,38 @@ class Controller {
/**
* get current character data from session
* ->
* @return array
*/
protected function getSessionCharacterData(){
public function getSessionCharacterData(){
$data = [];
$currentSessionCharacters = (array)$this->getF3()->get(Api\User::SESSION_KEY_CHARACTERS);
$requestedCharacterId = 0;
// get all characterData from currently active characters
if($this->getF3()->get('AJAX')){
// Ajax request -> get characterId from Header (if already available!)
$header = $this->getRequestHeaders();
$requestedCharacterId = (int)$header['Pf-Character'];
if($user = $this->getUser()){
$requestedCharacterId = 0;
if(
$requestedCharacterId > 0 &&
(int)$this->getF3()->get(Api\User::SESSION_KEY_TEMP_CHARACTER_ID) === $requestedCharacterId
){
// characterId is available in Javascript
// -> clear temp characterId for next character login/switch
$this->getF3()->clear(Api\User::SESSION_KEY_TEMP_CHARACTER_ID);
}
}
// get all characterData from currently active characters
if($this->getF3()->get('AJAX')){
// Ajax request -> get characterId from Header (if already available!)
$header = $this->getRequestHeaders();
$requestedCharacterId = (int)$header['Pf-Character'];
if($requestedCharacterId <= 0){
// Ajax BUT characterID not yet set as HTTP header
// OR non Ajax -> get characterId from temp session (e.g. from HTTP redirect)
$requestedCharacterId = (int)$this->getF3()->get(Api\User::SESSION_KEY_TEMP_CHARACTER_ID);
}
if($requestedCharacterId > 0){
// search for session character data
foreach($currentSessionCharacters as $characterData){
if($requestedCharacterId === (int)$characterData['ID']){
$data = $characterData;
break;
if(
$requestedCharacterId > 0 &&
(int)$this->getF3()->get(Api\User::SESSION_KEY_TEMP_CHARACTER_ID) === $requestedCharacterId
){
// requested characterId is "now" available on the client (Javascript)
// -> clear temp characterId for next character login/switch
$this->getF3()->clear(Api\User::SESSION_KEY_TEMP_CHARACTER_ID);
}
}
}elseif( !empty($currentSessionCharacters) ){
// no character was requested ($requestedCharacterId = 0) AND session characters were found
// -> get first matched character (e.g. user open browser tab)
$data = $currentSessionCharacters[0];
}
if( !empty($data) ){
// check if character still exists on DB (e.g. was manually removed in the meantime)
// -> This should NEVER happen just for security and "local development"
$character = Model\BasicModel::getNew('CharacterModel');
$character->getById( (int)$data['ID']);
if(
$character->dry() ||
!$character->hasUserCharacter()
){
// character data is invalid!
$data = [];
if($requestedCharacterId <= 0){
// Ajax BUT characterID not yet set as HTTP header
// OR non Ajax -> get characterId from temp session (e.g. from HTTP redirect)
$requestedCharacterId = (int)$this->getF3()->get(Api\User::SESSION_KEY_TEMP_CHARACTER_ID);
}
$data = $user->getSessionCharacterData($requestedCharacterId);
}
return $data;

View File

@@ -8,8 +8,8 @@
namespace Model;
use Controller\Api\User;
use Controller\Controller;
use Controller\Api\User as User;
use Controller\Controller as Controller;
use DB\SQL\Schema;
class CharacterLogModel extends BasicModel {
@@ -192,6 +192,10 @@ class CharacterLogModel extends BasicModel {
return $logData;
}
/**
* @param int $systemId
* @return int
*/
public function set_systemId($systemId){
if($systemId > 0){
$this->updateCharacterSessionLocation($systemId);
@@ -205,20 +209,21 @@ class CharacterLogModel extends BasicModel {
*/
protected function updateCharacterSessionLocation($systemId){
$controller = new Controller();
$f3 = $this->getF3();
$systemId = (int)$systemId;
if(
( $activeCharacter = $controller->getCharacter() ) &&
( $activeCharacter->_id === $this->characterId->_id )
!empty($sessionCharacter = $controller->getSessionCharacterData()) &&
$sessionCharacter['ID'] === $this->get('characterId', true)
){
$prevSystemId = (int)$f3->get( User::SESSION_KEY_CHARACTERS_PREV_SYSTEM_ID);
$prevSystemId = (int)$sessionCharacter['PREV_SYSTEM_ID'];
if($prevSystemId === 0){
$f3->set( User::SESSION_KEY_CHARACTERS_PREV_SYSTEM_ID, $systemId);
$sessionCharacter['PREV_SYSTEM_ID'] = (int)$systemId;
}else{
$f3->set( User::SESSION_KEY_CHARACTERS_PREV_SYSTEM_ID, (int)$this->systemId);
$sessionCharacter['PREV_SYSTEM_ID'] = $this->systemId;
}
$sessionCharacters = CharacterModel::mergeSessionCharacterData([$sessionCharacter]);
$this->getF3()->set(User::SESSION_KEY_CHARACTERS, $sessionCharacters);
}
}

View File

@@ -10,8 +10,8 @@ namespace Model;
use Controller;
use Controller\Ccp\Sso as Sso;
use Controller\Api\User as User;
use DB\SQL\Schema;
use Data\Mapper as Mapper;
class CharacterModel extends BasicModel {
@@ -527,4 +527,29 @@ class CharacterModel extends BasicModel {
}
}
/**
* merges two multidimensional characterSession arrays by checking characterID
* @param array $characterDataBase
* @return array
*/
static function mergeSessionCharacterData(array $characterDataBase = []){
$addData = [];
// get current session characters to be merged with
$characterData = (array)self::getF3()->get(User::SESSION_KEY_CHARACTERS);
foreach($characterDataBase as $i => $baseData){
foreach($characterData as $data){
if((int)$baseData['ID'] === (int)$data['ID']){
// overwrite static data -> should NEVER change on merge!
$characterDataBase[$i]['NAME'] = $data['NAME'];
$characterDataBase[$i]['TIME'] = $data['TIME'];
}else{
$addData[] = $data;
}
}
}
return array_merge($characterDataBase, $addData);
}
}

View File

@@ -10,7 +10,7 @@ namespace Model;
use DB\SQL\Schema;
use Controller;
use Controller\Api;
use Controller\Api\User as User;
use Exception;
class UserModel extends BasicModel {
@@ -152,6 +152,61 @@ class UserModel extends BasicModel {
return $this->getByForeignKey('name', $name, [], 0);
}
/**
* get current character data from session
* -> if §characterID == 0 -> get first character data (random)
* @param int $characterId
* @param bool $objectCheck
* @return array
*/
public function getSessionCharacterData($characterId = 0, $objectCheck = true){
$data = [];
$characterId = (int)$characterId;
$currentSessionUser = (array)$this->getF3()->get(User::SESSION_KEY_USER);
if($this->_id === $currentSessionUser['ID']){
// user matches session data
$sessionCharacters = (array)$this->getF3()->get(User::SESSION_KEY_CHARACTERS);
if($characterId > 0){
// search for specific characterData
foreach($sessionCharacters as $characterData){
if($characterId === (int)$characterData['ID']){
$data = $characterData;
break;
}
}
}elseif( !empty($sessionCharacters) ){
// no character was requested ($requestedCharacterId = 0) AND session characters were found
// -> get first matched character (e.g. user open browser tab)
$data = $sessionCharacters[0];
}
}
if(
$objectCheck === true &&
!empty($data)
){
// check if character still exists on DB (e.g. was manually removed in the meantime)
// -> This should NEVER happen just for security and "local development"
/**
* @var $character CharacterModel
*/
$character = BasicModel::getNew('CharacterModel');
$character->getById( (int)$data['ID']);
if(
$character->dry() ||
!$character->hasUserCharacter()
){
// character data is invalid!
$data = [];
}
}
return $data;
}
/**
* get all userCharacters models for a user
* characters will be checked/updated on login by CCP API call