public function index() { $request = RequestWrapper::$request; $target = $request->get('player'); $target_id = $request->get('player_id'); if ($target_id) { $target_player_obj = Player::find($target_id); } else { $target_player_obj = Player::findByName($target); } if ($target_player_obj === null) { $template = 'no-player.tpl'; $viewed_name_for_title = null; $parts = array(); } else { $attack_error = 'You must become a ninja first.'; $clan = Clan::findByMember($target_player_obj); $combat_skills = null; $display_clan_options = false; $items = null; $same_clan = false; $self = false; $targeted_skills = null; $template = 'player.tpl'; $viewed_name_for_title = $target_player_obj->name(); $viewing_player_obj = Player::find(SessionFactory::getSession()->get('player_id')); $kills_today = query_item('SELECT sum(killpoints) FROM levelling_log WHERE _player_id = :player_id AND killsdate = CURRENT_DATE AND killpoints > 0', [':player_id' => $target_player_obj->id()]); $rank_spot = query_item('SELECT rank_id FROM rankings WHERE player_id = :player_id limit 1', [':player_id' => $target_player_obj->id()]); if ($viewing_player_obj !== null) { $viewers_clan = Clan::findByMember($viewing_player_obj); $self = $viewing_player_obj->id() === $target_player_obj->id(); $params = ['required_turns' => 0, 'ignores_stealth' => true]; $AttackLegal = new AttackLegal($viewing_player_obj, $target_player_obj, $params); $AttackLegal->check(false); $attack_error = $AttackLegal->getError(); if (!$attack_error && !$self) { // They're not dead or otherwise unattackable. // Pull the items and some necessary data about them. $inventory = new Inventory($viewing_player_obj); $items = $inventory->counts(); $skillDAO = new SkillDAO(); if (!$viewing_player_obj->isAdmin()) { $combat_skills = $skillDAO->getSkillsByTypeAndClass($viewing_player_obj->_class_id, 'combat', $viewing_player_obj->level); $targeted_skills = $skillDAO->getSkillsByTypeAndClass($viewing_player_obj->_class_id, 'targeted', $viewing_player_obj->level); } else { $combat_skills = $skillDAO->all('combat'); $targeted_skills = $skillDAO->all('targeted'); } } if ($clan && $viewers_clan) { $same_clan = $clan->id == $viewers_clan->id; $display_clan_options = !$self && $same_clan && $viewing_player_obj->isClanLeader(); } } $parts = ['viewing_player_obj' => $viewing_player_obj, 'target_player_obj' => $target_player_obj, 'combat_skills' => $combat_skills, 'targeted_skills' => $targeted_skills, 'self' => $self, 'rank_spot' => $rank_spot, 'kills_today' => $kills_today, 'status_list' => Player::getStatusList($target_player_obj->id()), 'clan' => $clan, 'items' => $items, 'account' => Account::findByChar($target_player_obj), 'same_clan' => $same_clan, 'display_clan_options' => $display_clan_options, 'attack_error' => $attack_error]; } $parts['authenticated'] = SessionFactory::getSession()->get('authenticated', false); $title = 'Ninja' . ($viewed_name_for_title ? ": {$viewed_name_for_title}" : ' Profile'); return new StreamedViewResponse($title, $template, $parts, ['quickstat' => 'player']); }
public static function createAccount($ninja_name, $email, $class_identity) { $found = Player::findByName($ninja_name); if ($found) { throw new Exception("Test user found [{$found}] with name [{$ninja_name}] already exists"); } $ip = isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1'; // Create test user, unconfirmed, whatever the default is for activity. $confirm = rand(1000, 9999); //generate confirmation code $class_id = query_item('SELECT class_id FROM class WHERE identity = :class_identity', [':class_identity' => $class_identity]); $ninja = new Player(); $ninja->uname = $ninja_name; $ninja->verification_number = $confirm; $ninja->active = 1; $ninja->_class_id = $class_id; $ninja->save(); Account::create($ninja->id(), $email, TestAccountCreateAndDestroy::$test_password, $confirm, 0, 1, $ip); if ($confirm) { $ninja->active = 1; $ninja->save(); $account = Account::findByChar($ninja); $account->confirmed = 1; $account->setOperational(true); $account->save(); } return $ninja->id(); }
/** * Check whether the player has the skill. */ public function hasSkill($skill, $char = null) { if ($char instanceof Player) { $player = $char; } else { $player = Player::findByName($char); } $skills = $this->skills($player); $skill = strtolower($skill); $levelReq = isset($skills[$skill]['level']) ? $skills[$skill]['level'] : 1; return isset($skills[$skill]['available']) && $player->level >= $levelReq; }
/** * Display the main admin area * * Includes player viewing, account duplicates checking, npc balacing * * @return Response */ public function index() { $request = RequestWrapper::$request; if (!$this->self || !$this->self->isAdmin()) { return new RedirectResponse(WEB_ROOT); } $error = null; $char_infos = null; $char_inventory = null; $first_message = null; $first_char = null; $first_account = null; $first_description = null; $dupes = AdminViews::dupedIps(); $stats = AdminViews::highRollers(); $npcs = NpcFactory::allNonTrivialNpcs(); $trivial_npcs = NpcFactory::allTrivialNpcs(); $char_ids = preg_split("/[,\\s]+/", $request->get('view')); $char_name = trim($request->get('char_name')); if ($char_name) { // View a target non-self character $first_char = Player::findByName($char_name); if (null !== $first_char && null !== $first_char->id()) { $char_ids = [$first_char->id()]; } } if (is_array($char_ids)) { // Get a different first character if an array is specified $first_char = $first_char ? $first_char : Player::find(reset($char_ids)); if ($first_char) { assert($first_char instanceof Player); $first_account = Account::findByChar($first_char); $char_inventory = AdminViews::charInventory($first_char); $first_message = $first_char->messages; $first_description = $first_char->description; } // All the rest multi-character table view try { $char_infos = AdminViews::charInfos($char_ids); } catch (InvalidArgumentException $e) { $error = $e->getMessage(); } } $parts = ['error' => $error, 'stats' => $stats, 'first_char' => $first_char, 'first_description' => $first_description, 'first_message' => $first_message, 'first_account' => $first_account, 'char_infos' => $char_infos, 'dupes' => $dupes, 'char_inventory' => $char_inventory, 'char_name' => $char_name, 'npcs' => $npcs, 'trivial_npcs' => $trivial_npcs]; return new StreamedViewResponse('Admin Actions', 'ninjamaster.tpl', $parts); }
/** * Send a private message to a player * * @param Container */ public function sendPersonal(Container $p_dependencies) { $request = RequestWrapper::$request; if ((int) $request->get('target_id')) { $recipient = Player::find((int) $request->get('target_id')); } else { if ($request->get('to')) { $recipient = Player::findByName($request->get('to')); } else { $recipient = null; } } if ($recipient) { Message::create(['send_from' => $p_dependencies['session']->get('player_id'), 'send_to' => $recipient->id(), 'message' => $request->get('message', null), 'type' => 0]); return new RedirectResponse('/messages?command=personal&individual_or_clan=1&message_sent_to=' . rawurlencode($recipient->name()) . '&informational=' . rawurlencode('Message sent to ' . $recipient->name() . '.')); } else { return new RedirectResponse('/messages?command=personal&error=' . rawurlencode('No such ninja to message.')); } }
/** * Command for the current user to offer their money as bounty on another player * * @param Container * @param target String The username of the player to offer a bounty on * @param amount int The amount of gold to spend on offering the bounty * @return StreamedViewResponse * * @TODO simplify the conditional branching */ public function offerBounty(Container $p_dependencies) { $request = RequestWrapper::$request; $targetName = $request->get('target'); $char = Player::findPlayable($this->getAccountId()); $target = Player::findByName($targetName); $amountIn = $request->get('amount'); $amount = intval($amountIn) !== 0 ? intval($amountIn) : null; $quickstat = false; $success = false; $authenticated = $char !== null; if (!$char) { $error = 2; // You don't have enough gold. } elseif (!$target) { $error = 1; // Target not found } elseif ($target->id() === $char->id()) { $error = 6; // Can't put a bounty on yourself. } else { $error = $this->validateBountyOffer($char, $target->id(), $amount); $amount = self::calculateMaxOffer($target->bounty, $amount); if (!$error) { $char->setGold($char->gold - $amount); // Subtract the gold. $target->setBounty($target->bounty + $amount); $target->save(); $char = $char->save(); Event::create($char->id(), $target->id(), $char->name() . " has offered " . $amount . " gold in reward for your head!"); $success = true; $quickstat = 'player'; } } return $this->render(['error' => $error, 'authenticated' => $authenticated, 'success' => $success, 'quickstat' => $quickstat, 'amount_in' => $amountIn, 'amount' => $amount, 'command' => 'offer', 'location' => 0, 'target' => $target]); }
public function testFindAccountByNinja() { $player = Player::findByName($this->test_ninja_name); $account = Account::findByChar($player); $this->assertNotNull($account); }
public function testFindByNameNegative() { $char = Player::findByName('BANANA_IS_FAKE$$$NOTREAL=;m"'); $this->assertNull($char); }
public function testSuccessfulSignupResultsInNoConfirmation() { $uname = 'KnownGood'; $email = '*****@*****.**'; // Due to the nature of hotmail, hotmail emails are listed // such that they will not be preconfirmed. This leaves an account needing confirmation. RequestWrapper::inject(new Request(['key' => 'password1', 'cpass' => 'password1', 'send_email' => $email, 'send_name' => $uname])); $controller = new SignupController(); $response = $controller->signup($this->m_dependencies); $account = Account::findByEmail($email); $player = Player::findByName($uname); $this->assertNotNull($player); $this->assertNotNull($account); $query_relationship = 'SELECT count(*) FROM account_players WHERE _account_id = :id1 AND _player_id = :id2'; $account_unconfirmed = null; if ($account && $player) { $relationship_count = query_item($query_relationship, [':id1' => $account->id(), ':id2' => $player->id()]); $account_unconfirmed = !$account->isConfirmed(); } else { $relationship_count = 0; } $delete_player = 'DELETE FROM players WHERE player_id = :id'; $delete_account = 'DELETE FROM accounts WHERE account_id = :id'; $delete_relationship = 'DELETE FROM account_players WHERE _account_id = :id1 OR _player_id = :id2'; query($delete_player, [':id' => $player->id()]); query($delete_account, [':id' => $account->id()]); query($delete_relationship, [':id1' => $account->id(), ':id2' => $player->id()]); $reflection = new \ReflectionProperty(get_class($response), 'data'); $reflection->setAccessible(true); $response_data = $reflection->getValue($response); $this->assertTrue($response_data['submit_successful'], 'Signup() returned error: ' . $response_data['error']); $this->assertEquals($relationship_count, 1); $this->assertTrue($account_unconfirmed); }
/** * Use, the skills_mod equivalent * * @note Test with urls like: * http://nw.local/skill/use/Fire%20Bolt/10 * http://nw.local/skill/self_use/Unstealth/ * http://nw.local/skill/self_use/Heal/ */ public function useSkill($self_use = false) { // Template vars. $display_sight_table = $generic_skill_result_message = $generic_state_change = $killed_target = $loot = $added_bounty = $bounty = $suicided = $destealthed = null; $error = null; $char_id = SessionFactory::getSession()->get('player_id'); $player = Player::find($char_id); $path = RequestWrapper::getPathInfo(); $slugs = $this->parseSlugs($path); // (fullpath0) /skill1/use2/Fire%20Bolt3/tchalvak4/(beagle5/) $act = isset($slugs[3]) ? $slugs[3] : null; $target = isset($slugs[4]) ? $slugs[4] : null; $target2 = isset($slugs[5]) ? $slugs[5] : null; if (!Filter::toNonNegativeInt($target)) { if ($self_use) { $target = $char_id; } else { if ($target !== null) { $targetObj = Player::findByName($target); $target = $targetObj ? $targetObj->id() : null; } else { $target = null; } } } if ($target2 && !Filter::toNonNegativeInt($target2)) { $target2Obj = Player::findByName($target2); $target2 = $target2Obj ? $target2Obj->id() : null; } $skillListObj = new Skill(); // *** Before level-based addition. $turn_cost = $skillListObj->getTurnCost(strtolower($act)); $ignores_stealth = $skillListObj->getIgnoreStealth($act); $self_usable = $skillListObj->getSelfUse($act); $use_on_target = $skillListObj->getUsableOnTarget($act); $ki_cost = 0; // Ki taken during use. $reuse = true; // Able to reuse the skill. $today = date("F j, Y, g:i a"); // Check whether the user actually has the needed skill. $has_skill = $skillListObj->hasSkill($act, $player); assert($turn_cost >= 0); if ($self_use) { // Use the skill on himself. $return_to_target = false; $target = $player; $target_id = null; } else { if ($target != '' && $target != $player->player_id) { $target = Player::find($target); $target_id = $target->id(); $return_to_target = true; } else { // For target that doesn't exist, e.g. http://nw.local/skill/use/Sight/zigzlklkj error_log('Info: Attempt to use a skill on a target that did not exist.'); return new RedirectResponse(WEB_ROOT . 'skill/?error=' . rawurlencode('Invalid target for skill [' . rawurlencode($act) . '].')); } } $covert = false; $victim_alive = true; $attacker_id = $player->name(); $attacker_char_id = $player->id(); $starting_turns = $player->turns; $level_check = $player->level - $target->level; if ($player->hasStatus(STEALTH)) { $attacker_id = 'A Stealthed Ninja'; } $use_attack_legal = true; if ($act == 'Clone Kill' || $act == 'Harmonize') { $has_skill = true; $use_attack_legal = false; $attack_allowed = true; $attack_error = null; $covert = true; } else { // *** Checks the skill use legality, as long as the target isn't self. $params = ['required_turns' => $turn_cost, 'ignores_stealth' => $ignores_stealth, 'self_use' => $self_use]; $AttackLegal = new AttackLegal($player, $target, $params); $update_timer = isset($this->update_timer) ? $this->update_timer : true; $attack_allowed = $AttackLegal->check($update_timer); $attack_error = $AttackLegal->getError(); } if (!$attack_error) { // Only bother to check for other errors if there aren't some already. if (!$has_skill || $act == '') { // Set the attack error to display that that skill wasn't available. $attack_error = 'You do not have the requested skill.'; } elseif ($starting_turns < $turn_cost) { $turn_cost = 0; $attack_error = "You do not have enough turns to use {$act}."; } } if (!$attack_error) { // Nothing to prevent the attack from happening. // Initial attack conditions are alright. $result = ''; if ($act == 'Sight') { $covert = true; $sight_data = $this->pullSightData($target); $display_sight_table = true; } elseif ($act == 'Steal') { $covert = true; $gold_decrease = min($target->gold, rand(5, 50)); $player->setGold($player->gold + $gold_decrease); $player->save(); $target->setGold($target->gold - $gold_decrease); $target->save(); $msg = "{$attacker_id} stole {$gold_decrease} gold from you."; Event::create($attacker_char_id, $target->id(), $msg); $generic_skill_result_message = "You have stolen {$gold_decrease} gold from __TARGET__!"; } else { if ($act == 'Unstealth') { $state = 'unstealthed'; if ($target->hasStatus(STEALTH)) { $target->subtractStatus(STEALTH); $generic_state_change = "You are now {$state}."; } else { $turn_cost = 0; $generic_state_change = "__TARGET__ is already {$state}."; } } else { if ($act == 'Stealth') { $covert = true; $state = 'stealthed'; if (!$target->hasStatus(STEALTH)) { $target->addStatus(STEALTH); $target->subtractStatus(STALKING); $generic_state_change = "__TARGET__ is now {$state}."; } else { $turn_cost = 0; $generic_state_change = "__TARGET__ is already {$state}."; } } else { if ($act == 'Stalk') { $state = 'stalking'; if (!$target->hasStatus(STALKING)) { $target->addStatus(STALKING); $target->subtractStatus(STEALTH); $generic_state_change = "__TARGET__ is now {$state}."; } else { $turn_cost = 0; $generic_state_change = "__TARGET__ is already {$state}."; } } else { if ($act == 'Kampo') { $covert = true; // *** Get Special Items From Inventory *** $user_id = $player->id(); $root_item_type = 7; $itemCount = query_item('SELECT sum(amount) AS c FROM inventory WHERE owner = :owner AND item_type = :type GROUP BY item_type', [':owner' => $user_id, ':type' => $root_item_type]); $turn_cost = min($itemCount, $starting_turns - 1, 2); // Costs 1 or two depending on the number of items. if ($turn_cost && $itemCount > 0) { // *** If special item count > 0 *** $inventory = new Inventory($player); $inventory->remove('ginsengroot', $itemCount); $inventory->add('tigersalve', $itemCount); $generic_skill_result_message = 'With intense focus you grind the ' . $itemCount . ' roots into potent formulas.'; } else { // *** no special items, give error message *** $turn_cost = 0; $generic_skill_result_message = 'You do not have the necessary ginsengroots or energy to create any Kampo formulas.'; } } else { if ($act == 'Poison Touch') { $covert = true; $target->addStatus(POISON); $target->addStatus(WEAKENED); // Weakness kills strength. $target_damage = rand(self::MIN_POISON_TOUCH, $this->maxPoisonTouch()); $victim_alive = $target->harm($target_damage); $generic_state_change = "__TARGET__ has been poisoned!"; $generic_skill_result_message = "__TARGET__ has taken {$target_damage} damage!"; $msg = "You have been poisoned by {$attacker_id}"; Event::create($attacker_char_id, $target->id(), $msg); } elseif ($act == 'Fire Bolt') { $target_damage = $this->fireBoltBaseDamage($player) + rand(1, $this->fireBoltMaxDamage($player)); $generic_skill_result_message = "__TARGET__ has taken {$target_damage} damage!"; $victim_alive = $target->harm($target_damage); $msg = "You have had fire bolt cast on you by " . $player->name(); Event::create($player->id(), $target->id(), $msg); } else { if ($act == 'Heal' || $act == 'Harmonize') { // This is the starting template for self-use commands, eventually it'll be all refactored. $harmonize = false; if ($act == 'Harmonize') { $harmonize = true; } $hurt = $target->is_hurt_by(); // Check how much the TARGET is hurt (not the originator, necessarily). // Check that the target is not already status healing. if ($target->hasStatus(HEALING) && !$player->isAdmin()) { $turn_cost = 0; $generic_state_change = '__TARGET__ is already under a healing aura.'; } elseif ($hurt < 1) { $turn_cost = 0; $generic_skill_result_message = '__TARGET__ is already fully healed.'; } else { if (!$harmonize) { $original_health = $target->health; $heal_points = $player->getStamina() + 1; $new_health = $target->heal($heal_points); // Won't heal more than possible $healed_by = $new_health - $original_health; } else { $start_health = $player->health; // Harmonize those chakra! $player = $this->harmonizeChakra($player); $healed_by = $player->health - $start_health; $ki_cost = $healed_by; } $target->addStatus(HEALING); $generic_skill_result_message = "__TARGET__ healed by {$healed_by} to " . $target->health . "."; if ($target->id() != $player->id()) { Event::create($attacker_char_id, $target->id(), "You have been healed by {$attacker_id} for {$healed_by}."); } } } else { if ($act == 'Ice Bolt') { if ($target->hasStatus(SLOW)) { $turn_cost = 0; $generic_skill_result_message = '__TARGET__ is already iced.'; } else { if ($target->turns >= 10) { $turns_decrease = rand(1, 5); $target->turns = $target->turns - $turns_decrease; // Changed ice bolt to kill stealth. $target->subtractStatus(STEALTH); $target->subtractStatus(STALKING); $target->addStatus(SLOW); $msg = "Ice bolt cast on you by {$attacker_id}, your turns have been reduced by {$turns_decrease}."; Event::create($attacker_char_id, $target->id(), $msg); $generic_skill_result_message = "__TARGET__'s turns reduced by {$turns_decrease}!"; } else { $turn_cost = 0; $generic_skill_result_message = "__TARGET__ does not have enough turns for you to take."; } } } else { if ($act == 'Cold Steal') { if ($target->hasStatus(SLOW)) { $turn_cost = 0; $generic_skill_result_message = '__TARGET__ is already iced.'; } else { $critical_failure = rand(1, 100); if ($critical_failure > 7) { // *** If the critical failure rate wasn't hit. if ($target->turns >= 10) { $turns_diff = rand(2, 7); $target->turns = $target->turns - $turns_diff; $player->turns = $player->turns + $turns_diff; // Stolen $target->addStatus(SLOW); $msg = "You have had Cold Steal cast on you for {$turns_diff} by {$attacker_id}"; Event::create($attacker_char_id, $target->id(), $msg); $generic_skill_result_message = "You cast Cold Steal on __TARGET__ and take {$turns_diff} turns."; } else { $turn_cost = 0; $generic_skill_result_message = '__TARGET__ did not have enough turns to give you.'; } } else { // *** CRITICAL FAILURE !! $player->addStatus(FROZEN); $unfreeze_time = date('F j, Y, g:i a', mktime(date('G') + 1, 0, 0, date('m'), date('d'), date('Y'))); $failure_msg = "You have experienced a critical failure while using Cold Steal. You will be unfrozen on {$unfreeze_time}"; Event::create((int) 0, $player->id(), $failure_msg); $generic_skill_result_message = "Cold Steal has backfired! You are frozen until {$unfreeze_time}!"; } } } else { if ($act == 'Clone Kill') { // Obliterates the turns and the health of similar accounts that get clone killed. $reuse = false; // Don't give a reuse link. $clone1 = Player::findByName($target); $clone2 = Player::findByName($target2); if (!$clone1 || !$clone2) { $not_a_ninja = $target; if (!$clone2) { $not_a_ninja = $target2; } $generic_skill_result_message = "There is no such ninja as {$not_a_ninja}."; } elseif ($clone1->id() == $clone2->id()) { $generic_skill_result_message = '__TARGET__ is just the same ninja, so not the same thing as a clone at all.'; } elseif ($clone1->id() == $char_id || $clone2->id() == $char_id) { $generic_skill_result_message = 'You cannot clone kill yourself.'; } else { // The two potential clones will be obliterated immediately if the criteria are met in CloneKill. $kill_or_fail = CloneKill::kill($player, $clone1, $clone2); if ($kill_or_fail !== false) { $generic_skill_result_message = $kill_or_fail; } else { $generic_skill_result_message = "Those two ninja don't seem to be clones."; } } } } } } } } } } } } // ************************** Section applies to all skills ****************************** if (!$victim_alive) { // Someone died. if ($target->player_id == $player->player_id) { // Attacker killed themself. $loot = 0; $suicided = true; } else { // Attacker killed someone else. $killed_target = true; $gold_mod = 0.15; $loot = floor($gold_mod * $target->gold); $player->setGold($player->gold + $loot); $target->setGold($target->gold - $loot); $player->addKills(1); $added_bounty = floor($level_check / 5); if ($added_bounty > 0) { $player->setBounty($player->bounty + $added_bounty * 25); } else { if ($target->bounty > 0 && $target->id() !== $player->id()) { // No suicide bounty, No bounty when your bounty getting ++ed. $player->setGold($player->gold + $target->bounty); // Reward the bounty $target->setBounty(0); // Wipe the bounty } } $target_message = "{$attacker_id} has killed you with {$act} and taken {$loot} gold."; Event::create($attacker_char_id, $target->id(), $target_message); $attacker_message = "You have killed {$target} with {$act} and taken {$loot} gold."; Event::create($target->id(), $player->id(), $attacker_message); } } if (!$covert && $player->hasStatus(STEALTH)) { $player->subtractStatus(STEALTH); $destealthed = true; } $target->save(); } // End of the skill use SUCCESS block. $player->turns = $player->turns - max(0, $turn_cost); // Take the skill use cost. $player->save(); $ending_turns = $player->turns; $target_ending_health = $target->health; $target_name = $target->name(); $parts = get_defined_vars(); $options = ['quickstat' => 'player']; return new StreamedViewResponse('Skill Effect', 'skills_mod.tpl', $parts, $options); }
function testPauseAccountAndLoginShouldFail() { $player = Player::findByName($this->test_ninja_name); $player->active = 1; $player->save(); $account = Account::findByChar($player); $account->confirmed = 1; $account->setOperational(true); $account->save(); $accountController = new AccountController(); $controller = new LoginController(); $res = $controller->performLogin($this->test_email, $this->test_password); $this->assertEmpty($res, 'Login should be successful when account is new'); // Fully pause the account, make the operational bit = false $player->active = 0; $player->save(); $account->setOperational(false); $account->save(); $res = $controller->performLogin($this->test_email, $this->test_password); $this->assertNotEmpty($res, 'Login should not be successful when account is paused'); }
/** * Helper to find a player by either id or name * * @return Player */ private function findPlayer($token) { if (Filter::toNonNegativeInt($token)) { $target = Player::find(Filter::toNonNegativeInt($token)); } else { $target = Player::findByName($token); } return $target; }