From d56a8ceaf07b5b0848945ba9868a2cdaf3b05111 Mon Sep 17 00:00:00 2001 From: xangelo Date: Mon, 9 May 2022 11:29:05 -0400 Subject: [PATCH] WIP: update to include sectors! --- dump.sql | 117 +++------------------------------ package.json | 8 ++- scripts/setup.ts | 13 ++++ src/api.ts | 20 +++--- src/config.ts | 3 +- src/lib/db.ts | 2 +- src/lib/server.ts | 6 +- src/render/fight.ts | 18 ++--- src/render/kingdom-overview.ts | 4 +- src/render/land-development.ts | 4 +- src/render/unit-training.ts | 4 +- src/repository/army.ts | 7 +- src/repository/city.ts | 86 +++++++++++++++++++----- src/tasks/fight.ts | 8 +-- 14 files changed, 136 insertions(+), 164 deletions(-) create mode 100644 scripts/setup.ts diff --git a/dump.sql b/dump.sql index cee6242..9cd3202 100644 --- a/dump.sql +++ b/dump.sql @@ -25,10 +25,14 @@ CREATE TABLE IF NOT EXISTS "cities" ( "barracks" int, "special_attacker_trainer" int, "special_defender_trainer" int, - "location_x" int, - "location_y" int, PRIMARY KEY("id") ); +CREATE TABLE IF NOT EXISTS "locations" ( + "sector_id" int, + "city_id" text unique, + "location_x" int, + "location_y" int +); CREATE TABLE IF NOT EXISTS "ticks" ( "current_tick" int, "last_tick_at" int @@ -105,111 +109,7 @@ CREATE TABLE IF NOT EXISTS "mail" ( PRIMARY KEY("id") ); INSERT INTO "accounts" VALUES ('-','Advisor','xos'); -INSERT INTO "accounts" VALUES ('54270f97-6c22-4398-a34e-0cd0ff3b8347','otaria','$2b$10$/N.WUQtnoGmPcwQuzZil/eKjh3tbs3ybU4CpUErfcZ01gaooS/YBm'); -INSERT INTO "cities" VALUES ('9a1350f6-2c5e-4676-ab68-f29d3a5dc617','934673de-27ad-452e-aba1-c7559f2b6c2c',100,24,2480498133976174,9770,8960,1782836,490,NULL,0,0,0,0,85,7,0,0,0,74,12); -INSERT INTO "cities" VALUES ('4d3a80e6-ba68-42ef-ac94-f9e04b1d7f02','f439c929-bade-4bf9-9c03-f50005e878e6',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,97,92); -INSERT INTO "cities" VALUES ('3bff09a5-2a83-4225-abb6-b9ed43058184','bcd32831-cb3b-4047-97dc-e87b9f8538c6',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,76,46); -INSERT INTO "cities" VALUES ('f832ff46-08d0-4581-9460-7eae7048e4cf','45dd633a-ef2c-4491-9224-4b6784e73e29',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,3,10); -INSERT INTO "cities" VALUES ('c1851f16-605a-4237-be11-6297ee46ff67','de51e72e-f51e-4f10-9a6e-9ecfc3c17126',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,13,61); -INSERT INTO "cities" VALUES ('0edbe4a9-1f57-422a-8089-496cd6c7c7a3','8731686f-3caf-4030-8825-30f616a86dcd',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,23,0); -INSERT INTO "cities" VALUES ('1c37d72d-0a73-422c-a93f-5eb5c0c97438','1e4646ee-2072-46a5-ab7b-4e0e05b1cf57',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,31,60); -INSERT INTO "cities" VALUES ('3039c15a-36ae-4342-9b92-f7c8d431a0d6','17940bd5-2aa7-455f-95bf-9eca87cbdd0c',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,72,82); -INSERT INTO "cities" VALUES ('1a6a926d-1223-4a06-95d7-5302bc370292','01fd5cdf-8fcb-4486-beac-805b7c6b222a',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,46,90); -INSERT INTO "cities" VALUES ('dea5617c-05bc-4551-95b6-40c2796007ee','be961d8f-e47a-426a-a262-9b3bf34da6f3',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,40,86); -INSERT INTO "cities" VALUES ('7e5b4d82-178f-4238-b5ba-19d3b3ecf13c','049043b0-ba9f-4c06-afb0-762d660a56c0',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,34,48); -INSERT INTO "cities" VALUES ('cbea0fc7-3422-4702-a433-39bc0633b1cd','a729651e-ac6a-4ce4-8008-e3e098f5f3e2',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,7,99); -INSERT INTO "cities" VALUES ('356b0b56-64b2-4c0b-a6d6-748aa013edeb','9476f5cd-be44-424f-a525-882d9c240896',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,55,1); -INSERT INTO "cities" VALUES ('41d90ecf-2961-413d-8f7e-b8ecc5af24f6','9b6aeb06-6a04-4413-a96f-2b33230eb426',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,7,32); -INSERT INTO "cities" VALUES ('8fa82c61-d205-455f-9e88-d7176c9e8a36','888e29e4-06e6-4ab8-a60e-dc483102f467',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,40,58); -INSERT INTO "cities" VALUES ('5d50dfbc-5cd7-4a94-8e52-7f12b7307e1d','1c648776-73a9-456a-8c9b-c0a23e9d19c0',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,58,5); -INSERT INTO "cities" VALUES ('f566302d-735e-4258-9ba6-d96ba5f359c0','727051d7-5b0b-4a1e-a6a4-1325d4a7ebbc',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,67,45); -INSERT INTO "cities" VALUES ('9aaff9eb-f047-43c9-a49d-122cb5defa5b','2d811a47-121d-4749-ae5b-bf6968c6de0e',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,87,14); -INSERT INTO "cities" VALUES ('b5592711-9411-4048-88b2-4de87dbc6c7b','fd3346c5-fdd6-4a8b-9aa1-aa8e2d8f7ce1',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,44,32); -INSERT INTO "cities" VALUES ('14693011-5e6b-4d02-accd-d81676e43220','00604e16-ba10-4a1b-bd5d-bcc839630a82',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,61,61); -INSERT INTO "cities" VALUES ('f0579927-6128-4cfc-a661-1d140c43adfc','b1c565eb-56e2-4c83-98cf-aa13317a6c2c',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,43,35); -INSERT INTO "cities" VALUES ('b5940bf2-64e7-4aee-9176-7d93242eb22c','d59a0464-2ffe-4b79-868c-7b960d2915b7',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,1,5); -INSERT INTO "cities" VALUES ('62f0555a-01bd-4cfc-8517-883100821d05','654856ed-0f83-4415-a9ca-31815b4bb28d',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,4,77); -INSERT INTO "cities" VALUES ('1b9034de-7eeb-4a32-b91c-596307d59f3d','6738f9ff-0dc7-4c30-ac24-12bc49ae6c4f',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,41,41); -INSERT INTO "cities" VALUES ('db3a2ae1-a773-4663-ab10-44edfb89d328','e1cc7c43-a70d-4e3b-bf52-b9eabee6bf41',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,96,6); -INSERT INTO "cities" VALUES ('6b988dc7-1c98-463c-9910-f31b6828cd2c','1dd518e6-322e-4634-b76a-bb9e4c4d9c63',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,82,60); -INSERT INTO "cities" VALUES ('e0bb4d85-7064-4a07-ab55-c33a0f66c86c','13ef9bd0-d7ae-403f-a497-3ea31e222a09',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,20,37); -INSERT INTO "cities" VALUES ('f6ddfec3-a254-46b2-81b6-2a14b7ed00f6','83e2cc80-b777-47f9-99f7-350020e14da0',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,6,99); -INSERT INTO "cities" VALUES ('4952f176-2597-4dd1-a9c8-b2bfa258f5b0','523ca052-4509-4266-9aa3-42c15e689982',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,38,28); -INSERT INTO "cities" VALUES ('1526636e-4acc-4216-bd7a-389d3640d77a','50c7d344-344d-4160-a920-ea4b182e0ef0',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,71,90); -INSERT INTO "cities" VALUES ('61305386-f8b8-496a-b073-76bae5af02d7','738b4d62-cc3b-41de-a852-1287b2acbd20',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,6,23); -INSERT INTO "cities" VALUES ('3ca0d9b4-0b4e-4bc8-ba26-05f2b7c6331e','ece23dbc-3a91-4a7b-a51a-fb629cc5bd72',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,61,94); -INSERT INTO "cities" VALUES ('202fb387-5414-4b05-91ea-a6a36d363013','dbafa7d8-4559-4f23-b105-46905e663ca1',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,56,96); -INSERT INTO "cities" VALUES ('47ccb44c-e9b8-433b-890b-fb80578ebbfd','643555fe-18ea-4d35-b4e9-cf6dac5f9d1a',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,40,91); -INSERT INTO "cities" VALUES ('536a343f-20c2-4823-a0da-2ec456351f7f','981145d8-285e-4b88-b766-ce2139cd1a75',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,11,32); -INSERT INTO "cities" VALUES ('6e096f8a-0c38-4951-88b5-19b1b8e8d721','e6321f65-3393-47b1-b77a-af7d7342c237',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,24,55); -INSERT INTO "cities" VALUES ('f3a89abf-0b1e-4eb1-a5f4-a6ecb4ac1811','b1cd8806-3b80-4416-9415-0dd9a2237ae0',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,79,52); -INSERT INTO "cities" VALUES ('123b12e6-0118-4d62-8225-2d8025030c4e','5852bbd0-51d6-4b61-afde-7f0f92162a1e',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,47,1); -INSERT INTO "cities" VALUES ('8475a1f1-ed7f-4205-aaa7-3cf6e4408253','1d852b2a-76b1-435d-8e19-dfac1729aa2e',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,20,31); -INSERT INTO "cities" VALUES ('ff0c82e8-afeb-4915-a2db-ec570a39e810','60c2de9c-7d70-44b8-8012-cef33c70097e',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,26,27); -INSERT INTO "cities" VALUES ('4acdd785-c606-432e-b83a-0cac33e5e45e','2727c469-9085-4350-9d66-44eca0c612ee',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,53,13); -INSERT INTO "cities" VALUES ('fb674506-2529-4930-937a-35102e291199','ae7d20de-9115-4b59-ae96-553beff36477',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,10,13); -INSERT INTO "cities" VALUES ('94cf3015-cd92-43ad-a10f-c0724f2680c9','43d54f20-2c91-4d46-b95e-f451105e0c97',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,11,4); -INSERT INTO "cities" VALUES ('f8f273c1-3238-40fd-ad4d-d5018c263e47','2aaa212d-3fa2-4ccf-a021-797856363af6',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,6,19); -INSERT INTO "cities" VALUES ('92e9722b-0379-4fea-a1d7-f70b8f4e2d7b','2cdf84d2-e0de-4daf-b0c5-b510464b82a5',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,68,34); -INSERT INTO "cities" VALUES ('b09c2842-e95f-4c0e-8742-7a965c755ff9','d3cd6a4c-81d6-4897-971d-b25168342a75',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,47,24); -INSERT INTO "cities" VALUES ('0546c5dd-8470-494b-93ea-5e24aedcb6b5','e345a220-4a8e-406d-9039-6798b4f81652',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,57,60); -INSERT INTO "cities" VALUES ('482bb899-af7f-4545-a5dc-e0c810f5fc9b','d02997b0-0830-4269-9a13-c472222bf28b',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,58,35); -INSERT INTO "cities" VALUES ('4b3ffe24-1645-4373-b69e-6a29f15d8215','53c20d14-9d3f-45fc-9736-e3e48bef2783',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,51,27); -INSERT INTO "cities" VALUES ('005a85fc-cf2e-4bc9-a39b-9a3bad23469d','6001a973-465f-4ced-839b-eac5463859af',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,52,50); -INSERT INTO "cities" VALUES ('cf862e8b-8465-4f23-a8d9-0e04a1603ea4','127b3a6e-1745-426a-8e28-d8ecbf4202be',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,13,9); -INSERT INTO "cities" VALUES ('6547eb32-4094-421b-97f1-3dc3fea0d6dd','c1d9e4db-9a02-4aac-86c9-0e8040e57a88',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,48,71); -INSERT INTO "cities" VALUES ('9083add2-37ad-40a2-a6ea-ee66c79c238a','accc82b9-189b-4b42-bc67-7c16abfa8c46',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,79,2); -INSERT INTO "cities" VALUES ('dfade128-f6f2-4552-9ebc-4037d255d557','f27bbdb7-8002-45cd-8f95-a88cdfaf63ba',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,95,79); -INSERT INTO "cities" VALUES ('bb016d2a-2d42-4ff5-abb1-7e996f20a748','a304e1bb-e420-4405-a76b-f5b5040568f2',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,97,0,0,0,0,84,61); -INSERT INTO "cities" VALUES ('02ca1f1c-3b22-4f20-a584-cc013a31dc2d','698d43ea-3df1-4ae1-8f15-536ea3147c8d',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,38,36); -INSERT INTO "cities" VALUES ('1ce47966-f1de-4db2-b2ac-babb63173309','9b91e1a8-0854-4e71-9c24-c5ff36fe008c',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,93,87); -INSERT INTO "cities" VALUES ('10264b6e-0711-49c6-a873-d68049e6898c','5eb1a39c-c916-4b4e-8e14-839bba6e6c5e',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,8,1); -INSERT INTO "cities" VALUES ('acedda91-c45e-41f7-b60b-2c4d5def0813','8292435b-baca-4961-8a77-eb48410488bf',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,77,34); -INSERT INTO "cities" VALUES ('4c0f3905-67cb-4cb2-bff5-be20708cf1a0','a58266cc-956d-45be-b3e3-5c00c9303e73',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,54,70); -INSERT INTO "cities" VALUES ('30b41df8-ff05-49a9-acf4-c2164571e0e6','e1501e6d-2dcd-4ca6-bf2b-c265472cd406',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,97,50); -INSERT INTO "cities" VALUES ('8ca8d68c-c381-4297-9337-39034f5782de','d2d2a7ac-754e-4a3d-880b-975d1be1676b',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,6,13); -INSERT INTO "cities" VALUES ('03a937a3-dccd-4668-97e0-fbab36267e16','1e598ca7-26cf-4046-a18f-1f1e0db0be3a',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,76,95); -INSERT INTO "cities" VALUES ('115ce7f8-c079-4056-8153-67aa4eb3736b','0e60ae00-38b5-42c7-a0b1-06f95810d0e2',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,59,6); -INSERT INTO "cities" VALUES ('4a1719ce-a802-4935-99a5-c0b52318c422','73997426-d16a-440d-b63a-679dda72b89c',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,92,12); -INSERT INTO "cities" VALUES ('23eb1c0d-e735-4624-a0e3-a20a52612a7b','a243a916-8953-41a4-b86f-1130bcb4dd00',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,59,6); -INSERT INTO "cities" VALUES ('4cf5ef70-d251-4b27-80aa-25dc03bbc2c7','babf461e-6239-4497-a504-5d24d9d689ca',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,16,90); -INSERT INTO "cities" VALUES ('ef403e54-b214-4cb4-801a-b5d44064e366','34b5fc5c-81a7-41a3-b41e-68030a0d0639',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,85,17); -INSERT INTO "cities" VALUES ('4ed70869-3ada-4787-a1ae-79e943d3c795','0055ef4e-84ab-417b-9873-b5b35f91b093',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,22,22); -INSERT INTO "cities" VALUES ('a3f53533-bf75-4382-993e-28a9d3811641','97c61058-454d-4738-bc27-92d7088372f1',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,76,3); -INSERT INTO "cities" VALUES ('00dc2a01-8703-474d-b9c3-d4db90b699bc','f5e33f96-cff4-4b04-a6d0-5732e9313de2',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,92,53); -INSERT INTO "cities" VALUES ('9a29ffef-8bfb-4dc1-ba5b-b42fe76f5f68','3b433e27-b34f-4333-9196-f86897a4a9db',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,64,75); -INSERT INTO "cities" VALUES ('a6a41994-561a-4b24-9c03-0ebcea4e9ca3','22a65552-9bac-4478-a925-2f517441ec98',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,91,18); -INSERT INTO "cities" VALUES ('630a2eb3-4799-4e04-b6de-95052b95f932','42e63cf7-8909-4a0e-b7f8-164a609efe33',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,19,52); -INSERT INTO "cities" VALUES ('f36bf98b-b54c-47f0-875a-0f753e38f49a','e7659374-ef74-44be-8deb-e355bda95c4f',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,94,97); -INSERT INTO "cities" VALUES ('20f32716-f7db-4a9d-970a-5a491288d11e','64844d0d-9ccc-4023-b1d6-ba1a3fa1322e',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,19,84); -INSERT INTO "cities" VALUES ('4e9e6e64-619e-4c91-8c13-db940cbe9af1','2b97dff6-1e2e-448b-a51c-337ecfe836d6',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,4,83); -INSERT INTO "cities" VALUES ('d8817d09-308d-46b2-a4ca-6bad80a2f83c','3483c0bc-6224-4b47-8b0d-4f4012693de1',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,10,66); -INSERT INTO "cities" VALUES ('1fc525e5-3eef-4007-8f4f-92822fb2f98f','20d52370-a7a6-4e93-8c1f-40535c7b5fd9',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,65,11); -INSERT INTO "cities" VALUES ('e2529402-9048-4dbc-bf5e-81ec115e4b85','7b271864-7671-49ee-8982-ab827d28ad45',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,11,60); -INSERT INTO "cities" VALUES ('44a1f18e-6bc5-4f54-b8e3-4c876408844b','21de73af-8d84-483d-85fd-a2cb57662eaa',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,91,60); -INSERT INTO "cities" VALUES ('b1cc4e47-eeb3-42f4-971a-998e1b663c53','988efec2-ed5a-4537-b50b-db0fa8f06445',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,58,93); -INSERT INTO "cities" VALUES ('42a03e80-0b93-48ca-9e89-056b305b9f31','9b05b8ce-a3c5-4f4a-907b-747aa9b1cf68',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,38,83); -INSERT INTO "cities" VALUES ('37b1a7df-890b-45d4-985d-831c3ef3fc74','8c9515fc-e18b-4132-a32b-ecbe7bbeb90f',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,90,80); -INSERT INTO "cities" VALUES ('12eab809-6d06-4302-8d5c-f32e4715edfd','b95f1bef-239e-4a7b-b6ec-f064c3ef9c54',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,45,5); -INSERT INTO "cities" VALUES ('9a5242b0-2737-4b90-9dbf-29812e399326','03c538b3-596b-4b89-b183-d18f5245c209',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,62,87); -INSERT INTO "cities" VALUES ('b8d35860-2911-4570-b0b3-10848311d5fe','4b808479-d427-4288-9454-fd2e4060aaee',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,64,25); -INSERT INTO "cities" VALUES ('b250ff81-7dc7-4e1b-a137-29c4ce4b9c5d','570d80f3-b158-42c6-9015-a98ffbdd7b5d',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,4,40); -INSERT INTO "cities" VALUES ('56920e71-4b84-460b-bfa1-e3971f5876f6','e945ac13-3c9d-4cd1-a1a6-ce417a6ff19a',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,92,30); -INSERT INTO "cities" VALUES ('6f2ed644-cf12-4d25-a04a-6f854f27d284','21dc5c4d-95d3-45bb-a66a-720f7766a383',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,6,24); -INSERT INTO "cities" VALUES ('979d63a6-7463-46b6-b401-d1fba912f6a5','a3b458af-d115-411d-ac9a-e8a3cac17920',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,60,58); -INSERT INTO "cities" VALUES ('1b40da4e-1e10-44fd-bf05-979822d351a6','5f4b42a6-6e71-4bd9-8c86-e7e3b347bf74',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,33,25); -INSERT INTO "cities" VALUES ('d51165ee-d0ff-4bb7-bf71-8107dc9c818d','7682b7c6-cdab-4c06-9ec0-5885f30ef608',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,88,92); -INSERT INTO "cities" VALUES ('d96d5b18-f93f-4121-bcc2-b0ed3cb91482','009ec244-231a-40e7-8aa5-d3ef38958f86',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,28,86); -INSERT INTO "cities" VALUES ('eb4596b2-87ad-47f2-8304-530f4533a4a6','0dc6ca85-7666-4ecd-b2f8-23c8dbcba13a',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,65,17); -INSERT INTO "cities" VALUES ('00ed9306-1fab-44c7-a42a-7890937c3815','aede9eb3-ac80-4d52-9654-4f3da412a335',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,3,84); -INSERT INTO "cities" VALUES ('8b2882e1-6ce1-47ee-98bb-4809fef7bb2e','2a189dba-307d-4cb5-b615-bb987917495e',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,95,30); -INSERT INTO "cities" VALUES ('211afe3c-beac-4034-8434-eb72048e63e6','666b614e-4584-41a6-9315-e42b0df7252a',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,76,60); -INSERT INTO "cities" VALUES ('12625b90-4d7d-4280-9390-b541f46123db','73c6d662-f08c-4f36-8135-8a7e82e89e56',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,22,89); -INSERT INTO "cities" VALUES ('6e6cb3c3-b3ba-40f7-8407-7f77553e1938','b7c8bafa-037f-44df-8c51-3aed4223dcec',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,56,36); -INSERT INTO "cities" VALUES ('c5924972-a2fb-4dfa-b1b7-e6b2fb2c2c6b','fa131a4a-2c37-4656-9a75-5b5b082cca6d',100,0,14712000,10000,10000,0,1000,NULL,0,0,0,0,100,0,0,0,0,73,98); -INSERT INTO "cities" VALUES ('3562c730-1d6a-47a1-89d1-dadb5e4bfa5d','83f82a2b-6b29-4cff-8937-baba748117d6',100,23,15094182,9900,8880,791122,1400,NULL,100,88,0,0,0,20,10,0,0,82,66); -INSERT INTO "cities" VALUES ('dfe2f966-71b9-4af9-80a7-f79525efe3af','54270f97-6c22-4398-a34e-0cd0ff3b8347',100,0,10600,10000,10000,9000,500,NULL,0,0,0,0,0,0,0,0,0,29,28); -INSERT INTO "ticks" VALUES (1,1651866761619); +INSERT INTO "locations" VALUES (1, '-', -1, -1); INSERT INTO "buildings" VALUES ('farms','Farms',20,0,40,1,14); INSERT INTO "buildings" VALUES ('barracks','Barracks',40,10,60,1,16); INSERT INTO "buildings" VALUES ('special_attacker_trainer','Sp. Attacker Trainer',80,40,100,2,20); @@ -218,5 +118,4 @@ INSERT INTO "units" VALUES ('soldiers','Soldiers',2,1,1,0,0,0,2,2.1,1); INSERT INTO "units" VALUES ('attackers','Attackers',5,2,0,1,0,0,3,4,1); INSERT INTO "units" VALUES ('defenders','Defenders',4,2,0,1,0,0,5,1,4); INSERT INTO "units" VALUES ('sp_attackers','Sp. Attacker',9,4,0,0,1,0,7,7,3); -INSERT INTO "units" VALUES ('sp_defenders','Sp. Defender',11,5,0,0,0,1,10,2,9); -COMMIT; +INSERT INTO "units" VALUES ('sp_defenders','Sp. Defender',11,5,0,0,0,1,10,2,9); \ No newline at end of file diff --git a/package.json b/package.json index 10fef74..070db23 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,10 @@ { "name": "tick-city", "scripts": { - "dev": "npx nodemon src/api.ts" + "dev": "npx nodemon src/api.ts", + "setup:rebels": "npx ts-node scripts/generate-cities.ts", + "setup:database": "npx ts-node scripts/setup.ts", + "setup": "npm run setup:database && npm run setup:rebels" }, "dependencies": { "@bull-board/api": "^3.11.0", @@ -30,5 +33,8 @@ "ts-node": "^10.7.0", "tsconfig-paths": "^4.0.0", "typescript": "^4.6.4" + }, + "volta": { + "node": "16.4.0" } } diff --git a/scripts/setup.ts b/scripts/setup.ts new file mode 100644 index 0000000..2485aae --- /dev/null +++ b/scripts/setup.ts @@ -0,0 +1,13 @@ +import { db } from '../src/lib/db'; +import fs from 'fs'; +import { join } from 'path'; + +fs.readFile(join(__dirname, '..', 'dump.sql'), {encoding: 'utf-8'} ,async (err, data) => { + if(err) + throw err; + + await db.raw(data); + + console.log('Database configured'); + process.exit(0); +}); \ No newline at end of file diff --git a/src/api.ts b/src/api.ts index e5e1557..7687367 100644 --- a/src/api.ts +++ b/src/api.ts @@ -79,8 +79,8 @@ server.post<{body: { server.get<{params: { cityId: string }}, string>('/city/:cityId', async req => { const account = await accountRepo.validate(req.authInfo.accountId, req.authInfo.token); - const yourCity = await cityRepo.FindOne({ owner: account.id }); - const city = await cityRepo.FindOne({ id: req.params.cityId }); + const yourCity = await cityRepo.getUsersCity(account.id); + const city = await cityRepo.findById(req.params.cityId); const acct = await accountRepo.FindOne({id: city.owner}); @@ -93,14 +93,14 @@ server.get<{params: { cityId: string }}, string>('/city/:cityId', async req => { server.get<{}, string>('/poll/overview', async req => { const account = await accountRepo.validate(req.authInfo.accountId, req.authInfo.token); - const city = await cityRepo.FindOne({ owner: account.id }); + const city = await cityRepo.getUsersCity(account.id); return renderKingomOverview(city, account); }); server.get<{}, string>('/poll/construction', async req => { const account = await accountRepo.validate(req.authInfo.accountId, req.authInfo.token); - const city = await cityRepo.FindOne({ owner: account.id }); + const city = await cityRepo.getUsersCity(account.id); const buildings = await cityRepo.buildingRepository.list(); const buildQueues = await cityRepo.getBuildQueues(account.id); @@ -109,7 +109,7 @@ server.get<{}, string>('/poll/construction', async req => { server.get<{}, string>('/poll/unit-training', async req => { const account = await accountRepo.validate(req.authInfo.accountId, req.authInfo.token); - const city = await cityRepo.FindOne({ owner: account.id }); + const city = await cityRepo.getUsersCity(account.id); const unitTrainingQueues = await cityRepo.getUnitTrainingQueues(account.id); const units = await cityRepo.unitRepository.list(); @@ -119,9 +119,9 @@ server.get<{}, string>('/poll/unit-training', async req => { server.get<{}, string>('/poll/map', async req => { const account = await accountRepo.validate(req.authInfo.accountId, req.authInfo.token); - const city = await cityRepo.FindOne({ owner: account.id }); + const city = await cityRepo.getUsersCity(account.id); - return renderOverworldMap(await cityRepo.FindAll(), city); + return renderOverworldMap(await cityRepo.findAllInSector(city.sector_id), city); }); server.get<{}, string>('/poll/mailroom', async req => { @@ -234,7 +234,7 @@ server.post<{ >('/attack', async req => { const acct = await accountRepo.validate(req.authInfo.accountId, req.authInfo.token); const city = await cityRepo.getUsersCity(acct.id); - const attackedCity = await cityRepo.FindOne({id: req.body.city}); + const attackedCity = await cityRepo.findById(req.body.city); const army = { soldiers: parseInt(req.body.soldiers), @@ -280,6 +280,4 @@ server.get('/attacks/outgoing', async req => { }); -server.start(); - -tick.trigger({lastTickAt: 0, lastTick: 0}); \ No newline at end of file +server.start(); \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index 908d21e..ad7a3c5 100644 --- a/src/config.ts +++ b/src/config.ts @@ -3,4 +3,5 @@ import { config as dotenv } from 'dotenv'; dotenv(); export const TICK_LENGTH = process.env.TICK_LENGTH || 1000 * 60 * 5; -export const API_PORT = process.env.API_PORT || '9090'; +export const API_PORT = process.env.API_PORT || 9090; +export const AVAILABLE_SECTORS = 1 diff --git a/src/lib/db.ts b/src/lib/db.ts index 5964ca9..e171859 100644 --- a/src/lib/db.ts +++ b/src/lib/db.ts @@ -3,7 +3,7 @@ import knex from 'knex'; export const db = knex({ client: 'better-sqlite3', connection: { - filename: './data.sql' + filename: './data.db' }, debug: true }); diff --git a/src/lib/server.ts b/src/lib/server.ts index 249cc06..13545e4 100644 --- a/src/lib/server.ts +++ b/src/lib/server.ts @@ -17,10 +17,10 @@ export type HttpHandler = (params: I & AuthInfo, rawReq: Request, rawRes: export class HttpServer { server: express.Application; - port: number; + port: string | number; bullAdapter: ExpressAdapter; - constructor(port: string) { - this.port = parseInt(port, 10); + constructor(port: string | number) { + this.port = port; this.bullAdapter = new ExpressAdapter() this.server = express(); this.configureMiddleWare(); diff --git a/src/render/fight.ts b/src/render/fight.ts index 833341e..a4864a2 100644 --- a/src/render/fight.ts +++ b/src/render/fight.ts @@ -2,24 +2,24 @@ import _ from "lodash"; import { DateTime } from "luxon"; import { Account } from "../repository/accounts"; import { ArmyQueueWithAttackedOwner } from "../repository/army"; -import { City, CityRepository } from "../repository/city"; +import { City, CityRepository, CityWithLocation } from "../repository/city"; const cityRepo = new CityRepository(); -export function renderOverworldMap(cities: City[], yourCity: City): string { - let map: City[][] = new Array(100); +export function renderOverworldMap(cities: CityWithLocation[], yourCity: CityWithLocation): string { + let map: CityWithLocation[][] = new Array(25); for(let i = 0; i < cities.length; ++i) { if(!map[cities[i].location_y]) { - map[cities[i].location_y] = new Array(100); + map[cities[i].location_y] = new Array(25); } map[cities[i].location_y][cities[i].location_x] = cities[i]; } let rows: string[] = []; - for(let y = 0; y < 100; ++y) { + for(let y = 0; y < 25; ++y) { rows[y] = ''; - for(let x = 0; x < 100; ++x) { + for(let x = 0; x < 25; ++x) { if(!map[y] || !map[y][x]) { rows[y] += '
' ; } @@ -36,7 +36,7 @@ export function renderOverworldMap(cities: City[], yourCity: City): string { rows[y] += ''; } let html = ` -

Map

+

Map

@@ -82,7 +82,7 @@ export function listOperations(outgoingOps: ArmyQueueWithAttackedOwner[]): strin return html; } -export async function launchOffensive(city: City, owner: Account, yourCity: City, you: Account): Promise { +export async function launchOffensive(city: CityWithLocation, owner: Account, yourCity: CityWithLocation, you: Account): Promise { const distance = cityRepo.distanceInHours(city, yourCity); const power = await cityRepo.power({ soldiers: yourCity.soldiers, @@ -92,7 +92,7 @@ export async function launchOffensive(city: City, owner: Account, yourCity: City sp_defenders: yourCity.sp_defenders }) let html = ` -

Viewing (${city.location_x},${city.location_y}) owned by ${owner.username}

+

Viewing (${city.location_x},${city.location_y}) owned by ${owner.username}

Report

This city is ${distance} hours away.

diff --git a/src/render/kingdom-overview.ts b/src/render/kingdom-overview.ts index 802eb01..d82f6a4 100644 --- a/src/render/kingdom-overview.ts +++ b/src/render/kingdom-overview.ts @@ -1,8 +1,8 @@ import { Account } from "../repository/accounts"; -import { City } from "../repository/city"; +import { CityWithLocation } from "../repository/city"; import * as _ from 'lodash'; -export function renderKingomOverview(city: City, account: Account): string { +export function renderKingomOverview(city: CityWithLocation, account: Account): string { return `

Kingdom Overview

diff --git a/src/render/land-development.ts b/src/render/land-development.ts index 0f58442..935ff74 100644 --- a/src/render/land-development.ts +++ b/src/render/land-development.ts @@ -1,5 +1,5 @@ import { BuildQueue } from "../repository/build-queue"; -import { City } from "../repository/city"; +import { CityWithLocation } from "../repository/city"; import { Building } from '../repository/buildings'; import _ from "lodash"; @@ -13,7 +13,7 @@ function progressBar(current, max): string { `; } -export function renderLandDevelopment(city: City, buildings: Building[], buildQueues: BuildQueue[]): string { +export function renderLandDevelopment(city: CityWithLocation, buildings: Building[], buildQueues: BuildQueue[]): string { const freeSpace = city.totalSpace - city.usedSpace; let html = `
diff --git a/src/render/unit-training.ts b/src/render/unit-training.ts index dfbbb1b..5b4ffcf 100644 --- a/src/render/unit-training.ts +++ b/src/render/unit-training.ts @@ -1,5 +1,5 @@ import _ from "lodash"; -import { City } from "../repository/city"; +import { CityWithLocation } from "../repository/city"; import { UnitTrainingQueue } from "../repository/training-queue"; import { Unit } from "../repository/unit"; @@ -13,7 +13,7 @@ function progressBar(current, max): string { `; } -export function renderUnitTraining(city: City, units: Unit[], trainingQueues: UnitTrainingQueue[]): string { +export function renderUnitTraining(city: CityWithLocation, units: Unit[], trainingQueues: UnitTrainingQueue[]): string { const unit = _.keyBy(units, 'slug'); let html = `
diff --git a/src/repository/army.ts b/src/repository/army.ts index d5e47e6..46ddf57 100644 --- a/src/repository/army.ts +++ b/src/repository/army.ts @@ -1,6 +1,6 @@ import { Repository } from "./base"; import { v4 as uuid } from 'uuid'; -import { City } from "./city"; +import { CityWithLocation } from "./city"; export type Army = { soldiers: number; @@ -30,7 +30,7 @@ export class ArmyRepository extends Repository { super('army_queue'); } - async create(owner: string, city: City, attacked_city: City, army: Army, distance: number): Promise { + async create(owner: string, city: CityWithLocation, attacked_city: CityWithLocation, army: Army, distance: number): Promise { // figure out the distance to the attacked city const info: ArmyQueue = { @@ -50,9 +50,10 @@ export class ArmyRepository extends Repository { async listOutgoing(city_id: string): Promise { return await (this.db.raw(`select - aq.*, o.username as attacked_account, c.location_x, c.location_y + aq.*, o.username as attacked_account, l.location_x, l.location_y, l.sector_id from army_queue aq join cities c on c.id = aq.attacked_city + join locations l on l.city_id = aq.attacked_city join accounts o on o.id = c.owner order by due asc`)) as ArmyQueueWithAttackedOwner[]; } diff --git a/src/repository/city.ts b/src/repository/city.ts index 4aaa127..df80878 100644 --- a/src/repository/city.ts +++ b/src/repository/city.ts @@ -1,13 +1,14 @@ import { v4 as uuid } from 'uuid'; import { ERROR_CODE, InsufficientResourceError, NotFoundError } from '../errors'; import {Repository} from './base'; +import * as config from '../config'; import { BuildQueue, BuildQueueRepository } from './build-queue'; import { DateTime, Duration } from 'luxon'; import { UnitTrainingQueue, UnitTrainingQueueRepository } from './training-queue'; import { coalesce } from '../lib/util'; import { Building, BuildingRepository } from './buildings'; import { Unit, UnitRepository } from './unit'; -import _ from 'lodash'; +import _, { random } from 'lodash'; import { Army, ArmyQueue, ArmyRepository } from './army'; export type City = { @@ -29,9 +30,13 @@ export type City = { barracks: number; special_attacker_trainer: number; special_defender_trainer: number; +} + +export type CityWithLocation = { + sector_id: number; location_x: number; location_y: number; -} +} & City; export class CityRepository extends Repository { buildQueue: BuildQueueRepository; @@ -49,7 +54,7 @@ export class CityRepository extends Repository { this.armyRepository = new ArmyRepository(); } - async create(accountId: string): Promise { + async create(accountId: string): Promise { const info: City = { id: uuid(), owner: accountId, @@ -69,32 +74,81 @@ export class CityRepository extends Repository { barracks: 0, special_attacker_trainer: 0, special_defender_trainer: 0, - location_x: _.random(0, 100), - location_y: _.random(0, 100) }; + await this.Insert(info); + // placement can happen randomly + const availableSectors = config.AVAILABLE_SECTORS; + const sector = _.random(1, availableSectors); - await this.Insert(info); + const location = { + sector_id: await this.getAvailableSector(), + location_x: random(0, 25), + location_y: random(0, 25) + } + + await this.db.raw('insert into locations (sector_id, city_id, location_x, location_y) values (?, ?, ?, ?)', [ + location.sector_id, + info.id, + location.location_x, + location.location_y + ]); + + return { + ...info, + sector_id: location.sector_id, + location_x: location.location_x, + location_y: location.location_y + }; + } + + async getAvailableSector(): Promise { + // figure out which sectors have space (40% fill rate at 25x25); + const availableSectors = await this.db.raw<{count: Number, sector_id: number}[]>(`select count(sector_id) as count, sector_id from locations group by sector_id`); + const sample = _.sample(availableSectors.filter(sector => sector.count < 250)) as {count: number, sector_id: number}; - return info; + if(!sample) { + return _.sortBy(availableSectors, 'sector_id').pop().sector_id+1; + } + + return sample.sector_id; } - async save(city: City) { + async save(city: Partial) { await this.Save(city, {id: city.id}); return city; } - async getUsersCity(owner: string): Promise { - const city = await this.FindOne({ - owner - }); + async findById(cityId: string): Promise { + const city = await this.db.raw(`select c.*, l.sector_id, l.location_x, l.location_y from cities c + join locations l on c.id = l.city_id + where id = ? limit 1`, [cityId]); if(!city) { throw new NotFoundError('User has no city', ERROR_CODE.NO_CITY); } - return city; + return city.pop(); + + } + + async getUsersCity(owner: string): Promise { + const city = await this.db.raw(`select c.*, l.sector_id, l.location_x, l.location_y from cities c + join locations l on c.id = l.city_id + where owner = ? limit 1`, [owner]); + + if(!city) { + throw new NotFoundError('User has no city', ERROR_CODE.NO_CITY); + } + + return city.pop(); + } + + findAllInSector(sector_id: number): Promise { + return this.db.raw(`select c.*, l.sector_id, l.location_x, l.location_y from cities c +join locations l on c.id = l.city_id +where l.sector_id = ?`, [sector_id]); } async buildBuilding(building: Building, amount: number, city: City): Promise { @@ -139,11 +193,11 @@ export class CityRepository extends Repository { * @param city1 * @param city2 */ - distanceInSeconds(city1: City, city2: City): number { + distanceInSeconds(city1: CityWithLocation, city2: CityWithLocation): number { return this.distanceInHours(city1, city2) * 60 * 60; } - distanceInHours(city1: City, city2: City): number { + distanceInHours(city1: CityWithLocation, city2: CityWithLocation): number { const dist = Math.sqrt( Math.pow((city2.location_x - city1.location_x), 2) + @@ -219,7 +273,7 @@ export class CityRepository extends Repository { return power } - async attack(attacker: City, attacked: City, army: Army): Promise { + async attack(attacker: CityWithLocation, attacked: CityWithLocation, army: Army): Promise { // validate the user has enough of a military! if(attacker.soldiers < army.soldiers) { throw new InsufficientResourceError('soldiers', army.soldiers, attacker.soldiers); diff --git a/src/tasks/fight.ts b/src/tasks/fight.ts index ceeb676..7be73a6 100644 --- a/src/tasks/fight.ts +++ b/src/tasks/fight.ts @@ -1,6 +1,6 @@ import { ArmyQueue } from "../repository/army" import { Task } from "./task"; -import { CityRepository, City } from "../repository/city"; +import { CityRepository, CityWithLocation } from "../repository/city"; import { MailRepository } from "../repository/mail"; const cityRepo = new CityRepository(); @@ -17,9 +17,9 @@ export const fight = new Task('fights', async (task, job) => { } // lets get the two cities! - const [attacker, attacked] = await Promise.all([ - cityRepo.FindOne({id: army.your_city}), - cityRepo.FindOne({id: army.attacked_city}) + const [attacker, attacked] = await Promise.all([ + cityRepo.findById(army.your_city), + cityRepo.findById(army.attacked_city) ]); if(!attacker) { -- 2.25.1