summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Model/Event/BaseEvent.php7
-rw-r--r--src/Model/Event/SendResources.php2
-rw-r--r--src/Model/Event/SendResourcesCarriers.php3
-rw-r--r--src/Model/Event/SendUnits.php2
-rw-r--r--src/Model/Event/TrainUnits.php2
-rw-r--r--src/Model/Event/UpgradeBuilding.php52
-rw-r--r--src/Model/Village.php2
-rw-r--r--src/Support/BuildingType.php0
-rw-r--r--src/View.php4
-rw-r--r--src/http/Controller/Building.php10
-rw-r--r--src/http/Controller/Event.php36
-rw-r--r--src/http/Controller/Login.php49
-rw-r--r--src/http/Controller/Map.php6
-rw-r--r--src/http/Controller/User.php58
-rw-r--r--src/http/Controller/Village.php69
-rw-r--r--src/http/Router.php4
-rw-r--r--src/http/Support/RouteLoader.php13
17 files changed, 285 insertions, 34 deletions
diff --git a/src/Model/Event/BaseEvent.php b/src/Model/Event/BaseEvent.php
index 2e2564b..0d50458 100644
--- a/src/Model/Event/BaseEvent.php
+++ b/src/Model/Event/BaseEvent.php
@@ -15,16 +15,15 @@ abstract class BaseEvent
public Event $event;
+ abstract function create(): void;
+ abstract function cancel(): void;
abstract function dbInsert(): void;
abstract function dbDelete(): void;
- abstract function cancel(): void;
- public function getEvent(): Event
+ public function populateEvent(): void
{
if (! isset($this->event)) {
$this->event = DB::fetch(Event::class, 'select * from events where id=:id', ['id' => $this->eventId])[0];
}
-
- return $this->event;
}
}
diff --git a/src/Model/Event/SendResources.php b/src/Model/Event/SendResources.php
index ea9361c..d8e4f85 100644
--- a/src/Model/Event/SendResources.php
+++ b/src/Model/Event/SendResources.php
@@ -94,7 +94,7 @@ class SendResources extends BaseEvent
public function cancel(): void
{
- $this->event = $this->getEvent();
+ $this->populateEvent();
$cancelTimeDiff = $this->event->createdAt->diff(new \DateTime());
$cancelTime = (new \DateTime())->add($cancelTimeDiff);
diff --git a/src/Model/Event/SendResourcesCarriers.php b/src/Model/Event/SendResourcesCarriers.php
index b6c3772..d129732 100644
--- a/src/Model/Event/SendResourcesCarriers.php
+++ b/src/Model/Event/SendResourcesCarriers.php
@@ -34,6 +34,9 @@ class SendResourcesCarriers extends BaseEvent
}
}
+ public function cancel(): void
+ {}
+
public function dbInsert(): void
{
DB::query(
diff --git a/src/Model/Event/SendUnits.php b/src/Model/Event/SendUnits.php
index c9afd6e..1b04333 100644
--- a/src/Model/Event/SendUnits.php
+++ b/src/Model/Event/SendUnits.php
@@ -104,7 +104,7 @@ class SendUnits extends BaseEvent
public function cancel(): void
{
- $this->event = $this->getEvent();
+ $this->populateEvent();
$cancelTimeDiff = $this->event->createdAt->diff(new \DateTime());
$cancelTime = (new \DateTime())->add($cancelTimeDiff);
diff --git a/src/Model/Event/TrainUnits.php b/src/Model/Event/TrainUnits.php
index 59b169f..a94a5a8 100644
--- a/src/Model/Event/TrainUnits.php
+++ b/src/Model/Event/TrainUnits.php
@@ -14,7 +14,7 @@ class TrainUnits extends BaseEvent
*/
public function __invoke(): void
{
- $this->getEvent();
+ $this->populateEvent();
DB::query(
<<<SQL
diff --git a/src/Model/Event/UpgradeBuilding.php b/src/Model/Event/UpgradeBuilding.php
index a3f3984..5993105 100644
--- a/src/Model/Event/UpgradeBuilding.php
+++ b/src/Model/Event/UpgradeBuilding.php
@@ -3,17 +3,21 @@
namespace App\Model\Event;
use App\DB;
+use App\Model\Village;
class UpgradeBuilding extends BaseEvent
{
public string $type;
+ public int $wood;
+ public int $clay;
+ public int $iron;
/**
* @return void
*/
public function __invoke(): void
{
- $this->getEvent();
+ $this->populateEvent();
DB::query(
<<<SQL
@@ -26,8 +30,44 @@ class UpgradeBuilding extends BaseEvent
);
}
+ /*public function populateEvent(): void
+ {
+ parent::populateEvent();
+
+ $event = DB::fetch(UpgradeBuilding::class, 'select * from events_upgrade_building where id=:id', ['id' => $this->id])[0];
+ $this->type = $event->type;
+ $this->wood = $event->wood;
+ $this->clay = $event->clay;
+ $this->iron = $event->iron;
+ }*/
+
+ public function create(): void
+ {
+ $this->populateEvent();
+
+ // remove resources
+ $village = Village::get($this->event->villageId);
+ $village->wood -= $this->wood;
+ $village->clay -= $this->clay;
+ $village->iron -= $this->iron;
+ $village->updateResources();
+
+ // add to db
+ $this->dbInsert();
+ }
+
public function cancel(): void
{
+ $this->populateEvent();
+
+ // add resources
+ $village = Village::get($this->event->villageId);
+ $village->wood += $this->wood;
+ $village->clay += $this->clay;
+ $village->iron += $this->iron;
+ $village->updateResources();
+
+ // remove from db
$this->dbDelete();
}
@@ -39,8 +79,14 @@ class UpgradeBuilding extends BaseEvent
);
DB::query(
- 'insert into events_upgrade_building (event_id, type) VALUES (:event_id, :type)',
- ['event_id' => DB::$connection->lastInsertId(), 'type' => $this->type]
+ 'insert into events_upgrade_building (event_id, type, wood, clay, iron) VALUES (:event_id, :type, :wood, :clay, :iron)',
+ [
+ 'event_id' => DB::$connection->lastInsertId(),
+ 'type' => $this->type,
+ 'wood' => $this->wood,
+ 'clay' => $this->clay,
+ 'iron' => $this->iron,
+ ]
);
}
diff --git a/src/Model/Village.php b/src/Model/Village.php
index ff0b7e8..8ecee2a 100644
--- a/src/Model/Village.php
+++ b/src/Model/Village.php
@@ -184,7 +184,7 @@ class Village
*
* @return array<int, Unit>
*/
- public static function getUnits(int $villageId, int $fetchFlag = Village::FETCH_UNIT_ALL, int $returnFlag = Village::RETURN_UNIT_EXISTING): array
+ public static function getUnits(int $villageId, int $fetchFlag = Village::FETCH_UNIT_RESIDENCE, int $returnFlag = Village::RETURN_UNIT_EXISTING): array
{
if ($fetchFlag == Village::FETCH_UNIT_HOME_AT_HOME) {
$units = DB::fetch(Unit::class, 'select * from village_units where home_village_id=:id and residence_village_id=:id', ['id' => $villageId]);
diff --git a/src/Support/BuildingType.php b/src/Support/BuildingType.php
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/Support/BuildingType.php
diff --git a/src/View.php b/src/View.php
index 10ce9db..761ef62 100644
--- a/src/View.php
+++ b/src/View.php
@@ -25,6 +25,10 @@ class View
// self::$twig->addExtension(new IntlExtension());
self::$twig->addFilter(new TwigFilter('buildTime', function ($buildTime) {
+ if ($buildTime > 3600*24) {
+ return @sprintf('%02d:%02d:%02d:%02d', $buildTime / (3600*24), $buildTime / 3600, ($buildTime / 60) % 60, $buildTime % 60);
+ }
+
return @sprintf('%02d:%02d:%02d', $buildTime / 3600, ($buildTime / 60) % 60, $buildTime % 60);
}));
}
diff --git a/src/http/Controller/Building.php b/src/http/Controller/Building.php
index 4a59f0e..d434fe8 100644
--- a/src/http/Controller/Building.php
+++ b/src/http/Controller/Building.php
@@ -21,10 +21,7 @@ class Building
$building = Model::getByVillage($village->id, $request->get('type')) ?? Model::getEmpty($village->id, $request->get('type'));
// resources
- foreach ($building->getResourceRequirements() as $resourceType => $resourceValue) {
- $village->{$resourceType} -= $resourceValue;
- }
- $village->updateResources();
+ $resourceRequirements = $building->getResourceRequirements();
// event
$event = new Event();
@@ -35,7 +32,10 @@ class Building
$upgradeBuildingEvent = new UpgradeBuilding();
$upgradeBuildingEvent->event = $event;
$upgradeBuildingEvent->type = $building->type;
- $upgradeBuildingEvent->dbInsert();
+ $upgradeBuildingEvent->wood = $resourceRequirements['wood'];
+ $upgradeBuildingEvent->clay = $resourceRequirements['clay'];
+ $upgradeBuildingEvent->iron = $resourceRequirements['iron'];
+ $upgradeBuildingEvent->create();
return new RedirectResponse(
Router::generate(
diff --git a/src/http/Controller/Event.php b/src/http/Controller/Event.php
index 8b9b92a..264fa26 100644
--- a/src/http/Controller/Event.php
+++ b/src/http/Controller/Event.php
@@ -8,7 +8,10 @@ use App\Model\Event\SendResources;
use App\Model\Event\SendUnits;
use App\Model\Event\TrainUnits;
use App\Model\Event\UpgradeBuilding;
+use App\Model\Unit;
+use App\Model\Unit\MailCarrier;
use App\Model\Village;
+use App\View;
use App\http\Router;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -20,6 +23,39 @@ class Event
#[Route(path: '/village/{x}/{y}/send-resources', methods: ['POST'])]
public function sendResources(Request $request): Response
{
+ $village = Village::getByCoordinates($request->get('x'), $request->get('y'));
+
+ $totalAmount = $request->get('wood') + $request->get('clay') + $request->get('iron') + $request->get('food');
+
+ $resourceCapabilities = MailCarrier::getResourceCapabilities($village);
+ $necessaryMailCarriers = ceil($totalAmount / $resourceCapabilities);
+ $mailCarriers = DB::fetch(MailCarrier::class, 'select sum(amount) as amount from village_units where type=:type and residence_village_id=:villageId and is_traveling=false', ['villageId' => $village->id, 'type' => 'MailCarrier'])[0]->amount ?? 0;
+ if ($mailCarriers === 0 || $totalAmount > $resourceCapabilities) {
+ return new Response(View::render('error.twig', ['message' => 'Insufficient Mail Carriers']), 403);
+ }
+
+ $destination = Village::get($request->get('village'));
+
+ // event
+ $event = new Model();
+ $event->time = (new \DateTime())->add(
+ \DateInterval::createFromDateString(
+ Unit::getTravelTime(new MailCarrier(), Village::getDistance($village->x, $village->y, $destination->x, $destination->y))
+ . ' seconds'
+ )
+ );
+ $event->villageId = $village->id;
+ $sendResourcesEvent = new SendResources();
+ $sendResourcesEvent->event = $event;
+ $sendResourcesEvent->wood = $request->get('wood');
+ $sendResourcesEvent->clay = $request->get('clay');
+ $sendResourcesEvent->iron = $request->get('iron');
+ $sendResourcesEvent->food = $request->get('food');
+ $sendResourcesEvent->source = $village->id;
+ $sendResourcesEvent->destination = $destination->id;
+ $sendResourcesEvent->dbInsert();
+
+
return new RedirectResponse(
Router::generate(
'village.show',
diff --git a/src/http/Controller/Login.php b/src/http/Controller/Login.php
index 8c04d85..37680a7 100644
--- a/src/http/Controller/Login.php
+++ b/src/http/Controller/Login.php
@@ -3,6 +3,7 @@
namespace App\http\Controller;
use App\DB;
+use App\Model\Building\Farm;
use App\View;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -26,15 +27,59 @@ class Login
if (empty($user)) {
$password = password_hash($request->get('password'), PASSWORD_DEFAULT);
DB::query('insert into users (username, password, email) values (:username, :password, :email)', ['username' => $email, 'password' => $password, 'email' => $email]);
+
+ $userId = DB::$connection->lastInsertId();
- // TODO: also insert new village at random free coordinates
+ // insert new village at random free coordinates
+ # TODO: check if coords are free
+ DB::query(
+ 'insert into villages (name, x, y, wood, clay, iron, food, satisfaction) values (:name, :x, :y, 100, 100, 100, 100, 100)',
+ [
+ 'name' => $email,
+ 'x' => random_int(-10, 10),
+ 'y' => random_int(-10, 10),
+ ]
+ );
+ $villageId = DB::$connection->lastInsertId();
+
+ DB::query('insert into user_villages (user_id, village_id) values (:user_id, :village_id)', [
+ 'user_id' => $userId,
+ 'village_id' => $villageId,
+ ]);
+
+ DB::query('insert into village_storage_config (wood, clay, iron, food, village_id) values (:wood, :clay, :iron, :food, :village_id)', [
+ 'wood' => 25,
+ 'clay' => 25,
+ 'iron' => 25,
+ 'food' => 25,
+ 'village_id' => $village->id,
+ ]);
+
+ $initialBuildings = ['TownHall', 'Storage', 'WoodCutter', 'ClayPit', 'IronMine', 'Farm'];
+ foreach ($initialBuildings as $buildingType) {
+ DB::query('insert into village_buildings (level, type, village_id) values (:level, :type, :village_id)', [
+ 'level' => 1,
+ 'type' => $buildingType,
+ 'village_id' => $villageId,
+ ]);
+ }
+
+ $initialUnits = ['WoodCutter', 'PitWorker', 'Miner', 'Farmer'];
+ foreach ($initialUnits as $unitType) {
+ DB::query('insert into village_units (amount, type, home_village_id, residence_village_id) values (:amount, :type, :village_id, :village_id)', [
+ 'amount' => 1,
+ 'type' => $unitType,
+ 'village_id' => $villageId,
+ ]);
+ }
} else {
$password = $user['password'];
+ $userId = $user['id'];
}
if (password_verify($request->get('password'), $password)) {
$_SESSION['user'] = [
- 'id' => $user['id'],
+ 'id' => $userId,
'username' => $user['username'],
];
diff --git a/src/http/Controller/Map.php b/src/http/Controller/Map.php
index 69d23e1..3b0773f 100644
--- a/src/http/Controller/Map.php
+++ b/src/http/Controller/Map.php
@@ -10,13 +10,17 @@ use Symfony\Component\Routing\Annotation\Route;
class Map
{
- #[Route(path: '/map/{x}/{y}/{range}', defaults: ['range' => 1], methods: ['GET'])]
+ #[Route(path: '/map/{x}/{y}/{range}', defaults: ['range' => 0], methods: ['GET'])]
public function region(Request $request): Response
{
$x = $request->get('x');
$y = $request->get('y');
$range = $request->get('range');
+ if ($range <= 0) {
+ $range = $_ENV['MAP_DEFAULT_RANGE'];
+ }
+
$statement = DB::query(
'select * from villages where x>=:x1 and x<=:x2 and y>=:y1 and y<=:y2',
[
diff --git a/src/http/Controller/User.php b/src/http/Controller/User.php
new file mode 100644
index 0000000..e38780f
--- /dev/null
+++ b/src/http/Controller/User.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace App\http\Controller;
+
+use App\DB;
+use App\View;
+use App\http\Router;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Attribute\Route;
+
+class User
+{
+ #[Route(path: '/account', methods: ['GET'])]
+ public function account(Request $request): Response
+ {
+ $user = DB::query('select username,email from users where id=:id', ['id' => $_SESSION['user']['id']])->fetch();
+
+ return new Response(View::render('account.twig', [
+ 'user' => $user,
+ ]));
+ }
+
+ #[Route(path: '/account', methods: ['POST'])]
+ public function accountSave(Request $request): Response
+ {
+ $username = $request->get('username');
+ $email = $request->get('email');
+
+ if ($request->get('password')) {
+ $password = password_hash($request->get('password'), PASSWORD_DEFAULT);
+ DB::query(
+ 'update users set username=:username, email=:email, password=:password where id=:id',
+ [
+ 'username' => $username,
+ 'email' => $email,
+ 'password' => $password,
+ 'id' => $_SESSION['user']['id'],
+ ]
+ );
+ } else {
+ DB::query(
+ 'update users set username=:username, email=:email where id=:id',
+ [
+ 'username' => $username,
+ 'email' => $email,
+ 'id' => $_SESSION['user']['id'],
+ ]
+ );
+ }
+
+ $_SESSION['user']['username'] = $request->get('username');
+
+
+ return new RedirectResponse(Router::generate('user.account'));
+ }
+}
diff --git a/src/http/Controller/Village.php b/src/http/Controller/Village.php
index 7b1f227..22713b1 100644
--- a/src/http/Controller/Village.php
+++ b/src/http/Controller/Village.php
@@ -4,6 +4,8 @@ namespace App\http\Controller;
use App\DB;
use App\Guard;
+use App\Model\Event\SendResources;
+use App\Model\Event\SendResourcesCarriers;
use App\Model\Event\SendUnits;
use App\Model\Event\TrainUnits;
use App\Model\Event\UpgradeBuilding;
@@ -27,7 +29,7 @@ class Village
join user_villages on villages.id = user_villages.village_id
where user_villages.user_id=:id
SQL,
- ['id' => $_SESSION['user']['id']]
+ ['id' => $_SESSION['user']['id'] ?? -1]
);
return new Response(View::render('villages.twig', [
@@ -55,26 +57,32 @@ class Village
)->fetchAll();
foreach ($eventsBuilding as $row) {
- $events['UpgradeBuilding'][$row['type']][] = DB::convertToModel(UpgradeBuilding::class, $row);
+ $model = DB::convertToModel(UpgradeBuilding::class, $row);
+ $model->populateEvent();
+
+ $events['UpgradeBuilding'][$row['type']][] = $model;
}
$eventsUnits = DB::query(
<<<SQL
select * from events_train_units as event
left join events on event.event_id = events.id
- where village_id=:id
+ where events.village_id=:id
SQL, ['id' => $village->id]
)->fetchAll();
foreach ($eventsUnits as $row) {
- $events['TrainUnits'][] = DB::convertToModel(TrainUnits::class, $row);
+ $model = DB::convertToModel(TrainUnits::class, $row);
+ $model->populateEvent();
+
+ $events['TrainUnits'][] = $model;
}
$eventsUnitsSendOwn = DB::query(
<<<SQL
select * from events_send_units as event
left join events on event.event_id = events.id
- where village_id=:id
+ where events.village_id=:id
SQL, ['id' => $village->id]
)->fetchAll();
@@ -87,7 +95,56 @@ class Village
)->fetchAll();
foreach ([...$eventsUnitsSendOwn, ...$eventsUnitsSendOther] as $row) {
- $events['SendUnits'][] = DB::convertToModel(SendUnits::class, $row);;
+ $model = DB::convertToModel(SendUnits::class, $row);
+ $model->populateEvent();
+
+ $events['SendUnits'][] = DB::convertToModel(SendUnits::class, $row);
+ }
+
+ $eventsResourcesSendOwn = DB::query(
+ <<<SQL
+ select * from events_send_resources as event
+ left join events on event.event_id = events.id
+ where events.village_id=:id
+ SQL, ['id' => $village->id]
+ )->fetchAll();
+
+ $eventsResourcesSendOther = DB::query(
+ <<<SQL
+ select * from events_send_resources as event
+ left join events on event.event_id = events.id
+ where (destination=:id or source=:id) and village_id!=:id and is_canceled=false
+ SQL, ['id' => $village->id]
+ )->fetchAll();
+
+ foreach ([...$eventsResourcesSendOwn, ...$eventsResourcesSendOther] as $row) {
+ $model = DB::convertToModel(SendResources::class, $row);
+ $model->populateEvent();
+
+ $events['SendResources'][] = DB::convertToModel(SendResources::class, $row);
+ }
+
+ $eventsResourcesCarriersSendOwn = DB::query(
+ <<<SQL
+ select * from events_send_resources_carriers as event
+ left join events on event.event_id = events.id
+ where events.village_id=:id
+ SQL, ['id' => $village->id]
+ )->fetchAll();
+
+ $eventsResourcesCarriersSendOther = DB::query(
+ <<<SQL
+ select * from events_send_resources_carriers as event
+ left join events on event.event_id = events.id
+ where (destination=:id or source=:id) and village_id!=:id
+ SQL, ['id' => $village->id]
+ )->fetchAll();
+
+ foreach ([...$eventsResourcesCarriersSendOwn, ...$eventsResourcesCarriersSendOther] as $row) {
+ $model = DB::convertToModel(SendResourcesCarriers::class, $row);
+ $model->populateEvent();
+
+ $events['SendResourcesCarriers'][] = $model;
}
$buildings = [];
diff --git a/src/http/Router.php b/src/http/Router.php
index db75f81..f279109 100644
--- a/src/http/Router.php
+++ b/src/http/Router.php
@@ -9,7 +9,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Generator\UrlGenerator;
-use Symfony\Component\Routing\Loader\AnnotationFileLoader;
+use Symfony\Component\Routing\Loader\AttributeFileLoader;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
@@ -28,7 +28,7 @@ class Router
self::$context->fromRequest($request);
self::$routes = new RouteCollection();
- $loader = new AnnotationFileLoader(new FileLocator(), new RouteLoader());
+ $loader = new AttributeFileLoader(new FileLocator(), new RouteLoader());
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(__DIR__ . '/Controller'));
foreach ($iterator as $file) {
/**@var \SplFileInfo $file*/
diff --git a/src/http/Support/RouteLoader.php b/src/http/Support/RouteLoader.php
index b0e74cb..d11011c 100644
--- a/src/http/Support/RouteLoader.php
+++ b/src/http/Support/RouteLoader.php
@@ -2,10 +2,10 @@
namespace App\http\Support;
-use Symfony\Component\Routing\Loader\AnnotationClassLoader;
+use Symfony\Component\Routing\Loader\AttributeClassLoader;
use Symfony\Component\Routing\Route;
-class RouteLoader extends AnnotationClassLoader
+class RouteLoader extends AttributeClassLoader
{
protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annotation) {
$route->setDefault('_', compact('class', 'method', 'annotation'));
@@ -15,10 +15,9 @@ class RouteLoader extends AnnotationClassLoader
{
$name = parent::getDefaultRouteName($class, $method);
- return str_replace(
- '_',
- '.',
- str_replace('app_controller_', '', $name)
- );
+ $name = preg_replace('/app_\w+_controller_/', '', $name);
+ $name = str_replace('_', '.', $name);
+
+ return $name;
}
}