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']); }
/** * Display the combat/action events and mark them as read when displayed. * * @return Response */ public function index() { $char = Player::find(SessionFactory::getSession()->get('player_id')); $events = $this->getEvents($char->id(), 300); $this->readEvents($char->id()); // mark events as viewed. $parts = ['events' => $events, 'has_clan' => (bool) Clan::findByMember($char), 'char' => $char]; return new StreamedViewResponse('Events', 'events.tpl', $parts, ['quickstat' => 'player']); }
/** * The standard homepage * * @return Response */ private function game() { // Get the actual values of the vars. $ninja = Player::find(SessionFactory::getSession()->get('player_id')); $playerInfo = $ninja->data(); $clan = $ninja ? Clan::findByMember($ninja) : null; $unreadCount = Message::where(['send_to' => $ninja->id(), 'unread' => 1])->count(); // Assign these vars to the template. $parts = ['main_src' => '/intro', 'body_classes' => 'main-body', 'version' => 'NW Version 1.7.5 2010.12.05', 'ninja' => $ninja, 'player_info' => $playerInfo, 'clan' => $clan, 'unread_message_count' => $unreadCount]; return new StreamedViewResponse('Live by the Shuriken', 'index.tpl', $parts, ['is_index' => true]); }
public function testStealthDecreasesStrengthIncreasesStamina() { $pc = new Player(); $str = $pc->getStrength(); $stamina = $pc->getStamina(); $speed = $pc->getSpeed(); $pc->addStatus(STEALTH); $this->assertTrue($pc->hasStatus(STEALTH)); $this->assertLessThan($str, $pc->getStrength(), 'Stealth failed to affect strength.'); $this->assertGreaterThan($stamina, $pc->getStamina(), 'Stealth status failed to affect stamina.'); $this->assertGreaterThan($speed, $pc->getSpeed(), 'Stealth status failed to affect speed.'); }
public function setUp() { $this->char = Player::find(TestAccountCreateAndDestroy::char_id()); SessionFactory::init(new MockArraySessionStorage()); $session = SessionFactory::getSession(); $session->set('player_id', $this->char->id()); // Mock the login. $request = new Request([], []); RequestWrapper::inject($request); }
/** */ public function setUp() { $this->m_dependencies = new Container(); $this->m_dependencies['session'] = function ($c) { return SessionFactory::getSession(); }; $this->m_dependencies['current_player'] = $this->m_dependencies->factory(function ($c) { return Player::find(SessionFactory::getSession()->get('player_id')); }); }
/** * Test that you can't attack if an excessive amount of turns is required */ public function testCantAttackIfExcessiveAmountOfTurnsIsRequired() { $confirm = true; $char_id = TestAccountCreateAndDestroy::create_testing_account($confirm); $this->oldify_character_last_attack($char_id); $char_2_id = TestAccountCreateAndDestroy::create_alternate_testing_account($confirm); $this->oldify_character_last_attack($char_2_id); $char = Player::find($char_2_id); $legal = new AttackLegal(Player::find($char_id), $char, ['required_turns' => 4000000000, 'ignores_stealth' => true]); $this->assertFalse($legal->check(false)); }
protected function setUp() { $this->player = new Player(); $this->player->uname = $this->data->uname; $this->player->player_id = $this->data->player_id; $this->player->level = $this->data->level; $this->player->health = $this->data->health; $this->player->stamina = Player::baseStaminaByLevel($this->data->level); $this->player->strength = Player::baseStrengthByLevel($this->data->level); $this->player->speed = Player::baseSpeedByLevel($this->data->level); }
public function setUp() { SessionFactory::init(new MockArraySessionStorage()); $char_id = TestAccountCreateAndDestroy::char_id(); $char = Player::find($char_id); $account = Account::findByChar($char); $account_id = $account->id(); SessionFactory::getSession()->set('authenticated', true); SessionFactory::getSession()->set('player_id', $char_id); SessionFactory::getSession()->set('account_id', $account_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; }
/** * Rewards bounty if defender has some, or increments attacker bounty if power disparity * * @return string */ public static function runBountyExchange(Player $user, $defender, $bounty_mod = 0) { assert($defender instanceof Character); // 'cause can't typehint interfaces if ($defender instanceof Player && $defender->bounty > 0) { $bounty = $defender->bounty; $defender->setBounty(0); $defender->save(); $user->setGold($user->gold + $bounty); $user->save(); return "You have received the {$bounty} gold bounty on {$defender}'s head for your deeds!"; } else { // Add bounty to attacker only if defender doesn't already have bounty on them. $disparity = (int) floor(($user->difficulty() - $defender->difficulty()) / 10); $bountyIncrease = min(self::BOUNTY_MIN, max(0, $disparity * static::BOUNTY_MULTIPLIER + $bounty_mod)); // Cap the increase. if ($bountyIncrease + $user->bounty > static::BOUNTY_MAX) { $bountyIncrease = static::BOUNTY_MAX - $user->bounty; } if ($bountyIncrease > 0) { // If Defender has no bounty and there was a level difference $user->setBounty($user->bounty + $bountyIncrease); $user->save(); return "Your victim was much weaker than you. The townsfolk are angered. A bounty of {$bountyIncrease} gold has been placed on your head!"; } else { return ''; } } }
public function testAttackWhenDead() { $attacker = Player::find(SessionFactory::getSession()->get('player_id')); $attacker->death(); $attacker->save(); $char_id_2 = TestAccountCreateAndDestroy::char_id_2(); $params = ['target' => $char_id_2]; $request = Request::create('/attack', 'GET', $params); RequestWrapper::inject($request); $response = $this->controller->index($this->m_dependencies); $this->assertInstanceOf(StreamedViewResponse::class, $response); $reflection = new \ReflectionProperty(get_class($response), 'data'); $reflection->setAccessible(true); $response_data = $reflection->getValue($response); $this->assertNotEmpty($response_data['error']); }
/** * 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); }
/** * Check if a player can access any of this controllers methods * * This method is a holdover from old times when controllers were * actually directly servable procedural scripts (ah the old days!) * If a page required you to be alive or logged in, we checked if * you were (among a bunch of other things, usually dropping variables * in the global namespace) and if you were not, returned an error. * Now, controllers do this at a class level, which is mostly nonsense * and requires that the router directly serve an error page. * * @return string * @TODO this whole thing should be factored out. */ public function validate() { $error = null; $player = Player::find(SessionFactory::getSession()->get('player_id')); if ((!SessionFactory::getSession()->get('authenticated') || !$player) && static::PRIV) { $error = 'log_in'; } elseif ($player && static::ALIVE) { // That page requires the player to be alive to view it if (!$player->health) { $error = 'dead'; } else { if ($player->hasStatus(FROZEN)) { $error = 'frozen'; } } } return $error; }
/** * 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.')); } }
/** * Perform the effects of a clonekill. * @return string outcome or false */ public static function kill(Player $self, Player $clone1, Player $clone2) { if (self::canKill($clone1, $clone2)) { $today = date("F j, Y, g:i a"); $clone1_health = $clone1->health; $clone2_health = $clone2->health; $clone1_turns = $clone1->turns; $clone2_turns = $clone2->turns; $clone1->changeTurns(-1 * $clone1->turns); $clone1->death(); $clone2->changeTurns(-1 * $clone2->turns); $clone2->death(); $clone1->save(); $clone2->save(); $result_message = "You obliterate the clone {$clone1->name()} for {$clone1_health} health, {$clone1_turns} turns\n and the clone {$clone2->name()} for {$clone2_health} health, {$clone2_turns} turns."; Event::create($self->id(), $clone1->id(), "You and {$clone2->name()} were Clone Killed at {$today}."); Event::create($self->id(), $clone2->id(), "You and {$clone1->name()} were Clone Killed at {$today}."); return $result_message; } else { return false; } }
/** * Displays a template wrapped in the header and footer as needed. */ public function displayPage($template, $title = null, $local_vars = array(), $options = null) { // Updates the quickstat via javascript if requested. $quickstat = isset($options['quickstat']) ? $options['quickstat'] : null; $quickstat = $quickstat ? $quickstat : (isset($local_vars['quickstat']) ? $local_vars['quickstat'] : null); $body_classes = isset($options['body_classes']) ? $options['body_classes'] : (isset($local_vars['body_classes']) ? $local_vars['body_classes'] : null); $is_index = isset($options['is_index']) ? $options['is_index'] : false; $user_id = SessionFactory::getSession()->get('player_id'); $player = Player::find($user_id); $public_char_info = $player ? $player->publicData() : []; // Char info to pass to javascript. $this->assign($local_vars); $this->assign('logged_in', $user_id); $this->assign('user_id', $user_id); $this->assign('title', $title); $this->assign('quickstat', $quickstat); $this->assign('is_index', $is_index); $this->assign('json_public_char_info', $public_char_info ? json_encode($public_char_info) : null); $this->assign('body_classes', $body_classes); $this->assign('main_template', $template); $this->display('full_template.tpl'); }
function smarty_function_health_percent($p_params) { $health = $p_params['health']; $level = $p_params['level']; return min(100, round($health / Player::maxHealthByLevel($level) * 100)); }
/** * Normal attack on a single thief. */ private function attackNormalThief(Player $player) { $damage = rand(0, 35); // Damage done $gold = 0; if ($victory = $player->harm($damage)) { $gold = rand(0, 40); // Gold in question if ($damage > 30) { // Steal gold $player->setGold(max(0, $player->gold - $gold)); } else { if ($damage < 30) { // award gold and item $player->setGold($player->gold + $gold); $inventory = new Inventory($player); $inventory->add('shuriken', 1); } } } $player->save(); return ['npc.thief.tpl', ['attack' => $damage, 'gold' => $gold, 'victory' => $victory]]; }
/** * Guard1: * Dam: 1 to attacker_str + 40 * Gold: 1 to attacker_str + 40 * Bounty: 10 + 0-10 * 1 in 9 chance of ginseng root * Guard2: Strength is about 30, which is multiplied by 2, + 1 point during damage calc. * Gold doesn't get boosted by strength */ public function testGuard2AbstractNpcIsSimilarToGuard1() { if (!DEBUG) { $this->markTestSkipped(); } $guard2 = new Npc('guard2'); $mock_pc = new Player(); $mock_pc->setStrength(30); $dam = $guard2->maxDamage($mock_pc); // partial_match_strength should add about 1/3rd of the enemies' strength as dam. $this->assertGreaterThan(40, $dam); $this->assertLessThan(80, $dam); // Dam is strength * 2 + 1 $this->assertLessThan(61, $guard2->gold()); $this->assertGreaterThan(40, $guard2->gold()); $this->assertGreaterThan(9, $guard2->bountyMod()); }
public function testFindPrivateMessagesForACertainChar() { $messageCount = 4; $this->messageData['send_to'] = $this->char_id; $this->messageData['send_from'] = $this->char_id_2; for ($count = 0; $count < $messageCount; $count++) { $this->messageData['message'] = 'Random phpunit test message' . $count; Message::create($this->messageData); // Test deletes these } $char = Player::find($this->char_id); $messages = Message::findByReceiver($char)->all(); $this->assertEquals($messageCount, count($messages)); Message::deleteByReceiver($char, 0); $this->assertEquals(0, Message::countByReceiver($char)); }
public function testFindAccountByNinja() { $player = Player::findByName($this->test_ninja_name); $account = Account::findByChar($player); $this->assertNotNull($account); }
/** */ public function testDojoChangeClassLowTurnsDoesNotError() { $request = Request::create('/', 'GET', ['requested_identity' => 'crane']); RequestWrapper::inject($request); $char = Player::find($this->char_id); $char->setStrength(400); $char->setTurns(0); $char->save(); $this->assertNotEmpty($this->controller->changeClass($this->m_dependencies)); }
require_once dirname(__DIR__ . '..') . '/lib/base.inc.php'; use Pimple\Container; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use NinjaWars\core\RouteNotFoundException; use NinjaWars\core\Router; use NinjaWars\core\environment\RequestWrapper; use NinjaWars\core\data\GameLog; use NinjaWars\core\data\Player; use NinjaWars\core\extensions\SessionFactory; // setup our runtime environment require_once LIB_ROOT . 'environment/bootstrap.php'; try { $container = new Container(); $container['current_player'] = function ($c) { return Player::find(SessionFactory::getSession()->get('player_id')); }; $container['session'] = function ($c) { return SessionFactory::getSession(); }; // Update the activity of the page viewer in the database. RequestWrapper::init(); GameLog::updateActivityInfo(RequestWrapper::$request, SessionFactory::getSession()); // get the request information to parse the route $response = Router::route(Request::createFromGlobals(), $container); if ($response instanceof Response) { $response->send(); } else { throw new \RuntimeException('Route returned something other than a Response'); } } catch (RouteNotFoundException $e) {
/** * Revive up to a small max in minor hours, and a stable percent on major hours. * * Generally the objective is to cause a minor-minor-major pattern: * Revive to a fixed minimum number of alive every time (minor or major), * and revive beyond the minimum, by percent, every major time * to slowly creep towards 100% by healing a percent of whoever is dead * For example, if 1,000 out of 1,000 are dead: * Minor revive heals to the minimum of 100 * Minor revive heals none (100 are already alive) * Major revive heals 50 from those that are dead (number 5% of all actives) * minor revive heals 0 (because at least 100 are already alive) * minor revive heals 0 (because at least 100 are already alive) * Major revive heals another 50 from those that are dead (if any) * etc * * Defaults * sample_use: revive_players(30, 3)); * @param array('minor_revive_to'=>100, 'major_revive_percent'=>5, * 'just_testing'=>false) * @return mixed */ public function revivePlayers($set = array()) { $minor_revive_to = isset($set['minor_revive_to']) ? $set['minor_revive_to'] : 100; $major_revive_percent = isset($set['major_revive_percent']) ? $set['major_revive_percent'] : 5; $major_hour = 3; // Hour for the major revive. $pc_data = self::pcsActiveDeadAlive(); assert($pc_data['active'] > 0); // If none dead, return false. if ($pc_data['dead'] < 1) { return array(0, 0); } $game_hour = self::gameHour(); assert(is_numeric($game_hour)); // Calculate the revive amount if (!($game_hour % $major_hour == 0)) { // minor if ($pc_data['alive'] >= $minor_revive_to) { return array(0, $pc_data['dead']); // No revives called for yet! } else { // else revive minor_revive_to - total_alive. $revive_amount = (int) floor($minor_revive_to - $pc_data['alive']); } } else { // major. $percent_int = (int) floor($major_revive_percent / 100 * $pc_data['active']); // Use the max of either pcs dead, or revives requested $revive_amount = min($percent_int, $pc_data['dead']); } assert(isset($revive_amount)); $maximum_heal = Player::maxHealthByLevel(MAX_PLAYER_LEVEL); $revived = self::performNecromancy($revive_amount, $maximum_heal, $game_hour); return [$revived, $pc_data['dead']]; }
/** * Just return a character wholesale */ public static function char() { return Player::find(TestAccountCreateAndDestroy::char_id()); }
function testGetClanObjectNumericRating() { $this->markTestIncomplete('Clan rating is not yet implemented'); $player1 = Player::find($this->char_id); $clan = Clan::find($this->clan_id); $this->assertTrue($clan->addMember($player1, $player1)); $this->assertTrue($clan->addMember(Player::find($this->char_id_2), $player1)); $this->assertTrue($clan->rating()); }
private function jsonIndex() { DatabaseConnection::getInstance(); $player = Player::find(SessionFactory::getSession()->get('player_id')); $events = []; $messages = []; $unread_messages = null; $unread_events = null; $items = null; if ($player) { $events = DatabaseConnection::$pdo->prepare("SELECT event_id, message AS event, date, send_to, send_from, unread, uname AS sender FROM events JOIN players ON player_id = send_from WHERE send_to = :userID and unread = 1 ORDER BY date DESC"); $events->bindValue(':userID', $player->id()); $events->execute(); $unread_events = $events->rowCount(); $messages = DatabaseConnection::$pdo->prepare("SELECT message_id, message, date, send_to, send_from, unread, uname AS sender FROM messages JOIN players ON player_id = send_from WHERE send_to = :userID1 AND send_from != :userID2 and unread = 1 ORDER BY date DESC"); $messages->bindValue(':userID1', $player->id()); $messages->bindValue(':userID2', $player->id()); $messages->execute(); $unread_messages = $messages->rowCount(); $items = query_array('SELECT item.item_display_name as item, amount FROM inventory join item on inventory.item_type = item.item_id WHERE owner = :user_id ORDER BY item_display_name', [':user_id' => $player->id()]); } return ['player' => $player ? $player->publicData() : [], 'member_counts' => $this->memberCounts(), 'unread_messages_count' => $unread_messages, 'message' => !empty($messages) ? $messages->fetch() : null, 'inventory' => ['inv' => 1, 'items' => $items, 'hash' => md5(strtotime("now"))], 'unread_events_count' => $unread_events, 'event' => !empty($events) ? $events->fetch() : null]; }
/** * @return void */ private function stealthStrike(Player $attacker, Player $target) { $target->harm($attacker->getStrength()); $attacker->turns = $attacker - turns - 1 * self::STEALTH_STRIKE_COST; }
/** * Returns a view spec hash for rendering a template * * @param Array $parts Hash of variables to pass to the view * @return Response */ private function render($parts) { $char = Player::findPlayable($this->getAccountId()); if (!$char) { $char = new Player(); } $myBounty = $char->bounty; // Pulling the bounties. $bounties = query_array("SELECT player_id, uname, bounty, class_name AS class, level, clan_id, clan_name\n FROM players JOIN class ON class_id = _class_id LEFT JOIN clan_player ON player_id = _player_id\n LEFT JOIN clan ON clan_id = _clan_id WHERE bounty > 0 AND active = 1 and health > 0 ORDER BY bounty DESC"); $parts['bounties'] = $bounties; $parts['myBounty'] = $myBounty; $parts['char'] = $char; $parts['display_gold'] = number_format($char->gold); $quickstat = $parts['quickstat']; return new StreamedViewResponse('Doshin Office', 'doshin.tpl', $parts, ['quickstat' => $quickstat]); }