549 Commits

Author SHA1 Message Date
phidias 26ee6cee64 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2026-03-20 15:33:38 +09:00
phidias ea70b81bcf . 2026-03-20 15:28:34 +09:00
phidias debf40be81 Merge branch 'explosivegaming:main' into aperx 2026-03-20 15:24:52 +09:00
phidias b0c2e722ed Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2026-03-19 17:38:53 +09:00
phidias a1ca42e44d . 2026-03-19 17:38:46 +09:00
phidias 9e86796cb9 Merge branch 'explosivegaming:main' into aperx 2026-03-19 17:20:12 +09:00
phidias 19a63fad1e Deleted translation using Weblate (German) 2026-01-15 10:44:08 +00:00
phidias e27a623fdf Deleted translation using Weblate (German) 2026-01-15 10:44:08 +00:00
phidias 0703807f1d Deleted translation using Weblate (German) 2026-01-15 10:44:07 +00:00
phidias fc04da8748 Deleted translation using Weblate (German) 2026-01-15 10:44:07 +00:00
phidias 2bdf18305f Deleted translation using Weblate (Spanish) 2026-01-15 10:44:07 +00:00
phidias 4ac29ce955 Deleted translation using Weblate (German) 2026-01-15 10:44:07 +00:00
phidias 4fcaea613c Deleted translation using Weblate (Spanish) 2026-01-15 10:44:00 +00:00
phidias 613be4986b Deleted translation using Weblate (Spanish) 2026-01-15 10:44:00 +00:00
phidias f1e6869db0 Deleted translation using Weblate (Spanish) 2026-01-15 10:44:00 +00:00
phidias 9b91ca4461 Deleted translation using Weblate (Spanish) 2026-01-15 10:43:59 +00:00
phidias b467a7af64 Deleted translation using Weblate (Portuguese) 2026-01-15 10:43:54 +00:00
phidias 1adbfd58d4 Deleted translation using Weblate (Portuguese) 2026-01-15 10:43:53 +00:00
phidias 7552cd4cdd Deleted translation using Weblate (Portuguese) 2026-01-15 10:43:52 +00:00
phidias 183f6b8807 Deleted translation using Weblate (Portuguese) 2026-01-15 10:43:52 +00:00
phidias d989526e6e Deleted translation using Weblate (Portuguese) 2026-01-15 10:43:52 +00:00
phidias b901ed040b Deleted translation using Weblate (French) 2026-01-15 10:43:46 +00:00
phidias 2167008c0c Deleted translation using Weblate (French) 2026-01-15 10:43:45 +00:00
phidias ee934ed1df Deleted translation using Weblate (French) 2026-01-15 10:43:44 +00:00
phidias a67c9ae738 Deleted translation using Weblate (French) 2026-01-15 10:43:44 +00:00
phidias 212a4ed1bc Deleted translation using Weblate (French) 2026-01-15 10:43:44 +00:00
phidias c03d707087 Added translation using Weblate (Portuguese) 2026-01-15 10:39:12 +00:00
phidias 3340e4c28d Added translation using Weblate (French) 2026-01-15 10:39:12 +00:00
phidias 26dfcf586f Added translation using Weblate (Spanish) 2026-01-15 10:39:12 +00:00
phidias 50a367f0ee Added translation using Weblate (German) 2026-01-15 10:39:12 +00:00
phidias cad9da0ba2 Added translation using Weblate (Portuguese) 2026-01-15 10:39:11 +00:00
phidias 1ae3bbbce3 Added translation using Weblate (French) 2026-01-15 10:39:11 +00:00
phidias 1a63c3ec09 Added translation using Weblate (Spanish) 2026-01-15 10:39:11 +00:00
phidias c673ab6984 Added translation using Weblate (German) 2026-01-15 10:39:11 +00:00
phidias 39d3890215 Added translation using Weblate (Portuguese) 2026-01-15 10:39:07 +00:00
phidias a12260dd87 Added translation using Weblate (French) 2026-01-15 10:39:07 +00:00
phidias 27a9247436 Added translation using Weblate (Spanish) 2026-01-15 10:39:07 +00:00
phidias d0e022a0cf Added translation using Weblate (German) 2026-01-15 10:39:07 +00:00
Weblate 250af62abe Added translation using Weblate (Chinese (Traditional Han script)) 2026-01-15 10:38:25 +00:00
Weblate bcb7a5816b Added translation using Weblate (Chinese (Simplified Han script)) 2026-01-15 10:38:25 +00:00
Weblate fb29f27755 Added translation using Weblate (Portuguese) 2026-01-15 10:38:25 +00:00
Weblate c7cfba2685 Added translation using Weblate (French) 2026-01-15 10:38:25 +00:00
Weblate befe2131f1 Added translation using Weblate (Spanish) 2026-01-15 10:38:25 +00:00
Weblate 49eccb36b1 Added translation using Weblate (German) 2026-01-15 10:38:25 +00:00
phidias d2e7dedf54 Added translation using Weblate (Portuguese) 2026-01-15 09:57:40 +00:00
phidias ded7b33716 Added translation using Weblate (French) 2026-01-15 09:57:40 +00:00
phidias d1a4e25274 Added translation using Weblate (Spanish) 2026-01-15 09:57:40 +00:00
phidias ed51b75671 Added translation using Weblate (German) 2026-01-15 09:57:40 +00:00
phidias 0d689790de Merge branch 'explosivegaming:main' into aperx 2026-01-15 13:57:41 +09:00
phidias b1db4657f4 . 2026-01-15 02:50:20 +09:00
phidias b8f466816f . 2026-01-15 02:37:33 +09:00
phidias 78033ccca9 . 2026-01-15 00:41:27 +09:00
phidias 0ef169b596 . 2026-01-15 00:39:52 +09:00
phidias e99a5befff . 2026-01-15 00:33:47 +09:00
phidias 85631f4fef . 2026-01-15 00:20:25 +09:00
phidias 167b6b083f . 2026-01-15 00:15:55 +09:00
phidias b6cc2bd2e3 . 2026-01-15 00:15:05 +09:00
phidias b75fc72a22 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2026-01-15 00:11:45 +09:00
phidias d475793c61 . 2026-01-15 00:11:42 +09:00
phidias fcf0d05a55 Merge pull request #20 from PHIDIAS0303/main
Refactor task list (#414)
2025-12-17 01:28:57 +09:00
phidias 0a4f4f35a1 Update _file_loader.lua 2025-12-17 01:28:07 +09:00
phidias 2daca9024a Merge branch 'aperx' into main 2025-12-17 01:27:33 +09:00
phidias 37afd11c24 Merge pull request #19 from PHIDIAS0303/main
Main
2025-12-04 01:31:37 +09:00
phidias 3a85a15e7a Merge branch 'main' of https://github.com/PHIDIAS0303/ExpCluster 2025-12-04 01:31:25 +09:00
phidias 255cf1e51b . 2025-09-23 19:35:49 +09:00
phidias afc3c94b13 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-09-23 19:33:46 +09:00
phidias a32095ae2d . 2025-09-23 19:33:39 +09:00
phidias 0dae21dfcb Merge branch 'explosivegaming:main' into aperx 2025-09-22 19:37:50 +09:00
phidias 7ff37d5dd2 Merge branch 'explosivegaming:main' into aperx 2025-09-17 19:06:27 +09:00
phidias d2332dfa47 Merge branch 'explosivegaming:main' into aperx 2025-09-05 22:20:26 +09:00
phidias d75abf7a10 Merge branch 'explosivegaming:main' into aperx 2025-09-05 02:11:24 +09:00
phidias 92a077a895 Merge branch 'explosivegaming:main' into aperx 2025-09-04 20:03:49 +09:00
phidias 54f3aed411 Merge branch 'explosivegaming:main' into aperx 2025-09-04 19:55:32 +09:00
phidias 1ccf766c63 Merge branch 'explosivegaming:main' into aperx 2025-09-04 19:20:06 +09:00
phidias fc8adaceda Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-09-02 22:53:18 +09:00
phidias a6aad24c77 . 2025-09-02 22:53:08 +09:00
phidias b7fa20439b Merge branch 'explosivegaming:main' into aperx 2025-09-02 13:43:43 +09:00
phidias 010d7caa0a Merge branch 'main' of https://github.com/PHIDIAS0303/ExpCluster 2025-09-01 01:21:26 +09:00
phidias c00470e58c . 2025-08-31 02:13:45 +09:00
phidias 0a97ac4ed3 Merge pull request #18 from PHIDIAS0303/main
Refactor some of the Guis from the legacy plugin (#399)
2025-08-31 01:55:04 +09:00
phidias b69653e85f . 2025-08-31 01:54:19 +09:00
phidias 19e2f819ff Merge branch 'main' of https://github.com/PHIDIAS0303/ExpCluster 2025-08-31 01:54:06 +09:00
phidias d917c50e3e . 2025-08-31 01:43:29 +09:00
phidias 0d519700b6 . 2025-08-31 01:41:02 +09:00
phidias 3891e48acd . 2025-08-31 01:36:03 +09:00
phidias b8c437fca1 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-08-26 13:34:29 +09:00
phidias 301d8647ec . 2025-08-26 13:14:52 +09:00
phidias 52261a06fd Merge pull request #17 from PHIDIAS0303/main
Fix no spawn force without players joining (#400)
2025-08-26 13:10:01 +09:00
phidias 9771ea8ce4 Merge branch 'aperx' into main 2025-08-26 13:09:44 +09:00
phidias 6df40ac157 . 2025-08-25 16:28:41 +09:00
phidias 8cc3805656 Merge branch 'main' into aperx 2025-08-11 02:17:48 +09:00
phidias 703d2981d0 Merge pull request #15 from PHIDIAS0303/main
Fix logic for afk kick (#395)
2025-06-16 00:35:25 +09:00
phidias 65d3c75032 Merge branch 'aperx' into main 2025-06-16 00:35:19 +09:00
phidias 6ba8316cff . 2025-06-16 00:21:16 +09:00
phidias 524654e935 . 2025-05-22 14:17:16 +09:00
phidias 6add30adf3 . 2025-05-19 15:23:20 +09:00
phidias f36403997a Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-05-19 15:22:58 +09:00
phidias a42802f509 .. 2025-05-19 15:22:56 +09:00
phidias b26cec6fae Merge branch 'explosivegaming:main' into aperx 2025-05-18 04:17:25 +09:00
phidias 0fa264ab0a . 2025-05-16 00:45:47 +09:00
phidias 5914aced5e . 2025-05-13 13:24:33 +09:00
phidias cf2b4476d5 . 2025-05-12 22:22:22 +09:00
phidias f79408d37c . 2025-05-12 22:03:43 +09:00
phidias 268feab5f7 . 2025-05-12 21:56:09 +09:00
phidias d61f163170 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-05-12 20:25:32 +09:00
phidias c36b92c401 . 2025-05-12 20:25:30 +09:00
phidias d851c11e39 Merge pull request #14 from PHIDIAS0303/main
Main
2025-04-27 13:08:51 +09:00
phidias 686efd2b30 Merge branch 'aperx' into main 2025-04-27 13:08:44 +09:00
phidias 2b3a49391f . 2025-04-26 14:16:06 +09:00
phidias 9a6e056008 . 2025-04-26 13:55:24 +09:00
phidias 350f8c3f8d . 2025-04-21 14:51:05 +09:00
phidias e405bd70ac . 2025-04-21 14:41:52 +09:00
phidias 90a3510068 . 2025-04-21 14:39:23 +09:00
phidias 41dd7517d8 . 2025-04-21 14:37:30 +09:00
phidias ee2b2b429d . 2025-04-21 14:27:04 +09:00
phidias 29bb17ed55 . 2025-04-21 14:21:03 +09:00
phidias 61644d1aef . 2025-04-20 14:02:16 +09:00
phidias 4365facdb5 . 2025-04-20 13:54:04 +09:00
phidias f0da6a6507 . 2025-04-19 12:46:12 +09:00
phidias 9e0ccf87e4 . 2025-04-19 12:41:56 +09:00
phidias 0afd445da9 . 2025-04-19 12:40:58 +09:00
phidias e368278d3b . 2025-04-19 12:40:35 +09:00
phidias e808e11dd4 . 2025-04-19 00:40:25 +09:00
phidias 0f54eaee0b . 2025-04-19 00:40:09 +09:00
phidias 7983992371 . 2025-04-19 00:34:37 +09:00
phidias 717955608f . 2025-04-19 00:30:46 +09:00
phidias e78920c4e6 . 2025-04-19 00:26:51 +09:00
phidias 24aafc36da . 2025-04-19 00:26:08 +09:00
phidias 93ea19e290 . 2025-04-19 00:20:48 +09:00
phidias 8ad47a1673 . 2025-04-19 00:16:31 +09:00
phidias 02774919cb . 2025-04-18 23:42:55 +09:00
phidias c6848b7a6e . 2025-04-18 23:27:39 +09:00
phidias 01269ec755 . 2025-04-18 23:19:14 +09:00
phidias 4e51816a69 . 2025-04-18 15:29:22 +09:00
phidias bfc91902c9 . 2025-04-16 18:04:30 +09:00
phidias e2667ada9f . 2025-04-16 18:00:47 +09:00
phidias f64d17772c . 2025-04-16 17:59:43 +09:00
phidias f09f3f2b8a . 2025-04-16 17:57:33 +09:00
phidias 79f67e0442 . 2025-04-16 17:52:20 +09:00
phidias 0efefab723 . 2025-04-16 17:50:44 +09:00
phidias c292004fc1 . 2025-04-16 17:49:16 +09:00
phidias 83f5d71225 . 2025-04-16 17:48:15 +09:00
phidias b9df5beb94 . 2025-04-16 17:47:42 +09:00
phidias 034973bed9 . 2025-04-16 17:46:26 +09:00
phidias d344131a74 . 2025-04-16 17:44:52 +09:00
phidias b05f7ee04f . 2025-04-16 17:40:52 +09:00
phidias 26d4f150d1 . 2025-04-16 17:39:36 +09:00
phidias 0020b79c1f . 2025-04-16 17:37:41 +09:00
phidias cd362e233f . 2025-04-16 17:35:54 +09:00
phidias 7da432dada . 2025-04-16 17:24:56 +09:00
phidias b2e0423655 . 2025-04-16 17:00:03 +09:00
phidias 388b25ca6b . 2025-04-13 00:17:22 +09:00
phidias bd8c2c19c0 . 2025-04-13 00:13:17 +09:00
phidias 7b7effd6ab . 2025-04-13 00:10:01 +09:00
phidias dcf9a58c21 . 2025-04-13 00:06:00 +09:00
phidias b2e5f6cb83 . 2025-04-13 00:04:23 +09:00
phidias 06529f5536 . 2025-04-13 00:01:55 +09:00
phidias 9cf7d7d7a2 Merge branch 'main' into aperx 2025-04-07 17:13:29 +09:00
phidias f88f348efc . 2025-04-07 17:09:21 +09:00
phidias 6c6a14376c . 2025-04-07 17:05:03 +09:00
phidias 02fb1c53e7 . 2025-04-07 17:02:14 +09:00
phidias edbc7de2d5 . 2025-03-23 01:25:40 +09:00
phidias 36ff0c4dcf . 2025-03-23 01:25:00 +09:00
phidias a13e0d0c11 . 2025-03-23 01:24:53 +09:00
phidias 0c143d9d2d . 2025-03-08 13:14:11 +09:00
phidias 981e5b9c2e . 2025-03-08 01:09:18 +09:00
phidias 2bb77fbd04 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-03-08 01:08:07 +09:00
phidias c95b812f5d . 2025-03-08 01:08:01 +09:00
phidias 15d0f02ea1 Merge branch 'explosivegaming:main' into aperx 2025-03-08 01:06:34 +09:00
phidias 6ce37fb677 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-03-08 01:05:26 +09:00
phidias 9d03982688 . 2025-03-08 01:05:16 +09:00
phidias 9190733d82 Merge branch 'explosivegaming:main' into aperx 2025-03-07 23:45:09 +09:00
phidias abcfc8f9ee . 2025-03-06 23:37:32 +09:00
phidias 4fa34c31d1 . 2025-03-06 23:29:40 +09:00
phidias 5939ff8e59 . 2025-03-06 23:05:10 +09:00
phidias e07a971e7d Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-03-06 22:20:22 +09:00
phidias e047c7ecf6 . 2025-03-06 22:20:11 +09:00
phidias 23d88c197e . 2025-03-06 22:19:44 +09:00
phidias 76cfb66d68 Merge branch 'explosivegaming:main' into aperx 2025-03-02 13:10:04 +09:00
phidias 33b7b7ffa0 Merge branch 'explosivegaming:main' into aperx 2025-03-01 23:23:46 +09:00
phidias 8ccaf47f6f . 2025-02-27 00:01:12 +09:00
phidias 704dd73df4 . 2025-02-26 23:58:33 +09:00
phidias 860cacf16f . 2025-02-26 23:58:00 +09:00
phidias 2c0040a033 . 2025-02-24 20:05:33 +09:00
phidias aa3976090f . 2025-02-24 19:07:03 +09:00
phidias 03e30caeda . 2025-02-24 19:01:15 +09:00
phidias f7805ae2a7 . 2025-02-24 18:59:47 +09:00
phidias fbf91f4310 . 2025-02-24 18:59:15 +09:00
phidias 3a8b217f8d . 2025-02-24 18:54:27 +09:00
phidias 1cfcdddfa5 . 2025-02-24 18:52:59 +09:00
phidias 8880eb6a57 . 2025-02-24 18:52:54 +09:00
phidias 07fe643d03 . 2025-02-24 18:47:57 +09:00
phidias 17b53a6695 . 2025-02-24 18:46:08 +09:00
phidias 51d266a667 . 2025-02-24 18:42:53 +09:00
phidias 36c65cbea0 . 2025-02-24 18:40:38 +09:00
phidias 32723e388b . 2025-02-24 18:37:55 +09:00
phidias 609796070f . 2025-02-24 18:36:29 +09:00
phidias 67ce09f96e . 2025-02-24 18:33:28 +09:00
phidias 082ee900f4 . 2025-02-24 18:02:03 +09:00
phidias 4e7776bc2d . 2025-02-24 17:44:39 +09:00
phidias 36931d9bb1 . 2025-02-24 17:25:19 +09:00
phidias 9786c95eda . 2025-02-24 17:15:44 +09:00
phidias 261041edd3 . 2025-02-24 17:06:55 +09:00
phidias 5800d4a590 . 2025-02-23 14:52:28 +09:00
phidias 60279c4a49 . 2025-02-23 14:47:07 +09:00
phidias 52c6887887 . 2025-02-23 14:34:02 +09:00
phidias 8b000613a2 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-02-23 14:33:50 +09:00
phidias 766e96a9fc . 2025-02-23 14:33:39 +09:00
phidias 510a119741 . 2025-02-23 14:04:07 +09:00
phidias 73d1352ac5 Merge branch 'explosivegaming:main' into aperx 2025-02-23 13:15:29 +09:00
phidias b3c70e7700 . 2025-02-23 12:47:01 +09:00
phidias 85f9ebd7d0 . 2025-02-22 23:42:26 +09:00
phidias 5add829a78 . 2025-02-22 23:23:58 +09:00
phidias ce73946885 . 2025-02-16 12:19:46 +09:00
phidias 88da422f9e . 2025-02-13 00:19:40 +09:00
phidias 5a006eaa25 . 2025-02-13 00:15:36 +09:00
phidias 63e21e1332 . 2025-02-13 00:13:02 +09:00
phidias 1ad8b3edd7 . 2025-02-13 00:09:02 +09:00
phidias 005a5501d8 . 2025-02-13 00:06:06 +09:00
phidias 62d818605a . 2025-02-13 00:00:35 +09:00
phidias aacbfa7c3b . 2025-02-12 23:57:00 +09:00
phidias a3fbdd195b . 2025-02-12 23:38:01 +09:00
phidias 63345c753c . 2025-02-12 23:37:34 +09:00
phidias f5d23e9a07 . 2025-02-12 22:42:01 +09:00
phidias e3a1b1f4fe . 2025-02-12 22:41:21 +09:00
phidias 2ec3813e2c . 2025-02-12 22:35:39 +09:00
phidias 4350cfad8d . 2025-02-12 22:29:36 +09:00
phidias e759ca3c48 . 2025-02-12 22:29:27 +09:00
phidias 2ab8a8ae66 . 2025-02-12 22:20:20 +09:00
phidias eb69977365 . 2025-02-12 22:17:50 +09:00
phidias 6bc077ed3e . 2025-02-12 22:13:10 +09:00
phidias b026a84e67 . 2025-02-12 21:59:29 +09:00
phidias 6da76c548e . 2025-02-12 20:53:44 +09:00
phidias 2a0b4f2bfb . 2025-02-12 20:50:38 +09:00
phidias 6ed3a8bd49 . 2025-02-12 20:50:24 +09:00
phidias 35631f45c6 . 2025-02-12 20:46:00 +09:00
phidias 822258eee0 . 2025-02-12 20:39:07 +09:00
phidias 9e0ed189ee . 2025-02-12 20:25:08 +09:00
phidias 29f997bde2 . 2025-02-12 20:22:34 +09:00
phidias 5f24583e90 . 2025-02-12 20:20:42 +09:00
phidias cea58693f9 . 2025-02-12 20:19:34 +09:00
phidias 3f2bb631f8 . 2025-02-12 20:14:21 +09:00
phidias 7b61c8b690 . 2025-02-12 20:12:51 +09:00
phidias 823af41ad4 . 2025-02-12 20:12:22 +09:00
phidias 2720c6938e . 2025-02-12 20:01:00 +09:00
phidias 95bdc0f0f3 . 2025-02-12 19:56:59 +09:00
phidias 20e98d4b13 . 2025-02-12 19:51:53 +09:00
phidias a900440fc4 . 2025-02-12 19:39:34 +09:00
phidias 2f1be9762f . 2025-02-12 19:33:43 +09:00
phidias 02561e36c6 . 2025-02-12 19:26:12 +09:00
phidias dfeec22b64 . 2025-02-12 19:19:02 +09:00
phidias 3059199512 . 2025-02-12 19:14:20 +09:00
phidias f332cd649a . 2025-02-12 19:12:34 +09:00
phidias 6934d44b1d . 2025-02-12 19:12:11 +09:00
phidias dcfb034b69 Merge pull request #12 from PHIDIAS0303/main
Main
2025-02-10 15:40:30 +09:00
phidias 2f2389f1ea . 2025-02-10 15:40:09 +09:00
phidias 127aace0ae . 2025-02-10 15:34:47 +09:00
phidias d219ef85f3 Merge branch 'aperx' into main 2025-02-10 15:27:14 +09:00
phidias adda5c0f9d . 2025-02-10 15:21:35 +09:00
phidias 1fc3047116 . 2025-02-10 15:11:43 +09:00
phidias df3daafc03 . 2025-02-10 15:09:28 +09:00
phidias 3ed1589e7e . 2025-02-10 15:07:18 +09:00
phidias 8ac99a0aa7 . 2025-02-10 04:27:48 +09:00
phidias 544782e65e . 2025-02-08 04:28:47 +09:00
phidias fa16c66f1e . 2025-02-08 04:26:04 +09:00
phidias 13d1452f42 . 2025-02-08 04:21:13 +09:00
phidias 3f6fb51383 . 2025-02-08 04:18:14 +09:00
phidias 71e8f39361 . 2025-02-08 04:16:15 +09:00
phidias 3174efafed .. 2025-02-08 04:15:58 +09:00
phidias af241f2f17 . 2025-02-08 04:11:31 +09:00
phidias 413083e03a . 2025-02-08 04:01:37 +09:00
phidias c241fbef0d . 2025-02-08 04:00:58 +09:00
phidias 4093d30ee5 . 2025-02-08 03:54:13 +09:00
phidias 432d29cc89 . 2025-02-08 03:49:37 +09:00
phidias 725ae0d7b3 . 2025-02-08 01:36:41 +09:00
phidias c7280169a4 . 2025-02-08 01:31:37 +09:00
phidias de5462662f . 2025-02-08 01:27:36 +09:00
phidias 0fea8692af . 2025-02-08 00:59:39 +09:00
phidias a1a9745319 . 2025-02-08 00:56:53 +09:00
phidias f261e1fbf4 . 2025-02-08 00:53:15 +09:00
phidias abfa6b6aba . 2025-02-08 00:43:55 +09:00
phidias 66cbb71c67 . 2025-02-08 00:43:02 +09:00
phidias d3b8c3252c . 2025-02-08 00:36:57 +09:00
phidias 374c727a4a . 2025-02-08 00:33:05 +09:00
phidias c3da0363f3 . 2025-02-08 00:28:26 +09:00
phidias 1df8fd0359 . 2025-02-08 00:23:00 +09:00
phidias d5803bed8d . 2025-02-08 00:18:04 +09:00
phidias c74121bdd4 . 2025-02-08 00:17:48 +09:00
phidias 52a94b7bd3 . 2025-02-08 00:13:27 +09:00
phidias 0a9d4f4c8c . 2025-02-08 00:11:35 +09:00
phidias a763d30e2b . 2025-02-08 00:02:01 +09:00
phidias 6318425f80 . 2025-02-08 00:01:08 +09:00
phidias c6d32f07b5 . 2025-02-07 23:10:52 +09:00
phidias fbd52f9943 . 2025-02-07 23:06:24 +09:00
phidias c8216806ea . 2025-02-07 23:01:41 +09:00
phidias 1e6d1b19de . 2025-02-07 22:53:07 +09:00
phidias 05eee28bb1 . 2025-02-07 22:46:55 +09:00
phidias d2eb463d21 . 2025-02-07 22:44:05 +09:00
phidias 5552e17715 . 2025-02-07 22:41:12 +09:00
phidias 96ac299263 . 2025-02-07 22:30:34 +09:00
phidias 5ebf2eb0bc . 2025-02-07 22:25:52 +09:00
phidias 31ec0afa5b . 2025-02-07 22:20:20 +09:00
phidias f0adfa3e32 . 2025-02-07 19:24:07 +09:00
phidias 04d55cec4a . 2025-02-07 19:23:42 +09:00
phidias 08fbb1fd84 . 2025-02-07 19:17:05 +09:00
phidias 39dbcfeaca . 2025-02-07 19:01:21 +09:00
phidias 2b66965d08 . 2025-02-07 18:59:13 +09:00
phidias d4e76de5fd . 2025-02-07 18:45:18 +09:00
phidias aeb1538095 . 2025-02-07 18:43:51 +09:00
phidias cbd776966e . 2025-02-07 18:40:33 +09:00
phidias 1daef1f216 . 2025-02-07 13:54:01 +09:00
phidias e34b6682ed . 2025-02-07 13:49:44 +09:00
phidias 8da7ab8586 . 2025-02-07 13:22:56 +09:00
phidias fb2a409d4c . 2025-02-07 02:25:40 +09:00
phidias a933eec9e3 Merge branch 'explosivegaming:main' into aperx 2025-02-06 23:24:57 +09:00
phidias 61494e9c48 . 2025-02-06 23:20:13 +09:00
phidias 5241a41ff3 . 2025-02-06 23:14:28 +09:00
phidias 2c4316a53b . 2025-02-06 22:40:01 +09:00
phidias f40fd155ab . 2025-02-06 22:38:21 +09:00
phidias e42d1a8280 . 2025-02-06 22:34:40 +09:00
phidias 68e523bc56 . 2025-02-06 22:30:29 +09:00
phidias dd20b145ab . 2025-02-06 22:25:04 +09:00
phidias 946cc583b1 . 2025-02-06 20:43:29 +09:00
phidias a3f3ec3991 . 2025-02-06 20:40:10 +09:00
phidias b94e5e4dad . 2025-02-06 20:34:23 +09:00
phidias 7da0cf78a8 . 2025-02-06 20:27:46 +09:00
phidias 31154f007e Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-02-05 17:35:40 +09:00
phidias 29395fe161 . 2025-02-05 17:35:07 +09:00
phidias d7c761d138 Merge branch 'explosivegaming:main' into aperx 2025-02-04 14:24:59 +09:00
phidias c8ca527005 . 2025-02-03 23:12:37 +09:00
phidias f63ebf8e7c . 2025-02-03 18:07:06 +09:00
phidias f7549b8017 .. 2025-02-03 18:06:54 +09:00
phidias 52e50fbb06 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-02-03 15:33:03 +09:00
phidias cd3cdda4bf . 2025-02-03 15:33:00 +09:00
phidias 8c727876bb Merge pull request #11 from PHIDIAS0303/main
Main
2025-02-03 15:13:51 +09:00
phidias 84cdc45362 Merge branch 'aperx' into main 2025-02-03 15:12:46 +09:00
phidias 7c9592bbb1 Merge pull request #10 from PHIDIAS0303/main
Main
2025-01-30 16:50:20 +09:00
phidias 8680e5fbfb Merge branch 'aperx' into main 2025-01-30 16:49:14 +09:00
phidias 6d19f8304d Merge pull request #9 from Cooldude2606/package/gui
Package/gui
2025-01-30 16:45:18 +09:00
phidias 40bf727e49 . 2025-01-29 00:45:39 +09:00
phidias 8407c1357d . 2025-01-29 00:43:43 +09:00
phidias c62cfc413d . 2025-01-29 00:36:26 +09:00
phidias fd5d95bcd8 . 2025-01-29 00:35:57 +09:00
phidias 4c257d1497 . 2025-01-29 00:35:15 +09:00
phidias cc590372de . 2025-01-29 00:34:20 +09:00
phidias fc7c9d41ad . 2025-01-29 00:32:54 +09:00
phidias 9e1f7530e2 . 2025-01-28 22:21:07 +09:00
phidias 8c79c0363c . 2025-01-28 21:53:14 +09:00
phidias d12ad7ed2e . 2025-01-28 21:00:45 +09:00
phidias 8f230bb393 . 2025-01-28 20:47:08 +09:00
phidias 97c6f7f3c3 . 2025-01-28 20:31:44 +09:00
phidias dbe3c873f6 . 2025-01-28 20:26:14 +09:00
phidias be6ccb27f1 . 2025-01-28 20:21:14 +09:00
phidias 1d4af30843 . 2025-01-28 19:49:14 +09:00
phidias a59f5830f2 . 2025-01-28 18:07:17 +09:00
phidias 8ae03a7ee1 . 2025-01-28 18:03:50 +09:00
phidias ddd6dc474f . 2025-01-28 18:03:36 +09:00
phidias 3ae1b7c1f8 . 2025-01-28 18:01:00 +09:00
phidias d475a55460 . 2025-01-28 17:55:04 +09:00
phidias 4bc18e10f5 . 2025-01-28 17:09:27 +09:00
phidias bbe25ec120 . 2025-01-28 17:05:23 +09:00
phidias 1aaae3fa13 . 2025-01-27 00:00:04 +09:00
phidias a7a0e85a95 . 2025-01-26 22:02:17 +09:00
phidias c2089a89ba . 2025-01-26 13:50:58 +09:00
phidias 94b3bd8c20 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-01-26 13:50:46 +09:00
phidias a86a625d62 . 2025-01-26 13:50:43 +09:00
phidias 42fe79ef91 Merge branch 'explosivegaming:main' into aperx 2025-01-26 03:42:45 +09:00
phidias 6890226f13 Merge pull request #8 from PHIDIAS0303/main
Add option for vlayer on space platforms (#365)
2025-01-25 03:04:34 +09:00
phidias c682b8b81b Merge branch 'aperx' into main 2025-01-25 03:03:58 +09:00
phidias 403bace3ab . 2025-01-23 22:22:53 +09:00
phidias c00f5b54a8 . 2025-01-23 22:17:26 +09:00
phidias cea73d7ab8 . 2025-01-23 22:16:21 +09:00
phidias bf29c1ccd9 . 2025-01-23 22:14:32 +09:00
phidias 6520014c47 . 2025-01-22 20:37:19 +09:00
phidias 064dead08c . 2025-01-22 20:27:50 +09:00
phidias 16574b5908 . 2025-01-22 20:26:23 +09:00
phidias 0eaa2b1542 . 2025-01-22 20:13:32 +09:00
phidias 1f7ac1ace5 . 2025-01-22 20:10:48 +09:00
phidias 357eba0e64 . 2025-01-22 19:51:04 +09:00
phidias 991d26510e . 2025-01-22 19:46:56 +09:00
phidias d4b4f50618 . 2025-01-22 18:42:39 +09:00
phidias 852cf45d0c . 2025-01-22 18:39:18 +09:00
phidias 5e1c27d52f . 2025-01-22 18:37:29 +09:00
phidias b297b0d0b7 . 2025-01-22 18:32:28 +09:00
phidias 733c70823a . 2025-01-22 18:31:07 +09:00
phidias fe901c5f11 . 2025-01-22 18:30:24 +09:00
phidias 112d5b7bda . 2025-01-22 18:27:36 +09:00
phidias 3914e4594d . 2025-01-22 18:17:14 +09:00
phidias b8f78835d0 . 2025-01-22 18:11:19 +09:00
phidias 70625f0888 . 2025-01-22 18:01:47 +09:00
phidias 3382250a34 Merge branch 'explosivegaming:main' into aperx 2025-01-22 17:29:22 +09:00
phidias 4ab3fb0b4d . 2025-01-21 20:42:09 +09:00
phidias d101dc1f11 . 2025-01-21 20:07:41 +09:00
phidias 9b72f9e127 . 2025-01-21 19:58:57 +09:00
phidias 8376f240bb . 2025-01-21 19:52:12 +09:00
phidias e3d42442d4 . 2025-01-21 19:33:31 +09:00
phidias 30f9e32550 . 2025-01-21 19:05:14 +09:00
phidias 3c876d4873 . 2025-01-20 22:54:38 +09:00
phidias ab12a8be52 . 2025-01-20 16:36:41 +09:00
phidias f95f5faad9 . 2025-01-20 16:33:10 +09:00
phidias f21586192d . 2025-01-20 16:29:52 +09:00
phidias 7b7482b70d . 2025-01-20 16:27:56 +09:00
phidias 79f6747f79 . 2025-01-20 16:26:27 +09:00
phidias 111c6e9b29 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-01-20 16:19:55 +09:00
phidias c56f8b4f27 . 2025-01-20 16:19:52 +09:00
phidias e9635796fa Merge branch 'explosivegaming:main' into aperx 2025-01-20 16:14:15 +09:00
phidias e291759cb7 . 2025-01-17 20:14:03 +09:00
phidias 3f351df82d . 2025-01-17 20:09:48 +09:00
phidias 3fd2876ba7 . 2025-01-17 20:07:36 +09:00
phidias e2173cc57d . 2025-01-17 20:05:42 +09:00
phidias 55fe9b6069 . 2025-01-17 18:05:21 +09:00
phidias be2ae106f5 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-01-16 14:07:00 +09:00
phidias f9405b930d . 2025-01-16 14:06:51 +09:00
phidias cff86b07f2 Merge branch 'explosivegaming:main' into aperx 2025-01-16 13:57:31 +09:00
phidias 8ad24b3afd . 2025-01-15 17:36:34 +09:00
phidias 9fb1af24d2 . 2025-01-15 16:50:05 +09:00
phidias 736df61152 . 2025-01-15 12:44:37 +09:00
phidias 7784dbf3ad . 2025-01-14 23:38:43 +09:00
phidias 29abf08b70 . 2025-01-14 19:48:51 +09:00
phidias 7c87cfc8bc . 2025-01-14 19:19:55 +09:00
phidias 781760d67e . 2025-01-14 19:13:57 +09:00
phidias fdf0cb66cf . 2025-01-14 18:53:31 +09:00
phidias 967225ebe9 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-01-14 18:48:28 +09:00
phidias d7dc4040c8 . 2025-01-14 18:48:24 +09:00
phidias ff5987d7f6 Merge pull request #7 from PHIDIAS0303/main
Main
2025-01-14 13:36:05 +09:00
phidias d1cb929c6d Merge branch 'aperx' into main 2025-01-14 13:35:26 +09:00
phidias 843de85206 . 2025-01-14 13:26:49 +09:00
phidias c10de39a89 . 2025-01-13 22:48:10 +09:00
phidias bfe5110254 . 2025-01-13 22:34:31 +09:00
phidias 4fa1ea4fb3 . 2025-01-13 22:03:03 +09:00
phidias 9e44de8850 . 2025-01-13 19:07:40 +09:00
phidias de6474dc76 . 2025-01-12 03:43:48 +09:00
phidias 8b67491d8c . 2025-01-12 03:26:24 +09:00
phidias da323d5152 . 2025-01-11 23:08:26 +09:00
phidias 0d8712dd6b . 2025-01-11 23:07:58 +09:00
phidias cf2f6cfb8c . 2025-01-11 23:07:07 +09:00
phidias 2ed7235f3d . 2025-01-11 23:05:39 +09:00
phidias c9700414c7 . 2025-01-11 22:10:26 +09:00
phidias 6bcd3bc641 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-01-11 22:09:38 +09:00
phidias a6ddf0c427 . 2025-01-11 22:09:35 +09:00
phidias 68e21db03a Merge branch 'explosivegaming:main' into aperx 2025-01-11 13:13:13 +09:00
phidias 5373b9d9bb Merge pull request #6 from PHIDIAS0303/main
vlayer 2.0 compatible (#353)
2025-01-11 03:42:52 +09:00
phidias eadca324e7 Merge branch 'aperx' into main 2025-01-11 03:42:38 +09:00
phidias 3632738501 . 2025-01-10 17:37:33 +09:00
phidias 645d693583 . 2025-01-10 14:22:33 +09:00
phidias ea04b93c7c . 2025-01-10 14:13:12 +09:00
phidias 518f1fc561 . 2025-01-10 14:04:17 +09:00
phidias 803192e01c . 2025-01-10 02:44:05 +09:00
phidias 8dac727396 . 2025-01-10 00:11:45 +09:00
phidias 7a5577452c . 2025-01-10 00:09:13 +09:00
phidias 8f5d3e4a65 . 2025-01-10 00:01:16 +09:00
phidias 6603a14fd3 . 2025-01-09 23:58:36 +09:00
phidias 46f35eadcc . 2025-01-09 23:58:26 +09:00
phidias 4136b5018b . 2025-01-09 23:54:15 +09:00
phidias 965c1c7712 . 2025-01-09 23:51:34 +09:00
phidias 82e858975b . 2025-01-09 23:49:44 +09:00
phidias f94e9bf17d . 2025-01-09 23:44:35 +09:00
phidias 10bf61247c . 2025-01-09 23:38:39 +09:00
phidias bd488aef76 . 2025-01-09 23:32:21 +09:00
phidias 397661728f . 2025-01-09 23:21:54 +09:00
phidias 5c15bbbe7c . 2025-01-09 22:33:27 +09:00
phidias 62ac9a6406 . 2025-01-09 22:25:49 +09:00
phidias f0172f6270 . 2025-01-09 22:00:17 +09:00
phidias 64ca88a198 . 2025-01-09 21:58:32 +09:00
phidias 6d44936364 . 2025-01-09 20:32:26 +09:00
phidias dee2600eec . 2025-01-09 20:27:47 +09:00
phidias 0a61893f68 . 2025-01-09 19:46:21 +09:00
phidias dd655807c4 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-01-09 14:42:36 +09:00
phidias f1868e883c . 2025-01-09 14:42:32 +09:00
phidias 91ddb5530a Merge pull request #5 from PHIDIAS0303/main
Main
2025-01-09 14:25:58 +09:00
phidias 65e6647068 Merge branch 'aperx' into main 2025-01-09 14:12:10 +09:00
phidias f0b066cdfe . 2025-01-09 14:07:40 +09:00
phidias b9de395a44 . 2025-01-09 03:49:22 +09:00
phidias 46bb73b927 . 2025-01-09 03:44:56 +09:00
phidias c168095249 . 2025-01-09 03:37:46 +09:00
phidias a02975853d . 2025-01-09 03:26:12 +09:00
phidias 64910c2821 . 2025-01-09 03:11:32 +09:00
phidias b56b53c268 . 2025-01-09 03:10:11 +09:00
phidias 292870bf8c . 2025-01-09 00:20:08 +09:00
phidias 72c1d73a20 . 2025-01-09 00:09:22 +09:00
phidias 055c9bb6ad Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-01-08 23:40:31 +09:00
phidias 7e7bf5708c . 2025-01-08 23:40:30 +09:00
phidias e250610273 Merge pull request #4 from PHIDIAS0303/main
Main
2025-01-08 23:34:30 +09:00
phidias 9265479565 Merge branch 'aperx' into main 2025-01-08 23:34:14 +09:00
phidias b3c19b8010 . 2025-01-08 23:27:14 +09:00
phidias a6da3a74c2 . 2025-01-08 22:22:21 +09:00
phidias ce146be986 . 2025-01-07 23:01:21 +09:00
phidias a03df60302 . 2025-01-07 22:59:50 +09:00
phidias 723f535ab6 . 2025-01-07 22:55:27 +09:00
phidias db70decbf3 . 2025-01-07 21:54:33 +09:00
phidias a38708c203 . 2025-01-07 20:15:03 +09:00
phidias 664c9e67c0 . 2025-01-07 19:35:02 +09:00
phidias 11eb7152bd . 2025-01-07 19:32:25 +09:00
phidias 155721938e . 2025-01-07 18:15:43 +09:00
phidias 251e41bba5 . 2025-01-07 18:07:38 +09:00
phidias fa3168e1ac . 2025-01-07 17:40:53 +09:00
phidias baf9e3f2df . 2025-01-07 17:39:47 +09:00
phidias b60045d70e Merge branch 'explosivegaming:main' into aperx 2025-01-05 04:07:09 +09:00
phidias 3e570b1599 . 2025-01-04 13:22:40 +09:00
phidias 81d9f59e81 Merge branch 'explosivegaming:main' into aperx 2025-01-04 13:10:26 +09:00
phidias 98f1dc6a29 Merge branch 'explosivegaming:main' into aperx 2025-01-04 04:14:08 +09:00
phidias eb97893b3e Merge branch 'explosivegaming:main' into aperx 2025-01-04 04:07:55 +09:00
phidias 599339f805 Merge branch 'explosivegaming:main' into aperx 2025-01-03 14:04:02 +09:00
phidias b920c2984d Merge branch 'explosivegaming:main' into aperx 2025-01-02 14:39:41 +09:00
phidias 4a14972412 . 2025-01-02 14:39:21 +09:00
phidias f5a830d1c6 . 2025-01-01 21:21:54 +09:00
phidias 9a82000792 . 2025-01-01 18:49:16 +09:00
phidias fb01bc1644 . 2025-01-01 17:42:06 +09:00
phidias d049126a54 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2025-01-01 17:40:54 +09:00
phidias 890019ca98 . 2025-01-01 17:40:51 +09:00
phidias fe53b474a0 Merge pull request #2 from PHIDIAS0303/main
Main
2025-01-01 17:29:49 +09:00
phidias 8192ebdd3c Merge branch 'aperx' into main 2025-01-01 17:28:23 +09:00
phidias a65a04c810 . 2025-01-01 17:26:07 +09:00
phidias 2749df9f08 . 2024-12-31 23:35:42 +09:00
phidias a991142279 . 2024-12-31 15:12:26 +09:00
phidias cb6ea27391 Merge branch 'aperx' of https://github.com/PHIDIAS0303/ExpCluster into aperx 2024-12-31 13:51:22 +09:00
phidias 6b88725af2 Merge pull request #1 from PHIDIAS0303/main
Main
2024-12-31 13:50:47 +09:00
phidias 118b99f521 . 2024-12-31 13:49:34 +09:00
phidias 25f495b4dd Merge branch 'aperx' into main 2024-12-31 13:48:39 +09:00
phidias 6d6e44f0da . 2024-12-31 13:42:37 +09:00
phidias 7555de476e . 2024-12-31 13:42:19 +09:00
phidias cf900d46cd . 2024-12-31 13:41:38 +09:00
phidias 2944e730b0 . 2024-12-31 13:41:06 +09:00
phidias 1eb7a27c71 . 2024-12-31 13:40:23 +09:00
phidias 3ab5becf16 . 2024-12-31 13:37:50 +09:00
phidias a0c0169a4b . 2024-12-31 13:34:15 +09:00
phidias dfd3f85975 . 2024-12-31 13:33:48 +09:00
phidias 4a1a451ff2 . 2024-12-31 13:14:27 +09:00
phidias d73688dd37 . 2024-12-31 13:13:02 +09:00
phidias 15141e98e0 . 2024-12-31 02:58:15 +09:00
phidias 51961d2aea . 2024-12-31 00:50:23 +09:00
phidias 3266f444cd . 2024-12-31 00:49:15 +09:00
phidias c5395e37b2 . 2024-12-31 00:45:23 +09:00
phidias d2e2e2d6c9 . 2024-12-31 00:28:24 +09:00
phidias bd5b217909 . 2024-12-30 22:38:40 +09:00
phidias 5ae20ac21c Update types.lua 2024-12-30 19:55:13 +09:00
phidias 3830a464f8 Update types.lua 2024-12-30 19:52:55 +09:00
phidias 4362b48106 . 2024-12-30 19:00:02 +09:00
phidias 43f61909e8 . 2024-12-30 18:25:03 +09:00
phidias 596ea47082 . 2024-12-30 16:30:41 +09:00
phidias 80cd1245e5 . 2024-12-30 16:09:23 +09:00
phidias 3e4318fcab . 2024-12-29 23:30:30 +09:00
phidias 47e900f735 . 2024-12-29 23:29:44 +09:00
phidias d88def830f . 2024-12-29 14:16:50 +09:00
phidias b32e854398 . 2024-12-29 14:12:50 +09:00
phidias e9f82db154 . 2024-12-29 14:10:55 +09:00
phidias 0a4b392cf3 . 2024-12-29 14:09:39 +09:00
phidias 87dbf0db57 . 2024-12-29 14:06:16 +09:00
phidias f5d548e709 . 2024-12-29 14:04:13 +09:00
50 changed files with 466 additions and 1984 deletions
+5
View File
@@ -1,3 +1,8 @@
dist/
node_modules/
.vscode
exp_util/node-compile-cache/
exp_commands/node-compile-cache/
exp_groups/node-compile-cache/
exp_legacy/node-compile-cache/
exp_scenario/node-compile-cache/
+1
View File
@@ -28,6 +28,7 @@ force=Invalid Force Name.
surface=Invalid Surface Name.
planet=Invalid Planet Name.
color=Invalid Color Name.
role=Invalid Role Name.
[exp-commands-authorities]
character-only=This command can not be used in remote view.
+1
View File
@@ -28,6 +28,7 @@ force=勢力名稱錯誤。
surface=地表名稱錯誤。
planet=星球名稱錯誤。
color=顏色名稱錯誤。
role=權限組名稱錯誤。
[exp-commands-authorities]
character-only=該命令不能在遠端視圖中使用。
+1
View File
@@ -28,6 +28,7 @@ force=勢力名稱錯誤。
surface=地表名稱錯誤。
planet=星球名稱錯誤。
color=顏色名稱錯誤。
role=權限組名稱錯誤。
[exp-commands-authorities]
character-only=該命令不能在遠端視圖中使用。
-282
View File
@@ -1,282 +0,0 @@
import * as lib from "@clusterio/lib";
import { BaseControllerPlugin, InstanceInfo } from "@clusterio/controller";
import {
PermissionStrings, PermissionStringsUpdate,
PermissionGroup, PermissionGroupUpdate,
InstancePermissionGroups,
PermissionInstanceId,
PermissionGroupEditEvent,
} from "./messages";
import path from "path";
import fs from "fs-extra";
export class ControllerPlugin extends BaseControllerPlugin {
static permissionGroupsPath = "exp_groups.json";
static userGroupsPath = "exp_user_groups.json";
userToGroup: Map<lib.User["id"], PermissionGroup> = new Map(); // TODO this needs to be per instance
permissionStrings!: Map<PermissionStrings["id"], PermissionStrings>;
permissionGroups!: Map<InstancePermissionGroups["id"], InstancePermissionGroups>;
async init() {
this.controller.handle(PermissionStringsUpdate, this.handlePermissionStringsUpdate.bind(this));
this.controller.handle(PermissionGroupUpdate, this.handlePermissionGroupUpdate.bind(this));
this.controller.handle(PermissionGroupEditEvent, this.handlePermissionGroupEditEvent.bind(this));
this.controller.subscriptions.handle(PermissionStringsUpdate, this.handlePermissionStringsSubscription.bind(this));
this.controller.subscriptions.handle(PermissionGroupUpdate, this.handlePermissionGroupSubscription.bind(this));
this.controller.subscriptions.handle(PermissionGroupEditEvent);
this.permissionStrings = new Map([["Global", new PermissionStrings("Global", new Set())]]);
this.permissionGroups = new Map([["Global", new InstancePermissionGroups("Global")]]);
await this.loadData();
// Add the default group if missing and add any missing cluster roles
const clusterRoles = [...this.controller.userManager.roles.values()]
for (const instanceGroups of this.permissionGroups.values()) {
const groups = instanceGroups.groups;
const instanceRoles = [...groups.values()].flatMap(group => [...group.roleIds.values()]);
const missingRoles = clusterRoles.filter(role => instanceRoles.includes(role.id));
const defaultGroup = groups.get("Default");
if (defaultGroup) {
for (const role of missingRoles) {
defaultGroup.roleIds.add(role.id)
}
} else {
groups.set("Default", new PermissionGroup(
instanceGroups.instanceId,
"Default",
groups.size,
new Set(missingRoles.map(role => role.id))
));
}
}
}
async onControllerConfigFieldChanged(field: string, curr: unknown, prev: unknown) {
if (field === "exp_groups.allow_role_inconsistency") {
// Do something with this.userToGroup
}
}
async onInstanceConfigFieldChanged(instance: InstanceInfo, field: string, curr: unknown, prev: unknown) {
this.logger.info(`controller::onInstanceConfigFieldChanged ${instance.id} ${field}`);
if (field === "exp_groups.sync_permission_groups") {
const updates = []
const now = Date.now();
if (curr) {
// Global sync enabled, we dont need the instance config
const instanceGroups = this.permissionGroups.get(instance.id);
if (instanceGroups) {
this.permissionGroups.delete(instance.id);
for (const group of instanceGroups.groups.values()) {
group.updatedAtMs = now;
group.isDeleted = true;
updates.push(group);
}
}
} else {
// Global sync disabled, make a copy of the global config as a base
const global = this.permissionGroups.get("Global")!;
const oldInstanceGroups = this.permissionGroups.get(instance.id);
const instanceGroups = new InstancePermissionGroups(
instance.id, new Map([...global.groups.values()].map(group => [group.name, group.copy(instance.id)]))
)
this.permissionGroups.set(instance.id, instanceGroups);
for (const group of instanceGroups.groups.values()) {
group.updatedAtMs = now;
updates.push(group);
}
// If it has an old config (unexpected) then deal with it
if (oldInstanceGroups) {
for (const group of oldInstanceGroups.groups.values()) {
if (!instanceGroups.groups.has(group.name)) {
group.updatedAtMs = now;
group.isDeleted = true;
updates.push(group);
}
}
}
}
// Send the updates to all instances and controls
if (updates.length) {
this.controller.subscriptions.broadcast(new PermissionGroupUpdate(updates));
}
}
}
async loadPermissionGroups() {
const file = path.resolve(this.controller.config.get("controller.database_directory"), ControllerPlugin.permissionGroupsPath);
this.logger.verbose(`Loading ${file}`);
try {
const content = await fs.readFile(file, { encoding: "utf8" });
for (const groupRaw of JSON.parse(content)) {
const group = PermissionGroup.fromJSON(groupRaw);
const instanceGroups = this.permissionGroups.get(group.instanceId);
if (instanceGroups) {
instanceGroups.groups.set(group.name, group);
} else {
this.permissionGroups.set(group.instanceId,
new InstancePermissionGroups(group.instanceId, new Map([[group.name, group]]))
);
}
};
} catch (err: any) {
if (err.code === "ENOENT") {
this.logger.verbose("Creating new permission group database");
return;
}
throw err;
}
}
async savePermissionGroups() {
const file = path.resolve(this.controller.config.get("controller.database_directory"), ControllerPlugin.permissionGroupsPath);
this.logger.verbose(`Writing ${file}`);
await lib.safeOutputFile(file, JSON.stringify(
[...this.permissionGroups.values()].flatMap(instanceGroups => [...instanceGroups.groups.values()])
));
}
async loadUserGroups() {
if (!this.controller.config.get("exp_groups.allow_role_inconsistency")) return;
const file = path.resolve(this.controller.config.get("controller.database_directory"), ControllerPlugin.userGroupsPath);
this.logger.verbose(`Loading ${file}`);
try {
const content = await fs.readFile(file, { encoding: "utf8" });
this.userToGroup = new Map(JSON.parse(content));
} catch (err: any) {
if (err.code === "ENOENT") {
this.logger.verbose("Creating new user group database");
return;
}
throw err;
}
}
async saveUserGroups() {
if (!this.controller.config.get("exp_groups.allow_role_inconsistency")) return;
const file = path.resolve(this.controller.config.get("controller.database_directory"), ControllerPlugin.userGroupsPath);
this.logger.verbose(`Writing ${file}`);
await lib.safeOutputFile(file, JSON.stringify([...this.permissionGroups.entries()]));
}
async loadData() {
await Promise.all([
this.loadPermissionGroups(),
this.loadUserGroups(),
])
}
async onSaveData() {
await Promise.all([
this.savePermissionGroups(),
this.saveUserGroups(),
])
}
addPermisisonGroup(instanceId: PermissionInstanceId, name: string, permissions = new Set<string>(), silent = false) {
const instanceGroups = this.permissionGroups.get(instanceId);
if (!instanceGroups) {
throw new Error("Instance ID does not exist");
}
if (instanceGroups.groups.has(name)) {
return instanceGroups.groups.get(name)!;
}
for (const group of instanceGroups.groups.values()) {
group.order += 1;
}
const group = new PermissionGroup(instanceId, name, 0, new Set(), permissions, Date.now(), false);
instanceGroups.groups.set(group.id, group);
if (!silent) {
this.controller.subscriptions.broadcast(new PermissionGroupUpdate([group]));
}
return group;
}
removePermissionGroup(instanceId: PermissionInstanceId, name: string, silent = false) {
const instanceGroups = this.permissionGroups.get(instanceId);
if (!instanceGroups) {
throw new Error("Instance ID does not exist");
}
const group = instanceGroups.groups.get(name)
if (!group) {
return null;
}
for (const nextGroup of instanceGroups.groups.values()) {
if (nextGroup.order > group.order) {
nextGroup.order -= 1;
}
}
instanceGroups.groups.delete(group.id);
group.updatedAtMs = Date.now();
group.isDeleted = true;
if (!silent) {
this.controller.subscriptions.broadcast(new PermissionGroupUpdate([group]));
}
return group;
}
async handlePermissionGroupEditEvent(event: PermissionGroupEditEvent) {
// TODO
}
async handlePermissionStringsUpdate(event: PermissionStringsUpdate) {
for (const update of event.updates) {
const global = this.permissionStrings.get("Global")!
this.permissionStrings.set(update.instanceId as number, update)
global.updatedAtMs = Math.max(global.updatedAtMs, update.updatedAtMs)
for (const permission of update.permissions) {
global.permissions.add(permission)
}
// TODO maybe check if changes have happened rather than always pushing updates
this.controller.subscriptions.broadcast(new PermissionStringsUpdate([global, update]))
}
}
async handlePermissionGroupUpdate(event: PermissionGroupUpdate) {
const updates = [];
for (const group of event.updates) {
const groups = this.permissionGroups.get(group.instanceId);
if (!groups) continue;
const existingGroup = groups.groups.get(group.id);
let update
if (!existingGroup) {
update = this.addPermisisonGroup(group.instanceId, group.name, group.permissions, true);
} else if (group.isDeleted) {
update = this.removePermissionGroup(group.instanceId, group.name, true);
} else {
existingGroup.permissions = group.permissions;
existingGroup.updatedAtMs = Date.now();
update = existingGroup;
}
if (update) updates.push(update);
}
this.controller.subscriptions.broadcast(new PermissionGroupUpdate(updates));
}
async handlePermissionStringsSubscription(request: lib.SubscriptionRequest, src: lib.Address) {
const updates = [ ...this.permissionStrings.values() ]
.filter(
value => value.updatedAtMs > request.lastRequestTimeMs,
)
return updates.length ? new PermissionStringsUpdate(updates) : null;
}
async handlePermissionGroupSubscription(request: lib.SubscriptionRequest, src: lib.Address) {
const updates = [ ...this.permissionGroups.values() ]
.flatMap(instanceGroups => [...instanceGroups.groups.values()])
.filter(
value => value.updatedAtMs > request.lastRequestTimeMs,
)
if (src.type === lib.Address.instance) {
const instanceUpdates = updates.filter(group => group.instanceId === src.id || group.instanceId === "Global");
this.logger.info(JSON.stringify(updates))
this.logger.info(JSON.stringify(instanceUpdates))
return instanceUpdates.length ? new PermissionGroupUpdate(instanceUpdates) : null;
}
return updates.length ? new PermissionGroupUpdate(updates) : null;
}
}
-84
View File
@@ -1,84 +0,0 @@
import * as lib from "@clusterio/lib";
import * as Messages from "./messages";
lib.definePermission({
name: "exp_groups.create_delete_groups",
title: "Create and delete permission groups",
description: "Create and delete permission groups.",
});
lib.definePermission({
name: "exp_groups.reorder_groups",
title: "Reorder permission groups",
description: "Reorder groups and link them to user roles.",
});
lib.definePermission({
name: "exp_groups.modify_permissions",
title: "Modify permission groups",
description: "Modify game permissions for groups.",
});
lib.definePermission({
name: "exp_groups.assign_players",
title: "Change player group",
description: "Change the permission group of a player",
});
lib.definePermission({
name: "exp_groups.list",
title: "View permission groups",
description: "View permission groups.",
});
lib.definePermission({
name: "exp_groups.list.subscribe",
title: "Subscribe to permission group updates",
description: "Subscribe to permission group updates.",
});
declare module "@clusterio/lib" {
export interface ControllerConfigFields {
"exp_groups.allow_role_inconsistency": boolean;
}
export interface InstanceConfigFields {
"exp_groups.sync_permission_groups": boolean;
}
}
export const plugin: lib.PluginDeclaration = {
name: "exp_groups",
title: "exp_groups",
description: "Create, modify, and link factorio permission groups to clusterio user roles.",
controllerEntrypoint: "./dist/node/controller",
controllerConfigFields: {
"exp_groups.allow_role_inconsistency": {
title: "Allow User Role Inconsistency",
description: "When true, users can be assgined to any group regardless of their roles",
type: "boolean",
initialValue: false,
},
},
instanceEntrypoint: "./dist/node/instance",
instanceConfigFields: {
"exp_groups.sync_permission_groups": {
title: "Sync Permission Groups",
description: "When true, the instance cannot deviate from the global group settings and will be hidden from the sellection dropdown.",
type: "boolean",
initialValue: true,
},
},
messages: [
Messages.PermissionGroupEditEvent,
Messages.PermissionStringsUpdate,
Messages.PermissionGroupUpdate,
],
webEntrypoint: "./web",
routes: [
"/exp_groups",
],
};
-129
View File
@@ -1,129 +0,0 @@
import * as lib from "@clusterio/lib";
import { BaseInstancePlugin } from "@clusterio/host";
import {
PermissionGroup, PermissionGroupEditEvent, PermissionGroupEditType,
PermissionGroupUpdate, PermissionInstanceId, PermissionStrings, PermissionStringsUpdate
} from "./messages";
const rconBase = "/sc local Groups = package.loaded['modules/exp_groups/module_exports'];"
type EditIPC = {
type: PermissionGroupEditType,
changes: string[],
group: string,
};
type CreateIPC = {
group: string,
defiantion: [boolean, string[] | {}]
}
type DeleteIPC = {
group: string,
}
export class InstancePlugin extends BaseInstancePlugin {
permissions: Set<string> = new Set();
permissionGroups = new lib.EventSubscriber(PermissionGroupUpdate, this.instance);
permissionGroupUpdates = new lib.EventSubscriber(PermissionGroupEditEvent, this.instance);
syncId: PermissionInstanceId = this.instance.config.get("exp_groups.sync_permission_groups") ? "Global" : this.instance.id;
async init() {
this.instance.server.handle("exp_groups-permission_group_edit", this.handleEditIPC.bind(this));
this.instance.server.handle("exp_groups-permission_group_create", this.handleCreateIPC.bind(this));
this.instance.server.handle("exp_groups-permission_group_delete", this.handleDeleteIPC.bind(this));
}
async onStart() {
// Send the most recent version of the permission string
const permissionsString = await this.sendRcon(rconBase + "rcon.print(Groups.get_actions_json())");
this.permissions = new Set(JSON.parse(permissionsString));
this.instance.sendTo("controller", new PermissionStringsUpdate([
new PermissionStrings(this.instance.id, this.permissions, Date.now())
]));
// Subscribe to get updates for permission groups
this.permissionGroups.subscribe(this.onPermissionGroupsUpdate.bind(this));
this.permissionGroupUpdates.subscribe(this.onPermissionGroupUpdate.bind(this));
}
async onControllerConnectionEvent(event: any) {
this.permissionGroups.handleConnectionEvent(event);
}
async onInstanceConfigFieldChanged(field: string, curr: unknown, prev: unknown) {
if (field === "exp_groups.sync_permission_groups") {
this.syncId = curr ? "Global" : this.instance.id;
const [snapshot, synced] = this.permissionGroups.getSnapshot();
if (synced && this.instance.status !== "running") await this.syncPermissionGroups(snapshot.values());
}
}
async onPermissionGroupsUpdate(event: PermissionGroupUpdate | null, synced: boolean) {
if (!synced || this.instance.status !== "running" || !event?.updates.length) return;
await this.syncPermissionGroups(event.updates);
}
async syncPermissionGroups(groups: Iterable<PermissionGroup>) {
const updateCommands = [rconBase];
for (const group of groups) {
if (group.instanceId === this.syncId && group.updatedAtMs > (this.permissionGroups.values.get(group.id)?.updatedAtMs ?? 0)) {
if (group.isDeleted) {
updateCommands.push(`Groups.destroy_group('${group.name}')`);
} else if (group.permissions.size < this.permissions.size / 2) {
updateCommands.push(`Groups.get_or_create('${group.name}'):from_json('${JSON.stringify([false, [...this.permissions.values()]])}')`);
} else {
const inverted = [...this.permissions.values()].filter(permission => !group.permissions.has(permission));
updateCommands.push(`Groups.get_or_create('${group.name}'):from_json('${JSON.stringify([true, inverted])}')`);
}
}
}
await this.sendRcon(updateCommands.join(";"), true);
}
async onPermissionGroupUpdate(event: PermissionGroupEditEvent | null, synced: boolean) {
if (!synced || this.instance.status !== "running" || !event) return;
if (event.src.equals(lib.Address.fromShorthand({ instanceId: this.instance.id }))) return;
const getCmd = `Groups.get_or_create('${event.group}')`;
if (event.type === "add_permissions") {
await this.sendRcon(rconBase + getCmd + `:allow_actions(Groups.json_to_actions('${JSON.stringify(event.changes)}'))`);
} else if (event.type === "remove_permissions") {
await this.sendRcon(rconBase + getCmd + `:disallow_actions(Groups.json_to_actions('${JSON.stringify(event.changes)}'))`);
} else if (event.type === "assign_players") {
await this.sendRcon(rconBase + getCmd + `:add_players(game.json_to_table('${JSON.stringify(event.changes)}'))`);
}
}
async handleEditIPC(event: EditIPC) {
this.logger.info(JSON.stringify(event))
this.instance.sendTo("controller", new PermissionGroupEditEvent(
lib.Address.fromShorthand({ instanceId: this.instance.id }),
event.type, event.group, event.changes
))
}
async handleCreateIPC(event: CreateIPC) {
this.logger.info(JSON.stringify(event))
if (!this.permissionGroups.synced) return;
let [defaultAllow, permissionsRaw] = event.defiantion;
if (!Array.isArray(permissionsRaw)) {
permissionsRaw = [] // lua outputs {} for empty arrays
}
const permissions = [...this.permissions.values()]
.filter(permission => defaultAllow !== (permissionsRaw as String[]).includes(permission));
this.instance.sendTo("controller", new PermissionGroupUpdate([ new PermissionGroup(
this.syncId, event.group, 0, new Set(), new Set(permissions)
) ]));
}
async handleDeleteIPC(event: DeleteIPC) {
if (!this.permissionGroups.synced) return;
const group = [...this.permissionGroups.values.values()]
.find(group => group.instanceId === this.syncId && group.name === event.group);
if (group) {
group.updatedAtMs = Date.now();
group.isDeleted = true;
this.instance.sendTo("controller", new PermissionGroupUpdate([ group ]));
}
}
}
-239
View File
@@ -1,239 +0,0 @@
import { User, InstanceDetails, IControllerUser, Link, MessageRequest, StringEnum, PermissionError, Address } from "@clusterio/lib";
import { Type, Static } from "@sinclair/typebox";
export const PermissionInstanceIdSchema = Type.Union([InstanceDetails.jsonSchema.properties.id, Type.Literal("Global")])
export type PermissionInstanceId = InstanceDetails["id"] | "Global"
export type GamePermission = string; // todo: maybe enum this?
/**
* Data class for permission groups
*/
export class PermissionGroup {
constructor(
public instanceId: PermissionInstanceId,
public name: string,
/** A lower order assumes a lower permission group */
public order: number = 0,
/** A role will use the highest order group it is apart of */
public roleIds: User["roleIds"] = new Set(),
public permissions: Set<GamePermission> = new Set(),
public updatedAtMs: number = 0,
public isDeleted: boolean = false,
) {
}
static jsonSchema = Type.Object({
instanceId: PermissionInstanceIdSchema,
name: Type.String(),
order: Type.Number(),
roleIds: Type.Array(Type.Number()),
permissions: Type.Array(Type.String()),
updatedAtMs: Type.Optional(Type.Number()),
isDeleted: Type.Optional(Type.Boolean()),
});
static fromJSON(json: Static<typeof this.jsonSchema>) {
return new this(
json.instanceId,
json.name,
json.order,
new Set(json.roleIds),
new Set(json.permissions),
json.updatedAtMs,
json.isDeleted
);
}
toJSON(): Static<typeof PermissionGroup.jsonSchema> {
return {
instanceId: this.instanceId,
name: this.name,
order: this.order,
roleIds: [...this.roleIds.values()],
permissions: [...this.permissions.values()],
updatedAtMs: this.updatedAtMs > 0 ? this.updatedAtMs : undefined,
isDeleted: this.isDeleted ? this.isDeleted : undefined,
}
}
get id() {
return `${this.instanceId}:${this.name}`;
}
copy(newInstanceId: PermissionInstanceId) {
return new PermissionGroup(
newInstanceId,
this.name,
this.order,
new Set(this.roleIds),
new Set(this.permissions),
Date.now(),
false
)
}
}
export class InstancePermissionGroups {
constructor(
public instanceId: PermissionInstanceId,
public groups: Map<PermissionGroup["name"], PermissionGroup> = new Map(),
) {
}
static jsonSchema = Type.Object({
instanceId: PermissionInstanceIdSchema,
permissionsGroups: Type.Array(PermissionGroup.jsonSchema),
});
static fromJSON(json: Static<typeof InstancePermissionGroups.jsonSchema>) {
return new InstancePermissionGroups(
json.instanceId,
new Map(json.permissionsGroups.map(group => [group.name, PermissionGroup.fromJSON(group)])),
);
}
toJSON() {
return {
instanceId: this.instanceId,
permissionsGroups: [...this.groups.values()],
}
}
getUserGroup(user: User) {
const groups = [...user.roleIds.values()].map(roleId =>
// There will always be one and only one group for each role
[...this.groups.values()].find(group => group.roleIds.has(roleId))!
);
return groups.reduce((highest, group) => highest.order > group.order ? highest : group);
}
get id() {
return this.instanceId;
}
}
export class PermissionGroupUpdate {
declare ["constructor"]: typeof PermissionGroupUpdate;
static type = "event" as const;
static src = ["controller", "instance"] as const;
static dst = ["control", "instance", "controller"] as const;
static plugin = "exp_groups" as const;
static permission = "exp_groups.list.subscribe";
constructor(
public updates: PermissionGroup[],
) { }
static jsonSchema = Type.Object({
"updates": Type.Array(PermissionGroup.jsonSchema),
});
static fromJSON(json: Static<typeof this.jsonSchema>) {
return new this(
json.updates.map(update => PermissionGroup.fromJSON(update))
);
}
}
export type PermissionGroupEditType = "assign_players" | "add_permissions" | "remove_permissions";
export class PermissionGroupEditEvent {
declare ["constructor"]: typeof PermissionGroupEditEvent;
static type = "event" as const;
static src = ["instance", "controller"] as const;
static dst = ["control", "instance", "controller"] as const;
static plugin = "exp_groups" as const;
static permission(user: IControllerUser, message: MessageRequest) {
if (typeof message.data === "object" && message.data !== null) {
const data = message.data as Static<typeof PermissionGroupEditEvent.jsonSchema>;
if (data.type === "add_permissions" || data.type === "remove_permissions") {
user.checkPermission("exp_groups.modify_permissions")
} else if (data.type === "assign_players") {
user.checkPermission("exp_groups.assign_players")
} else {
throw new PermissionError("Permission denied");
}
};
}
constructor(
public src: Address,
public type: PermissionGroupEditType,
public group: string,
public changes: String[],
) { }
static jsonSchema = Type.Object({
"src": Address.jsonSchema,
"type": StringEnum(["assign_players", "add_permissions", "remove_permissions"]),
"group": Type.String(),
"changes": Type.Array(Type.String()),
});
static fromJSON(json: Static<typeof this.jsonSchema>) {
return new this(Address.fromJSON(json.src), json.type, json.group, json.changes);
}
}
export class PermissionStrings {
constructor(
public instanceId: PermissionInstanceId,
public permissions: Set<GamePermission>,
public updatedAtMs: number = 0,
public isDeleted: boolean = false,
) {
}
static jsonSchema = Type.Object({
instanceId: PermissionInstanceIdSchema,
permissions: Type.Array(Type.String()),
updatedAtMs: Type.Optional(Type.Number()),
isDeleted: Type.Optional(Type.Boolean()),
});
static fromJSON(json: Static<typeof PermissionStrings.jsonSchema>) {
return new PermissionStrings(
json.instanceId,
new Set(json.permissions),
json.updatedAtMs,
json.isDeleted
);
}
toJSON() {
return {
instanceId: this.instanceId,
permissions: [...this.permissions.values()],
updatedAtMs: this.updatedAtMs > 0 ? this.updatedAtMs : undefined,
isDeleted: this.isDeleted ? this.isDeleted : undefined,
}
}
get id() {
return this.instanceId
}
}
export class PermissionStringsUpdate {
declare ["constructor"]: typeof PermissionStringsUpdate;
static type = "event" as const;
static src = ["instance", "controller"] as const;
static dst = ["controller", "control"] as const;
static plugin = "exp_groups" as const;
static permission = "exp_groups.list.subscribe";
constructor(
public updates: PermissionStrings[],
) { }
static jsonSchema = Type.Object({
"updates": Type.Array(PermissionStrings.jsonSchema),
});
static fromJSON(json: Static<typeof this.jsonSchema>) {
return new this(
json.updates.map(update => PermissionStrings.fromJSON(update))
);
}
}
-127
View File
@@ -1,127 +0,0 @@
local clusterio_api = require("modules/clusterio/api")
local Global = require("modules/exp_util/global")
local Groups = require("modules/exp_groups")
local pending_updates = {}
Global.register(pending_updates, function(tbl)
pending_updates = tbl
end)
local function on_permission_group_added(event)
if not event.player_index then return end
pending_updates[event.group.name] = {
created = true,
sync_all = true,
tick = event.tick,
permissions = {},
players = {},
}
end
local function on_permission_group_deleted(event)
if not event.player_index then return end
local existing = pending_updates[event.group_name]
pending_updates[event.group_name] = nil
if not existing or not existing.created then
clusterio_api.send_json("exp_groups-permission_group_delete", {
group = event.group_name,
})
end
end
local function on_permission_group_edited(event)
if not event.player_index then return end
local pending = pending_updates[event.group.name]
if not pending then
pending = {
tick = event.tick,
permissions = {},
players = {},
}
pending_updates[event.group.name] = pending
end
pending.tick = event.tick
if event.type == "add-permission" then
if not pending.sync_all then
pending.permissions[event.action] = true
end
elseif event.type == "remove-permission" then
if not pending.sync_all then
pending.permissions[event.action] = false
end
elseif event.type == "enable-all" then
pending.sync_all = true
elseif event.type == "disable-all" then
pending.sync_all = true
elseif event.type == "add-player" then
local player = game.get_player(event.other_player_index) --- @cast player -nil
pending.players[player.name] = true
elseif event.type == "remove-player" then
local player = game.get_player(event.other_player_index) --- @cast player -nil
pending.players[player.name] = nil
elseif event.type == "rename" then
pending.created = true
pending.sync_all = true
local old = pending_updates[event.old_name]
if old then pending.players = old.players end
on_permission_group_deleted{
tick = event.tick, player_index = event.player_index, group_name = event.old_name,
}
end
end
local function send_updates()
local tick = game.tick - 600 -- 10 Seconds
local done = {}
for group_name, pending in pairs(pending_updates) do
if pending.tick < tick then
done[group_name] = true
if pending.sync_all then
clusterio_api.send_json("exp_groups-permission_group_create", {
group = group_name, defiantion = Groups.get_group(group_name):to_json(true),
})
else
if next(pending.players) then
clusterio_api.send_json("exp_groups-permission_group_edit", {
type = "assign_players", group = group_name, changes = table.get_keys(pending.players),
})
end
local add, remove = {}, {}
for permission, state in pairs(pending.permissions) do
if state then
add[#add + 1] = permission
else
remove[#remove + 1] = permission
end
end
if next(add) then
clusterio_api.send_json("exp_groups-permission_group_edit", {
type = "add_permissions", group = group_name, changes = Groups.actions_to_names(add),
})
end
if next(remove) then
clusterio_api.send_json("exp_groups-permission_group_edit", {
type = "remove_permissions", group = group_name, changes = Groups.actions_to_names(remove),
})
end
end
end
end
for group_name in pairs(done) do
pending_updates[group_name] = nil
end
end
return {
events = {
[defines.events.on_permission_group_added] = on_permission_group_added,
[defines.events.on_permission_group_deleted] = on_permission_group_deleted,
[defines.events.on_permission_group_edited] = on_permission_group_edited,
},
on_nth_tick = {
[300] = send_updates,
},
}
-12
View File
@@ -1,12 +0,0 @@
{
"name": "exp_groups",
"load": [
"control.lua"
],
"require": [
],
"dependencies": {
"clusterio": "*",
"exp_util": "*"
}
}
-306
View File
@@ -1,306 +0,0 @@
local Async = require("modules/exp_util/async")
local table_to_json = helpers.table_to_json
local json_to_table = helpers.json_to_table
--- Top level module table, contains event handlers and public methods
local Groups = {}
--- @class ExpGroup : LuaPermissionGroup
--- @field group LuaPermissionGroup The permission group for this group proxy
Groups._prototype = {}
Groups._metatable = {
__index = setmetatable(Groups._prototype, {
--- @type any Annotation required because otherwise it is typed as 'table'
__index = function(self, key)
return self.group[key]
end,
}),
__class = "ExpGroup",
}
local action_to_name = {}
for name, action in pairs(defines.input_action) do
action_to_name[action] = name
end
--- Async Functions
-- These are required to allow bypassing edit_permission_group
--- Add a player to a permission group, requires edit_permission_group
--- @param player LuaPlayer Player to add to the group
--- @param group LuaPermissionGroup Group to add the player to
--- @return boolean # True if successful
local function add_player_to_group(player, group)
return group.add_player(player)
end
--- Add a players to a permission group, requires edit_permission_group
--- @param players LuaPlayer[] Players to add to the group
--- @param group LuaPermissionGroup Group to add the players to
--- @return boolean # True if successful
local function add_players_to_group(players, group)
local add_player = group.add_player
if not add_player(players[1]) then
return false
end
for i = 2, #players do
add_player(players[i])
end
return true
end
-- Async will bypass edit_permission_group but takes at least one tick
local add_player_to_group_async = Async.register(add_player_to_group)
local add_players_to_group_async = Async.register(add_players_to_group)
--- Static methods for gettings, creating and removing permission groups
--- Gets the permission group proxy with the given name or group ID.
--- @param group_name string|uint32 The name or id of the permission group
--- @return ExpGroup?
function Groups.get_group(group_name)
local group = game.permissions.get_group(group_name)
if group == nil then return nil end
return setmetatable({
group = group,
}, Groups._metatable)
end
--- Gets the permission group proxy for a players group
--- @param player LuaPlayer The player to get the group of
--- @return ExpGroup?
function Groups.get_player_group(player)
local group = player.permission_group
if group == nil then return nil end
return setmetatable({
group = group,
}, Groups._metatable)
end
--- Creates a new permission group, requires add_permission_group
--- @param group_name string Name of the group to create
--- @return ExpGroup
function Groups.new_group(group_name)
local group = game.permissions.get_group(group_name)
assert(group == nil, "Group already exists with name: " .. group_name)
group = game.permissions.create_group(group_name)
assert(group ~= nil, "Requires permission add_permission_group")
return setmetatable({
group = group,
}, Groups._metatable)
end
--- Get or create a permisison group, must use the group name not the group id
--- @param group_name string Name of the group to create
--- @return ExpGroup
function Groups.get_or_create(group_name)
local group = game.permissions.get_group(group_name)
if group then
return setmetatable({
group = group,
}, Groups._metatable)
else
group = game.permissions.create_group(group_name)
assert(group ~= nil, "Requires permission add_permission_group")
return setmetatable({
group = group,
}, Groups._metatable)
end
end
--- Destory a permission group, moves all players to default group
--- @param group_name string|uint32 The name or id of the permission group to destroy
--- @param move_to_name string|uint32? The name or id of the permission group to move players to
function Groups.destroy_group(group_name, move_to_name)
local group = game.permissions.get_group(group_name)
if group == nil then return end
local players = group.players
if #players > 0 then
local move_to = game.permissions.get_group(move_to_name or "Default")
for _, player in ipairs(players) do
player.permission_group = move_to
end
end
local success = group.destroy()
assert(success, "Requires permission delete_permission_group")
end
--- Prototype methods for modifying and working with permission groups
--- Add a player to the permission group
--- @param player LuaPlayer The player to add to the group
function Groups._prototype:add_player(player)
if not add_player_to_group(player, self.group) then
add_player_to_group_async(player, self.group)
end
end
--- Add players to the permission group
--- @param players LuaPlayer[] The player to add to the group
function Groups._prototype:add_players(players)
if not add_players_to_group(players, self.group) then
add_players_to_group_async(players, self.group)
end
end
--- Move all players to another group
--- @param other_group ExpGroup The group to move players to, default is the Default group
function Groups._prototype:move_players(other_group)
if not add_players_to_group(self.group.players, other_group.group) then
add_players_to_group_async(self.group.players, other_group.group)
end
end
--- Allow a set of actions for this group
--- @param actions defines.input_action[] Actions to allow
--- @return ExpGroup
function Groups._prototype:allow_actions(actions)
local set_allow = self.group.set_allows_action
for _, action in ipairs(actions) do
set_allow(action, true)
end
return self
end
--- Disallow a set of actions for this group
--- @param actions defines.input_action[] Actions to disallow
--- @return ExpGroup
function Groups._prototype:disallow_actions(actions)
local set_allow = self.group.set_allows_action
for _, action in ipairs(actions) do
set_allow(action, false)
end
return self
end
--- Reset the allowed state of all actions
--- @param allowed boolean? default true for allow all actions, false to disallow all actions
--- @return ExpGroup
function Groups._prototype:reset(allowed)
local set_allow = self.group.set_allows_action
if allowed == nil then allowed = true end
for _, action in pairs(defines.input_action) do
set_allow(action, allowed)
end
return self
end
--- Returns if the group is allowed a given action
--- @param action string|defines.input_action Actions to test
--- @return boolean # True if successful
function Groups._prototype:allows(action)
if type(action) == "string" then
return self.group.allows_action(defines.input_action[action])
end
return self.group.allows_action(action)
end
--- Print a message to all players in the group
function Groups._prototype:print(...)
for _, player in ipairs(self.group.players) do
player.print(...)
end
end
--- Static and Prototype methods for use with IPC
--- Convert an array of strings into an array of action names
--- @param actions_names string[] An array of action names
--- @return defines.input_action[]
local function names_to_actions(actions_names)
--- @type defines.input_action[], number[], number
local actions, invalid, invalid_i = {}, {}, 1
for i, action_name in ipairs(actions_names) do
local action = defines.input_action[action_name] --[[ @as defines.input_action? ]]
if action then
actions[i] = action
else
invalid[invalid_i] = i
invalid_i = invalid_i + 1
end
end
local last = #actions
for _, i in ipairs(invalid) do
actions[i] = actions[last]
last = last - 1
end
return actions
end
--- Get the action names from the action numbers
function Groups.actions_to_names(actions)
local names = {}
for i, action in ipairs(actions) do
names[i] = action_to_name[action]
end
return names
end
--- Get all input actions that are defined
function Groups.get_actions_json()
local rtn, rtn_i = {}, 1
for name in pairs(defines.input_action) do
rtn[rtn_i] = name
rtn_i = rtn_i + 1
end
return table_to_json(rtn)
end
--- Convert a json string array into an array of input actions
--- @param json string A json string representing a string array of actions
--- @return defines.input_action[]
function Groups.json_to_actions(json)
local tbl = json_to_table(json)
assert(tbl, "Invalid Json String")
--- @cast tbl string[]
return names_to_actions(tbl)
end
--- Returns the shortest defination of the allowed actions
-- The first value of the return can be passed to :reset
function Groups._prototype:to_json(raw)
local allow, disallow = {}, {}
local allow_i, disallow_i = 1, 1
local allows = self.group.allows_action
for name, action in pairs(defines.input_action) do
if allows(action) then
allow[allow_i] = name
allow_i = allow_i + 1
else
disallow[disallow_i] = name
disallow_i = disallow_i + 1
end
end
if allow_i >= disallow_i then
return raw and { true, disallow } or table_to_json{ true, disallow }
end
return raw and { false, allow } or table_to_json{ false, allow }
end
--- Restores this group to the state given in a json string
--- @param json string The json string to restore from
function Groups._prototype:from_json(json)
local tbl = json_to_table(json)
assert(tbl and type(tbl[1]) == "boolean" and type(tbl[2]) == "table", "Invalid Json String")
if tbl[1] then
self:reset(true):disallow_actions(names_to_actions(tbl[2]))
return
end
self:reset(false):allow_actions(names_to_actions(tbl[2]))
end
return Groups
-4
View File
@@ -1,4 +0,0 @@
{
"extends": "../tsconfig.browser.json",
"include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ],
}
-7
View File
@@ -1,7 +0,0 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.browser.json" },
{ "path": "./tsconfig.node.json" }
]
}
-5
View File
@@ -1,5 +0,0 @@
{
"extends": "../tsconfig.node.json",
"include": ["./**/*.ts"],
"exclude": ["test/*", "./dist/*"],
}
-129
View File
@@ -1,129 +0,0 @@
import React, { useState } from 'react';
import { Tree } from 'antd';
import type { TreeDataNode, TreeProps } from 'antd';
const defaultData: TreeDataNode[] = [
{
title: "Group 1",
key: "G-1",
icon: false,
children: [
{
title: "Role 1",
key: "R-1"
},
{
title: "Role 2",
key: "R-2"
},
{
title: "Role 3",
key: "R-3"
}
]
},
{
title: "Group 2",
key: "G-2",
icon: false,
children: [
{
title: "Role 4",
key: "R-4"
},
{
title: "Role 5",
key: "R-5"
}
]
},
{
title: "Default",
key: "G-3",
icon: false,
children: [
{
title: "Role 6",
key: "R-6"
}
]
}
];
export function GroupTree() {
const [gData, setGData] = useState(defaultData);
const onDrop: TreeProps['onDrop'] = (info) => {
const dropKey = info.node.key;
const dragKey = info.dragNode.key;
const dropPos = info.node.pos.split('-');
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]); // the drop position relative to the drop node, inside 0, top -1, bottom 1
const findKey = (
data: TreeDataNode[],
key: React.Key,
callback: (node: TreeDataNode, i: number, data: TreeDataNode[]) => void,
) => {
for (let i = 0; i < data.length; i++) {
if (data[i].key === key) {
return callback(data[i], i, data);
}
if (data[i].children) {
findKey(data[i].children!, key, callback);
}
}
};
const data = [...gData]
// Find dragObject
let dragObj: TreeDataNode;
findKey(data, dragKey, (item, index, arr) => {
arr.splice(index, 1);
dragObj = item;
});
if (!info.dropToGap) {
// Drop on the content
findKey(data, dropKey, (item) => {
item.children = item.children || [];
// where to insert. New item was inserted to the start of the array in this example, but can be anywhere
item.children.unshift(dragObj);
});
} else {
let ar: TreeDataNode[] = [];
let i: number;
findKey(data, dropKey, (_item, index, arr) => {
ar = arr;
i = index;
});
if (dropPosition === -1) {
// Drop on the top of the drop node
ar.splice(i!, 0, dragObj!);
} else {
// Drop on the bottom of the drop node
ar.splice(i! + 1, 0, dragObj!);
}
}
setGData(data)
};
const allowDrop: TreeProps['allowDrop'] = ({dragNode, dropNode, dropPosition}) => {
const dragType = (dragNode.key as string).charAt(0);
const dropType = (dropNode.key as string).charAt(0);
return dropType === dragType && dropPosition != 0 || dragType === "R" && dropType === "G" && dropPosition == 0
}
return (
<Tree
className="draggable-tree"
defaultExpandAll={true}
draggable
blockNode
onDrop={onDrop}
allowDrop={allowDrop}
treeData={gData}
/>
);
};
-82
View File
@@ -1,82 +0,0 @@
import React, {
useContext, useEffect, useState,
useCallback, useSyncExternalStore,
} from "react";
// import {
//
// } from "antd";
import {
BaseWebPlugin, PageLayout, PageHeader, Control, ControlContext, notifyErrorHandler,
useInstances,
} from "@clusterio/web_ui";
import { PermissionGroupUpdate, PermissionInstanceId, PermissionStringsUpdate } from "../messages";
import * as lib from "@clusterio/lib";
import { GroupTree } from "./components/groupTree";
function MyTemplatePage() {
const control = useContext(ControlContext);
const plugin = control.plugins.get("exp_groups") as WebPlugin;
const [permissionStrings, permissionStringsSynced] = plugin.usePermissionStrings();
const [permissionGroups, permissionGroupsSynced] = plugin.usePermissionGroups();
const [instances, instancesSync] = useInstances();
let [roles, setRoles] = useState<lib.Role[]>([]);
useEffect(() => {
control.send(new lib.RoleListRequest()).then(newRoles => {
setRoles(newRoles);
}).catch(notifyErrorHandler("Error fetching role list"));
}, []);
return <PageLayout nav={[{ name: "exp_groups" }]}>
<PageHeader title="exp_groups" />
Permission Strings: {String(permissionStringsSynced)} {JSON.stringify([...permissionStrings.values()])} <br/>
Permission Groups: {String(permissionGroupsSynced)} {JSON.stringify([...permissionGroups.values()])} <br/>
Instances: {String(instancesSync)} {JSON.stringify([...instances.values()].map(instance => [instance.id, instance.name]))} <br/>
Roles: {JSON.stringify([...roles.values()].map(role => [role.id, role.name]))} <br/>
<GroupTree/>
</PageLayout>;
}
export class WebPlugin extends BaseWebPlugin {
permissionStrings = new lib.EventSubscriber(PermissionStringsUpdate, this.control);
permissionGroups = new lib.EventSubscriber(PermissionGroupUpdate, this.control);
async init() {
this.pages = [
{
path: "/exp_groups",
sidebarName: "exp_groups",
permission: "exp_groups.list",
content: <MyTemplatePage/>,
},
];
}
useInstancePermissionStrings(instanceId?: PermissionInstanceId) {
const [permissionStrings, synced] = this.usePermissionStrings();
return [instanceId !== undefined ? permissionStrings.get(instanceId) : undefined, synced] as const;
}
usePermissionStrings() {
const control = useContext(ControlContext);
const subscribe = useCallback((callback: () => void) => this.permissionStrings.subscribe(callback), [control]);
return useSyncExternalStore(subscribe, () => this.permissionStrings.getSnapshot());
}
useInstancePermissionGroups(instanceId?: PermissionInstanceId) {
const [permissionGroups, synced] = this.usePermissionGroups();
return [instanceId !== undefined ? [...permissionGroups.values()].filter(group => group.instanceId === instanceId) : undefined, synced] as const;
}
usePermissionGroups() {
const control = useContext(ControlContext);
const subscribe = useCallback((callback: () => void) => this.permissionGroups.subscribe(callback), [control]);
return useSyncExternalStore(subscribe, () => this.permissionGroups.getSnapshot());
}
}
-32
View File
@@ -1,32 +0,0 @@
"use strict";
const path = require("path");
const webpack = require("webpack");
const { merge } = require("webpack-merge");
const common = require("@clusterio/web_ui/webpack.common");
module.exports = (env = {}) => merge(common(env), {
context: __dirname,
entry: "./web/index.tsx",
output: {
path: path.resolve(__dirname, "dist", "web"),
},
plugins: [
new webpack.container.ModuleFederationPlugin({
name: "exp_groups",
library: { type: "window", name: "plugin_exp_groups" },
exposes: {
"./": "./index.ts",
"./package.json": "./package.json",
"./web": "./web/index.tsx",
},
shared: {
"@clusterio/lib": { import: false },
"@clusterio/web_ui": { import: false },
"antd": { import: false },
"react": { import: false },
"react-dom": { import: false },
},
}),
],
});
-1
View File
@@ -1,4 +1,3 @@
[exp-gui]
clear-left-flow=Hide all open windows.
close-toolbar=__CONTROL_LEFT_CLICK__: Toggle Settings\n__CONTROL_RIGHT_CLICK__: Close Toolbar
+1 -2
View File
@@ -23,13 +23,12 @@ return {
--- GUI
"modules.gui.readme",
"modules.gui.rocket-info",
"modules.gui.warp-list",
"modules.gui.player-list",
"modules.gui.vlayer",
"modules.gui._role_updates",
"modules.graftorio.require", -- graftorio
-- "modules.graftorio.require", -- graftorio
--- Config Files
"config.expcore.permission_groups", -- loads some predefined permission groups
"config.expcore.roles", -- loads some predefined roles
+34 -33
View File
@@ -4,7 +4,7 @@
--- These are called factories because they return another function
-- use these as a simple methods of adding new items
-- they will do most of the work for you
-- ['item-name'] = factory(params)
-- ["item-name"] = factory(params)
-- luacheck:ignore 212/amount_made 212/items_made 212/player
-- Use these to adjust for ticks ie game.tick < 5*minutes
@@ -12,7 +12,7 @@
local seconds, minutes, hours = 60, 3600, 216000
--- Use to make a split point for the number of items given based on time
-- ['stone-furnace']=cutoff_time(5*minutes, 4,0) -- before 5 minutes give four items after 5 minutes give none
-- ["stone-furnace"]=cutoff_time(5*minutes, 4,0) -- before 5 minutes give four items after 5 minutes give none
local function cutoff_time(time, before, after)
return function(amount_made, items_made, player)
if game.tick < time then
@@ -24,7 +24,8 @@ local function cutoff_time(time, before, after)
end
--- Use to make a split point for the number of items given based on amount made
-- ['firearm-magazine']=cutoff_amount_made(100, 10, 0) -- give 10 items until 100 items have been made
-- ["firearm-magazine"]=cutoff_amount_made(100, 10, 0) -- give 10 items until 100 items have been made
--[[
local function cutoff_amount_made(amount, before, after)
return function(amount_made, items_made, player)
if amount_made < amount then
@@ -34,9 +35,11 @@ local function cutoff_amount_made(amount, before, after)
end
end
end
]]
--- Same as above but will not give any items if x amount has been made of another item, useful for tiers
-- ['light-armor']=cutoff_amount_made_unless(5, 0,1,'heavy-armor',5) -- give light armor once 5 have been made unless 5 heavy armor has been made
-- ["light-armor"]=cutoff_amount_made_unless(5, 0,1,"heavy-armor",5) -- give light armor once 5 have been made unless 5 heavy armor has been made
--[[
local function cutoff_amount_made_unless(amount, before, after, second_item, second_amount)
return function(amount_made, items_made, player)
if items_made(second_item) < second_amount then
@@ -50,9 +53,11 @@ local function cutoff_amount_made_unless(amount, before, after, second_item, sec
end
end
end
]]
-- Use for mass production items where you want the amount to change based on the amount already made
-- ['iron-plate']=scale_amount_made(5*minutes, 10, 10) -- for first 5 minutes give 10 items then after apply a factor of 10
-- ["iron-plate"]=scale_amount_made(5*minutes, 10, 10) -- for first 5 minutes give 10 items then after apply a factor of 10
--[[
local function scale_amount_made(amount, before, scalar)
return function(amount_made, items_made, player)
if amount_made < amount then
@@ -62,12 +67,13 @@ local function scale_amount_made(amount, before, scalar)
end
end
end
]]
--[[
Common values
game.tick is the amount of time the game has been on for
amount_made is the amount of that item which has been made
items_made('item-name') will return the amount of any item made
items_made("item-name") will return the amount of any item made
player is the player who just spawned
hours, minutes, seconds are the number of ticks in each unit of time
]]
@@ -78,35 +84,30 @@ return {
friendly_fire = false, --- @setting friendly_fire weather players will be able to attack each other on the same force
disable_crashsite = true, --- @setting disable_crashsite weather to disable creation of the crashsite
enemy_expansion = false, --- @setting enemy_expansion a catch all for in case the map settings file fails to load
chart_radius = 10 * 32, --- @setting chart_radius the number of tiles that will be charted when the map starts
chart_radius = 16 * 32, --- @setting chart_radius the number of tiles that will be charted when the map starts
items = { --- @setting items items and there condition for being given
-- ['item-name'] = function(amount_made, production_stats, player) return <Number> end -- 0 means no items given
-- Plates
["iron-plate"] = scale_amount_made(100, 10, 10),
["copper-plate"] = scale_amount_made(100, 0, 8),
["steel-plate"] = scale_amount_made(100, 0, 4),
-- Secondary Items
["electronic-circuit"] = scale_amount_made(1000, 0, 6),
["iron-gear-wheel"] = scale_amount_made(1000, 0, 6),
-- Starting Items
["burner-mining-drill"] = cutoff_time(10 * minutes, 4, 0),
["stone-furnace"] = cutoff_time(10 * minutes, 4, 0),
-- Armor
["light-armor"] = cutoff_amount_made_unless(5, 0, 1, "heavy-armor", 5),
["heavy-armor"] = cutoff_amount_made(5, 0, 1),
-- Weapon
["pistol"] = cutoff_amount_made_unless(0, 1, 1, "submachine-gun", 5),
["submachine-gun"] = cutoff_amount_made(5, 0, 1),
-- Ammo
["firearm-magazine"] = cutoff_amount_made_unless(100, 10, 0, "piercing-rounds-magazine", 100),
["piercing-rounds-magazine"] = cutoff_amount_made(100, 0, 10),
["iron-ore"] = cutoff_time(20 * minutes, 80, 0),
["stone"] = cutoff_time(20 * minutes, 20, 0),
["coal"] = cutoff_time(20 * minutes, 20, 0),
-- ["burner-mining-drill"]=cutoff_time(20 * minutes, 8, 0),
-- ["stone-furnace"]=cutoff_time(20 * minutes, 8, 0),
["submachine-gun"] = 1,
["piercing-rounds-magazine"] = 20,
["construction-robot"] = 10,
["modular-armor"] = 1,
["solar-panel-equipment"] = 16,
["belt-immunity-equipment"] = 1,
["battery-equipment"] = 2,
["personal-roboport-equipment"] = 1
--[[
['construction-robot'] = 10,
['modular-armor'] = 1,
['solar-panel-equipment'] = 16,
['belt-immunity-equipment'] = 1,
['battery-equipment'] = 2,
['personal-roboport-equipment'] = 1
["construction-robot"] = 50,
["spidertron"] = 1,
["spidertron-remote"] = 1,
["modular-armor"] = 1,
["solar-panel-equipment"] = 60,
["belt-immunity-equipment"] = 1,
["battery-equipment"] = 6,
["personal-roboport-equipment"] = 5
]]
}
}
+1 -4
View File
@@ -26,12 +26,9 @@ local afk_time_units = {
return {
messages = { --- @setting messages will trigger when ever the word is said
["discord"] = { "info.discord" },
["expgaming"] = { "info.website" },
["aperx"] = { "info.website" },
["website"] = { "info.website" },
["status"] = { "info.status" },
["github"] = { "info.github" },
["patreon"] = { "info.patreon" },
["donate"] = { "info.patreon" },
["command"] = { "info.custom-commands" },
["commands"] = { "info.custom-commands" },
["softmod"] = { "info.softmod" },
+12 -11
View File
@@ -11,15 +11,16 @@ return {
player_kicks = true,
player_promotes = false,
player_jail = true,
["config"] = true,
["purge"] = true,
["c"] = true,
["command"] = true,
["silent-command"] = true,
["measured-command"] = true,
["banlist"] = true,
["permissions"] = true,
["editor"] = true,
["cheat"] = true,
["open"] = false,
['config']=false,
['purge']=false,
['c']=false,
['sc']=false,
['command']=false,
['silent-command']=false,
['measured-command']=false,
['banlist']=false,
['permissions']=false,
['editor']=false,
['cheat']=false,
['open']=false
}
@@ -1,5 +1,5 @@
--- Use this file to add new permission groups to the game;
-- start with Permission_Groups.new_group('name');
-- start with Permission_Groups.new_group("name");
-- then use either :allow_all() or :disallow_all() to set the default for non specified actions;
-- then use :allow{} and :disallow{} to specify certain actions to allow/disallow
-- @config Permission-Groups
@@ -9,6 +9,9 @@ local Groups = require("modules.exp_legacy.expcore.permission_groups") --- @dep
Groups.new_group("Admin")
:allow_all()
Groups.new_group("Mod")
:allow_all()
:disallow{
"add_permission_group", -- admin
"delete_permission_group",
@@ -17,11 +20,6 @@ Groups.new_group("Admin")
"map_editor_action",
"toggle_map_editor",
"change_multiplayer_config",
"set_heat_interface_mode",
"set_heat_interface_temperature",
"set_infinity_container_filter_item",
"set_infinity_container_remove_unfiltered_items",
"set_infinity_pipe_filter",
}
Groups.new_group("Trusted")
@@ -34,12 +32,12 @@ Groups.new_group("Trusted")
"map_editor_action",
"toggle_map_editor",
"change_multiplayer_config",
"set_heat_interface_mode",
"set_heat_interface_mode", -- trusted
"set_heat_interface_temperature",
"set_infinity_container_filter_item",
"set_infinity_container_remove_unfiltered_items",
"set_infinity_pipe_filter",
"admin_action", -- trusted
"admin_action",
}
Groups.new_group("Standard")
@@ -58,10 +56,8 @@ Groups.new_group("Standard")
"set_infinity_container_remove_unfiltered_items",
"set_infinity_pipe_filter",
"admin_action", -- trusted
"delete_space_platform",
"change_programmable_speaker_alert_parameters", -- standard
"drop_item",
"open_new_platform_button_from_rocket_silo",
"set_rocket_silo_send_to_orbit_automated_mode",
}
Groups.new_group("Guest")
@@ -80,21 +76,24 @@ Groups.new_group("Guest")
"set_infinity_container_remove_unfiltered_items",
"set_infinity_pipe_filter",
"admin_action", -- trusted
"delete_space_platform",
"change_programmable_speaker_alert_parameters", -- standard
"change_programmable_speaker_circuit_parameters", -- guest
"change_programmable_speaker_parameters",
"drop_item",
"open_new_platform_button_from_rocket_silo",
"set_rocket_silo_send_to_orbit_automated_mode",
"change_programmable_speaker_parameters", -- guest
"open_new_platform_button_from_rocket_silo",
"instantly_create_space_platform",
"cancel_delete_space_platform",
"rename_space_platform",
-- "launch_rocket",
"change_train_stop_station",
-- 'deconstruct',
-- "deconstruct",
"remove_cables",
"remove_train_station",
"reset_assembling_machine",
"rotate_entity",
-- 'use_artillery_remote', -- not in 2.0
"launch_rocket",
"cancel_research",
-- 'activate_cut', -- not in 2.0
"flush_opened_entity_fluid",
"flush_opened_entity_specific_fluid",
}
@@ -108,15 +107,15 @@ Groups.new_group("Restricted")
local trusted_time = 60*60*60*10 -- 10 hour
local standard_time = 60*60*60*3 -- 3 hour
local function assign_group(player)
local current_group_name = player.permission_group and player.permission_group.name or 'None'
local current_group_name = player.permission_group and player.permission_group.name or "None"
if player.admin then
Permission_Groups.set_player_group(player,'Admin')
elseif player.online_time > trusted_time or current_group_name == 'Trusted' then
Permission_Groups.set_player_group(player,'Trusted')
elseif player.online_time > standard_time or current_group_name == 'Standard' then
Permission_Groups.set_player_group(player,'Standard')
Permission_Groups.set_player_group(player,"Admin")
elseif player.online_time > trusted_time or current_group_name == "Trusted" then
Permission_Groups.set_player_group(player,"Trusted")
elseif player.online_time > standard_time or current_group_name == "Standard" then
Permission_Groups.set_player_group(player,"Standard")
else
Permission_Groups.set_player_group(player,'Guest')
Permission_Groups.set_player_group(player,"Guest")
end
end
+176 -167
View File
@@ -26,6 +26,7 @@ Roles.new_role("System", "SYS")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_flag("deconlog-bypass")
:set_allow_all()
Roles.new_role("Senior Administrator", "SAdmin")
@@ -36,13 +37,9 @@ Roles.new_role("Senior Administrator", "SAdmin")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_flag("deconlog-bypass")
:set_parent("Administrator")
:allow{
"command/_rcon",
"command/debug",
"command/set-cheat-mode",
"command/research-all",
}
:set_allow_all()
Roles.new_role("Administrator", "Admin")
:set_permission_group("Admin")
@@ -51,63 +48,57 @@ Roles.new_role("Administrator", "Admin")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_flag("deconlog-bypass")
:set_parent("Senior Moderator")
:allow{
"command/_rcon",
"command/debug",
"command/set-cheat-mode",
"command/research-all"
}
Roles.new_role("Senior Moderator", "SMod")
:set_permission_group("Mod")
:set_custom_color{ r = 0, g = 170, b = 0 }
:set_flag("is_admin")
:set_flag("is_system")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_flag("deconlog-bypass")
:set_parent("Moderator")
:allow{
"gui/warp-list/bypass-proximity",
"gui/warp-list/bypass-cooldown",
"command/connect-all",
"command/connect-all"
}
Roles.new_role("Moderator", "Mod")
:set_permission_group("Admin")
:set_permission_group("Mod")
:set_custom_color{ r = 0, g = 170, b = 0 }
:set_flag("is_admin")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_parent("Trainee")
:set_flag("deconlog-bypass")
:set_parent("Trainee Moderator")
:allow{
"command/assign-role",
"command/unassign-role",
"command/repair",
"command/kill/always",
"command/clear-tag/always",
"command/spawn/always",
"command/clear-reports",
"command/clear-warnings",
"command/clear-script-warnings",
"command/clear-last-warnings",
"command/clear-inventory",
"command/kill-enemies",
"command/remove-enemies",
--'command/bonus',
"command/home",
"command/set-home",
"command/get-home",
"command/return",
"command/connect-player",
"command/set-bot-queue",
"command/set-game-speed",
"command/set-friendly-fire",
"command/set-always-day",
"command/set-pollution-enabled",
"command/clear-pollution",
"gui/rocket-info/toggle-active",
"gui/rocket-info/remote_launch",
"gui/bonus",
"fast-tree-decon",
}
Roles.new_role("Trainee", "TrMod")
:set_permission_group("Admin")
Roles.new_role("Trainee Moderator", "Trainee")
:set_permission_group("Mod")
:set_custom_color{ r = 0, g = 170, b = 0 }
:set_flag("is_admin")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_parent("Veteran")
:set_flag("instant-respawn")
:set_flag("deconlog-bypass")
:set_parent("Board Member")
:allow{
"command/assign-role",
"command/unassign-role",
"command/admin-chat",
"command/goto",
"command/protect-tag",
"command/teleport",
"command/bring",
"command/create-warning",
@@ -115,19 +106,30 @@ Roles.new_role("Trainee", "TrMod")
"command/get-reports",
"command/protect-entity",
"command/protect-area",
"command/protect-tag",
"command/jail",
"command/unjail",
"command/kick",
"command/ban",
"command/spectate",
"command/follow",
"command/search",
"command/search-online",
"command/search-amount",
"command/search-recent",
"command/clear-blueprints",
"gui/playerdata",
"command/clear-pollution",
"command/set-pollution-enabled",
"command/set-bot-queue",
"command/set-game-speed",
"command/kill-enemies",
"command/remove-enemies",
"command/set-friendly-fire",
"command/set-always-day",
"command/clear-reports",
"command/clear-warnings",
"command/clear-script-warnings",
"command/clear-last-warnings",
"command/clear-inventory",
"command/connect-player",
"command/kill/always",
-- "command/clear-tag/always",
"command/spawn/always",
"gui/playerdata"
}
--- Trusted Roles
@@ -137,81 +139,95 @@ Roles.new_role("Board Member", "Board")
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_parent("Sponsor")
:allow{
"command/goto",
"command/repair",
"command/spectate",
"command/follow",
"gui/playerdata",
}
Roles.new_role("Senior Backer", "Backer")
:set_permission_group("Trusted")
:set_custom_color{ r = 238, g = 172, b = 44 }
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_parent("Sponsor")
:allow{
}
Roles.new_role("Sponsor", "Spon")
:set_permission_group("Trusted")
:set_custom_color{ r = 238, g = 172, b = 44 }
:set_flag("is_spectator")
:set_flag("report-immune")
:set_flag("instant-respawn")
:set_flag("deconlog-bypass")
:set_parent("Supporter")
:allow{
"gui/rocket-info/toggle-active",
"gui/rocket-info/remote_launch",
"gui/bonus",
--"command/bonus",
"command/home",
"command/set-home",
"command/get-home",
"command/return",
"fast-tree-decon",
}
Roles.new_role("Supporter", "Sup")
:set_permission_group("Trusted")
:set_custom_color{ r = 230, g = 99, b = 34 }
:set_flag("is_spectator")
:set_parent("Veteran")
:set_flag("instant-respawn")
:set_flag("deconlog-bypass")
:set_parent("Partner")
:allow{
"command/tag-color",
"command/jail",
"command/unjail",
"command/set-join-message",
"command/remove-join-message",
}
Roles.new_role("Partner", "Part")
:set_permission_group("Trusted")
:set_custom_color{ r = 140, g = 120, b = 200 }
:set_custom_color{ r = 24, g = 172, b = 188 }
:set_flag("is_spectator")
:set_parent("Veteran")
:set_flag("instant-respawn")
:set_flag("deconlog-bypass")
:set_parent("Senior Member")
:allow{
"command/jail",
"command/unjail",
}
local hours10, hours250 = 10 * 216000, 250 * 60
Roles.new_role("Senior Member", "SMem")
:set_permission_group("Trusted")
:set_custom_color{ r = 24, g = 172, b = 188 }
:set_flag("is_spectator")
:set_flag("deconlog-bypass")
:set_flag("instant-respawn")
:set_parent("Member")
:allow{
}
--- Standard User Roles
Roles.new_role("Member", "Mem")
:set_permission_group("Trusted")
:set_custom_color{ r = 24, g = 172, b = 188 }
:set_flag("instant-respawn")
:set_flag("deconlog-bypass")
:set_parent("Veteran")
:allow{
"command/set-join-message",
"command/remove-join-message",
"gui/vlayer-edit",
"gui/rocket-info/toggle-active",
"gui/rocket-info/remote_launch",
"gui/tool",
-- "command/tag-color",
"command/clear-blueprints",
--"command/bonus",
"gui/bonus",
"command/personal-logistic",
"command/home",
"command/set-home",
"command/get-home",
"command/return",
"command/goto",
"command/jail",
"command/unjail",
"command/spectate",
"command/follow",
"command/repair",
"fast-tree-decon"
}
local hours6, hours250 = 6 * 216000, 250 * 60
Roles.new_role("Veteran", "Vet")
:set_permission_group("Trusted")
:set_custom_color{ r = 140, g = 120, b = 200 }
:set_parent("Member")
:set_flag("deconlog-bypass")
:set_parent("Regular")
:allow{
"gui/surveillance",
"gui/warp-list/add",
"gui/warp-list/edit",
"command/chat-bot",
"command/chat-commands",
"command/clear-ground-items",
"command/clear-blueprints-radius",
"command/set-trains-to-automatic",
"command/set-auto-research",
"command/lawnmower",
"command/waterfill",
"command/artillery"
}
:set_auto_assign_condition(function(player)
if player.online_time >= hours10 then
if player.online_time >= hours6 then
return true
else
local stats = Statistics:get(player, {})
@@ -220,44 +236,25 @@ Roles.new_role("Veteran", "Vet")
end
end)
--- Standard User Roles
Roles.new_role("Member", "Mem")
:set_permission_group("Standard")
:set_custom_color{ r = 24, g = 172, b = 188 }
:set_flag("deconlog-bypass")
:set_parent("Regular")
:allow{
"gui/task-list/add",
"gui/task-list/edit",
"gui/warp-list/add",
"gui/warp-list/edit",
"gui/surveillance",
"gui/vlayer-edit",
"gui/tool",
"command/save-quickbar",
"command/vlayer-info",
"command/personal-logistic",
"command/lawnmower",
"command/waterfill",
"command/artillery",
}
local hours3, hours15 = 3 * 216000, 15 * 60
local hours1, hours15 = 1 * 216000, 15 * 60
Roles.new_role("Regular", "Reg")
:set_permission_group("Standard")
:set_custom_color{ r = 79, g = 155, b = 163 }
:set_parent("Guest")
:allow{
"gui/task-list/add",
"gui/task-list/edit",
"command/kill",
"command/rainbow",
"command/spawn",
"command/me",
"command/vlayer-info",
"standard-decon",
"bypass-entity-protection",
"bypass-nukeprotect",
"bypass-nukeprotect"
}
:set_auto_assign_condition(function(player)
if player.online_time >= hours3 then
if player.online_time >= hours1 then
return true
else
local stats = Statistics:get(player, {})
@@ -271,8 +268,8 @@ local default = Roles.new_role("Guest", "")
:set_permission_group("Guest")
:set_custom_color{ r = 185, g = 187, b = 160 }
:allow{
"command/tag",
"command/tag-clear",
-- "command/tag",
-- "command/tag-clear",
"command/commands",
"command/get-roles",
"command/locate",
@@ -280,6 +277,7 @@ local default = Roles.new_role("Guest", "")
"command/ratio",
"command/server-ups",
"command/save-data",
"command/save-quickbar",
"command/data-preference",
"command/connect",
"gui/player-list",
@@ -292,7 +290,6 @@ local default = Roles.new_role("Guest", "")
"gui/research",
"gui/autofill",
"gui/module",
"gui/landfill",
"gui/production",
}
@@ -312,57 +309,69 @@ Roles.define_role_order{
"System", -- Best to keep root at top
"Senior Administrator",
"Administrator",
"Senior Moderator",
"Moderator",
"Trainee",
"Trainee Moderator",
"Board Member",
"Senior Backer",
"Sponsor",
"Supporter",
"Partner",
"Veteran",
"Senior Member",
"Member",
"Veteran",
"Regular",
"Jail",
"Guest", -- Default must be last if you want to apply restrictions to other roles
"Guest" -- Default must be last if you want to apply restrictions to other roles
}
Roles.override_player_roles{
["PHIDIAS0303"] = { "Moderator", "Board Member", "Member" },
["aldldl"] = { "Administrator", "Moderator", "Member" },
["arty714"] = { "Senior Administrator", "Moderator", "Member" },
["Cooldude2606"] = { "Senior Administrator", "Moderator", "Member" },
["Drahc_pro"] = { "Administrator", "Moderator", "Member" },
["mark9064"] = { "Administrator", "Moderator", "Member" },
["7h3w1z4rd"] = { "Moderator", "Member" },
["FlipHalfling90"] = { "Moderator", "Member" },
["hamsterbryan"] = { "Moderator", "Member" },
["HunterOfGames"] = { "Moderator", "Member" },
["NextIdea"] = { "Moderator", "Member" },
["TheKernel32"] = { "Moderator", "Member" },
["TheKernel64"] = { "Moderator", "Member" },
["tovernaar123"] = { "Moderator", "Member" },
["UUBlueFire"] = { "Moderator", "Member" },
["AssemblyStorm"] = { "Moderator", "Member" },
["banakeg"] = { "Moderator", "Member" },
["connormkii"] = { "Moderator", "Member" },
["cydes"] = { "Moderator", "Member" },
["darklich14"] = { "Moderator", "Member" },
["facere"] = { "Moderator", "Member" },
["freek18"] = { "Moderator", "Member" },
["Gizan"] = { "Moderator", "Member" },
["LoicB"] = { "Moderator", "Member" },
["M74132"] = { "Moderator", "Member" },
["mafisch3"] = { "Moderator", "Member" },
["maplesyrup01"] = { "Moderator", "Member" },
["ookl"] = { "Moderator", "Member" },
["Phoenix27833"] = { "Moderator", "Member" },
["porelos"] = { "Moderator", "Member" },
["Ruuyji"] = { "Moderator", "Member" },
["samy115"] = { "Moderator", "Member" },
["SilentLog"] = { "Moderator", "Member" },
["Tcheko"] = { "Moderator", "Member" },
["thadius856"] = { "Moderator", "Member" },
["whoami32"] = { "Moderator", "Member" },
["Windbomb"] = { "Moderator", "Member" },
["XenoCyber"] = { "Moderator", "Member" },
["PHIDIAS0303"] = { "Senior Administrator" },
["7h3w1z4rd"] = { "Moderator" },
["aldldl"] = { "Moderator" },
["arty714"] = { "Moderator" },
["AssemblyStorm"] = { "Moderator" },
["banakeg"] = { "Moderator" },
["connormkii"] = { "Moderator" },
["cydes"] = { "Moderator" },
["Cooldude2606"] = { "Moderator" },
["darklich14"] = { "Moderator" },
["Drahc_pro"] = { "Moderator" },
["facere"] = { "Moderator" },
["freek18"] = { "Moderator" },
["FlipHalfling90"] = { "Moderator" },
["Gizan"] = { "Moderator" },
["hamsterbryan"] = { "Moderator" },
["hidden_relic"] = { "Moderator" },
["Hova"] = { "Moderator" },
["HunterOfGames"] = { "Moderator" },
["LoicB"] = { "Moderator" },
["M74132"] = { "Moderator" },
["MadKatz"] = { "Moderator" },
["mafisch3"] = { "Moderator" },
["maplesyrup01"] = { "Moderator" },
["mark9064"] = { "Moderator" },
["nallaj"] = { "Moderator" },
["NextIdea"] = { "Moderator" },
["oof2win2"] = { "Moderator" },
["ookl"] = { "Moderator" },
["Phoenix27833"] = { "Moderator" },
["porelos"] = { "Moderator" },
["Ruuyji"] = { "Moderator" },
["samy115"] = { "Moderator" },
["SilentLog"] = { "Moderator" },
["Tcheko"] = { "Moderator" },
["thadius856"] = { "Moderator" },
["TheKernel32"] = { "Moderator" },
["TheKernel64"] = { "Moderator" },
["tovernaar123"] = { "Moderator" },
["UUBlueFire"] = { "Moderator" },
["whoami32"] = { "Moderator" },
["Windbomb"] = { "Moderator" },
["Windsinger"] = { "Moderator" },
["XenoCyber"] = { "Moderator" },
["Athenaa"] = { "Trainee Moderator" },
["hihicome3"] = { "Trainee Moderator" },
["JamesJung"] = { "Trainee Moderator" },
["konohaScarlet_"] = { "Trainee Moderator" },
["majoro"] = { "Trainee Moderator" },
["rongli"] = { "Trainee Moderator" },
}
@@ -1,8 +1,2 @@
return {
Cooldude2606 = "Lua lets you set metatables on numbers, did you know that? Cooldude2606 knows this.",
samy115 = "Tremble in fear as the banhammer is now here, its owner: samy115",
XenoCyber = '"Fire Fire Fire" oops wrong game, have no fear XenoCyber is here',
HunterOfGames = "Unable to support HunterOfGames. You must construct additional miners.",
ookl = 'ookl says: "Pineapples are amazing, hello everyone!"',
arty714 = "Arty\'s Potato made it!",
}
+43 -143
View File
@@ -4,10 +4,10 @@
return {
spawn_area = { --- @setting spawn_area Settings relating to the whole spawn area
-- Enable predefined patches: 128, else: 32
deconstruction_radius = 20, -- @setting deconstruction_radius All entities within this radius will be removed
tile_radius = 20,
deconstruction_tile = "concrete", --- @setting deconstruction_tile Tile to be placed in the deconstruction radius, use nil for map gen
landfill_radius = 50, --- @setting pattern_radius All water within this radius will be land filled
deconstruction_radius = 12, -- @setting deconstruction_radius All entities within this radius will be removed
deconstruction_tile = "refined-concrete", --- @setting deconstruction_tile Tile to be placed in the deconstruction radius, use nil for map gen
tile_radius = 14,
landfill_radius = 16, --- @setting pattern_radius All water within this radius will be land filled
},
turrets = { --- @setting turrets Settings relating to adding turrets to spawn
enabled = true, --- @setting enabled Whether turrets will be added to spawn
@@ -15,10 +15,10 @@ return {
refill_time = 60 * 60 * 5, --- @setting refill_time The time in ticks between each refill of the turrets, only change if having lag issues
offset = { x = 0, y = 0 }, --- @setting offset The position offset to apply to turrets
locations = { --- @setting locations The locations of all turrets, this list can change during runtime
{ -3, -3 },
{ 3, -3 },
{ -3, 3 },
{ 3, 3 },
{ -2, -2 },
{ 2, -2 },
{ -2, 2 },
{ 2, 2 },
},
},
afk_belts = { --- @setting afk_belts Settings relating to adding afk belts to spawn
@@ -27,9 +27,11 @@ return {
protected = true, --- @setting protected Whether belts will be protected from player interaction
offset = { x = 0, y = 0 }, --- @setting offset The position offset to apply to afk belts
locations = { --- @setting locations The locations to spawn afk belts at, given as the top left position
{ -5, -5 }, { 5, -5 },
{ -5, 5 }, { 5, 5 },
},
{ 4, 4 },
{ 4, -4 },
{ -4, 4 },
{ -4, -4 }
}
},
water = { --- @setting water Settings relating to adding water to spawn
enabled = true, --- @setting enabled Whether water tiles will be added to spawn
@@ -37,147 +39,45 @@ return {
offset = { x = 0, y = 0 }, --- @setting offset The position offset to apply to water tiles
locations = { --- @setting locations The location of the water tiles {x,y}
-- Each is a 3x3 with the closest tile to 0,0 removed
{ 7, 8 }, { 7, 9 }, { 8, 7 }, { 8, 8 }, { 8, 9 }, { 9, 7 }, { 9, 8 }, { 9, 9 }, -- Bottom Right
{ 7, -9 }, { 7, -10 }, { 8, -8 }, { 8, -9 }, { 8, -10 }, { 9, -8 }, { 9, -9 }, { 9, -10 }, -- Top Right
{ -8, -9 }, { -8, -10 }, { -9, -8 }, { -9, -9 }, { -9, -10 }, { -10, -8 }, { -10, -9 }, { -10, -10 }, -- Top Left
{ -8, 8 }, { -8, 9 }, { -9, 7 }, { -9, 8 }, { -9, 9 }, { -10, 7 }, { -10, 8 }, { -10, 9 }, -- Bottom Left
},
{ 5, 6 }, { 5, 7 }, { 6, 5 }, { 6, 6 }, { 6, 7 }, { 7, 5 }, { 7, 6 }, { 7, 7 },
{ 5, -7 }, { 5, -8 }, { 6, -6 }, { 6, -7 }, { 6, -8 }, { 7, -6 }, { 7, -7 }, { 7, -8 },
{ -6, 6 }, { -6, 7 }, { -7, 5 }, { -7, 6 }, { -7, 7 }, { -8, 5 }, { -8, 6 }, { -8, 7 },
{ -6, -7 }, { -6, -8 }, { -7, -6 }, { -7, -7 }, { -7, -8 }, { -8, -6 }, { -8, -7 }, { -8, -8 },
}
},
entities = { --- @setting entities Settings relating to adding entities to spawn
enabled = true, --- @setting enabled Whether entities will be added to spawn
protected = true, --- @setting protected Whether entities will be protected from player interaction
operable = true, --- @setting operable Whether entities can be opened by players, must be true if chests are used
offset = { x = 0, y = -2 }, --- @setting offset The position offset to apply to entities
offset = { x = 0, y = 0 }, --- @setting offset The position offset to apply to entities
locations = { --- @setting locations The location and names of entities {name,x,y}
{ "stone-wall", -10, -5 }, { "stone-wall", -10, -4 }, { "stone-wall", -10, -3 }, { "stone-wall", -10, -2 }, { "stone-wall", -10, -1 }, { "stone-wall", -10, 0 }, { "stone-wall", -10, 3 }, { "stone-wall", -10, 4 }, { "stone-wall", -10, 5 },
{ "stone-wall", -10, 6 }, { "stone-wall", -10, 7 }, { "stone-wall", -10, 8 }, { "small-lamp", -8, -4 }, { "small-lamp", -8, -1 }, { "iron-chest", -8, 0 }, { "iron-chest", -8, 3 }, { "small-lamp", -8, 4 },
{ "small-lamp", -8, 7 }, { "stone-wall", -7, -8 }, { "small-electric-pole", -7, -2 }, { "iron-chest", -7, 0 }, { "iron-chest", -7, 3 }, { "small-electric-pole", -7, 5 }, { "stone-wall", -7, 11 }, { "stone-wall", -6, -8 }, { "small-lamp", -6, -6 },
{ "iron-chest", -6, 0 }, { "iron-chest", -6, 3 }, { "small-lamp", -6, 9 }, { "stone-wall", -6, 11 }, { "stone-wall", -5, -8 }, { "small-lamp", -5, -1 }, { "iron-chest", -5, 0 }, { "iron-chest", -5, 3 }, { "small-lamp", -5, 4 }, { "stone-wall", -5, 11 },
{ "stone-wall", -4, -8 }, { "small-electric-pole", -4, -5 }, { "iron-chest", -4, 0 }, { "iron-chest", -4, 3 }, { "small-electric-pole", -4, 8 }, { "stone-wall", -4, 11 }, { "stone-wall", -3, -8 }, { "small-lamp", -3, -6 }, { "small-lamp", -3, -3 }, { "small-lamp", -3, 6 },
{ "small-lamp", -3, 9 }, { "stone-wall", -3, 11 }, { "stone-wall", -2, -8 }, { "iron-chest", -2, -6 }, { "iron-chest", -2, -5 }, { "iron-chest", -2, -4 }, { "iron-chest", -2, -3 }, { "iron-chest", -2, -2 }, { "iron-chest", -2, 5 }, { "iron-chest", -2, 6 },
{ "iron-chest", -2, 7 }, { "iron-chest", -2, 8 }, { "iron-chest", -2, 9 }, { "stone-wall", -2, 11 }, { "stone-wall", 1, -8 }, { "iron-chest", 1, -6 },
{ "iron-chest", 1, -5 }, { "iron-chest", 1, -4 }, { "iron-chest", 1, -3 }, { "iron-chest", 1, -2 }, { "iron-chest", 1, 5 }, { "iron-chest", 1, 6 }, { "iron-chest", 1, 7 }, { "iron-chest", 1, 8 }, { "iron-chest", 1, 9 }, { "stone-wall", 1, 11 },
{ "stone-wall", 2, -8 }, { "small-lamp", 2, -6 }, { "small-lamp", 2, -3 }, { "small-lamp", 2, 6 }, { "small-lamp", 2, 9 }, { "stone-wall", 2, 11 }, { "stone-wall", 3, -8 }, { "small-electric-pole", 3, -5 }, { "iron-chest", 3, 0 }, { "iron-chest", 3, 3 },
{ "small-electric-pole", 3, 8 }, { "stone-wall", 3, 11 }, { "stone-wall", 4, -8 }, { "small-lamp", 4, -1 }, { "iron-chest", 4, 0 }, { "iron-chest", 4, 3 }, { "small-lamp", 4, 4 }, { "stone-wall", 4, 11 }, { "stone-wall", 5, -8 }, { "small-lamp", 5, -6 },
{ "iron-chest", 5, 0 }, { "iron-chest", 5, 3 }, { "small-lamp", 5, 9 }, { "stone-wall", 5, 11 }, { "stone-wall", 6, -8 }, { "small-electric-pole", 6, -2 }, { "iron-chest", 6, 0 }, { "iron-chest", 6, 3 }, { "small-electric-pole", 6, 5 }, { "stone-wall", 6, 11 },
{ "small-lamp", 7, -4 }, { "small-lamp", 7, -1 }, { "iron-chest", 7, 0 }, { "iron-chest", 7, 3 }, { "small-lamp", 7, 4 }, { "small-lamp", 7, 7 }, { "stone-wall", 9, -5 },
{ "stone-wall", 9, -4 }, { "stone-wall", 9, -3 }, { "stone-wall", 9, -2 }, { "stone-wall", 9, -1 }, { "stone-wall", 9, 0 }, { "stone-wall", 9, 3 }, { "stone-wall", 9, 4 }, { "stone-wall", 9, 5 }, { "stone-wall", 9, 6 }, { "stone-wall", 9, 7 },
{ "stone-wall", 9, 8 },
},
{ "steel-chest", 1, 3 }, { "steel-chest", 1, 4 }, { "steel-chest", 1, 5 },
{ "steel-chest", 3, 1 }, { "steel-chest", 4, 1 }, { "steel-chest", 5, 1 },
{ "steel-chest", 1, -4 }, { "steel-chest", 1, -5 }, { "steel-chest", 1, -6 },
{ "steel-chest", 3, -2 }, { "steel-chest", 4, -2 }, { "steel-chest", 5, -2 },
{ "steel-chest", -2, 3 }, { "steel-chest", -2, 4 }, { "steel-chest", -2, 5 },
{ "steel-chest", -4, 1 }, { "steel-chest", -5, 1 }, { "steel-chest", -6, 1 },
{ "steel-chest", -2, -4 }, { "steel-chest", -2, -5 }, { "steel-chest", -2, -6 },
{ "steel-chest", -4, -2 }, { "steel-chest", -5, -2 }, { "steel-chest", -6, -2 },
{ "medium-electric-pole", 2, 3 }, { "medium-electric-pole", 2, -4 }, { "medium-electric-pole", -3, 3 }, { "medium-electric-pole", -3, -4 },
{ "small-lamp", 2, 4 }, { "small-lamp", 2, -5 }, { "small-lamp", -3, 4 }, { "small-lamp", -3, -5 },
{ "small-lamp", 4, 2 }, { "small-lamp", 4, -3 }, { "small-lamp", -5, 2 }, { "small-lamp", -5, -3 },
{ "stone-wall", 1, 7 }, { "stone-wall", 2, 7 }, { "stone-wall", 3, 7 }, { "stone-wall", 4, 7 },
{ "stone-wall", 7, 1 }, { "stone-wall", 7, 2 }, { "stone-wall", 7, 3 }, { "stone-wall", 7, 4 },
{ "stone-wall", 1, -8 }, { "stone-wall", 2, -8 }, { "stone-wall", 3, -8 }, { "stone-wall", 4, -8 },
{ "stone-wall", 7, -2 }, { "stone-wall", 7, -3 }, { "stone-wall", 7, -4 }, { "stone-wall", 7, -5 },
{ "stone-wall", -2, 7 }, { "stone-wall", -3, 7 }, { "stone-wall", -4, 7 }, { "stone-wall", -5, 7 },
{ "stone-wall", -8, 1 }, { "stone-wall", -8, 2 }, { "stone-wall", -8, 3 }, { "stone-wall", -8, 4 },
{ "stone-wall", -2, -8 }, { "stone-wall", -3, -8 }, { "stone-wall", -4, -8 }, { "stone-wall", -5, -8 },
{ "stone-wall", -8, -2 }, { "stone-wall", -8, -3 }, { "stone-wall", -8, -4 }, { "stone-wall", -8, -5 },
}
},
pattern = {
enabled = true, --- @setting enabled Whether pattern tiles will be added to spawn
pattern_tile = "stone-path", --- @setting pattern_tile The tile to be used for the pattern
offset = { x = 0, y = -2 }, --- @setting offset The position offset to apply to pattern tiles
enabled = false, --- @setting enabled Whether pattern tiles will be added to spawn
pattern_tile = "refined-concrete", --- @setting pattern_tile The tile to be used for the pattern
offset = { x = 0, y = 0 }, --- @setting offset The position offset to apply to pattern tiles
locations = { --- @setting locations The location of the pattern tiles {x,y}
{ -49, -3 }, { -49, -2 }, { -49, 1 }, { -49, 2 }, { -49, 5 }, { -49, 6 }, { -48, -4 }, { -48, -3 }, { -48, -2 }, { -48, 1 }, { -48, 2 }, { -48, 5 }, { -48, 6 }, { -48, 7 }, { -47, -7 }, { -47, -6 }, { -47, -5 }, { -47, -4 }, { -47, -3 }, { -47, -2 }, { -47, 5 }, { -47, 6 }, { -47, 7 }, { -47, 8 }, { -47, 9 }, { -47, 10 }, { -46, -8 }, { -46, -7 }, { -46, -6 }, { -46, -5 },
{ -46, -4 }, { -46, -3 }, { -46, -2 }, { -46, -1 }, { -46, 4 }, { -46, 5 }, { -46, 6 }, { -46, 7 }, { -46, 8 }, { -46, 9 }, { -46, 10 }, { -46, 11 }, { -45, -17 }, { -45, -16 }, { -45, -15 }, { -45, -14 }, { -45, -13 }, { -45, -12 }, { -45, -9 }, { -45, -8 }, { -45, -7 }, { -45, -2 }, { -45, -1 }, { -45, 0 }, { -45, 1 }, { -45, 2 }, { -45, 3 }, { -45, 4 }, { -45, 5 }, { -45, 10 },
{ -45, 11 }, { -45, 12 }, { -45, 15 }, { -45, 16 }, { -45, 17 }, { -45, 18 }, { -45, 19 }, { -45, 20 }, { -44, -18 }, { -44, -17 }, { -44, -16 }, { -44, -15 }, { -44, -14 }, { -44, -13 }, { -44, -12 }, { -44, -9 }, { -44, -8 }, { -44, -1 }, { -44, 0 }, { -44, 1 }, { -44, 2 }, { -44, 3 }, { -44, 4 }, { -44, 11 }, { -44, 12 }, { -44, 15 }, { -44, 16 }, { -44, 17 }, { -44, 18 }, { -44, 19 },
{ -44, 20 }, { -44, 21 }, { -43, -19 }, { -43, -18 }, { -43, -17 }, { -43, -1 }, { -43, 0 }, { -43, 1 }, { -43, 2 }, { -43, 3 }, { -43, 4 }, { -43, 20 }, { -43, 21 }, { -43, 22 }, { -42, -19 }, { -42, -18 }, { -42, -1 }, { -42, 0 }, { -42, 1 }, { -42, 2 }, { -42, 3 }, { -42, 4 }, { -42, 21 }, { -42, 22 }, { -41, -25 }, { -41, -24 }, { -41, -19 }, { -41, -18 }, { -41, -13 }, { -41, -12 },
{ -41, -11 }, { -41, -10 }, { -41, -5 }, { -41, -4 }, { -41, 7 }, { -41, 8 }, { -41, 13 }, { -41, 14 }, { -41, 15 }, { -41, 16 }, { -41, 21 }, { -41, 22 }, { -41, 27 }, { -41, 28 }, { -40, -26 }, { -40, -25 }, { -40, -24 }, { -40, -20 }, { -40, -19 }, { -40, -18 }, { -40, -13 }, { -40, -12 }, { -40, -11 }, { -40, -10 }, { -40, -5 }, { -40, -4 }, { -40, 7 }, { -40, 8 }, { -40, 13 }, { -40, 14 },
{ -40, 15 }, { -40, 16 }, { -40, 21 }, { -40, 22 }, { -40, 23 }, { -40, 27 }, { -40, 28 }, { -40, 29 }, { -39, -27 }, { -39, -26 }, { -39, -25 }, { -39, -24 }, { -39, -21 }, { -39, -20 }, { -39, -19 }, { -39, -13 }, { -39, -12 }, { -39, -5 }, { -39, -4 }, { -39, -3 }, { -39, -2 }, { -39, -1 }, { -39, 0 }, { -39, 1 }, { -39, 2 }, { -39, 3 }, { -39, 4 }, { -39, 5 }, { -39, 6 }, { -39, 7 },
{ -39, 8 }, { -39, 15 }, { -39, 16 }, { -39, 22 }, { -39, 23 }, { -39, 24 }, { -39, 27 }, { -39, 28 }, { -39, 29 }, { -39, 30 }, { -38, -27 }, { -38, -26 }, { -38, -25 }, { -38, -24 }, { -38, -21 }, { -38, -20 }, { -38, -13 }, { -38, -12 }, { -38, -5 }, { -38, -4 }, { -38, -3 }, { -38, -2 }, { -38, -1 }, { -38, 0 }, { -38, 1 }, { -38, 2 }, { -38, 3 }, { -38, 4 }, { -38, 5 }, { -38, 6 },
{ -38, 7 }, { -38, 8 }, { -38, 15 }, { -38, 16 }, { -38, 23 }, { -38, 24 }, { -38, 27 }, { -38, 28 }, { -38, 29 }, { -38, 30 }, { -37, -17 }, { -37, -16 }, { -37, -13 }, { -37, -12 }, { -37, -11 }, { -37, -10 }, { -37, -4 }, { -37, -3 }, { -37, -2 }, { -37, -1 }, { -37, 0 }, { -37, 3 }, { -37, 4 }, { -37, 5 }, { -37, 6 }, { -37, 7 }, { -37, 13 }, { -37, 14 }, { -37, 15 }, { -37, 16 },
{ -37, 19 }, { -37, 20 }, { -36, -17 }, { -36, -16 }, { -36, -13 }, { -36, -12 }, { -36, -11 }, { -36, -10 }, { -36, -9 }, { -36, -3 }, { -36, -2 }, { -36, -1 }, { -36, 0 }, { -36, 3 }, { -36, 4 }, { -36, 5 }, { -36, 6 }, { -36, 12 }, { -36, 13 }, { -36, 14 }, { -36, 15 }, { -36, 16 }, { -36, 19 }, { -36, 20 }, { -35, -29 }, { -35, -28 }, { -35, -23 }, { -35, -22 }, { -35, -17 }, { -35, -16 },
{ -35, -12 }, { -35, -11 }, { -35, -10 }, { -35, -9 }, { -35, -8 }, { -35, 11 }, { -35, 12 }, { -35, 13 }, { -35, 14 }, { -35, 15 }, { -35, 19 }, { -35, 20 }, { -35, 25 }, { -35, 26 }, { -35, 31 }, { -35, 32 }, { -34, -30 }, { -34, -29 }, { -34, -28 }, { -34, -23 }, { -34, -22 }, { -34, -17 }, { -34, -16 }, { -34, -15 }, { -34, -11 }, { -34, -10 }, { -34, -9 }, { -34, -8 }, { -34, 11 }, { -34, 12 },
{ -34, 13 }, { -34, 14 }, { -34, 18 }, { -34, 19 }, { -34, 20 }, { -34, 25 }, { -34, 26 }, { -34, 31 }, { -34, 32 }, { -34, 33 }, { -33, -31 }, { -33, -30 }, { -33, -29 }, { -33, -28 }, { -33, -23 }, { -33, -22 }, { -33, -16 }, { -33, -15 }, { -33, -14 }, { -33, -5 }, { -33, -4 }, { -33, -1 }, { -33, 0 }, { -33, 3 }, { -33, 4 }, { -33, 7 }, { -33, 8 }, { -33, 17 }, { -33, 18 }, { -33, 19 },
{ -33, 25 }, { -33, 26 }, { -33, 31 }, { -33, 32 }, { -33, 33 }, { -33, 34 }, { -32, -32 }, { -32, -31 }, { -32, -30 }, { -32, -29 }, { -32, -28 }, { -32, -27 }, { -32, -23 }, { -32, -22 }, { -32, -21 }, { -32, -15 }, { -32, -14 }, { -32, -6 }, { -32, -5 }, { -32, -4 }, { -32, -1 }, { -32, 0 }, { -32, 3 }, { -32, 4 }, { -32, 7 }, { -32, 8 }, { -32, 9 }, { -32, 17 }, { -32, 18 }, { -32, 24 },
{ -32, 25 }, { -32, 26 }, { -32, 30 }, { -32, 31 }, { -32, 32 }, { -32, 33 }, { -32, 34 }, { -32, 35 }, { -31, -33 }, { -31, -32 }, { -31, -31 }, { -31, -30 }, { -31, -29 }, { -31, -28 }, { -31, -27 }, { -31, -26 }, { -31, -22 }, { -31, -21 }, { -31, -20 }, { -31, -19 }, { -31, -18 }, { -31, -11 }, { -31, -10 }, { -31, -9 }, { -31, -8 }, { -31, -7 }, { -31, -6 }, { -31, -5 }, { -31, -1 }, { -31, 0 },
{ -31, 1 }, { -31, 2 }, { -31, 3 }, { -31, 4 }, { -31, 8 }, { -31, 9 }, { -31, 10 }, { -31, 11 }, { -31, 12 }, { -31, 13 }, { -31, 14 }, { -31, 21 }, { -31, 22 }, { -31, 23 }, { -31, 24 }, { -31, 25 }, { -31, 29 }, { -31, 30 }, { -31, 31 }, { -31, 32 }, { -31, 33 }, { -31, 34 }, { -31, 35 }, { -31, 36 }, { -30, -33 }, { -30, -32 }, { -30, -31 }, { -30, -30 }, { -30, -29 }, { -30, -28 },
{ -30, -27 }, { -30, -26 }, { -30, -21 }, { -30, -20 }, { -30, -19 }, { -30, -18 }, { -30, -11 }, { -30, -10 }, { -30, -9 }, { -30, -8 }, { -30, -7 }, { -30, -6 }, { -30, -1 }, { -30, 0 }, { -30, 1 }, { -30, 2 }, { -30, 3 }, { -30, 4 }, { -30, 9 }, { -30, 10 }, { -30, 11 }, { -30, 12 }, { -30, 13 }, { -30, 14 }, { -30, 21 }, { -30, 22 }, { -30, 23 }, { -30, 24 }, { -30, 29 }, { -30, 30 },
{ -30, 31 }, { -30, 32 }, { -30, 33 }, { -30, 34 }, { -30, 35 }, { -30, 36 }, { -29, -37 }, { -29, -36 }, { -29, -30 }, { -29, -29 }, { -29, -28 }, { -29, -27 }, { -29, -26 }, { -29, -15 }, { -29, -14 }, { -29, -10 }, { -29, -9 }, { -29, -8 }, { -29, -7 }, { -29, 10 }, { -29, 11 }, { -29, 12 }, { -29, 13 }, { -29, 17 }, { -29, 18 }, { -29, 29 }, { -29, 30 }, { -29, 31 }, { -29, 32 }, { -29, 33 },
{ -29, 39 }, { -29, 40 }, { -28, -38 }, { -28, -37 }, { -28, -36 }, { -28, -29 }, { -28, -28 }, { -28, -27 }, { -28, -26 }, { -28, -16 }, { -28, -15 }, { -28, -14 }, { -28, -9 }, { -28, -8 }, { -28, 11 }, { -28, 12 }, { -28, 17 }, { -28, 18 }, { -28, 19 }, { -28, 29 }, { -28, 30 }, { -28, 31 }, { -28, 32 }, { -28, 39 }, { -28, 40 }, { -28, 41 }, { -27, -39 }, { -27, -38 }, { -27, -37 }, { -27, -36 },
{ -27, -23 }, { -27, -22 }, { -27, -19 }, { -27, -18 }, { -27, -17 }, { -27, -16 }, { -27, -15 }, { -27, -5 }, { -27, -4 }, { -27, -1 }, { -27, 0 }, { -27, 1 }, { -27, 2 }, { -27, 3 }, { -27, 4 }, { -27, 7 }, { -27, 8 }, { -27, 18 }, { -27, 19 }, { -27, 20 }, { -27, 21 }, { -27, 22 }, { -27, 25 }, { -27, 26 }, { -27, 39 }, { -27, 40 }, { -27, 41 }, { -27, 42 }, { -26, -39 }, { -26, -38 },
{ -26, -37 }, { -26, -36 }, { -26, -24 }, { -26, -23 }, { -26, -22 }, { -26, -19 }, { -26, -18 }, { -26, -17 }, { -26, -16 }, { -26, -6 }, { -26, -5 }, { -26, -4 }, { -26, -1 }, { -26, 0 }, { -26, 1 }, { -26, 2 }, { -26, 3 }, { -26, 4 }, { -26, 7 }, { -26, 8 }, { -26, 9 }, { -26, 19 }, { -26, 20 }, { -26, 21 }, { -26, 22 }, { -26, 25 }, { -26, 26 }, { -26, 27 }, { -26, 39 }, { -26, 40 },
{ -26, 41 }, { -26, 42 }, { -25, -33 }, { -25, -32 }, { -25, -31 }, { -25, -30 }, { -25, -25 }, { -25, -24 }, { -25, -23 }, { -25, -22 }, { -25, -19 }, { -25, -18 }, { -25, -17 }, { -25, -9 }, { -25, -8 }, { -25, -7 }, { -25, -6 }, { -25, -5 }, { -25, -4 }, { -25, -1 }, { -25, 0 }, { -25, 1 }, { -25, 2 }, { -25, 3 }, { -25, 4 }, { -25, 7 }, { -25, 8 }, { -25, 9 }, { -25, 10 }, { -25, 11 },
{ -25, 12 }, { -25, 20 }, { -25, 21 }, { -25, 22 }, { -25, 25 }, { -25, 26 }, { -25, 27 }, { -25, 28 }, { -25, 33 }, { -25, 34 }, { -25, 35 }, { -25, 36 }, { -24, -33 }, { -24, -32 }, { -24, -31 }, { -24, -30 }, { -24, -29 }, { -24, -25 }, { -24, -24 }, { -24, -23 }, { -24, -22 }, { -24, -19 }, { -24, -18 }, { -24, -9 }, { -24, -8 }, { -24, -7 }, { -24, -6 }, { -24, -5 }, { -24, -4 }, { -24, -1 },
{ -24, 0 }, { -24, 1 }, { -24, 2 }, { -24, 3 }, { -24, 4 }, { -24, 7 }, { -24, 8 }, { -24, 9 }, { -24, 10 }, { -24, 11 }, { -24, 12 }, { -24, 21 }, { -24, 22 }, { -24, 25 }, { -24, 26 }, { -24, 27 }, { -24, 28 }, { -24, 32 }, { -24, 33 }, { -24, 34 }, { -24, 35 }, { -24, 36 }, { -23, -37 }, { -23, -36 }, { -23, -30 }, { -23, -29 }, { -23, -28 }, { -23, -19 }, { -23, -18 }, { -23, -15 },
{ -23, -14 }, { -23, -9 }, { -23, -8 }, { -23, -7 }, { -23, -6 }, { -23, -5 }, { -23, 0 }, { -23, 1 }, { -23, 2 }, { -23, 3 }, { -23, 8 }, { -23, 9 }, { -23, 10 }, { -23, 11 }, { -23, 12 }, { -23, 17 }, { -23, 18 }, { -23, 21 }, { -23, 22 }, { -23, 31 }, { -23, 32 }, { -23, 33 }, { -23, 39 }, { -23, 40 }, { -22, -38 }, { -22, -37 }, { -22, -36 }, { -22, -29 }, { -22, -28 }, { -22, -19 },
{ -22, -18 }, { -22, -15 }, { -22, -14 }, { -22, -13 }, { -22, -9 }, { -22, -8 }, { -22, -7 }, { -22, -6 }, { -22, 1 }, { -22, 2 }, { -22, 9 }, { -22, 10 }, { -22, 11 }, { -22, 12 }, { -22, 16 }, { -22, 17 }, { -22, 18 }, { -22, 21 }, { -22, 22 }, { -22, 31 }, { -22, 32 }, { -22, 39 }, { -22, 40 }, { -22, 41 }, { -21, -41 }, { -21, -40 }, { -21, -39 }, { -21, -38 }, { -21, -37 }, { -21, -29 },
{ -21, -28 }, { -21, -25 }, { -21, -24 }, { -21, -23 }, { -21, -22 }, { -21, -21 }, { -21, -20 }, { -21, -19 }, { -21, -18 }, { -21, -15 }, { -21, -14 }, { -21, -13 }, { -21, -12 }, { -21, -3 }, { -21, -2 }, { -21, 5 }, { -21, 6 }, { -21, 15 }, { -21, 16 }, { -21, 17 }, { -21, 18 }, { -21, 21 }, { -21, 22 }, { -21, 23 }, { -21, 24 }, { -21, 25 }, { -21, 26 }, { -21, 27 }, { -21, 28 }, { -21, 31 },
{ -21, 32 }, { -21, 40 }, { -21, 41 }, { -21, 42 }, { -21, 43 }, { -21, 44 }, { -20, -42 }, { -20, -41 }, { -20, -40 }, { -20, -39 }, { -20, -38 }, { -20, -29 }, { -20, -28 }, { -20, -25 }, { -20, -24 }, { -20, -23 }, { -20, -22 }, { -20, -21 }, { -20, -20 }, { -20, -19 }, { -20, -18 }, { -20, -15 }, { -20, -14 }, { -20, -13 }, { -20, -12 }, { -20, -3 }, { -20, -2 }, { -20, -1 }, { -20, 4 }, { -20, 5 },
{ -20, 6 }, { -20, 15 }, { -20, 16 }, { -20, 17 }, { -20, 18 }, { -20, 21 }, { -20, 22 }, { -20, 23 }, { -20, 24 }, { -20, 25 }, { -20, 26 }, { -20, 27 }, { -20, 28 }, { -20, 31 }, { -20, 32 }, { -20, 41 }, { -20, 42 }, { -20, 43 }, { -20, 44 }, { -20, 45 }, { -19, -43 }, { -19, -42 }, { -19, -41 }, { -19, -35 }, { -19, -34 }, { -19, -33 }, { -19, -32 }, { -19, -25 }, { -19, -24 }, { -19, -23 },
{ -19, -15 }, { -19, -14 }, { -19, -13 }, { -19, -9 }, { -19, -8 }, { -19, -7 }, { -19, -6 }, { -19, -2 }, { -19, -1 }, { -19, 0 }, { -19, 1 }, { -19, 2 }, { -19, 3 }, { -19, 4 }, { -19, 5 }, { -19, 9 }, { -19, 10 }, { -19, 11 }, { -19, 12 }, { -19, 16 }, { -19, 17 }, { -19, 18 }, { -19, 26 }, { -19, 27 }, { -19, 28 }, { -19, 35 }, { -19, 36 }, { -19, 37 }, { -19, 38 }, { -19, 44 },
{ -19, 45 }, { -19, 46 }, { -18, -43 }, { -18, -42 }, { -18, -35 }, { -18, -34 }, { -18, -33 }, { -18, -32 }, { -18, -31 }, { -18, -26 }, { -18, -25 }, { -18, -24 }, { -18, -15 }, { -18, -14 }, { -18, -10 }, { -18, -9 }, { -18, -8 }, { -18, -7 }, { -18, -6 }, { -18, -1 }, { -18, 0 }, { -18, 1 }, { -18, 2 }, { -18, 3 }, { -18, 4 }, { -18, 9 }, { -18, 10 }, { -18, 11 }, { -18, 12 }, { -18, 13 },
{ -18, 17 }, { -18, 18 }, { -18, 27 }, { -18, 28 }, { -18, 29 }, { -18, 34 }, { -18, 35 }, { -18, 36 }, { -18, 37 }, { -18, 38 }, { -18, 45 }, { -18, 46 }, { -17, -43 }, { -17, -42 }, { -17, -32 }, { -17, -31 }, { -17, -30 }, { -17, -27 }, { -17, -26 }, { -17, -25 }, { -17, -21 }, { -17, -20 }, { -17, -19 }, { -17, -18 }, { -17, -17 }, { -17, -16 }, { -17, -15 }, { -17, -14 }, { -17, -11 }, { -17, -10 },
{ -17, -9 }, { -17, -8 }, { -17, -7 }, { -17, -6 }, { -17, 0 }, { -17, 1 }, { -17, 2 }, { -17, 3 }, { -17, 9 }, { -17, 10 }, { -17, 11 }, { -17, 12 }, { -17, 13 }, { -17, 14 }, { -17, 17 }, { -17, 18 }, { -17, 19 }, { -17, 20 }, { -17, 21 }, { -17, 22 }, { -17, 23 }, { -17, 24 }, { -17, 28 }, { -17, 29 }, { -17, 30 }, { -17, 33 }, { -17, 34 }, { -17, 35 }, { -17, 45 }, { -17, 46 },
{ -16, -43 }, { -16, -42 }, { -16, -31 }, { -16, -30 }, { -16, -27 }, { -16, -26 }, { -16, -21 }, { -16, -20 }, { -16, -19 }, { -16, -18 }, { -16, -17 }, { -16, -16 }, { -16, -15 }, { -16, -14 }, { -16, -11 }, { -16, -10 }, { -16, -9 }, { -16, -8 }, { -16, -7 }, { -16, -6 }, { -16, 1 }, { -16, 2 }, { -16, 9 }, { -16, 10 }, { -16, 11 }, { -16, 12 }, { -16, 13 }, { -16, 14 }, { -16, 17 }, { -16, 18 },
{ -16, 19 }, { -16, 20 }, { -16, 21 }, { -16, 22 }, { -16, 23 }, { -16, 24 }, { -16, 29 }, { -16, 30 }, { -16, 33 }, { -16, 34 }, { -16, 45 }, { -16, 46 }, { -15, -43 }, { -15, -42 }, { -15, -39 }, { -15, -38 }, { -15, -37 }, { -15, -36 }, { -15, -35 }, { -15, -34 }, { -15, -20 }, { -15, -19 }, { -15, -18 }, { -15, -17 }, { -15, -10 }, { -15, -9 }, { -15, -8 }, { -15, -7 }, { -15, -3 }, { -15, -2 },
{ -15, 1 }, { -15, 2 }, { -15, 5 }, { -15, 6 }, { -15, 10 }, { -15, 11 }, { -15, 12 }, { -15, 13 }, { -15, 20 }, { -15, 21 }, { -15, 22 }, { -15, 23 }, { -15, 37 }, { -15, 38 }, { -15, 39 }, { -15, 40 }, { -15, 41 }, { -15, 42 }, { -15, 45 }, { -15, 46 }, { -14, -43 }, { -14, -42 }, { -14, -39 }, { -14, -38 }, { -14, -37 }, { -14, -36 }, { -14, -35 }, { -14, -34 }, { -14, -33 }, { -14, -19 },
{ -14, -18 }, { -14, -9 }, { -14, -8 }, { -14, -4 }, { -14, -3 }, { -14, -2 }, { -14, 1 }, { -14, 2 }, { -14, 5 }, { -14, 6 }, { -14, 7 }, { -14, 11 }, { -14, 12 }, { -14, 21 }, { -14, 22 }, { -14, 36 }, { -14, 37 }, { -14, 38 }, { -14, 39 }, { -14, 40 }, { -14, 41 }, { -14, 42 }, { -14, 45 }, { -14, 46 }, { -13, -39 }, { -13, -38 }, { -13, -35 }, { -13, -34 }, { -13, -33 }, { -13, -32 },
{ -13, -29 }, { -13, -28 }, { -13, -15 }, { -13, -14 }, { -13, -5 }, { -13, -4 }, { -13, -3 }, { -13, -2 }, { -13, 5 }, { -13, 6 }, { -13, 7 }, { -13, 8 }, { -13, 17 }, { -13, 18 }, { -13, 31 }, { -13, 32 }, { -13, 35 }, { -13, 36 }, { -13, 37 }, { -13, 38 }, { -13, 41 }, { -13, 42 }, { -12, -39 }, { -12, -38 }, { -12, -35 }, { -12, -34 }, { -12, -33 }, { -12, -32 }, { -12, -29 }, { -12, -28 },
{ -12, -27 }, { -12, -16 }, { -12, -15 }, { -12, -14 }, { -12, -13 }, { -12, -5 }, { -12, -4 }, { -12, -3 }, { -12, -2 }, { -12, 5 }, { -12, 6 }, { -12, 7 }, { -12, 8 }, { -12, 16 }, { -12, 17 }, { -12, 18 }, { -12, 19 }, { -12, 30 }, { -12, 31 }, { -12, 32 }, { -12, 35 }, { -12, 36 }, { -12, 37 }, { -12, 38 }, { -12, 41 }, { -12, 42 }, { -11, -43 }, { -11, -42 }, { -11, -34 }, { -11, -33 },
{ -11, -32 }, { -11, -29 }, { -11, -28 }, { -11, -27 }, { -11, -26 }, { -11, -23 }, { -11, -22 }, { -11, -21 }, { -11, -20 }, { -11, -17 }, { -11, -16 }, { -11, -15 }, { -11, -14 }, { -11, -13 }, { -11, -12 }, { -11, -9 }, { -11, -8 }, { -11, 1 }, { -11, 2 }, { -11, 11 }, { -11, 12 }, { -11, 15 }, { -11, 16 }, { -11, 17 }, { -11, 18 }, { -11, 19 }, { -11, 20 }, { -11, 23 }, { -11, 24 }, { -11, 25 },
{ -11, 26 }, { -11, 29 }, { -11, 30 }, { -11, 31 }, { -11, 32 }, { -11, 35 }, { -11, 36 }, { -11, 37 }, { -11, 45 }, { -11, 46 }, { -10, -44 }, { -10, -43 }, { -10, -42 }, { -10, -33 }, { -10, -32 }, { -10, -29 }, { -10, -28 }, { -10, -27 }, { -10, -26 }, { -10, -23 }, { -10, -22 }, { -10, -21 }, { -10, -20 }, { -10, -17 }, { -10, -16 }, { -10, -15 }, { -10, -14 }, { -10, -13 }, { -10, -12 }, { -10, -9 },
{ -10, -8 }, { -10, -7 }, { -10, 0 }, { -10, 1 }, { -10, 2 }, { -10, 3 }, { -10, 10 }, { -10, 11 }, { -10, 12 }, { -10, 15 }, { -10, 16 }, { -10, 17 }, { -10, 18 }, { -10, 19 }, { -10, 20 }, { -10, 23 }, { -10, 24 }, { -10, 25 }, { -10, 26 }, { -10, 29 }, { -10, 30 }, { -10, 31 }, { -10, 32 }, { -10, 35 }, { -10, 36 }, { -10, 45 }, { -10, 46 }, { -10, 47 }, { -9, -45 }, { -9, -44 },
{ -9, -43 }, { -9, -29 }, { -9, -28 }, { -9, -27 }, { -9, -23 }, { -9, -22 }, { -9, -21 }, { -9, -20 }, { -9, -17 }, { -9, -16 }, { -9, -15 }, { -9, -14 }, { -9, -13 }, { -9, -8 }, { -9, -7 }, { -9, -6 }, { -9, -5 }, { -9, -1 }, { -9, 0 }, { -9, 1 }, { -9, 2 }, { -9, 3 }, { -9, 4 }, { -9, 8 }, { -9, 9 }, { -9, 10 }, { -9, 11 }, { -9, 16 }, { -9, 17 }, { -9, 18 },
{ -9, 19 }, { -9, 20 }, { -9, 23 }, { -9, 24 }, { -9, 25 }, { -9, 26 }, { -9, 30 }, { -9, 31 }, { -9, 32 }, { -9, 46 }, { -9, 47 }, { -9, 48 }, { -8, -45 }, { -8, -44 }, { -8, -30 }, { -8, -29 }, { -8, -28 }, { -8, -24 }, { -8, -23 }, { -8, -22 }, { -8, -21 }, { -8, -20 }, { -8, -17 }, { -8, -16 }, { -8, -15 }, { -8, -14 }, { -8, -7 }, { -8, -6 }, { -8, -5 }, { -8, -4 },
{ -8, -1 }, { -8, 0 }, { -8, 1 }, { -8, 2 }, { -8, 3 }, { -8, 4 }, { -8, 7 }, { -8, 8 }, { -8, 9 }, { -8, 10 }, { -8, 17 }, { -8, 18 }, { -8, 19 }, { -8, 20 }, { -8, 23 }, { -8, 24 }, { -8, 25 }, { -8, 26 }, { -8, 27 }, { -8, 31 }, { -8, 32 }, { -8, 33 }, { -8, 47 }, { -8, 48 }, { -7, -45 }, { -7, -44 }, { -7, -39 }, { -7, -38 }, { -7, -37 }, { -7, -36 },
{ -7, -31 }, { -7, -30 }, { -7, -29 }, { -7, -25 }, { -7, -24 }, { -7, -23 }, { -7, -22 }, { -7, -21 }, { -7, -11 }, { -7, -10 }, { -7, -7 }, { -7, -6 }, { -7, -5 }, { -7, -4 }, { -7, 7 }, { -7, 8 }, { -7, 9 }, { -7, 10 }, { -7, 13 }, { -7, 14 }, { -7, 24 }, { -7, 25 }, { -7, 26 }, { -7, 27 }, { -7, 28 }, { -7, 32 }, { -7, 33 }, { -7, 34 }, { -7, 39 }, { -7, 40 },
{ -7, 41 }, { -7, 42 }, { -7, 47 }, { -7, 48 }, { -6, -46 }, { -6, -45 }, { -6, -44 }, { -6, -39 }, { -6, -38 }, { -6, -37 }, { -6, -36 }, { -6, -35 }, { -6, -31 }, { -6, -30 }, { -6, -25 }, { -6, -24 }, { -6, -23 }, { -6, -22 }, { -6, -12 }, { -6, -11 }, { -6, -10 }, { -6, -6 }, { -6, -5 }, { -6, 8 }, { -6, 9 }, { -6, 13 }, { -6, 14 }, { -6, 15 }, { -6, 25 }, { -6, 26 },
{ -6, 27 }, { -6, 28 }, { -6, 33 }, { -6, 34 }, { -6, 38 }, { -6, 39 }, { -6, 40 }, { -6, 41 }, { -6, 42 }, { -6, 47 }, { -6, 48 }, { -6, 49 }, { -5, -47 }, { -5, -46 }, { -5, -45 }, { -5, -44 }, { -5, -37 }, { -5, -36 }, { -5, -35 }, { -5, -34 }, { -5, -19 }, { -5, -18 }, { -5, -13 }, { -5, -12 }, { -5, -11 }, { -5, -10 }, { -5, -1 }, { -5, 0 }, { -5, 1 }, { -5, 2 },
{ -5, 3 }, { -5, 4 }, { -5, 13 }, { -5, 14 }, { -5, 15 }, { -5, 16 }, { -5, 21 }, { -5, 22 }, { -5, 37 }, { -5, 38 }, { -5, 39 }, { -5, 40 }, { -5, 47 }, { -5, 48 }, { -5, 49 }, { -5, 50 }, { -4, -47 }, { -4, -46 }, { -4, -45 }, { -4, -44 }, { -4, -43 }, { -4, -37 }, { -4, -36 }, { -4, -35 }, { -4, -34 }, { -4, -19 }, { -4, -18 }, { -4, -17 }, { -4, -13 }, { -4, -12 },
{ -4, -11 }, { -4, -10 }, { -4, -2 }, { -4, -1 }, { -4, 0 }, { -4, 1 }, { -4, 2 }, { -4, 3 }, { -4, 4 }, { -4, 5 }, { -4, 13 }, { -4, 14 }, { -4, 15 }, { -4, 16 }, { -4, 20 }, { -4, 21 }, { -4, 22 }, { -4, 37 }, { -4, 38 }, { -4, 39 }, { -4, 40 }, { -4, 46 }, { -4, 47 }, { -4, 48 }, { -4, 49 }, { -4, 50 }, { -3, -44 }, { -3, -43 }, { -3, -42 }, { -3, -41 },
{ -3, -40 }, { -3, -37 }, { -3, -36 }, { -3, -35 }, { -3, -34 }, { -3, -31 }, { -3, -30 }, { -3, -29 }, { -3, -28 }, { -3, -25 }, { -3, -24 }, { -3, -23 }, { -3, -22 }, { -3, -18 }, { -3, -17 }, { -3, -16 }, { -3, -7 }, { -3, -6 }, { -3, -3 }, { -3, -2 }, { -3, -1 }, { -3, 0 }, { -3, 3 }, { -3, 4 }, { -3, 5 }, { -3, 6 }, { -3, 9 }, { -3, 10 }, { -3, 19 }, { -3, 20 },
{ -3, 21 }, { -3, 25 }, { -3, 26 }, { -3, 27 }, { -3, 28 }, { -3, 31 }, { -3, 32 }, { -3, 33 }, { -3, 34 }, { -3, 37 }, { -3, 38 }, { -3, 39 }, { -3, 40 }, { -3, 43 }, { -3, 44 }, { -3, 45 }, { -3, 46 }, { -3, 47 }, { -2, -43 }, { -2, -42 }, { -2, -41 }, { -2, -40 }, { -2, -37 }, { -2, -36 }, { -2, -35 }, { -2, -34 }, { -2, -31 }, { -2, -30 }, { -2, -29 }, { -2, -28 },
{ -2, -25 }, { -2, -24 }, { -2, -23 }, { -2, -22 }, { -2, -21 }, { -2, -17 }, { -2, -16 }, { -2, -15 }, { -2, -8 }, { -2, -7 }, { -2, -6 }, { -2, -3 }, { -2, -2 }, { -2, -1 }, { -2, 0 }, { -2, 3 }, { -2, 4 }, { -2, 5 }, { -2, 6 }, { -2, 9 }, { -2, 10 }, { -2, 11 }, { -2, 18 }, { -2, 19 }, { -2, 20 }, { -2, 24 }, { -2, 25 }, { -2, 26 }, { -2, 27 }, { -2, 28 },
{ -2, 31 }, { -2, 32 }, { -2, 33 }, { -2, 34 }, { -2, 37 }, { -2, 38 }, { -2, 39 }, { -2, 40 }, { -2, 43 }, { -2, 44 }, { -2, 45 }, { -2, 46 }, { -1, -47 }, { -1, -46 }, { -1, -43 }, { -1, -42 }, { -1, -41 }, { -1, -40 }, { -1, -37 }, { -1, -36 }, { -1, -29 }, { -1, -28 }, { -1, -25 }, { -1, -24 }, { -1, -23 }, { -1, -22 }, { -1, -21 }, { -1, -20 }, { -1, -17 }, { -1, -16 },
{ -1, -15 }, { -1, -14 }, { -1, -13 }, { -1, -12 }, { -1, -9 }, { -1, -8 }, { -1, -7 }, { -1, -6 }, { -1, -3 }, { -1, -2 }, { -1, 5 }, { -1, 6 }, { -1, 9 }, { -1, 10 }, { -1, 11 }, { -1, 12 }, { -1, 15 }, { -1, 16 }, { -1, 17 }, { -1, 18 }, { -1, 19 }, { -1, 20 }, { -1, 23 }, { -1, 24 }, { -1, 25 }, { -1, 26 }, { -1, 27 }, { -1, 28 }, { -1, 31 }, { -1, 32 },
{ -1, 39 }, { -1, 40 }, { -1, 43 }, { -1, 44 }, { -1, 45 }, { -1, 46 }, { -1, 49 }, { -1, 50 }, { 0, -47 }, { 0, -46 }, { 0, -43 }, { 0, -42 }, { 0, -41 }, { 0, -40 }, { 0, -37 }, { 0, -36 }, { 0, -29 }, { 0, -28 }, { 0, -25 }, { 0, -24 }, { 0, -23 }, { 0, -22 }, { 0, -21 }, { 0, -20 }, { 0, -17 }, { 0, -16 }, { 0, -15 }, { 0, -14 }, { 0, -13 }, { 0, -12 },
{ 0, -9 }, { 0, -8 }, { 0, -7 }, { 0, -6 }, { 0, -3 }, { 0, -2 }, { 0, 5 }, { 0, 6 }, { 0, 9 }, { 0, 10 }, { 0, 11 }, { 0, 12 }, { 0, 15 }, { 0, 16 }, { 0, 17 }, { 0, 18 }, { 0, 19 }, { 0, 20 }, { 0, 23 }, { 0, 24 }, { 0, 25 }, { 0, 26 }, { 0, 27 }, { 0, 28 }, { 0, 31 }, { 0, 32 }, { 0, 39 }, { 0, 40 }, { 0, 43 }, { 0, 44 },
{ 0, 45 }, { 0, 46 }, { 0, 49 }, { 0, 50 }, { 1, -43 }, { 1, -42 }, { 1, -41 }, { 1, -40 }, { 1, -37 }, { 1, -36 }, { 1, -35 }, { 1, -34 }, { 1, -31 }, { 1, -30 }, { 1, -29 }, { 1, -28 }, { 1, -25 }, { 1, -24 }, { 1, -23 }, { 1, -22 }, { 1, -21 }, { 1, -17 }, { 1, -16 }, { 1, -15 }, { 1, -8 }, { 1, -7 }, { 1, -6 }, { 1, -3 }, { 1, -2 }, { 1, -1 },
{ 1, 0 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 9 }, { 1, 10 }, { 1, 11 }, { 1, 18 }, { 1, 19 }, { 1, 20 }, { 1, 24 }, { 1, 25 }, { 1, 26 }, { 1, 27 }, { 1, 28 }, { 1, 31 }, { 1, 32 }, { 1, 33 }, { 1, 34 }, { 1, 37 }, { 1, 38 }, { 1, 39 }, { 1, 40 }, { 1, 43 }, { 1, 44 }, { 1, 45 }, { 1, 46 }, { 2, -44 }, { 2, -43 },
{ 2, -42 }, { 2, -41 }, { 2, -40 }, { 2, -37 }, { 2, -36 }, { 2, -35 }, { 2, -34 }, { 2, -31 }, { 2, -30 }, { 2, -29 }, { 2, -28 }, { 2, -25 }, { 2, -24 }, { 2, -23 }, { 2, -22 }, { 2, -18 }, { 2, -17 }, { 2, -16 }, { 2, -7 }, { 2, -6 }, { 2, -3 }, { 2, -2 }, { 2, -1 }, { 2, 0 }, { 2, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }, { 2, 9 }, { 2, 10 },
{ 2, 19 }, { 2, 20 }, { 2, 21 }, { 2, 25 }, { 2, 26 }, { 2, 27 }, { 2, 28 }, { 2, 31 }, { 2, 32 }, { 2, 33 }, { 2, 34 }, { 2, 37 }, { 2, 38 }, { 2, 39 }, { 2, 40 }, { 2, 43 }, { 2, 44 }, { 2, 45 }, { 2, 46 }, { 2, 47 }, { 3, -47 }, { 3, -46 }, { 3, -45 }, { 3, -44 }, { 3, -43 }, { 3, -37 }, { 3, -36 }, { 3, -35 }, { 3, -34 }, { 3, -19 },
{ 3, -18 }, { 3, -17 }, { 3, -13 }, { 3, -12 }, { 3, -11 }, { 3, -10 }, { 3, -2 }, { 3, -1 }, { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 13 }, { 3, 14 }, { 3, 15 }, { 3, 16 }, { 3, 20 }, { 3, 21 }, { 3, 22 }, { 3, 37 }, { 3, 38 }, { 3, 39 }, { 3, 40 }, { 3, 46 }, { 3, 47 }, { 3, 48 }, { 3, 49 }, { 3, 50 },
{ 4, -47 }, { 4, -46 }, { 4, -45 }, { 4, -44 }, { 4, -37 }, { 4, -36 }, { 4, -35 }, { 4, -34 }, { 4, -19 }, { 4, -18 }, { 4, -13 }, { 4, -12 }, { 4, -11 }, { 4, -10 }, { 4, -1 }, { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 4 }, { 4, 13 }, { 4, 14 }, { 4, 15 }, { 4, 16 }, { 4, 21 }, { 4, 22 }, { 4, 37 }, { 4, 38 }, { 4, 39 }, { 4, 40 },
{ 4, 47 }, { 4, 48 }, { 4, 49 }, { 4, 50 }, { 5, -46 }, { 5, -45 }, { 5, -44 }, { 5, -39 }, { 5, -38 }, { 5, -37 }, { 5, -36 }, { 5, -35 }, { 5, -31 }, { 5, -30 }, { 5, -25 }, { 5, -24 }, { 5, -23 }, { 5, -22 }, { 5, -12 }, { 5, -11 }, { 5, -10 }, { 5, -6 }, { 5, -5 }, { 5, 8 }, { 5, 9 }, { 5, 13 }, { 5, 14 }, { 5, 15 }, { 5, 25 }, { 5, 26 },
{ 5, 27 }, { 5, 28 }, { 5, 33 }, { 5, 34 }, { 5, 38 }, { 5, 39 }, { 5, 40 }, { 5, 41 }, { 5, 42 }, { 5, 47 }, { 5, 48 }, { 5, 49 }, { 6, -45 }, { 6, -44 }, { 6, -39 }, { 6, -38 }, { 6, -37 }, { 6, -36 }, { 6, -31 }, { 6, -30 }, { 6, -29 }, { 6, -25 }, { 6, -24 }, { 6, -23 }, { 6, -22 }, { 6, -21 }, { 6, -11 }, { 6, -10 }, { 6, -7 }, { 6, -6 },
{ 6, -5 }, { 6, -4 }, { 6, 7 }, { 6, 8 }, { 6, 9 }, { 6, 10 }, { 6, 13 }, { 6, 14 }, { 6, 24 }, { 6, 25 }, { 6, 26 }, { 6, 27 }, { 6, 28 }, { 6, 32 }, { 6, 33 }, { 6, 34 }, { 6, 39 }, { 6, 40 }, { 6, 41 }, { 6, 42 }, { 6, 47 }, { 6, 48 }, { 7, -45 }, { 7, -44 }, { 7, -30 }, { 7, -29 }, { 7, -28 }, { 7, -24 }, { 7, -23 }, { 7, -22 },
{ 7, -21 }, { 7, -20 }, { 7, -17 }, { 7, -16 }, { 7, -15 }, { 7, -14 }, { 7, -7 }, { 7, -6 }, { 7, -5 }, { 7, -4 }, { 7, -1 }, { 7, 0 }, { 7, 1 }, { 7, 2 }, { 7, 3 }, { 7, 4 }, { 7, 7 }, { 7, 8 }, { 7, 9 }, { 7, 10 }, { 7, 17 }, { 7, 18 }, { 7, 19 }, { 7, 20 }, { 7, 23 }, { 7, 24 }, { 7, 25 }, { 7, 26 }, { 7, 27 }, { 7, 31 },
{ 7, 32 }, { 7, 33 }, { 7, 47 }, { 7, 48 }, { 8, -45 }, { 8, -44 }, { 8, -43 }, { 8, -29 }, { 8, -28 }, { 8, -27 }, { 8, -23 }, { 8, -22 }, { 8, -21 }, { 8, -20 }, { 8, -17 }, { 8, -16 }, { 8, -15 }, { 8, -14 }, { 8, -13 }, { 8, -8 }, { 8, -7 }, { 8, -6 }, { 8, -5 }, { 8, -1 }, { 8, 0 }, { 8, 1 }, { 8, 2 }, { 8, 3 }, { 8, 4 }, { 8, 8 },
{ 8, 9 }, { 8, 10 }, { 8, 11 }, { 8, 16 }, { 8, 17 }, { 8, 18 }, { 8, 19 }, { 8, 20 }, { 8, 23 }, { 8, 24 }, { 8, 25 }, { 8, 26 }, { 8, 30 }, { 8, 31 }, { 8, 32 }, { 8, 46 }, { 8, 47 }, { 8, 48 }, { 9, -44 }, { 9, -43 }, { 9, -42 }, { 9, -33 }, { 9, -32 }, { 9, -29 }, { 9, -28 }, { 9, -27 }, { 9, -26 }, { 9, -23 }, { 9, -22 }, { 9, -21 },
{ 9, -20 }, { 9, -17 }, { 9, -16 }, { 9, -15 }, { 9, -14 }, { 9, -13 }, { 9, -12 }, { 9, -9 }, { 9, -8 }, { 9, -7 }, { 9, 0 }, { 9, 1 }, { 9, 2 }, { 9, 3 }, { 9, 10 }, { 9, 11 }, { 9, 12 }, { 9, 15 }, { 9, 16 }, { 9, 17 }, { 9, 18 }, { 9, 19 }, { 9, 20 }, { 9, 23 }, { 9, 24 }, { 9, 25 }, { 9, 26 }, { 9, 29 }, { 9, 30 }, { 9, 31 },
{ 9, 32 }, { 9, 35 }, { 9, 36 }, { 9, 45 }, { 9, 46 }, { 9, 47 }, { 10, -43 }, { 10, -42 }, { 10, -34 }, { 10, -33 }, { 10, -32 }, { 10, -29 }, { 10, -28 }, { 10, -27 }, { 10, -26 }, { 10, -23 }, { 10, -22 }, { 10, -21 }, { 10, -20 }, { 10, -17 }, { 10, -16 }, { 10, -15 }, { 10, -14 }, { 10, -13 }, { 10, -12 }, { 10, -9 }, { 10, -8 }, { 10, 1 }, { 10, 2 }, { 10, 11 },
{ 10, 12 }, { 10, 15 }, { 10, 16 }, { 10, 17 }, { 10, 18 }, { 10, 19 }, { 10, 20 }, { 10, 23 }, { 10, 24 }, { 10, 25 }, { 10, 26 }, { 10, 29 }, { 10, 30 }, { 10, 31 }, { 10, 32 }, { 10, 35 }, { 10, 36 }, { 10, 37 }, { 10, 45 }, { 10, 46 }, { 11, -39 }, { 11, -38 }, { 11, -35 }, { 11, -34 }, { 11, -33 }, { 11, -32 }, { 11, -29 }, { 11, -28 }, { 11, -27 }, { 11, -16 },
{ 11, -15 }, { 11, -14 }, { 11, -13 }, { 11, -5 }, { 11, -4 }, { 11, -3 }, { 11, -2 }, { 11, 5 }, { 11, 6 }, { 11, 7 }, { 11, 8 }, { 11, 16 }, { 11, 17 }, { 11, 18 }, { 11, 19 }, { 11, 30 }, { 11, 31 }, { 11, 32 }, { 11, 35 }, { 11, 36 }, { 11, 37 }, { 11, 38 }, { 11, 41 }, { 11, 42 }, { 12, -39 }, { 12, -38 }, { 12, -35 }, { 12, -34 }, { 12, -33 }, { 12, -32 },
{ 12, -29 }, { 12, -28 }, { 12, -15 }, { 12, -14 }, { 12, -5 }, { 12, -4 }, { 12, -3 }, { 12, -2 }, { 12, 5 }, { 12, 6 }, { 12, 7 }, { 12, 8 }, { 12, 17 }, { 12, 18 }, { 12, 31 }, { 12, 32 }, { 12, 35 }, { 12, 36 }, { 12, 37 }, { 12, 38 }, { 12, 41 }, { 12, 42 }, { 13, -43 }, { 13, -42 }, { 13, -39 }, { 13, -38 }, { 13, -37 }, { 13, -36 }, { 13, -35 }, { 13, -34 },
{ 13, -33 }, { 13, -19 }, { 13, -18 }, { 13, -9 }, { 13, -8 }, { 13, -4 }, { 13, -3 }, { 13, -2 }, { 13, 1 }, { 13, 2 }, { 13, 5 }, { 13, 6 }, { 13, 7 }, { 13, 11 }, { 13, 12 }, { 13, 21 }, { 13, 22 }, { 13, 36 }, { 13, 37 }, { 13, 38 }, { 13, 39 }, { 13, 40 }, { 13, 41 }, { 13, 42 }, { 13, 45 }, { 13, 46 }, { 14, -43 }, { 14, -42 }, { 14, -39 }, { 14, -38 },
{ 14, -37 }, { 14, -36 }, { 14, -35 }, { 14, -34 }, { 14, -20 }, { 14, -19 }, { 14, -18 }, { 14, -17 }, { 14, -10 }, { 14, -9 }, { 14, -8 }, { 14, -7 }, { 14, -3 }, { 14, -2 }, { 14, 1 }, { 14, 2 }, { 14, 5 }, { 14, 6 }, { 14, 10 }, { 14, 11 }, { 14, 12 }, { 14, 13 }, { 14, 20 }, { 14, 21 }, { 14, 22 }, { 14, 23 }, { 14, 37 }, { 14, 38 }, { 14, 39 }, { 14, 40 },
{ 14, 41 }, { 14, 42 }, { 14, 45 }, { 14, 46 }, { 15, -43 }, { 15, -42 }, { 15, -31 }, { 15, -30 }, { 15, -27 }, { 15, -26 }, { 15, -21 }, { 15, -20 }, { 15, -19 }, { 15, -18 }, { 15, -17 }, { 15, -16 }, { 15, -15 }, { 15, -14 }, { 15, -11 }, { 15, -10 }, { 15, -9 }, { 15, -8 }, { 15, -7 }, { 15, -6 }, { 15, 1 }, { 15, 2 }, { 15, 9 }, { 15, 10 }, { 15, 11 }, { 15, 12 },
{ 15, 13 }, { 15, 14 }, { 15, 17 }, { 15, 18 }, { 15, 19 }, { 15, 20 }, { 15, 21 }, { 15, 22 }, { 15, 23 }, { 15, 24 }, { 15, 29 }, { 15, 30 }, { 15, 33 }, { 15, 34 }, { 15, 45 }, { 15, 46 }, { 16, -43 }, { 16, -42 }, { 16, -32 }, { 16, -31 }, { 16, -30 }, { 16, -27 }, { 16, -26 }, { 16, -25 }, { 16, -21 }, { 16, -20 }, { 16, -19 }, { 16, -18 }, { 16, -17 }, { 16, -16 },
{ 16, -15 }, { 16, -14 }, { 16, -11 }, { 16, -10 }, { 16, -9 }, { 16, -8 }, { 16, -7 }, { 16, -6 }, { 16, 0 }, { 16, 1 }, { 16, 2 }, { 16, 3 }, { 16, 9 }, { 16, 10 }, { 16, 11 }, { 16, 12 }, { 16, 13 }, { 16, 14 }, { 16, 17 }, { 16, 18 }, { 16, 19 }, { 16, 20 }, { 16, 21 }, { 16, 22 }, { 16, 23 }, { 16, 24 }, { 16, 28 }, { 16, 29 }, { 16, 30 }, { 16, 33 },
{ 16, 34 }, { 16, 35 }, { 16, 45 }, { 16, 46 }, { 17, -43 }, { 17, -42 }, { 17, -35 }, { 17, -34 }, { 17, -33 }, { 17, -32 }, { 17, -31 }, { 17, -26 }, { 17, -25 }, { 17, -24 }, { 17, -15 }, { 17, -14 }, { 17, -10 }, { 17, -9 }, { 17, -8 }, { 17, -7 }, { 17, -6 }, { 17, -1 }, { 17, 0 }, { 17, 1 }, { 17, 2 }, { 17, 3 }, { 17, 4 }, { 17, 9 }, { 17, 10 }, { 17, 11 },
{ 17, 12 }, { 17, 13 }, { 17, 17 }, { 17, 18 }, { 17, 27 }, { 17, 28 }, { 17, 29 }, { 17, 34 }, { 17, 35 }, { 17, 36 }, { 17, 37 }, { 17, 38 }, { 17, 45 }, { 17, 46 }, { 18, -43 }, { 18, -42 }, { 18, -41 }, { 18, -35 }, { 18, -34 }, { 18, -33 }, { 18, -32 }, { 18, -25 }, { 18, -24 }, { 18, -23 }, { 18, -15 }, { 18, -14 }, { 18, -13 }, { 18, -9 }, { 18, -8 }, { 18, -7 },
{ 18, -6 }, { 18, -2 }, { 18, -1 }, { 18, 0 }, { 18, 1 }, { 18, 2 }, { 18, 3 }, { 18, 4 }, { 18, 5 }, { 18, 9 }, { 18, 10 }, { 18, 11 }, { 18, 12 }, { 18, 16 }, { 18, 17 }, { 18, 18 }, { 18, 26 }, { 18, 27 }, { 18, 28 }, { 18, 35 }, { 18, 36 }, { 18, 37 }, { 18, 38 }, { 18, 44 }, { 18, 45 }, { 18, 46 }, { 19, -42 }, { 19, -41 }, { 19, -40 }, { 19, -39 },
{ 19, -38 }, { 19, -29 }, { 19, -28 }, { 19, -25 }, { 19, -24 }, { 19, -23 }, { 19, -22 }, { 19, -21 }, { 19, -20 }, { 19, -19 }, { 19, -18 }, { 19, -15 }, { 19, -14 }, { 19, -13 }, { 19, -12 }, { 19, -3 }, { 19, -2 }, { 19, -1 }, { 19, 4 }, { 19, 5 }, { 19, 6 }, { 19, 15 }, { 19, 16 }, { 19, 17 }, { 19, 18 }, { 19, 21 }, { 19, 22 }, { 19, 23 }, { 19, 24 }, { 19, 25 },
{ 19, 26 }, { 19, 27 }, { 19, 28 }, { 19, 31 }, { 19, 32 }, { 19, 41 }, { 19, 42 }, { 19, 43 }, { 19, 44 }, { 19, 45 }, { 20, -41 }, { 20, -40 }, { 20, -39 }, { 20, -38 }, { 20, -37 }, { 20, -29 }, { 20, -28 }, { 20, -25 }, { 20, -24 }, { 20, -23 }, { 20, -22 }, { 20, -21 }, { 20, -20 }, { 20, -19 }, { 20, -18 }, { 20, -15 }, { 20, -14 }, { 20, -13 }, { 20, -12 }, { 20, -3 },
{ 20, -2 }, { 20, 5 }, { 20, 6 }, { 20, 15 }, { 20, 16 }, { 20, 17 }, { 20, 18 }, { 20, 21 }, { 20, 22 }, { 20, 23 }, { 20, 24 }, { 20, 25 }, { 20, 26 }, { 20, 27 }, { 20, 28 }, { 20, 31 }, { 20, 32 }, { 20, 40 }, { 20, 41 }, { 20, 42 }, { 20, 43 }, { 20, 44 }, { 21, -38 }, { 21, -37 }, { 21, -36 }, { 21, -29 }, { 21, -28 }, { 21, -19 }, { 21, -18 }, { 21, -15 },
{ 21, -14 }, { 21, -13 }, { 21, -9 }, { 21, -8 }, { 21, -7 }, { 21, -6 }, { 21, 1 }, { 21, 2 }, { 21, 9 }, { 21, 10 }, { 21, 11 }, { 21, 12 }, { 21, 16 }, { 21, 17 }, { 21, 18 }, { 21, 21 }, { 21, 22 }, { 21, 31 }, { 21, 32 }, { 21, 39 }, { 21, 40 }, { 21, 41 }, { 22, -37 }, { 22, -36 }, { 22, -30 }, { 22, -29 }, { 22, -28 }, { 22, -19 }, { 22, -18 }, { 22, -15 },
{ 22, -14 }, { 22, -9 }, { 22, -8 }, { 22, -7 }, { 22, -6 }, { 22, -5 }, { 22, 0 }, { 22, 1 }, { 22, 2 }, { 22, 3 }, { 22, 8 }, { 22, 9 }, { 22, 10 }, { 22, 11 }, { 22, 12 }, { 22, 17 }, { 22, 18 }, { 22, 21 }, { 22, 22 }, { 22, 31 }, { 22, 32 }, { 22, 33 }, { 22, 39 }, { 22, 40 }, { 23, -33 }, { 23, -32 }, { 23, -31 }, { 23, -30 }, { 23, -29 }, { 23, -25 },
{ 23, -24 }, { 23, -23 }, { 23, -22 }, { 23, -19 }, { 23, -18 }, { 23, -9 }, { 23, -8 }, { 23, -7 }, { 23, -6 }, { 23, -5 }, { 23, -4 }, { 23, -1 }, { 23, 0 }, { 23, 1 }, { 23, 2 }, { 23, 3 }, { 23, 4 }, { 23, 7 }, { 23, 8 }, { 23, 9 }, { 23, 10 }, { 23, 11 }, { 23, 12 }, { 23, 21 }, { 23, 22 }, { 23, 25 }, { 23, 26 }, { 23, 27 }, { 23, 28 }, { 23, 32 },
{ 23, 33 }, { 23, 34 }, { 23, 35 }, { 23, 36 }, { 24, -33 }, { 24, -32 }, { 24, -31 }, { 24, -30 }, { 24, -25 }, { 24, -24 }, { 24, -23 }, { 24, -22 }, { 24, -19 }, { 24, -18 }, { 24, -17 }, { 24, -9 }, { 24, -8 }, { 24, -7 }, { 24, -6 }, { 24, -5 }, { 24, -4 }, { 24, -1 }, { 24, 0 }, { 24, 1 }, { 24, 2 }, { 24, 3 }, { 24, 4 }, { 24, 7 }, { 24, 8 }, { 24, 9 },
{ 24, 10 }, { 24, 11 }, { 24, 12 }, { 24, 20 }, { 24, 21 }, { 24, 22 }, { 24, 25 }, { 24, 26 }, { 24, 27 }, { 24, 28 }, { 24, 33 }, { 24, 34 }, { 24, 35 }, { 24, 36 }, { 25, -39 }, { 25, -38 }, { 25, -37 }, { 25, -36 }, { 25, -24 }, { 25, -23 }, { 25, -22 }, { 25, -19 }, { 25, -18 }, { 25, -17 }, { 25, -16 }, { 25, -6 }, { 25, -5 }, { 25, -4 }, { 25, -1 }, { 25, 0 },
{ 25, 1 }, { 25, 2 }, { 25, 3 }, { 25, 4 }, { 25, 7 }, { 25, 8 }, { 25, 9 }, { 25, 19 }, { 25, 20 }, { 25, 21 }, { 25, 22 }, { 25, 25 }, { 25, 26 }, { 25, 27 }, { 25, 39 }, { 25, 40 }, { 25, 41 }, { 25, 42 }, { 26, -39 }, { 26, -38 }, { 26, -37 }, { 26, -36 }, { 26, -23 }, { 26, -22 }, { 26, -19 }, { 26, -18 }, { 26, -17 }, { 26, -16 }, { 26, -15 }, { 26, -5 },
{ 26, -4 }, { 26, -1 }, { 26, 0 }, { 26, 1 }, { 26, 2 }, { 26, 3 }, { 26, 4 }, { 26, 7 }, { 26, 8 }, { 26, 18 }, { 26, 19 }, { 26, 20 }, { 26, 21 }, { 26, 22 }, { 26, 25 }, { 26, 26 }, { 26, 39 }, { 26, 40 }, { 26, 41 }, { 26, 42 }, { 27, -38 }, { 27, -37 }, { 27, -36 }, { 27, -29 }, { 27, -28 }, { 27, -27 }, { 27, -26 }, { 27, -16 }, { 27, -15 }, { 27, -14 },
{ 27, -9 }, { 27, -8 }, { 27, 11 }, { 27, 12 }, { 27, 17 }, { 27, 18 }, { 27, 19 }, { 27, 29 }, { 27, 30 }, { 27, 31 }, { 27, 32 }, { 27, 39 }, { 27, 40 }, { 27, 41 }, { 28, -37 }, { 28, -36 }, { 28, -30 }, { 28, -29 }, { 28, -28 }, { 28, -27 }, { 28, -26 }, { 28, -15 }, { 28, -14 }, { 28, -10 }, { 28, -9 }, { 28, -8 }, { 28, -7 }, { 28, 10 }, { 28, 11 }, { 28, 12 },
{ 28, 13 }, { 28, 17 }, { 28, 18 }, { 28, 29 }, { 28, 30 }, { 28, 31 }, { 28, 32 }, { 28, 33 }, { 28, 39 }, { 28, 40 }, { 29, -33 }, { 29, -32 }, { 29, -31 }, { 29, -30 }, { 29, -29 }, { 29, -28 }, { 29, -27 }, { 29, -26 }, { 29, -21 }, { 29, -20 }, { 29, -19 }, { 29, -18 }, { 29, -11 }, { 29, -10 }, { 29, -9 }, { 29, -8 }, { 29, -7 }, { 29, -6 }, { 29, -1 }, { 29, 0 },
{ 29, 1 }, { 29, 2 }, { 29, 3 }, { 29, 4 }, { 29, 9 }, { 29, 10 }, { 29, 11 }, { 29, 12 }, { 29, 13 }, { 29, 14 }, { 29, 21 }, { 29, 22 }, { 29, 23 }, { 29, 24 }, { 29, 29 }, { 29, 30 }, { 29, 31 }, { 29, 32 }, { 29, 33 }, { 29, 34 }, { 29, 35 }, { 29, 36 }, { 30, -33 }, { 30, -32 }, { 30, -31 }, { 30, -30 }, { 30, -29 }, { 30, -28 }, { 30, -27 }, { 30, -26 },
{ 30, -22 }, { 30, -21 }, { 30, -20 }, { 30, -19 }, { 30, -18 }, { 30, -11 }, { 30, -10 }, { 30, -9 }, { 30, -8 }, { 30, -7 }, { 30, -6 }, { 30, -5 }, { 30, -1 }, { 30, 0 }, { 30, 1 }, { 30, 2 }, { 30, 3 }, { 30, 4 }, { 30, 8 }, { 30, 9 }, { 30, 10 }, { 30, 11 }, { 30, 12 }, { 30, 13 }, { 30, 14 }, { 30, 21 }, { 30, 22 }, { 30, 23 }, { 30, 24 }, { 30, 25 },
{ 30, 29 }, { 30, 30 }, { 30, 31 }, { 30, 32 }, { 30, 33 }, { 30, 34 }, { 30, 35 }, { 30, 36 }, { 31, -32 }, { 31, -31 }, { 31, -30 }, { 31, -29 }, { 31, -28 }, { 31, -27 }, { 31, -23 }, { 31, -22 }, { 31, -21 }, { 31, -15 }, { 31, -14 }, { 31, -6 }, { 31, -5 }, { 31, -4 }, { 31, -1 }, { 31, 0 }, { 31, 3 }, { 31, 4 }, { 31, 7 }, { 31, 8 }, { 31, 9 }, { 31, 17 },
{ 31, 18 }, { 31, 24 }, { 31, 25 }, { 31, 26 }, { 31, 30 }, { 31, 31 }, { 31, 32 }, { 31, 33 }, { 31, 34 }, { 31, 35 }, { 32, -31 }, { 32, -30 }, { 32, -29 }, { 32, -28 }, { 32, -23 }, { 32, -22 }, { 32, -16 }, { 32, -15 }, { 32, -14 }, { 32, -5 }, { 32, -4 }, { 32, -1 }, { 32, 0 }, { 32, 3 }, { 32, 4 }, { 32, 7 }, { 32, 8 }, { 32, 17 }, { 32, 18 }, { 32, 19 },
{ 32, 25 }, { 32, 26 }, { 32, 31 }, { 32, 32 }, { 32, 33 }, { 32, 34 }, { 33, -30 }, { 33, -29 }, { 33, -28 }, { 33, -23 }, { 33, -22 }, { 33, -17 }, { 33, -16 }, { 33, -15 }, { 33, -11 }, { 33, -10 }, { 33, -9 }, { 33, -8 }, { 33, 11 }, { 33, 12 }, { 33, 13 }, { 33, 14 }, { 33, 18 }, { 33, 19 }, { 33, 20 }, { 33, 25 }, { 33, 26 }, { 33, 31 }, { 33, 32 }, { 33, 33 },
{ 34, -29 }, { 34, -28 }, { 34, -23 }, { 34, -22 }, { 34, -17 }, { 34, -16 }, { 34, -12 }, { 34, -11 }, { 34, -10 }, { 34, -9 }, { 34, -8 }, { 34, 11 }, { 34, 12 }, { 34, 13 }, { 34, 14 }, { 34, 15 }, { 34, 19 }, { 34, 20 }, { 34, 25 }, { 34, 26 }, { 34, 31 }, { 34, 32 }, { 35, -17 }, { 35, -16 }, { 35, -13 }, { 35, -12 }, { 35, -11 }, { 35, -10 }, { 35, -9 }, { 35, -3 },
{ 35, -2 }, { 35, -1 }, { 35, 0 }, { 35, 3 }, { 35, 4 }, { 35, 5 }, { 35, 6 }, { 35, 12 }, { 35, 13 }, { 35, 14 }, { 35, 15 }, { 35, 16 }, { 35, 19 }, { 35, 20 }, { 36, -17 }, { 36, -16 }, { 36, -13 }, { 36, -12 }, { 36, -11 }, { 36, -10 }, { 36, -4 }, { 36, -3 }, { 36, -2 }, { 36, -1 }, { 36, 0 }, { 36, 3 }, { 36, 4 }, { 36, 5 }, { 36, 6 }, { 36, 7 },
{ 36, 13 }, { 36, 14 }, { 36, 15 }, { 36, 16 }, { 36, 19 }, { 36, 20 }, { 37, -27 }, { 37, -26 }, { 37, -25 }, { 37, -24 }, { 37, -21 }, { 37, -20 }, { 37, -13 }, { 37, -12 }, { 37, -5 }, { 37, -4 }, { 37, -3 }, { 37, -2 }, { 37, -1 }, { 37, 0 }, { 37, 1 }, { 37, 2 }, { 37, 3 }, { 37, 4 }, { 37, 5 }, { 37, 6 }, { 37, 7 }, { 37, 8 }, { 37, 15 }, { 37, 16 },
{ 37, 23 }, { 37, 24 }, { 37, 27 }, { 37, 28 }, { 37, 29 }, { 37, 30 }, { 38, -27 }, { 38, -26 }, { 38, -25 }, { 38, -24 }, { 38, -21 }, { 38, -20 }, { 38, -19 }, { 38, -13 }, { 38, -12 }, { 38, -5 }, { 38, -4 }, { 38, -3 }, { 38, -2 }, { 38, -1 }, { 38, 0 }, { 38, 1 }, { 38, 2 }, { 38, 3 }, { 38, 4 }, { 38, 5 }, { 38, 6 }, { 38, 7 }, { 38, 8 }, { 38, 15 },
{ 38, 16 }, { 38, 22 }, { 38, 23 }, { 38, 24 }, { 38, 27 }, { 38, 28 }, { 38, 29 }, { 38, 30 }, { 39, -26 }, { 39, -25 }, { 39, -24 }, { 39, -20 }, { 39, -19 }, { 39, -18 }, { 39, -13 }, { 39, -12 }, { 39, -11 }, { 39, -10 }, { 39, -5 }, { 39, -4 }, { 39, 7 }, { 39, 8 }, { 39, 13 }, { 39, 14 }, { 39, 15 }, { 39, 16 }, { 39, 21 }, { 39, 22 }, { 39, 23 }, { 39, 27 },
{ 39, 28 }, { 39, 29 }, { 40, -25 }, { 40, -24 }, { 40, -19 }, { 40, -18 }, { 40, -13 }, { 40, -12 }, { 40, -11 }, { 40, -10 }, { 40, -5 }, { 40, -4 }, { 40, 7 }, { 40, 8 }, { 40, 13 }, { 40, 14 }, { 40, 15 }, { 40, 16 }, { 40, 21 }, { 40, 22 }, { 40, 27 }, { 40, 28 }, { 41, -19 }, { 41, -18 }, { 41, -1 }, { 41, 0 }, { 41, 1 }, { 41, 2 }, { 41, 3 }, { 41, 4 },
{ 41, 21 }, { 41, 22 }, { 42, -19 }, { 42, -18 }, { 42, -17 }, { 42, -1 }, { 42, 0 }, { 42, 1 }, { 42, 2 }, { 42, 3 }, { 42, 4 }, { 42, 20 }, { 42, 21 }, { 42, 22 }, { 43, -18 }, { 43, -17 }, { 43, -16 }, { 43, -15 }, { 43, -14 }, { 43, -13 }, { 43, -12 }, { 43, -9 }, { 43, -8 }, { 43, -1 }, { 43, 0 }, { 43, 1 }, { 43, 2 }, { 43, 3 }, { 43, 4 }, { 43, 11 },
{ 43, 12 }, { 43, 15 }, { 43, 16 }, { 43, 17 }, { 43, 18 }, { 43, 19 }, { 43, 20 }, { 43, 21 }, { 44, -17 }, { 44, -16 }, { 44, -15 }, { 44, -14 }, { 44, -13 }, { 44, -12 }, { 44, -9 }, { 44, -8 }, { 44, -7 }, { 44, -2 }, { 44, -1 }, { 44, 0 }, { 44, 1 }, { 44, 2 }, { 44, 3 }, { 44, 4 }, { 44, 5 }, { 44, 10 }, { 44, 11 }, { 44, 12 }, { 44, 15 }, { 44, 16 },
{ 44, 17 }, { 44, 18 }, { 44, 19 }, { 44, 20 }, { 45, -8 }, { 45, -7 }, { 45, -6 }, { 45, -5 }, { 45, -4 }, { 45, -3 }, { 45, -2 }, { 45, -1 }, { 45, 4 }, { 45, 5 }, { 45, 6 }, { 45, 7 }, { 45, 8 }, { 45, 9 }, { 45, 10 }, { 45, 11 }, { 46, -7 }, { 46, -6 }, { 46, -5 }, { 46, -4 }, { 46, -3 }, { 46, -2 }, { 46, 5 }, { 46, 6 }, { 46, 7 }, { 46, 8 },
{ 46, 9 }, { 46, 10 }, { 47, -4 }, { 47, -3 }, { 47, -2 }, { 47, 1 }, { 47, 2 }, { 47, 5 }, { 47, 6 }, { 47, 7 }, { 48, -3 }, { 48, -2 }, { 48, 1 }, { 48, 2 }, { 48, 5 }, { 48, 6 },
},
}
},
resource_tiles = {
enabled = false,
+10 -10
View File
@@ -8,8 +8,8 @@ return {
unlimited_capacity = false, --- @setting unlimited_capacity When true the vlayer has an unlimited energy capacity, accumulators are not required
unlimited_surface_area = false, --- @setting unlimited_surface_area When true the vlayer has an unlimited surface area, landfill is not required
modded_auto_downgrade = false, --- @setting modded_auto_downgrade When true modded items will be converted into their base game equivalent, original items can not be recovered
power_on_space = false, --- @setting power_on_space When true allow on spaceship
modded_auto_downgrade = true, --- @setting modded_auto_downgrade When true modded items will be converted into their base game equivalent, original items can not be recovered
power_on_space = true, --- @setting power_on_space When true allow on spaceship
power_on_space_research = { --- @setting power_on_space_research the research level needed to use power_on_space
name = "research-productivity",
level = 10
@@ -29,10 +29,10 @@ return {
},
interface_limit = { --- @setting interface_limit Sets the limit for the number of vlayer interfaces that can be created
energy = 1, -- >1 allows for disconnected power networks to receive power
circuit = 20, -- No caveats
storage_input = 20, -- No caveats
storage_output = 1, -- >0 allows for item teleportation (allowed_items only)
energy = 100, -- >1 allows for disconnected power networks to receive power
circuit = 100, -- No caveats
storage_input = 100, -- No caveats
storage_output = 100, -- >0 allows for item teleportation (allowed_items only)
},
allowed_items = { --- @setting allowed_items List of all items allowed in vlayer storage and their properties
@@ -73,22 +73,22 @@ return {
required_area = 0,
surface_area = 0,
fuel_value = 4, -- MJ
power = false, -- turn all coal to power to reduce trash
power = true, -- turn all coal to power to reduce trash
},
["solid-fuel"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 12, -- MJ
power = false, -- turn all solid fuel to power to reduce trash
power = true, -- turn all solid fuel to power to reduce trash
},
["rocket-fuel"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 100, -- MJ
power = false, -- turn all rocket fuel to power to reduce trash
}
power = true, -- turn all rocket fuel to power to reduce trash
},
},
modded_items = { --- @setting modded_items List of all modded items allowed in vlayer storage and their base game equivalent
+6 -11
View File
@@ -1,22 +1,17 @@
[links]
discord=https://discord.explosivegaming.nl
website=https://www.explosivegaming.nl
status=https://status.explosivegaming.nl
github=https://github.com/explosivegaming/ExpCluster
patreon=https://www.patreon.com/ExpGaming
website=https://aperx.org
github=https://github.com/PHIDIAS0303/ExpCluster
discord=
[info]
players-online=There are __1__ players online
total-map-time=This map has been on for __1__
discord=Join us on our discord at: https://discord.explosivegaming.nl
website=Please visit our website at: https://www.explosivegaming.nl
status=Want to check if out servers are down? Visit: https://status.explosivegaming.nl
github=Want to help improve our server with some extra features? Help us at: https://github.com/explosivegaming/ExpCluster
patreon=Consider supporting our server at: https://www.patreon.com/ExpGaming
website=Please visit our website at: https://aperx.org
github=Want to help improve our server with some extra features? Help us at: https://github.com/PHIDIAS0303/ExpCluster
discord=
custom-commands=We use custom commands, such as /tag and /me, use /chelp for more info.
read-readme=Make sure you have read the information gui (It can be found through the info mark on the top left)
softmod=We run a softmod on our servers. A softmod is a custom scenario that runs on this server, an example is the player list.
redmew=We don't talk about redmew here; they beat us to 1000 members ;-;
lhd=All trains must be LHD! This is a long standing rule on our servers, please respect this.
[warnings]
+1 -1
View File
@@ -2,7 +2,7 @@
description-add=Sets / Gets your custom join message.
description-remove=Removes you custom join message.
arg-message=Your custom join message.
greet=[color=0,1,0] Welcome to explosive gaming community server! If you like the server join our discord: __1__ [/color]
greet=[color=0,1,0] Welcome to APERX gaming community server! __1__[/color]
message-set=Your join message has been updated.
message-get=Your join message is: __1__
message-cleared=Your join message has been cleared.
+15 -20
View File
@@ -88,8 +88,8 @@ goto-edit=Edit warp icon
[readme]
main-tooltip=Infomation
welcome-tab=Welcome
welcome-tooltip=Welcome to Explosive Gaming
welcome-general=Welcome to Explosive Gaming; we host many factorio servers. While you are here, we ask you to follow our rules. You can find these in the tab above. You can also find our custom commands and links to our other servers. This map has been online for __2__.\nPlease note that our servers reset periodically, the next reset is: __1__
welcome-tooltip=Welcome to APERX
welcome-general=Welcome to APERX; we host many factorio servers. While you are here, we ask you to follow our rules. You can find these in the tab above. You can also find our custom commands and links to our other servers. This map has been online for __2__.\nPlease note that our servers reset periodically, the next reset is: __1__
welcome-roles=We run a custom role system to help protect the work of others. As a result you may not be able to use your deconstruction planner yet or drop item on the groud. Roles also give you access to some custom features such as adding tasks to our task list or making new warp points.\nYou have been assigned the roles: __1__
welcome-chat=Chatting can be difficult for new players because its different than other games! Its very simple, the button you need to press is the “GRAVE/TILDE” key (which is located under the “ESC key”) - If you would like to change the key, go to your Controls tab in options.\nThe setting you need to change is “Toggle chat (and Lua console)” you currently have it set to "__CONTROL__toggle-console__"
rules-tab=Rules
@@ -117,22 +117,18 @@ servers-tab=Servers
servers-tooltip=Links to our other servers and sites
servers-general=This is only one of our servers for factorio, we host many of others as well. Below you can find details about all the servers that we host as well as links to our external services such as discord or github.
servers-factorio=Factorio Servers
servers-1=S1 Public
servers-d1=This is our 48 hour reset server.
servers-2=S2 Off
servers-d2=This server is closed.
servers-3=S3 Weekly
servers-d3=This is our weekly reset server.
servers-4=S4 Monthly
servers-d4=This is our monthly reset server.
servers-5=S5 Modded
servers-d5=This is our modded server, see discord for details.
servers-6=S6 Donator
servers-d6=This is our donator only server, online when requested.
servers-7=S7 Event
servers-d7=This is our event server, we try to run events at least once per week.
servers-8=S8 T̷-̶s̶-̴:̷
servers-d8=N̵o̴ ̶o̷-̶e̵ ̴k̸n̷-̶w̵s̸ ̴w̷h̷a̶-̶ ̷h̴a̴p̷p̴e̷n̷s̸ ̷o̶n̴ ̷t̶h̴-̶s̶ ̷s̷e̶r̸v̸e̴r̷,̶ ̸i̸t̴ ̷m̶-̸g̴h̶t̷ ̸n̸-̶t̵ ̷e̴v̸e̸n̶t̷ ̵-̷x̴i̵s̶t̸.̸
servers-1=S1
servers-d1=This server resets regularly.
servers-2=S2
servers-d2=This server resets regularly.
servers-3=S3
servers-d3=This server resets regularly.
servers-5=S5
servers-d5=This server is only for members. Check discord for more details.
servers-6=S6
servers-d6=This server is only for members. Check discord for more details.
servers-8=S8
servers-d8=This server is only for event and others. Check discord for more details.
servers-connect-Offline=Server is currently offline
servers-connect-Current=This is your current server
servers-connect-Version=Server is on a different version: __1__
@@ -145,9 +141,8 @@ backers-tab=Backers
backers-tooltip=People who have helped make our server
backers-general=We would like to thank all our staff and backers who have helped our community grow. Our staff have helped to keep our servers safe from trolls and a fun place to play. Our backers have helped us to cover our running costs and provide a great community for us all to enjoy together.
backers-management=Administrators
backers-board=Board Members and Senior Backers
backers-staff=Staff Members
backers-backers=Sponsors and Supporters
backers-backers=Board Members, Supporters, and Partners
backers-active=Active Players
data-tab=Data
data-tooltip=All of your stored player data
+6 -11
View File
@@ -1,22 +1,17 @@
[links]
discord=https://discord.explosivegaming.nl
website=https://www.explosivegaming.nl
status=https://status.explosivegaming.nl
github=https://github.com/explosivegaming/ExpCluster
patreon=https://www.patreon.com/ExpGaming
website=https://aperx.org
github=https://github.com/PHIDIAS0303/ExpCluster
discord=
[info]
players-online=現在有 __1__ 人在線
total-map-time=地圖時間為 __1__
discord=加入社群: https://discord.explosivegaming.nl
website=訪問網站: https://www.explosivegaming.nl
status=伺服器狀態: https://status.explosivegaming.nl
github=增加功能或回報錯誤: https://github.com/explosivegaming/ExpCluster
patreon=支持我們: https://www.patreon.com/ExpGaming
website=訪問網站: https://aperx.org
github=增加功能或回報錯誤: https://github.com/PHIDIAS0303/ExpCluster
discord=
custom-commands=這裹使用了自制指令,如 /tag 和 /me。可使用 /chelp 查看更多。
read-readme=確保你已閱讀相關資訊。按左上 i 圖標可再次查看。
softmod=這裹用了自設情境,是一種軟裝模組。
redmew=
lhd=列車必須是左則通行。這是本服務器長久以來的規則。
[warnings]
+1 -1
View File
@@ -2,7 +2,7 @@
description-add=設定 / 取得你的加入信息。
description-remove=移除你的加入信息。
arg-message=你的加入信息。
greet=[color=0,1,0] 歡迎來到 EXP 的服務器! 若果你喜歡本服務器可加入 DISCORD: __1__ [/color]
greet=[color=0,1,0] 歡迎來到 APERX 的服務器! __1__[/color]
message-set=你的加入信息已更新。
message-get=你的加入信息為: __1__
message-cleared=你的加入信息已清除。
+16 -21
View File
@@ -88,8 +88,8 @@ goto-edit=修改傳送陣圖案
[readme]
main-tooltip=資訊
welcome-tab=歡迎
welcome-tooltip=歡迎來到 Explosive Gaming
welcome-general=歡迎來到 Explosive Gaming; 你在這裏的時候要遵守規則。 你可以在左上方的介面找到更多資訊。 地圖時間 __2__。\n下次地圖重設: __1__
welcome-tooltip=歡迎來到 APERX
welcome-general=歡迎來到 APERX; 你在這裏的時候要遵守規則。 你可以在左上方的介面找到更多資訊。 地圖時間 __2__。\n下次地圖重設: __1__
welcome-roles=我們有自訂的身份組來保護其他用戶。 所以你有機會不能使用拆除規劃器或掉東西。 身份組給予你各種權限\n你有以下身份組: __1__
welcome-chat=你可以使用 「重音符/抑音符」 鍵 (ESC 鍵 下方) - 你也可以在選項中修改按鍵。\n你目前設定為 「__CONTROL__toggle-console__」
rules-tab=規則
@@ -117,22 +117,18 @@ servers-tab=伺服器
servers-tooltip=到其他伺服器及網站的連結
servers-general=這是其中一個伺服器。你可以在下方找到其他同樣是由我們運行的伺服器資料。
servers-factorio=異星工廠伺服器
servers-1=S1 公共
servers-d1=這個服務器每兩日重設。
servers-2=S2 -
servers-d2=這個服務器沒在營運
servers-3=S3 周
servers-d3=這個服務器每週重設。
servers-4=S4 月
servers-d4=這個服務器每月重設
servers-5=S5 模組
servers-d5=這個服務器運行模組,可在 Discord 中得到更多資訊。
servers-6=S6 Donator
servers-d6=這個服務器為支持者運行,可在 Discord 中得到更多資訊。
servers-7=S7 項目
servers-d7=這個服務器只在有項目期間運行。
servers-8=S8 T̷-̶s̶-̴:̷
servers-d8=N̵o̴ ̶o̷-̶e̵ ̴k̸n̷-̶w̵s̸ ̴w̷h̷a̶-̶ ̷h̴a̴p̷p̴e̷n̷s̸ ̷o̶n̴ ̷t̶h̴-̶s̶ ̷s̷e̶r̸v̸e̴r̷,̶ ̸i̸t̴ ̷m̶-̸g̴h̶t̷ ̸n̸-̶t̵ ̷e̴v̸e̸n̶t̷ ̵-̷x̴i̵s̶t̸。̸
servers-1=S1
servers-d1=這個服務器定期重設。
servers-2=S2
servers-d2=這個服務器定期重設
servers-3=S3
servers-d3=這個服務器定期重設。
servers-5=S5
servers-d5=這個服務器只為會員運行,可在 Discord 中得到更多資訊
servers-6=S6
servers-d6=這個服務器只為會員運行,可在 Discord 中得到更多資訊。
servers-8=S8
servers-d8=這個服務器只在活動和其他時運行,可在 Discord 中得到更多資訊。
servers-connect-Offline=該服務器目前沒有在運行
servers-connect-Current=你目前所在的伺服器
servers-connect-Version=該服務器運行不同的遊戲版本: __1__
@@ -144,10 +140,9 @@ servers-open-in-browser=可在你的瀏覽器中打開
backers-tab=支持者
backers-tooltip=支持者
backers-general=他們為服務器運行提供了不少幫助。
backers-management=系統管理員
backers-board=議員
backers-management=管理員
backers-staff=職員
backers-backers=支持者
backers-backers=議員,支持者,和夥伴
backers-active=活躍玩家
data-tab=資料
data-tooltip=所有已存資料
+6 -11
View File
@@ -1,22 +1,17 @@
[links]
discord=https://discord.explosivegaming.nl
website=https://www.explosivegaming.nl
status=https://status.explosivegaming.nl
github=https://github.com/explosivegaming/ExpCluster
patreon=https://www.patreon.com/ExpGaming
website=https://aperx.org
github=https://github.com/PHIDIAS0303/ExpCluster
discord=
[info]
players-online=現在有 __1__ 人在線
total-map-time=地圖時間為 __1__
discord=加入社群: https://discord.explosivegaming.nl
website=訪問網站: https://www.explosivegaming.nl
status=伺服器狀態: https://status.explosivegaming.nl
github=增加功能或回報錯誤: https://github.com/explosivegaming/ExpCluster
patreon=支持我們: https://www.patreon.com/ExpGaming
website=訪問網站: https://aperx.org
github=增加功能或回報錯誤: https://github.com/PHIDIAS0303/ExpCluster
discord=
custom-commands=這裹使用了自制指令,如 /tag 和 /me。可使用 /chelp 查看更多。
read-readme=確保你已閱讀相關資訊。按左上 i 圖標可再次查看。
softmod=這裹用了自設情境,是一種軟裝模組。
redmew=
lhd=列車必須是左則通行。這是本服務器長久以來的規則。
[warnings]
+1 -1
View File
@@ -2,7 +2,7 @@
description-add=設定 / 取得你的加入信息。
description-remove=移除你的加入信息。
arg-message=你的加入信息。
greet=[color=0,1,0] 歡迎來到 EXP 的服務器! 若果你喜歡本服務器可加入 DISCORD: __1__ [/color]
greet=[color=0,1,0] 歡迎來到 APERX 的服務器! __1__[/color]
message-set=你的加入信息已更新。
message-get=你的加入信息為: __1__
message-cleared=你的加入信息已清除。
+16 -21
View File
@@ -88,8 +88,8 @@ goto-edit=修改傳送陣圖案
[readme]
main-tooltip=資訊
welcome-tab=歡迎
welcome-tooltip=歡迎來到 Explosive Gaming
welcome-general=歡迎來到 Explosive Gaming; 你在這裏的時候要遵守規則。 你可以在左上方的介面找到更多資訊。 地圖時間 __2__。\n下次地圖重設: __1__
welcome-tooltip=歡迎來到 APERX
welcome-general=歡迎來到 APERX; 你在這裏的時候要遵守規則。 你可以在左上方的介面找到更多資訊。 地圖時間 __2__。\n下次地圖重設: __1__
welcome-roles=我們有自訂的身份組來保護其他用戶。 所以你有機會不能使用拆除規劃器或掉東西。 身份組給予你各種權限\n你有以下身份組: __1__
welcome-chat=你可以使用 「重音符/抑音符」 鍵 (ESC 鍵 下方) - 你也可以在選項中修改按鍵。\n你目前設定為 「__CONTROL__toggle-console__」
rules-tab=規則
@@ -117,22 +117,18 @@ servers-tab=伺服器
servers-tooltip=到其他伺服器及網站的連結
servers-general=這是其中一個伺服器。你可以在下方找到其他同樣是由我們運行的伺服器資料。
servers-factorio=異星工廠伺服器
servers-1=S1 公共
servers-d1=這個服務器每兩日重設。
servers-2=S2 -
servers-d2=這個服務器沒在營運
servers-3=S3 周
servers-d3=這個服務器每週重設。
servers-4=S4 月
servers-d4=這個服務器每月重設
servers-5=S5 模組
servers-d5=這個服務器運行模組,可在 Discord 中得到更多資訊。
servers-6=S6 Donator
servers-d6=這個服務器為支持者運行,可在 Discord 中得到更多資訊。
servers-7=S7 項目
servers-d7=這個服務器只在有項目期間運行。
servers-8=S8 T̷-̶s̶-̴:̷
servers-d8=N̵o̴ ̶o̷-̶e̵ ̴k̸n̷-̶w̵s̸ ̴w̷h̷a̶-̶ ̷h̴a̴p̷p̴e̷n̷s̸ ̷o̶n̴ ̷t̶h̴-̶s̶ ̷s̷e̶r̸v̸e̴r̷,̶ ̸i̸t̴ ̷m̶-̸g̴h̶t̷ ̸n̸-̶t̵ ̷e̴v̸e̸n̶t̷ ̵-̷x̴i̵s̶t̸。̸
servers-1=S1
servers-d1=這個服務器定期重設。
servers-2=S2
servers-d2=這個服務器定期重設
servers-3=S3
servers-d3=這個服務器定期重設。
servers-5=S5
servers-d5=這個服務器只為會員運行,可在 Discord 中得到更多資訊
servers-6=S6
servers-d6=這個服務器只為會員運行,可在 Discord 中得到更多資訊。
servers-8=S8
servers-d8=這個服務器只在活動和其他時運行,可在 Discord 中得到更多資訊。
servers-connect-Offline=該服務器目前沒有在運行
servers-connect-Current=你目前所在的伺服器
servers-connect-Version=該服務器運行不同的遊戲版本: __1__
@@ -144,10 +140,9 @@ servers-open-in-browser=可在你的瀏覽器中打開
backers-tab=支持者
backers-tooltip=支持者
backers-general=他們為服務器運行提供了不少幫助。
backers-management=系統管理員
backers-board=議員
backers-management=管理員
backers-staff=職員
backers-backers=支持者
backers-backers=議員,支持者,和夥伴
backers-active=活躍玩家
data-tab=資料
data-tooltip=所有已存資料
+9 -9
View File
@@ -341,9 +341,9 @@ function vlayer.create_input_interface(surface, position, circuit, last_user)
end
if circuit then
for k, _ in pairs(circuit) do
for _, v in pairs(circuit[k]) do
interface.connect_neighbour{ wire = defines.wire_type[k], target_entity = v }
for k, _ in pairs({ defines.wire_connector_id.circuit_red, defines.wire_connector_id.circuit_green }) do
for _, v in pairs(circuit.get_wire_connector{ wire_connector_id = k, or_create = false }.real_connections) do
interface.connect_to{ target = v.target }
end
end
end
@@ -419,9 +419,9 @@ function vlayer.create_output_interface(surface, position, circuit, last_user)
end
if circuit then
for k, _ in pairs(circuit) do
for _, v in pairs(circuit[k]) do
interface.connect_neighbour{ wire = defines.wire_type[k], target_entity = v }
for k, _ in pairs({ defines.wire_connector_id.circuit_red, defines.wire_connector_id.circuit_green }) do
for _, v in pairs(circuit.get_wire_connector{ wire_connector_id = k, or_create = false }.real_connections) do
interface.connect_to{ target = v.target }
end
end
end
@@ -566,9 +566,9 @@ function vlayer.create_circuit_interface(surface, position, circuit, last_user)
end
if circuit then
for k, _ in pairs(circuit) do
for _, v in pairs(circuit[k]) do
interface.connect_neighbour{ wire = defines.wire_type[k], target_entity = v }
for k, _ in pairs({ defines.wire_connector_id.circuit_red, defines.wire_connector_id.circuit_green }) do
for _, v in pairs(circuit.get_wire_connector{ wire_connector_id = k, or_create = false }.real_connections) do
interface.connect_to{ target = v.target }
end
end
end
@@ -189,6 +189,10 @@ function Warps.make_warp_area(warp_id)
if entity.type == "electric-pole" then
warp.electric_pole = entity
end
if entity.name == "small-lamp" then
entity.always_on = true
end
end
end
+7 -7
View File
@@ -113,7 +113,7 @@ local welcome_time_format = ExpUtil.format_time_factory_locale{ format = "long",
--- Content area for the welcome tab
define_tab({ "readme.welcome-tab" }, { "readme.welcome-tooltip" }, Gui.define("readme_welcome")
:draw(function(_, parent)
local server_details = { name = "ExpGaming S0 - Local", welcome = "Failed to load description: disconnected from external api.", reset_time = "Non Set", branch = "Unknown" }
local server_details = { name = "APERX S0 - Local", welcome = "Failed to load description: disconnected from external api.", reset_time = "Non Set", branch = "Unknown" }
if External.valid() then server_details = External.get_current_server() end
local container = parent.add{ type = "flow", direction = "vertical" }
local player = Gui.get_player(parent)
@@ -223,7 +223,7 @@ define_tab({ "readme.servers-tab" }, { "readme.servers-tooltip" }, Gui.define("r
end
else
local factorio_servers = title_table(scroll_pane, 225, { "readme.servers-factorio" }, 2)
for i = 1, 8 do
for _, i in pairs{ 1, 2, 3, 5, 6, 8 } do
Gui.elements.centered_label(factorio_servers, 110, { "readme.servers-" .. i })
Gui.elements.centered_label(factorio_servers, 460, { "readme.servers-d" .. i })
end
@@ -231,7 +231,7 @@ define_tab({ "readme.servers-tab" }, { "readme.servers-tooltip" }, Gui.define("r
-- Add the external links
local external_links = title_table(scroll_pane, 235, { "readme.servers-external" }, 2)
for _, key in ipairs{ "discord", "website", "patreon", "status", "github" } do
for _, key in ipairs{ "website", "github" } do
local upper_key = key:gsub("^%l", string.upper)
Gui.elements.centered_label(external_links, 110, upper_key)
Gui.elements.centered_label(external_links, 460, { "links." .. key }, { "readme.servers-open-in-browser" })
@@ -255,10 +255,10 @@ define_tab({ "readme.backers-tab" }, { "readme.backers-tooltip" }, Gui.define("r
local done = {}
local groups = {
{ _roles = { "Senior Administrator", "Administrator" }, _title = { "readme.backers-management" }, _width = 230 },
{ _roles = { "Board Member", "Senior Backer" }, _title = { "readme.backers-board" }, _width = 145 }, -- change role to board
{ _roles = { "Sponsor", "Supporter" }, _title = { "readme.backers-backers" }, _width = 196 }, -- change to backer
{ _roles = { "Moderator", "Trainee" }, _title = { "readme.backers-staff" }, _width = 235 },
{ _roles = {}, _time = 3 * 3600 * 60, _title = { "readme.backers-active" }, _width = 235 },
{ _roles = { "Senior Moderator", "Moderator", "Trainee Moderator" }, _title = { "readme.backers-staff" }, _width = 230 },
{ _roles = { "Board Member", "Supporter", "Partner" }, _title = { "readme.backers-backers" }, _width = 230 }, -- change role to board
{ _roles = { "Veteran" }, _title = { "readme.backers-active" }, _width = 230 },
-- _time = 3 * 3600 * 60
}
-- Fill by player roles
+14 -1
View File
@@ -19,11 +19,24 @@ Storage.register(research, function(tbl)
research = tbl
end)
local mod_set = "base"
for _, mod_name in ipairs(config.mod_set_lookup) do
if script.active_mods[mod_name] then
mod_set = mod_name
break
end
end
if script.active_mods["space-age"] and script.active_mods["PHI-CL"] and settings.startup["PHI-VP"] and settings.startup["PHI-VP-MAIN"] then
mod_set = "space-age"
end
--- @param force LuaForce
--- @param silent boolean True when no message should be printed
local function queue_research(force, silent)
local res_q = force.research_queue
local res = force.technologies[config.bonus_inventory.log[config.mod_set].name]
local res = force.technologies[config.bonus_inventory.log[mod_set].name]
if #res_q < config.queue_amount then
for i = #res_q, config.queue_amount - 1 do
+1 -1
View File
@@ -77,6 +77,6 @@ add(require("modules/exp_scenario/gui/player_stats"))
add(require("modules/exp_scenario/gui/production_stats"))
add(require("modules/exp_scenario/gui/quick_actions"))
add(require("modules/exp_scenario/gui/research_milestones"))
add(require("modules/exp_scenario/gui/science_production"))
-- add(require("modules/exp_scenario/gui/science_production"))
add(require("modules/exp_scenario/gui/surveillance"))
add(require("modules/exp_scenario/gui/task_list"))
@@ -37,11 +37,8 @@ local function on_pre_player_died(event)
local player = assert(game.get_player(event.player_index))
local cause = event.cause
if cause then
if cause.type == "character" then
add_log_line("[DEATH]", player.name, "died because of", (cause.player and cause.player.name) or cause.name)
else
add_log_line("[DEATH]", player.name, "died because of", cause.name)
end
local by_player = event.cause.player
add_log_line("[DEATH]", player.name, "died because of", by_player and by_player.name or event.cause.name)
else
add_log_line("[DEATH]", player.name, "died because of unknown reason")
end
@@ -70,7 +67,7 @@ end
--- @param event EventData.on_player_left_game
local function on_player_left_game(event)
local player = assert(game.get_player(event.player_index))
add_log_line("[LEAVE]", player.name, config.disconnect_reason[event.reason])
add_log_line("[LEAVE]", game.players[event.player_index].name, config.disconnect_reason[event.reason])
end
local e = defines.events
@@ -10,7 +10,7 @@ local events = require("modules.exp_legacy.config.inventory_clear")
--- @param event { player_index: number }
local function clear_items(event)
if not event.player_index then return end
if event.player_index then return end
local player = assert(game.get_player(event.player_index))
local inventory = assert(player.get_main_inventory())
ExpUtil.transfer_inventory_to_surface{
+2 -3
View File
@@ -20,7 +20,7 @@ export class InstancePlugin extends BaseInstancePlugin {
this.clearInterval();
this.setInterval();
} else if (field === "exp_server_ups.average_interval") {
this.gameTimes.splice(curr as number);
this.gameTimes = [];
}
}
@@ -51,8 +51,7 @@ export class InstancePlugin extends BaseInstancePlugin {
if (collected > 0) {
const minTick = this.gameTimes[0];
const maxTick = this.gameTimes[collected];
const interval = this.instance.config.get("exp_server_ups.update_interval") / 1000;
ups = (maxTick - minTick) / (collected * interval);
ups = (maxTick - minTick) / (collected * (this.instance.config.get("exp_server_ups.update_interval") / 1000));
}
try {
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE martif PUBLIC "ISO 12200:1999A//DTD MARTIF core (DXFcdV04)//EN" "TBXcdv04.dtd">
<martif type="TBX">
<martifHeader>
<fileDesc>
<sourceDesc>
<p>Weblate Glossary</p>
</sourceDesc>
</fileDesc>
</martifHeader>
<text>
<body>
</body>
</text>
</martif>
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE martif PUBLIC "ISO 12200:1999A//DTD MARTIF core (DXFcdV04)//EN" "TBXcdv04.dtd">
<martif type="TBX">
<martifHeader>
<fileDesc>
<sourceDesc>
<p>Weblate Glossary</p>
</sourceDesc>
</fileDesc>
</martifHeader>
<text>
<body>
</body>
</text>
</martif>