From 9618fd3add331bb45ddf34fbbdb8ad3e097a42ed Mon Sep 17 00:00:00 2001 From: Graham Knop Date: Tue, 8 Mar 2011 13:57:34 -0600 Subject: [PATCH 1/8] simplify lacuna.psgi --- bin/lacuna.psgi | 416 ++++++++++++++++++++++++------------------------ 1 file changed, 211 insertions(+), 205 deletions(-) diff --git a/bin/lacuna.psgi b/bin/lacuna.psgi index f9e36dff..83086270 100644 --- a/bin/lacuna.psgi +++ b/bin/lacuna.psgi @@ -6,6 +6,7 @@ use Log::Log4perl; use Log::Any::Adapter; use Lacuna; use Plack::Builder; +use JSON qw(encode_json); $|=1; @@ -16,216 +17,221 @@ use Log::Log4perl; Log::Log4perl::init('/data/Lacuna-Server/etc/log4perl.conf'); Log::Any::Adapter->set('Log::Log4perl'); -my $urlmap = Plack::App::URLMap->new; - -$urlmap->map('/starman_ping' => sub { [200, [ 'Content-Type' => 'text/plain'], [ 'pong' ]] } ); - -$urlmap->map("/map" => Lacuna::RPC::Map->new->to_app); -$urlmap->map("/body" => Lacuna::RPC::Body->new->to_app); -$urlmap->map("/empire" => Lacuna::RPC::Empire->new->to_app); -$urlmap->map("/alliance" => Lacuna::RPC::Alliance->new->to_app); -$urlmap->map("/inbox" => Lacuna::RPC::Inbox->new->to_app); -$urlmap->map("/stats" => Lacuna::RPC::Stats->new->to_app); -$urlmap->map("/pay" => Lacuna::Web::Pay->new->to_app); -$urlmap->map("/chat" => Lacuna::Web::Chat->new->to_app); -$urlmap->map("/chat/rpc" => Lacuna::RPC::Chat->new->to_app); -$urlmap->map("/entertainment/vote" => Lacuna::Web::EntertainmentVote->new->to_app); -$urlmap->map("/announcement" => Lacuna::Web::Announcement->new->to_app); -$urlmap->map("/facebook" => Lacuna::Web::Facebook->new->to_app); -$urlmap->map("/apikey" => Lacuna::Web::ApiKey->new->to_app); -$urlmap->map("/essentia-code" => Lacuna::RPC::EssentiaCode->new->to_app); -$urlmap->map("/captcha" => Lacuna::RPC::Captcha->new->to_app); - -# buildings -$urlmap->map(Lacuna::RPC::Building::DistributionCenter->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::SAW->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::AtmosphericEvaporator->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::GreatBallOfJunk->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::JunkHengeSculpture->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::MetalJunkArches->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::PyramidJunkSculpture->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::SpaceJunkPark->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::ThemePark->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::BlackHoleGenerator->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::TheDillonForge->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::HallsOfVrbansk->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::GratchsGauntlet->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::KasternsKeep->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::SubspaceSupplyDepot->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::SupplyPod->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::PantheonOfHagness->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Capitol->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Stockpile->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Algae->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Apple->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Bean->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beeldeban->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Bread->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Burger->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Cheese->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Chip->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Cider->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Corn->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::CornMeal->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::EssentiaVein->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Volcano->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::MassadsHenge->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::LibraryOfJith->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::NaturalSpring->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::OracleOfAnid->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::TempleOfTheDrajilites->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::GeoThermalVent->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::InterDimensionalRift->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::CitadelOfKnope->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::CrashedShipSite->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::KalavianRuins->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Grove->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Sand->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Lagoon->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Crater->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Dairy->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Denton->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Development->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Embassy->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::EnergyReserve->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Entertainment->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Espionage->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Fission->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::FoodReserve->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Fusion->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::DeployedBleeder->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::GasGiantLab->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::GasGiantPlatform->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Geo->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Hydrocarbon->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Intelligence->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Lapis->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Malcud->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Mine->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::MiningMinistry->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Network19->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Observatory->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::OreRefinery->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::OreStorage->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Pancake->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Park->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Pie->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::PlanetaryCommand->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Potato->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Propulsion->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Oversight->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::RockyOutcrop->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Lake->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Security->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Shake->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Shipyard->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Singularity->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Soup->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::SpacePort->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Syrup->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::TerraformingLab->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::GeneticsLab->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Archaeology->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::TerraformingPlatform->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Trade->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Transporter->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::University->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::WasteEnergy->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::WasteRecycling->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::WasteSequestration->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::WasteDigester->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::WasteTreatment->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::WaterProduction->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::WaterPurification->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::WaterReclamation->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::WaterStorage->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Wheat->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach1->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach2->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach3->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach4->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach5->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach6->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach7->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach8->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach9->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach10->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach11->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach12->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Beach13->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::PilotTraining->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::MissionCommand->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::CloakingLab->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::MunitionsLab->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::LuxuryHousing->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::Ravine->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::AlgaePond->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::LapisForest->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::BeeldebanNest->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::MalcudField->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::SSLa->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::SSLb->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::SSLc->new->to_app_with_url); -$urlmap->map(Lacuna::RPC::Building::SSLd->new->to_app_with_url); - - -# admin -my $admin = builder { - enable "Auth::Basic", authenticator => sub { - my ($username, $password) = @_; - return 0 unless $username; - my $empire = Lacuna->db->resultset('Lacuna::DB::Result::Empire')->search({name => $username, is_admin => 1},{rows=>1})->single; - return 0 unless defined $empire; - return $empire->is_password_valid($password); - }; - Lacuna::Web::Admin->new->to_app; -}; -$urlmap->map("/admin" => $admin); - -# mission curator -my $curator = builder { - enable "Auth::Basic", authenticator => sub { - my ($username, $password) = @_; - return 0 unless $username; - my $empire = Lacuna->db->resultset('Lacuna::DB::Result::Empire')->search({name => $username, is_mission_curator => 1},{rows=>1})->single; - return 0 unless defined $empire; - return $empire->is_password_valid($password); - }; - Lacuna::Web::MissionCurator->new->to_app; -}; -$urlmap->map("/missioncurator" => $curator); - -my $online = builder { +my $offline = [ 500, + [ 'Content-Type' => 'application/json-rpc' ], + [ encode_json( { + "jsonrpc" => "2.0", + "error" => { + "code" => -32000, + "message" => "The server is offline for maintenance.", + } + } ) ], +]; + +my $gameover = [ 500, + [ 'Content-Type' => 'application/json-rpc' ], + [ encode_json( { + "jsonrpc" => "2.0", + "error" => { + "code" => 1200, + "message" => "Game Over", + "data" => "http://community.lacunaexanse.com/wiki/hall-of-fame", + } + } ) ], +]; + +builder { enable 'CrossOrigin', origins => '*', methods => ['GET', 'POST'], max_age => 60*60*24*30, headers => '*'; - $urlmap->to_app; -}; - -my $offline = [ 500, - ['Content-Type' => 'application/json-rpc' ], - [ '{"jsonrpc" : "2.0", "error" : { "code" : "-32000", "message" : "The server is offline for maintenance." }}' ], - ]; -my $gameover = [ 1200, - ['Content-Type' => 'application/json-rpc' ], - [ '{"jsonrpc" : "2.0", "error" : { "code" : "1200", "message" : "Game Over", "data" : "http://community.lacunaexanse.com/wiki/hall-of-fame" }}' ], - ]; + enable sub { + my $app = shift; + return sub { + my ($env) = @_; + my $status = Lacuna->cache->get('server','status'); + if ($status eq 'Offline') { + return $offline; + } + elsif ($status eq 'Game Over') { + return $gameover; + } + $app->($env); + } + }; -print "Server Up\n"; -my $app = sub { - my @args = @_; - my $status = Lacuna->cache->get('server','status'); - if ($status eq 'Offline') { - return $offline; - } - elsif ($status eq 'Game Over') { - return $gameover; + mount '/starman_ping' => sub { [200, [ 'Content-Type' => 'text/plain'], [ 'pong' ]] }; + + mount "/map" => Lacuna::RPC::Map->new->to_app; + mount "/body" => Lacuna::RPC::Body->new->to_app; + mount "/empire" => Lacuna::RPC::Empire->new->to_app; + mount "/alliance" => Lacuna::RPC::Alliance->new->to_app; + mount "/inbox" => Lacuna::RPC::Inbox->new->to_app; + mount "/stats" => Lacuna::RPC::Stats->new->to_app; + mount "/pay" => Lacuna::Web::Pay->new->to_app; + mount "/chat" => Lacuna::Web::Chat->new->to_app; + mount "/chat/rpc" => Lacuna::RPC::Chat->new->to_app; + mount "/entertainment/vote" => Lacuna::Web::EntertainmentVote->new->to_app; + mount "/announcement" => Lacuna::Web::Announcement->new->to_app; + mount "/facebook" => Lacuna::Web::Facebook->new->to_app; + mount "/apikey" => Lacuna::Web::ApiKey->new->to_app; + mount "/essentia-code" => Lacuna::RPC::EssentiaCode->new->to_app; + mount "/captcha" => Lacuna::RPC::Captcha->new->to_app; + + for my $building (qw( + Lacuna::RPC::Building::DistributionCenter + Lacuna::RPC::Building::SAW + Lacuna::RPC::Building::AtmosphericEvaporator + Lacuna::RPC::Building::GreatBallOfJunk + Lacuna::RPC::Building::JunkHengeSculpture + Lacuna::RPC::Building::MetalJunkArches + Lacuna::RPC::Building::PyramidJunkSculpture + Lacuna::RPC::Building::SpaceJunkPark + Lacuna::RPC::Building::ThemePark + Lacuna::RPC::Building::BlackHoleGenerator + Lacuna::RPC::Building::TheDillonForge + Lacuna::RPC::Building::HallsOfVrbansk + Lacuna::RPC::Building::GratchsGauntlet + Lacuna::RPC::Building::KasternsKeep + Lacuna::RPC::Building::SubspaceSupplyDepot + Lacuna::RPC::Building::SupplyPod + Lacuna::RPC::Building::PantheonOfHagness + Lacuna::RPC::Building::Capitol + Lacuna::RPC::Building::Stockpile + Lacuna::RPC::Building::Algae + Lacuna::RPC::Building::Apple + Lacuna::RPC::Building::Bean + Lacuna::RPC::Building::Beeldeban + Lacuna::RPC::Building::Bread + Lacuna::RPC::Building::Burger + Lacuna::RPC::Building::Cheese + Lacuna::RPC::Building::Chip + Lacuna::RPC::Building::Cider + Lacuna::RPC::Building::Corn + Lacuna::RPC::Building::CornMeal + Lacuna::RPC::Building::EssentiaVein + Lacuna::RPC::Building::Volcano + Lacuna::RPC::Building::MassadsHenge + Lacuna::RPC::Building::LibraryOfJith + Lacuna::RPC::Building::NaturalSpring + Lacuna::RPC::Building::OracleOfAnid + Lacuna::RPC::Building::TempleOfTheDrajilites + Lacuna::RPC::Building::GeoThermalVent + Lacuna::RPC::Building::InterDimensionalRift + Lacuna::RPC::Building::CitadelOfKnope + Lacuna::RPC::Building::CrashedShipSite + Lacuna::RPC::Building::KalavianRuins + Lacuna::RPC::Building::Grove + Lacuna::RPC::Building::Sand + Lacuna::RPC::Building::Lagoon + Lacuna::RPC::Building::Crater + Lacuna::RPC::Building::Dairy + Lacuna::RPC::Building::Denton + Lacuna::RPC::Building::Development + Lacuna::RPC::Building::Embassy + Lacuna::RPC::Building::EnergyReserve + Lacuna::RPC::Building::Entertainment + Lacuna::RPC::Building::Espionage + Lacuna::RPC::Building::Fission + Lacuna::RPC::Building::FoodReserve + Lacuna::RPC::Building::Fusion + Lacuna::RPC::Building::DeployedBleeder + Lacuna::RPC::Building::GasGiantLab + Lacuna::RPC::Building::GasGiantPlatform + Lacuna::RPC::Building::Geo + Lacuna::RPC::Building::Hydrocarbon + Lacuna::RPC::Building::Intelligence + Lacuna::RPC::Building::Lapis + Lacuna::RPC::Building::Malcud + Lacuna::RPC::Building::Mine + Lacuna::RPC::Building::MiningMinistry + Lacuna::RPC::Building::Network19 + Lacuna::RPC::Building::Observatory + Lacuna::RPC::Building::OreRefinery + Lacuna::RPC::Building::OreStorage + Lacuna::RPC::Building::Pancake + Lacuna::RPC::Building::Park + Lacuna::RPC::Building::Pie + Lacuna::RPC::Building::PlanetaryCommand + Lacuna::RPC::Building::Potato + Lacuna::RPC::Building::Propulsion + Lacuna::RPC::Building::Oversight + Lacuna::RPC::Building::RockyOutcrop + Lacuna::RPC::Building::Lake + Lacuna::RPC::Building::Security + Lacuna::RPC::Building::Shake + Lacuna::RPC::Building::Shipyard + Lacuna::RPC::Building::Singularity + Lacuna::RPC::Building::Soup + Lacuna::RPC::Building::SpacePort + Lacuna::RPC::Building::Syrup + Lacuna::RPC::Building::TerraformingLab + Lacuna::RPC::Building::GeneticsLab + Lacuna::RPC::Building::Archaeology + Lacuna::RPC::Building::TerraformingPlatform + Lacuna::RPC::Building::Trade + Lacuna::RPC::Building::Transporter + Lacuna::RPC::Building::University + Lacuna::RPC::Building::WasteEnergy + Lacuna::RPC::Building::WasteRecycling + Lacuna::RPC::Building::WasteSequestration + Lacuna::RPC::Building::WasteDigester + Lacuna::RPC::Building::WasteTreatment + Lacuna::RPC::Building::WaterProduction + Lacuna::RPC::Building::WaterPurification + Lacuna::RPC::Building::WaterReclamation + Lacuna::RPC::Building::WaterStorage + Lacuna::RPC::Building::Wheat + Lacuna::RPC::Building::Beach1 + Lacuna::RPC::Building::Beach2 + Lacuna::RPC::Building::Beach3 + Lacuna::RPC::Building::Beach4 + Lacuna::RPC::Building::Beach5 + Lacuna::RPC::Building::Beach6 + Lacuna::RPC::Building::Beach7 + Lacuna::RPC::Building::Beach8 + Lacuna::RPC::Building::Beach9 + Lacuna::RPC::Building::Beach10 + Lacuna::RPC::Building::Beach11 + Lacuna::RPC::Building::Beach12 + Lacuna::RPC::Building::Beach13 + Lacuna::RPC::Building::PilotTraining + Lacuna::RPC::Building::MissionCommand + Lacuna::RPC::Building::CloakingLab + Lacuna::RPC::Building::MunitionsLab + Lacuna::RPC::Building::LuxuryHousing + Lacuna::RPC::Building::Ravine + Lacuna::RPC::Building::AlgaePond + Lacuna::RPC::Building::LapisForest + Lacuna::RPC::Building::BeeldebanNest + Lacuna::RPC::Building::MalcudField + Lacuna::RPC::Building::SSLa + Lacuna::RPC::Building::SSLb + Lacuna::RPC::Building::SSLc + Lacuna::RPC::Building::SSLd + )) { + mount $building->new->to_app_with_url; } - else { - return $online->(@args); - } -}; -$app; + mount '/admin' => builder { + enable "Auth::Basic", authenticator => sub { + my ($username, $password) = @_; + return 0 unless $username; + my $empire = Lacuna->db->resultset('Lacuna::DB::Result::Empire')->search({name => $username, is_admin => 1},{rows=>1})->single; + return 0 unless defined $empire; + return $empire->is_password_valid($password); + }; + Lacuna::Web::Admin->new->to_app; + }; + mount "/missioncurator" => builder { + enable "Auth::Basic", authenticator => sub { + my ($username, $password) = @_; + return 0 unless $username; + my $empire = Lacuna->db->resultset('Lacuna::DB::Result::Empire')->search({name => $username, is_mission_curator => 1},{rows=>1})->single; + return 0 unless defined $empire; + return $empire->is_password_valid($password); + }; + Lacuna::Web::MissionCurator->new->to_app; + }; +}; -- 2.51.2 From 468bfad7d700a8c45edbe0e8d2e9cda37802d673 Mon Sep 17 00:00:00 2001 From: Graham Knop Date: Tue, 8 Mar 2011 14:59:36 -0600 Subject: [PATCH 2/8] don't allow trading a fraction of a resource --- lib/Lacuna/Role/Trader.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Lacuna/Role/Trader.pm b/lib/Lacuna/Role/Trader.pm index 64f76613..efc9f52d 100644 --- a/lib/Lacuna/Role/Trader.pm +++ b/lib/Lacuna/Role/Trader.pm @@ -9,6 +9,7 @@ my $have_exception = [1011, 'You cannot offer to trade something you do not have my $cargo_exception = 'You need %s cargo space to trade that.'; my $offer_nothing_exception = [1013, 'It appears that you have offered nothing.']; my $ask_nothing_exception = [1013, 'It appears that you have asked for nothing.']; +my $fractional_offer_exception = [1013, 'You cannot offer a fraction of a resource.']; sub market { return Lacuna->db->resultset('Lacuna::DB::Result::Market'); @@ -44,6 +45,7 @@ sub check_payload { given($item->{type}) { when ([qw(water energy waste), ORE_TYPES, FOOD_TYPES]) { confess $offer_nothing_exception unless ($item->{quantity} > 0); + confess $fractional_offer_exception if ($item->{quantity} != int($item->{quantity})); confess $have_exception unless ($body->type_stored($item->{type}) >= $item->{quantity}); $space_used += $item->{quantity}; } -- 2.51.2 From b0e1548995240d0eb6ee81c890663cb5ad21e79e Mon Sep 17 00:00:00 2001 From: Graham Knop Date: Tue, 8 Mar 2011 15:15:57 -0600 Subject: [PATCH 3/8] fix ship stealth calculation --- lib/Lacuna/DB/Result/Building/Shipyard.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Lacuna/DB/Result/Building/Shipyard.pm b/lib/Lacuna/DB/Result/Building/Shipyard.pm index 9dfa4fb3..aa804191 100644 --- a/lib/Lacuna/DB/Result/Building/Shipyard.pm +++ b/lib/Lacuna/DB/Result/Building/Shipyard.pm @@ -274,8 +274,8 @@ sub set_ship_hold_size { sub set_ship_stealth { my ($self, $ship) = @_; - my $cloaking_level = (defined $self->cloaking_lab) ? $self->cloaking_lab->level : 1; - my $ptf = ($ship->pilotable && defined $self->pilot_training_facility) ? $self->pilot_training_facility->level : 1; + my $cloaking_level = (defined $self->cloaking_lab) ? $self->cloaking_lab->level : 0; + my $ptf = ($ship->pilotable && defined $self->pilot_training_facility) ? $self->pilot_training_facility->level : 0; my $css_level = (defined $self->crashed_ship_site) ? $self->crashed_ship_site->level : 0; my $improvement = 1 + ($self->level * 0.01) + ($ptf * 0.03) + ($cloaking_level * 0.05) + ($css_level * 0.05) + ($self->body->empire->deception_affinity * 0.03); $ship->stealth(sprintf('%.0f', $ship->base_stealth * $improvement )); -- 2.51.2 From 26f9d7c2b32bbee60b2f8b602688f1d0654e217c Mon Sep 17 00:00:00 2001 From: Matthew Musgrove Date: Tue, 8 Mar 2011 19:22:49 -0600 Subject: [PATCH 4/8] Trigger captcha when sending spies. Rename Captcha::Spies to Captcha::AssignSpies. Removed Captcha::Ships from LoadWithSpies since it was not being triggered. --- lib/Lacuna/RPC/Building/Intelligence.pm | 2 +- lib/Lacuna/RPC/Building/SpacePort.pm | 2 ++ .../Role/Captcha/{Spies.pm => AssignSpies.pm} | 2 +- lib/Lacuna/Role/Captcha/SendSpies.pm | 22 +++++++++++++++++++ lib/Lacuna/Role/Ship/Send/LoadWithSpies.pm | 2 -- 5 files changed, 26 insertions(+), 4 deletions(-) rename lib/Lacuna/Role/Captcha/{Spies.pm => AssignSpies.pm} (86%) create mode 100644 lib/Lacuna/Role/Captcha/SendSpies.pm diff --git a/lib/Lacuna/RPC/Building/Intelligence.pm b/lib/Lacuna/RPC/Building/Intelligence.pm index be9d4226..277775af 100644 --- a/lib/Lacuna/RPC/Building/Intelligence.pm +++ b/lib/Lacuna/RPC/Building/Intelligence.pm @@ -6,7 +6,7 @@ no warnings qw(uninitialized); extends 'Lacuna::RPC::Building'; use Lacuna::Util qw(randint); -with 'Lacuna::Role::Captcha::Spies'; +with 'Lacuna::Role::Captcha::AssignSpies'; sub app_url { return '/intelligence'; diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index ace947e2..61cbee45 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -8,6 +8,8 @@ use Lacuna::Constants qw(SHIP_TYPES); use Lacuna::Util qw(format_date); use feature "switch"; +with 'Lacuna::Role::Captcha::AssignSpies'; + sub app_url { return '/spaceport'; } diff --git a/lib/Lacuna/Role/Captcha/Spies.pm b/lib/Lacuna/Role/Captcha/AssignSpies.pm similarity index 86% rename from lib/Lacuna/Role/Captcha/Spies.pm rename to lib/Lacuna/Role/Captcha/AssignSpies.pm index bcef1e94..7b912777 100644 --- a/lib/Lacuna/Role/Captcha/Spies.pm +++ b/lib/Lacuna/Role/Captcha/AssignSpies.pm @@ -1,4 +1,4 @@ -package Lacuna::Role::Captcha::Spies; +package Lacuna::Role::Captcha::AssignSpies; use Moose::Role; diff --git a/lib/Lacuna/Role/Captcha/SendSpies.pm b/lib/Lacuna/Role/Captcha/SendSpies.pm new file mode 100644 index 00000000..375a6232 --- /dev/null +++ b/lib/Lacuna/Role/Captcha/SendSpies.pm @@ -0,0 +1,22 @@ +package Lacuna::Role::Captcha::SendSpies; + +use Moose::Role; + +before 'prepare_send_spies' => sub { + my ($self, $session_id, $on_body_id, $to_body_id) = @_; + my $empire = $self->get_empire_by_session($session_id); + unless ($empire->current_session->check_captcha()) { + confess [1016,'Needs to solve a captcha.']; + } +}; + +before 'send_spies' => sub { + my ($self, $session_id, $on_body_id, $to_body_id, $ship_id, $spy_ids) = @_; + my $empire = $self->get_empire_by_session($session_id); + unless ($empire->current_session->check_captcha()) { + confess [1016,'Needs to solve a captcha.']; + } +}; + + +1; diff --git a/lib/Lacuna/Role/Ship/Send/LoadWithSpies.pm b/lib/Lacuna/Role/Ship/Send/LoadWithSpies.pm index 2b764970..57c42a29 100644 --- a/lib/Lacuna/Role/Ship/Send/LoadWithSpies.pm +++ b/lib/Lacuna/Role/Ship/Send/LoadWithSpies.pm @@ -3,8 +3,6 @@ package Lacuna::Role::Ship::Send::LoadWithSpies; use strict; use Moose::Role; -with 'Lacuna::Role::Captcha::Ships'; - after send => sub { my $self = shift; return if $self->payload->{spies}[0]; -- 2.51.2 From 0c026f212917a78e6fdff42801145b2162114082 Mon Sep 17 00:00:00 2001 From: Matthew Musgrove Date: Tue, 8 Mar 2011 20:24:26 -0600 Subject: [PATCH 5/8] Correct captcha role to use. --- lib/Lacuna/RPC/Building/SpacePort.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 61cbee45..b6360e5a 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -8,7 +8,7 @@ use Lacuna::Constants qw(SHIP_TYPES); use Lacuna::Util qw(format_date); use feature "switch"; -with 'Lacuna::Role::Captcha::AssignSpies'; +with 'Lacuna::Role::Captcha::SendSpies'; sub app_url { return '/spaceport'; -- 2.51.2 From 4eaeb50fd1d8a2dc95de6cbd9986988979bee674 Mon Sep 17 00:00:00 2001 From: Matthew Musgrove Date: Tue, 8 Mar 2011 20:52:32 -0600 Subject: [PATCH 6/8] Remove the Captcha roles and use Guard.pm instead --- lib/Lacuna/RPC/Building/Intelligence.pm | 2 -- lib/Lacuna/RPC/Building/SpacePort.pm | 6 ++++-- lib/Lacuna/Role/Captcha/AssignSpies.pm | 14 -------------- lib/Lacuna/Role/Captcha/SendSpies.pm | 22 ---------------------- lib/Lacuna/Role/Captcha/Ships.pm | 13 ------------- 5 files changed, 4 insertions(+), 53 deletions(-) delete mode 100644 lib/Lacuna/Role/Captcha/AssignSpies.pm delete mode 100644 lib/Lacuna/Role/Captcha/SendSpies.pm delete mode 100644 lib/Lacuna/Role/Captcha/Ships.pm diff --git a/lib/Lacuna/RPC/Building/Intelligence.pm b/lib/Lacuna/RPC/Building/Intelligence.pm index 9f202e0b..214a4c10 100644 --- a/lib/Lacuna/RPC/Building/Intelligence.pm +++ b/lib/Lacuna/RPC/Building/Intelligence.pm @@ -6,8 +6,6 @@ no warnings qw(uninitialized); extends 'Lacuna::RPC::Building'; use Lacuna::Util qw(randint); -with 'Lacuna::Role::Captcha::AssignSpies'; - sub app_url { return '/intelligence'; } diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 0de6377b..74aabab8 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -8,8 +8,6 @@ use Lacuna::Constants qw(SHIP_TYPES); use Lacuna::Util qw(format_date); use feature "switch"; -with 'Lacuna::Role::Captcha::SendSpies'; - sub app_url { return '/spaceport'; } @@ -226,6 +224,8 @@ sub prepare_send_spies { confess [ 1013, sprintf('%s is an isolationist empire, and must be left alone.',$to_body->empire->name)]; } + $empire->current_session->check_captcha; + my $ships = Lacuna->db->resultset('Lacuna::DB::Result::Ships')->search( {type => { in => [qw(spy_pod cargo_ship smuggler_ship dory spy_shuttle barge)]}, task=>'Docked', body_id => $on_body_id}, {order_by => 'name', rows=>100} @@ -268,6 +268,8 @@ sub send_spies { confess [ 1013, sprintf('%s is an isolationist empire, and must be left alone.',$to_body->empire->name)]; } + $empire->current_session->check_captcha; + # get the ship my $ship = Lacuna->db->resultset('Lacuna::DB::Result::Ships')->find($ship_id); unless (defined $ship) { diff --git a/lib/Lacuna/Role/Captcha/AssignSpies.pm b/lib/Lacuna/Role/Captcha/AssignSpies.pm deleted file mode 100644 index 7b912777..00000000 --- a/lib/Lacuna/Role/Captcha/AssignSpies.pm +++ /dev/null @@ -1,14 +0,0 @@ -package Lacuna::Role::Captcha::AssignSpies; - -use Moose::Role; - -before 'assign_spy' => sub { - my ($self, $session_id, $building_id, $spy_id, $assignment) = @_; - my $empire = $self->get_empire_by_session($session_id); - unless ($empire->current_session->check_captcha()) { - confess [1016,'Needs to solve a captcha.']; - } -}; - - -1; diff --git a/lib/Lacuna/Role/Captcha/SendSpies.pm b/lib/Lacuna/Role/Captcha/SendSpies.pm deleted file mode 100644 index 375a6232..00000000 --- a/lib/Lacuna/Role/Captcha/SendSpies.pm +++ /dev/null @@ -1,22 +0,0 @@ -package Lacuna::Role::Captcha::SendSpies; - -use Moose::Role; - -before 'prepare_send_spies' => sub { - my ($self, $session_id, $on_body_id, $to_body_id) = @_; - my $empire = $self->get_empire_by_session($session_id); - unless ($empire->current_session->check_captcha()) { - confess [1016,'Needs to solve a captcha.']; - } -}; - -before 'send_spies' => sub { - my ($self, $session_id, $on_body_id, $to_body_id, $ship_id, $spy_ids) = @_; - my $empire = $self->get_empire_by_session($session_id); - unless ($empire->current_session->check_captcha()) { - confess [1016,'Needs to solve a captcha.']; - } -}; - - -1; diff --git a/lib/Lacuna/Role/Captcha/Ships.pm b/lib/Lacuna/Role/Captcha/Ships.pm deleted file mode 100644 index e6d556e8..00000000 --- a/lib/Lacuna/Role/Captcha/Ships.pm +++ /dev/null @@ -1,13 +0,0 @@ -package Lacuna::Role::Captcha::Ships; - -use Moose::Role; - -before 'can_send_to_target' => sub { - my ($self, $target) = @_; - my $empire = $self->body->empire; - unless ($empire->current_session->check_captcha()) { - confess [1016,'Needs to solve a captcha.']; - } -}; - -1; -- 2.51.2 From 8b4464112606eaa0a2b9ce6bb3f2d55e7cf6d542 Mon Sep 17 00:00:00 2001 From: Matthew Musgrove Date: Tue, 8 Mar 2011 21:09:00 -0600 Subject: [PATCH 7/8] Updated SpacePort.t --- t/SpacePort.t | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/t/SpacePort.t b/t/SpacePort.t index 65186f14..7c529f3e 100644 --- a/t/SpacePort.t +++ b/t/SpacePort.t @@ -1,5 +1,5 @@ use lib '../lib'; -use Test::More tests => 13; +use Test::More tests => 14; use Test::Deep; use Data::Dumper; use 5.010; @@ -65,12 +65,6 @@ is(ref $result->{result}{recallable}, 'ARRAY', "can see what ships are available $empire->is_isolationist(0); $empire->update; -$result = $tester->post('spaceport', 'prepare_send_spies', [$session_id, $home->id, $home->id ]); -is(ref $result->{result}{spies}, 'ARRAY', "can prepare for send spies"); - -$result = $tester->post('spaceport', 'prepare_fetch_spies', [$session_id, $home->id, $home->id ]); -is(ref $result->{result}{ships}, 'ARRAY', "can prepare for fetch spies"); - my $shipyard = Lacuna::db->resultset('Lacuna::DB::Result::Building')->new({ x => 0, y => 2, @@ -104,13 +98,22 @@ $enemy->empire->update; @ships = map { $_->id } @ships; diag explain @ships; + +$result = $tester->post('spaceport', 'prepare_send_spies', [$session_id, $home->id, $home->id ]); +is( $result->{error}{code}, 1016, 'Needs to solve a captcha.' ); + $result = $tester->post('spaceport', 'send_fleet', [$session_id, [ @ships ], { body_id => $enemy->empire->home_planet->id } ] ); is( $result->{error}{code}, 1016, 'Needs to solve a captcha.' ); Lacuna->cache->set('captcha', $session_id, { guid => 1111, solution => 1111 }, 60 * 30 ); -$result = $tester->post('captcha','solve', [$session_id, 1111, 1111]); -is($result->{result}, 1, 'Solved captcha'); +ok( eval{ $tester->post('captcha','solve', [$session_id, 1111, 1111]) }, 'Solved captcha' ); + +$result = $tester->post('spaceport', 'prepare_send_spies', [$session_id, $home->id, $home->id ]); +is( ref $result->{result}{spies}, 'ARRAY', "can prepare for send spies" ); + +$result = $tester->post('spaceport', 'prepare_fetch_spies', [$session_id, $home->id, $home->id ]); +is( ref $result->{result}{ships}, 'ARRAY', "can prepare for fetch spies"); $result = $tester->post('spaceport', 'send_fleet', [$session_id, [ @ships ], { body_id => $enemy->empire->home_planet->id } ] ); ok($result->{result}{fleet}[0]{ship}{date_arrives}, "fleet sent"); -- 2.51.2 From ea7252187abc93412755089fa92d2b28c4577395 Mon Sep 17 00:00:00 2001 From: Matthew Musgrove Date: Tue, 8 Mar 2011 23:47:42 -0600 Subject: [PATCH 8/8] Added filter and sort capability to the spaceport's view_all_ships() method. --- docs/SpacePort.pod | 25 +++++++++- lib/Lacuna/RPC/Building/SpacePort.pm | 75 +++++++++++++++++++++++++++- t/SpacePort.t | 7 ++- var/www/public/changes.txt | 1 + 4 files changed, 103 insertions(+), 5 deletions(-) diff --git a/docs/SpacePort.pod b/docs/SpacePort.pod index bb63527f..aa876f8b 100644 --- a/docs/SpacePort.pod +++ b/docs/SpacePort.pod @@ -29,7 +29,7 @@ This method is extended to include a list of docked ships. } -=head2 view_all_ships ( session_id, building_id, page_number ) +=head2 view_all_ships ( session_id, building_id, [ page_number, items_per_page, filter, sort ] ) Shows you all your ships whatever they are doing. @@ -102,7 +102,28 @@ The unique id of the space port. =head3 page_number -Defaults to page 1. Shows 25 at a time. +Optional. An integer representing the page of ships to return. Defaults to 1. + +=head3 items_per_page + +Optional. An integer representing the number of items per page to return. Defaults to 25. + +=head3 filter + +Optional. A hash reference that contains the filter criteria. Valid filter option keys include task, type and tag. Valid tasks include Docked, Building, Mining, Travelling, and Defend. Valid types are the existing ship types. Valid tags include Trade, Colonization, Intelligence, Exploration, War, and Mining. The filter option values should be passed as an array reference or scalar. Tags will be converted to types prior to filtering. (This means that if tags and types are passed together, the types will be overwritten when the tags are converted.) + + { "task" : "Defend" } + + { "tag" : "Mining" } + + { "task" : "Docked", "type" : "freighter" } + + { "tag" : [ "Colonization", "Exploration" ], "task" : "Travelling" } + +=head3 sort + +Optional. A string with the column to sort on. Defaults to 'type'. (A second sort column, 'name', is added to your chosen sort column.) Valid columns to sort on include: combat, name, speed, stealth, task, and type. + =head2 view_foreign_ships ( session_id, building_id, page_number ) diff --git a/lib/Lacuna/RPC/Building/SpacePort.pm b/lib/Lacuna/RPC/Building/SpacePort.pm index 74aabab8..ad9e92bf 100644 --- a/lib/Lacuna/RPC/Building/SpacePort.pm +++ b/lib/Lacuna/RPC/Building/SpacePort.pm @@ -429,13 +429,84 @@ sub view_ships_travelling { } sub view_all_ships { - my ($self, $session_id, $building_id, $page_number) = @_; + my ($self, $session_id, $building_id, $page_number, $items_per_page, $filter, $sort) = @_; + if (defined $filter && ref $filter ne 'HASH') { + confess [-32602, 'The filter parameter should be a hash reference. For example { "task" : "Docked" }.']; + } my $empire = $self->get_empire_by_session($session_id); my $building = $self->get_building($empire, $building_id); $page_number ||= 1; + $items_per_page ||= 25; + $filter //= {}; + $sort //= 'type'; + + if ($sort && $sort ~~ [qw(combat name speed stealth task type)]) { + if ( $sort ne 'name' ) { + $sort = [ $sort, 'name' ]; + } + else { + $sort = [ 'name' ]; + } + } + + if ($filter) { + # Valid filter options include... + my $options = { + task => [qw(Docked Building Mining Travelling Defend)], + tags => [qw(Trade Colonization Intelligence Exploration War Mining)], + type => [SHIP_TYPES], + }; + + # Pull in the list of ship types by tag + my %tag; + foreach my $type (SHIP_TYPES) { + my $ship = Lacuna->db->resultset('Lacuna::DB::Result::Ships')->new({type=>$type}); + my @tags = @{$ship->build_tags}; + for my $tag ( @tags ) { + push @{$tag{$tag}}, $type; + } + } + + for my $key ( keys %{$filter} ) { + # Throw away bad keys + unless ($key ~~ [keys %$options]) { + delete $filter->{$key}; + next; + } + + # Throw away bad values + my $value = $filter->{$key}; + if (ref($value) eq 'ARRAY') { + @$value = grep { $_ ~~ $options->{$key} } @$value; + } + elsif (! ref($value)) { + delete $filter->{$key} unless ($value ~~ $options->{$key}); + } + else { + delete $filter->{$key}; + } + + # Convert tags to types (destructive) + if ($key eq 'tags') { + if (ref($value) eq 'ARRAY') { + my @types; + for my $tag ( @$value ) { + push @types, @{$tag{$tag}}; + } + my %types = map { $_ => 1 } @types; + $filter->{type} = [ sort keys %types ]; + } + else { + $filter->{type} = $tag{$value}; + } + delete $filter->{tags}; + } + } + } + my $body = $building->body; my @fleet; - my $ships = $building->ships->search({}, {rows=>25, order_by => ['type','name'], page=>$page_number}); + my $ships = $building->ships->search( $filter, { rows => $items_per_page, order_by => $sort, page => $page_number } ); while (my $ship = $ships->next) { $ship->body($body); push @fleet, $ship->get_status; diff --git a/t/SpacePort.t b/t/SpacePort.t index 7c529f3e..6f50b63f 100644 --- a/t/SpacePort.t +++ b/t/SpacePort.t @@ -1,5 +1,5 @@ use lib '../lib'; -use Test::More tests => 14; +use Test::More tests => 15; use Test::Deep; use Data::Dumper; use 5.010; @@ -121,6 +121,11 @@ ok($result->{result}{fleet}[0]{ship}{date_arrives}, "fleet sent"); $result = $tester->post('spaceport', 'send_ship', [$session_id, $sweeper->id, { body_id => $enemy->empire->home_planet->id } ] ); ok($result->{result}{ship}{date_arrives}, "sweeper sent"); +$result = $tester->post('spaceport', 'view_all_ships', + [$session_id, $spaceport->id, undef, undef, { task => "Docked", tags => [qw(Trade Mining)]}, 'combat'] +); +is(ref $result->{result}{ships}, 'ARRAY', "can see all my ships"); + END { $enemy->cleanup; $tester->cleanup; diff --git a/var/www/public/changes.txt b/var/www/public/changes.txt index e87778a7..84f86342 100644 --- a/var/www/public/changes.txt +++ b/var/www/public/changes.txt @@ -5,6 +5,7 @@ - API: Running spy missions require the new captchas. - API: Added send_fleet() to spaceport to allow sending multiple ships to a single target at once. This requires a valid captcha. - API: Added mission_count to spy status. + - API: Added filter and sort capability to the spaceport's view_all_ships() method. 2.4700 - Rule: Spies now have a minimum recovery time of 1 hour. -- 2.51.2