cyberia 3.2.9 → 3.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/.github/workflows/engine-cyberia.cd.yml +6 -0
  2. package/.github/workflows/npmpkg.ci.yml +1 -0
  3. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  4. package/.github/workflows/release.cd.yml +1 -0
  5. package/.vscode/extensions.json +9 -9
  6. package/.vscode/settings.json +20 -4
  7. package/CHANGELOG.md +213 -1
  8. package/CLI-HELP.md +92 -23
  9. package/README.md +190 -348
  10. package/bin/build.js +24 -8
  11. package/bin/build.template.js +187 -0
  12. package/bin/cyberia.js +229 -52
  13. package/bin/deploy.js +12 -2
  14. package/bin/index.js +229 -52
  15. package/bump.config.js +26 -0
  16. package/conf.js +130 -24
  17. package/deployment.yaml +4 -2
  18. package/hardhat/package-lock.json +113 -144
  19. package/hardhat/package.json +4 -3
  20. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  21. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  22. package/manifests/deployment/dd-cyberia-development/deployment.yaml +4 -2
  23. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  24. package/manifests/deployment/dd-test-development/deployment.yaml +4 -2
  25. package/manifests/kind-config-dev.yaml +8 -0
  26. package/manifests/lxd/lxd-admin-profile.yaml +12 -3
  27. package/manifests/mongodb/pv-pvc.yaml +44 -8
  28. package/manifests/mongodb/statefulset.yaml +55 -68
  29. package/manifests/mongodb-4.4/headless-service.yaml +10 -0
  30. package/manifests/mongodb-4.4/kustomization.yaml +3 -1
  31. package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
  32. package/manifests/mongodb-4.4/pv-pvc.yaml +10 -14
  33. package/manifests/mongodb-4.4/statefulset.yaml +79 -0
  34. package/manifests/mongodb-4.4/storage-class.yaml +9 -0
  35. package/manifests/valkey/statefulset.yaml +1 -1
  36. package/manifests/valkey/valkey-nodeport.yaml +17 -0
  37. package/package.json +27 -15
  38. package/scripts/ipxe-setup.sh +52 -49
  39. package/scripts/k3s-node-setup.sh +81 -46
  40. package/scripts/lxd-vm-setup.sh +193 -8
  41. package/scripts/maas-nat-firewalld.sh +145 -0
  42. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +38 -33
  43. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +16 -16
  44. package/src/api/core/core.router.js +19 -14
  45. package/src/api/core/core.service.js +5 -5
  46. package/src/api/crypto/crypto.router.js +18 -12
  47. package/src/api/crypto/crypto.service.js +3 -3
  48. package/src/api/cyberia-action/cyberia-action.model.js +1 -1
  49. package/src/api/cyberia-action/cyberia-action.router.js +22 -18
  50. package/src/api/cyberia-action/cyberia-action.service.js +5 -5
  51. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +74 -0
  52. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +99 -0
  53. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +98 -0
  54. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +152 -0
  55. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +25 -20
  56. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +6 -6
  57. package/src/api/cyberia-entity/cyberia-entity.router.js +22 -18
  58. package/src/api/cyberia-entity/cyberia-entity.service.js +5 -5
  59. package/src/api/cyberia-instance/cyberia-fallback-world.js +79 -4
  60. package/src/api/cyberia-instance/cyberia-instance.router.js +57 -52
  61. package/src/api/cyberia-instance/cyberia-instance.service.js +10 -10
  62. package/src/api/cyberia-instance/cyberia-world-generator.js +3 -3
  63. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +14 -48
  64. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +22 -18
  65. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +5 -5
  66. package/src/api/cyberia-map/cyberia-map.router.js +35 -30
  67. package/src/api/cyberia-map/cyberia-map.service.js +7 -7
  68. package/src/api/cyberia-quest/cyberia-quest.model.js +1 -1
  69. package/src/api/cyberia-quest/cyberia-quest.router.js +22 -18
  70. package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
  71. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +22 -18
  72. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +5 -5
  73. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +451 -0
  74. package/src/api/default/default.router.js +22 -18
  75. package/src/api/default/default.service.js +5 -5
  76. package/src/api/document/document.router.js +28 -23
  77. package/src/api/document/document.service.js +100 -23
  78. package/src/api/file/file.router.js +19 -13
  79. package/src/api/file/file.service.js +9 -7
  80. package/src/api/instance/instance.router.js +29 -24
  81. package/src/api/instance/instance.service.js +6 -6
  82. package/src/api/ipfs/ipfs.router.js +21 -16
  83. package/src/api/ipfs/ipfs.service.js +8 -8
  84. package/src/api/object-layer/object-layer.router.js +512 -507
  85. package/src/api/object-layer/object-layer.service.js +17 -14
  86. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +22 -18
  87. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +5 -5
  88. package/src/api/test/test.router.js +17 -12
  89. package/src/api/types.js +24 -0
  90. package/src/api/user/guest.service.js +5 -4
  91. package/src/api/user/user.router.js +297 -288
  92. package/src/api/user/user.service.js +100 -35
  93. package/src/cli/baremetal.js +132 -101
  94. package/src/cli/cluster.js +700 -232
  95. package/src/cli/db.js +59 -60
  96. package/src/cli/deploy.js +216 -137
  97. package/src/cli/fs.js +13 -3
  98. package/src/cli/index.js +80 -15
  99. package/src/cli/ipfs.js +4 -6
  100. package/src/cli/kubectl.js +4 -1
  101. package/src/cli/lxd.js +1099 -223
  102. package/src/cli/monitor.js +9 -3
  103. package/src/cli/release.js +334 -140
  104. package/src/cli/repository.js +68 -23
  105. package/src/cli/run.js +193 -49
  106. package/src/cli/secrets.js +11 -2
  107. package/src/cli/test.js +9 -3
  108. package/src/client/Default.index.js +9 -3
  109. package/src/client/components/core/Auth.js +5 -0
  110. package/src/client/components/core/ClientEvents.js +76 -0
  111. package/src/client/components/core/EventBus.js +4 -0
  112. package/src/client/components/core/Modal.js +82 -41
  113. package/src/client/components/core/PanelForm.js +56 -52
  114. package/src/client/components/core/Worker.js +162 -363
  115. package/src/client/components/cyberia/MapEngineCyberia.js +1 -1
  116. package/src/client/components/cyberia/SharedDefaultsCyberia.js +330 -0
  117. package/src/client/public/cyberia-docs/ARCHITECTURE.md +50 -410
  118. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +114 -327
  119. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +200 -222
  120. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +203 -185
  121. package/src/client/public/cyberia-docs/CYBERIA.md +259 -0
  122. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +2 -2
  123. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  124. package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +106 -0
  125. package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
  126. package/src/client/services/cyberia-client-hints/cyberia-client-hints.service.js +99 -0
  127. package/src/client/ssr/views/CyberiaServerMetrics.js +982 -0
  128. package/src/client/sw/core.sw.js +174 -112
  129. package/src/db/DataBaseProvider.js +115 -15
  130. package/src/db/mariadb/MariaDB.js +2 -1
  131. package/src/db/mongo/MongoBootstrap.js +657 -0
  132. package/src/db/mongo/MongooseDB.js +129 -21
  133. package/src/grpc/cyberia/grpc-server.js +25 -57
  134. package/src/index.js +1 -1
  135. package/src/runtime/cyberia-client/Dockerfile +24 -3
  136. package/src/runtime/cyberia-client/Dockerfile.dev +82 -0
  137. package/src/runtime/cyberia-server/Dockerfile +29 -4
  138. package/src/runtime/cyberia-server/Dockerfile.dev +71 -0
  139. package/src/runtime/express/Express.js +2 -2
  140. package/src/runtime/wp/Wp.js +8 -5
  141. package/src/server/auth.js +2 -2
  142. package/src/server/client-build-docs.js +1 -1
  143. package/src/server/client-build.js +94 -129
  144. package/src/server/conf.js +86 -83
  145. package/src/server/process.js +180 -19
  146. package/src/server/proxy.js +9 -2
  147. package/src/server/runtime.js +1 -1
  148. package/src/server/start.js +17 -5
  149. package/src/server/valkey.js +2 -0
  150. package/src/ws/IoInterface.js +16 -16
  151. package/src/ws/core/channels/core.ws.chat.js +11 -11
  152. package/src/ws/core/channels/core.ws.mailer.js +29 -29
  153. package/src/ws/core/channels/core.ws.stream.js +19 -19
  154. package/src/ws/core/core.ws.connection.js +8 -8
  155. package/src/ws/core/core.ws.server.js +6 -5
  156. package/src/ws/default/channels/default.ws.main.js +10 -10
  157. package/src/ws/default/default.ws.connection.js +4 -4
  158. package/src/ws/default/default.ws.server.js +4 -3
  159. package/bin/file.js +0 -202
  160. package/bin/vs.js +0 -74
  161. package/bin/zed.js +0 -84
  162. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +0 -574
  163. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +0 -467
  164. package/src/client/ssr/email/DefaultRecoverEmail.js +0 -21
  165. package/src/client/ssr/email/DefaultVerifyEmail.js +0 -17
  166. package/src/client/ssr/pages/CyberiaServerMetrics.js +0 -461
  167. /package/src/client/ssr/{offline → views}/Maintenance.js +0 -0
  168. /package/src/client/ssr/{offline → views}/NoNetworkConnection.js +0 -0
  169. /package/src/client/ssr/{pages → views}/Test.js +0 -0
@@ -5,59 +5,64 @@ import express from 'express';
5
5
 
6
6
  const logger = loggerFactory(import.meta);
7
7
 
8
- const CyberiaInstanceRouter = (options) => {
9
- const router = express.Router();
10
- const authMiddleware = options.authMiddleware;
11
- // ── Custom actions (must come before generic /:id routes) ──────────────
12
- router.get(`/fallback-world`, async (req, res) => await CyberiaInstanceController.fallbackWorld(req, res, options));
13
- router.get(
14
- `/:id/portal-connect`,
15
- authMiddleware,
16
- userGuard,
17
- async (req, res) => await CyberiaInstanceController.portalConnect(req, res, options),
18
- );
8
+ class CyberiaInstanceRouter {
9
+ /**
10
+ * @param {import('../types.js').RouterOptions} options
11
+ * @returns {import('express').Router}
12
+ */
13
+ static router(options) {
14
+ const router = express.Router();
15
+ // ── Custom actions (must come before generic /:id routes) ──────────────
16
+ router.get(`/fallback-world`, async (req, res) => await CyberiaInstanceController.fallbackWorld(req, res, options));
17
+ router.get(
18
+ `/:id/portal-connect`,
19
+ options.authMiddleware,
20
+ userGuard,
21
+ async (req, res) => await CyberiaInstanceController.portalConnect(req, res, options),
22
+ );
19
23
 
20
- router.post(
21
- `/:id`,
22
- authMiddleware,
23
- userGuard,
24
- async (req, res) => await CyberiaInstanceController.post(req, res, options),
25
- );
26
- router.post(
27
- `/`,
28
- authMiddleware,
29
- userGuard,
30
- async (req, res) => await CyberiaInstanceController.post(req, res, options),
31
- );
32
- router.get(`/:id`, async (req, res) => await CyberiaInstanceController.get(req, res, options));
33
- router.get(`/`, async (req, res) => await CyberiaInstanceController.get(req, res, options));
34
- router.put(
35
- `/:id`,
36
- authMiddleware,
37
- userGuard,
38
- async (req, res) => await CyberiaInstanceController.put(req, res, options),
39
- );
40
- router.put(
41
- `/`,
42
- authMiddleware,
43
- userGuard,
44
- async (req, res) => await CyberiaInstanceController.put(req, res, options),
45
- );
46
- router.delete(
47
- `/:id`,
48
- authMiddleware,
49
- userGuard,
50
- async (req, res) => await CyberiaInstanceController.delete(req, res, options),
51
- );
52
- router.delete(
53
- `/`,
54
- authMiddleware,
55
- adminGuard,
56
- async (req, res) => await CyberiaInstanceController.delete(req, res, options),
57
- );
58
- return router;
59
- };
24
+ router.post(
25
+ `/:id`,
26
+ options.authMiddleware,
27
+ userGuard,
28
+ async (req, res) => await CyberiaInstanceController.post(req, res, options),
29
+ );
30
+ router.post(
31
+ `/`,
32
+ options.authMiddleware,
33
+ userGuard,
34
+ async (req, res) => await CyberiaInstanceController.post(req, res, options),
35
+ );
36
+ router.get(`/:id`, async (req, res) => await CyberiaInstanceController.get(req, res, options));
37
+ router.get(`/`, async (req, res) => await CyberiaInstanceController.get(req, res, options));
38
+ router.put(
39
+ `/:id`,
40
+ options.authMiddleware,
41
+ userGuard,
42
+ async (req, res) => await CyberiaInstanceController.put(req, res, options),
43
+ );
44
+ router.put(
45
+ `/`,
46
+ options.authMiddleware,
47
+ userGuard,
48
+ async (req, res) => await CyberiaInstanceController.put(req, res, options),
49
+ );
50
+ router.delete(
51
+ `/:id`,
52
+ options.authMiddleware,
53
+ userGuard,
54
+ async (req, res) => await CyberiaInstanceController.delete(req, res, options),
55
+ );
56
+ router.delete(
57
+ `/`,
58
+ options.authMiddleware,
59
+ adminGuard,
60
+ async (req, res) => await CyberiaInstanceController.delete(req, res, options),
61
+ );
62
+ return router;
63
+ }
64
+ }
60
65
 
61
- const ApiRouter = CyberiaInstanceRouter;
66
+ const ApiRouter = (options) => CyberiaInstanceRouter.router(options);
62
67
 
63
68
  export { ApiRouter, CyberiaInstanceRouter };
@@ -1,4 +1,4 @@
1
- import { DataBaseProvider } from '../../db/DataBaseProvider.js';
1
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
2
  import { loggerFactory } from '../../server/logger.js';
3
3
  import { DataQuery } from '../../server/data-query.js';
4
4
  import { connectPortals } from './cyberia-portal-connector.js';
@@ -9,9 +9,9 @@ const logger = loggerFactory(import.meta);
9
9
  class CyberiaInstanceService {
10
10
  static post = async (req, res, options) => {
11
11
  /** @type {import('./cyberia-instance.model.js').CyberiaInstanceModel} */
12
- const CyberiaInstance = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstance;
12
+ const CyberiaInstance = DataBaseProviderService.getModel("CyberiaInstance", options);
13
13
  const CyberiaInstanceConf =
14
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
14
+ DataBaseProviderService.getModel("CyberiaInstanceConf", options);
15
15
  if (req.auth && req.auth.user) req.body.creator = req.auth.user._id;
16
16
  const instance = await new CyberiaInstance(req.body).save();
17
17
 
@@ -37,7 +37,7 @@ class CyberiaInstanceService {
37
37
  };
38
38
  static get = async (req, res, options) => {
39
39
  /** @type {import('./cyberia-instance.model.js').CyberiaInstanceModel} */
40
- const CyberiaInstance = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstance;
40
+ const CyberiaInstance = DataBaseProviderService.getModel("CyberiaInstance", options);
41
41
  const populateCreator = { path: 'creator', model: 'User', select: '_id username' };
42
42
  if (req.params.id) return await CyberiaInstance.findById(req.params.id).populate(populateCreator);
43
43
 
@@ -54,13 +54,13 @@ class CyberiaInstanceService {
54
54
  };
55
55
  static put = async (req, res, options) => {
56
56
  /** @type {import('./cyberia-instance.model.js').CyberiaInstanceModel} */
57
- const CyberiaInstance = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstance;
57
+ const CyberiaInstance = DataBaseProviderService.getModel("CyberiaInstance", options);
58
58
  const instance = await CyberiaInstance.findById(req.params.id);
59
59
  if (!instance) throw new Error('instance not found');
60
60
  if (req.auth.user.role !== 'admin' && String(instance.creator) !== String(req.auth.user._id))
61
61
  throw new Error('insufficient permission');
62
62
  if (req.body.thumbnail && instance.thumbnail && String(req.body.thumbnail) !== String(instance.thumbnail)) {
63
- const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
63
+ const File = DataBaseProviderService.getModel("File", options);
64
64
  await File.findByIdAndDelete(instance.thumbnail);
65
65
  }
66
66
  return await CyberiaInstance.findByIdAndUpdate(req.params.id, req.body, { returnDocument: 'after' });
@@ -80,8 +80,8 @@ class CyberiaInstanceService {
80
80
  * ?persist=true — save generated portals to DB
81
81
  */
82
82
  static portalConnect = async (req, res, options) => {
83
- const CyberiaInstance = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstance;
84
- const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
83
+ const CyberiaInstance = DataBaseProviderService.getModel("CyberiaInstance", options);
84
+ const CyberiaMap = DataBaseProviderService.getModel("CyberiaMap", options);
85
85
 
86
86
  const instance = await CyberiaInstance.findById(req.params.id).lean();
87
87
  if (!instance) throw new Error('instance not found');
@@ -116,14 +116,14 @@ class CyberiaInstanceService {
116
116
 
117
117
  static delete = async (req, res, options) => {
118
118
  /** @type {import('./cyberia-instance.model.js').CyberiaInstanceModel} */
119
- const CyberiaInstance = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstance;
119
+ const CyberiaInstance = DataBaseProviderService.getModel("CyberiaInstance", options);
120
120
  if (req.params.id) {
121
121
  const instance = await CyberiaInstance.findById(req.params.id);
122
122
  if (!instance) throw new Error('instance not found');
123
123
  if (req.auth.user.role !== 'admin' && String(instance.creator) !== String(req.auth.user._id))
124
124
  throw new Error('insufficient permission');
125
125
  if (instance.thumbnail) {
126
- const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
126
+ const File = DataBaseProviderService.getModel("File", options);
127
127
  await File.findByIdAndDelete(instance.thumbnail);
128
128
  }
129
129
  return await CyberiaInstance.findByIdAndDelete(req.params.id);
@@ -19,9 +19,9 @@
19
19
  import {
20
20
  ENTITY_TYPE_DEFAULTS,
21
21
  RESOURCE_ENTITY_TYPE_DEFAULTS,
22
- } from '../cyberia-instance-conf/cyberia-instance-conf.defaults.js';
23
-
24
- import { DefaultCyberiaItems, ITEM_TYPES } from '../../client/components/cyberia-portal/CommonCyberiaPortal.js';
22
+ DefaultCyberiaItems,
23
+ ITEM_TYPES,
24
+ } from '../cyberia-server-defaults/cyberia-server-defaults.js';
25
25
 
26
26
  import { PORTAL_MODES, PORTAL_MODE_COLOR_KEY, EXTRA_PORTAL_MODES } from './cyberia-portal-connector.js';
27
27
 
@@ -1,16 +1,5 @@
1
1
  import { Schema, model } from 'mongoose';
2
- import { CYBERIA_INSTANCE_CONF_DEFAULTS as D } from './cyberia-instance-conf.defaults.js';
3
-
4
- const ColorEntrySchema = new Schema(
5
- {
6
- key: { type: String, required: true },
7
- r: { type: Number, default: 0 },
8
- g: { type: Number, default: 0 },
9
- b: { type: Number, default: 0 },
10
- a: { type: Number, default: 255 },
11
- },
12
- { _id: false },
13
- );
2
+ import { CYBERIA_INSTANCE_CONF_DEFAULTS as D } from '../cyberia-server-defaults/cyberia-server-defaults.js';
14
3
 
15
4
  // ObjectLayer inventory slot: itemId + whether it starts active + initial quantity.
16
5
  // Used by EntityDefaultSchema.defaultObjectLayers.
@@ -23,6 +12,9 @@ const ObjectLayerSlotSchema = new Schema(
23
12
  { _id: false },
24
13
  );
25
14
 
15
+ // Per-entity-type simulation defaults. ONLY authoritative item-id wiring
16
+ // lives here — presentation (palette, colour keys) is the client's
17
+ // responsibility and travels through the CyberiaClientHints REST contract.
26
18
  const EntityDefaultSchema = new Schema(
27
19
  {
28
20
  // Entity category string (matches entity_type_str / bot Behavior in game engine)
@@ -30,13 +22,10 @@ const EntityDefaultSchema = new Schema(
30
22
  // Default ObjectLayer item IDs when the entity is alive and carries no assigned items.
31
23
  liveItemIds: { type: [String], default: [] },
32
24
  // Default ObjectLayer item IDs for the dead / ghost / respawning state.
33
- // Empty array = use liveItemIds solid fill color.
34
25
  deadItemIds: { type: [String], default: [] },
35
26
  // Resource-only inventory items granted on extraction/depletion.
36
27
  // These are not auto-activated on the entity itself.
37
28
  dropItemIds: { type: [String], default: [] },
38
- // Palette key for solid-color fallback when no OL items are assigned.
39
- colorKey: { type: String, default: '' },
40
29
  // Full default ObjectLayer inventory for this entity type.
41
30
  // Each entry specifies itemId, whether it starts active, and its initial quantity.
42
31
  // The coin slot must always have active:false — coins are non-activable.
@@ -55,26 +44,14 @@ const SkillConfigEntrySchema = new Schema(
55
44
  );
56
45
 
57
46
  // ── StatusIconEntrySchema ────────────────────────────────────────────────────
58
- // Maps a u8 status ID to an overhead icon and a border colour used by the
59
- // interaction bubble / interact overlay on the C/WASM client.
60
- // See STATUS_ICONS in cyberia-instance-conf.defaults.js.
61
- const StatusIconBorderColorSchema = new Schema(
62
- {
63
- r: { type: Number, default: 100 },
64
- g: { type: Number, default: 100 },
65
- b: { type: Number, default: 100 },
66
- a: { type: Number, default: 200 },
67
- },
68
- { _id: false },
69
- );
70
-
47
+ // Numeric Entity Status Indicator (ESI) IDs. The Go server stamps one of
48
+ // these u8 IDs on every entity in the AOI binary wire format. Visual
49
+ // resolution (icon stem, border colour, bounce) is the C client's job and
50
+ // arrives through the /api/cyberia-client-hints REST contract — NOT here.
71
51
  const StatusIconEntrySchema = new Schema(
72
52
  {
73
53
  id: { type: Number, required: true },
74
54
  name: { type: String, default: '' },
75
- iconId: { type: String, default: null },
76
- bounce: { type: Boolean, default: false },
77
- borderColor: { type: StatusIconBorderColorSchema },
78
55
  description: { type: String, default: '' },
79
56
  },
80
57
  { _id: false },
@@ -82,7 +59,7 @@ const StatusIconEntrySchema = new Schema(
82
59
 
83
60
  // ── EconomyRulesSchema ───────────────────────────────────────────────────────
84
61
  // Mirrors the EconomyRules proto message and the economyRules sub-document in
85
- // cyberia-instance-conf.defaults.js. All fields default from those canonical
62
+ // cyberia-server-defaults.js. All fields default from those canonical
86
63
  // values so a freshly created document is immediately playable.
87
64
  // See OFF_CHAIN_ECONOMY.md for the full Fountain & Sink architecture.
88
65
  const EconomyRulesSchema = new Schema(
@@ -105,7 +82,7 @@ const EconomyRulesSchema = new Schema(
105
82
  // ── EquipmentRulesSchema ─────────────────────────────────────────────────────
106
83
  // Governs which ObjectLayer item types can be simultaneously active on a
107
84
  // character entity and enforces the one-active-per-type constraint.
108
- // See EQUIPMENT_RULES_DEFAULTS in cyberia-instance-conf.defaults.js.
85
+ // See EQUIPMENT_RULES_DEFAULTS in cyberia-server-defaults.js.
109
86
  const EquipmentRulesSchema = new Schema(
110
87
  {
111
88
  // Item types that players are allowed to activate (equip).
@@ -147,20 +124,9 @@ const CyberiaInstanceConfSchema = new Schema(
147
124
  // Back-reference to the owning instance (indexed for fast lookup by code).
148
125
  instanceCode: { type: String, required: true, unique: true, trim: true },
149
126
 
150
- // ── Rendering / camera ──────────────────────────────────────────
151
- cellSize: { type: Number, default: D.cellSize },
152
- fps: { type: Number, default: D.fps },
153
- interpolationMs: { type: Number, default: D.interpolationMs },
154
- defaultObjWidth: { type: Number, default: D.defaultObjWidth },
155
- defaultObjHeight: { type: Number, default: D.defaultObjHeight },
156
- cameraSmoothing: { type: Number, default: D.cameraSmoothing },
157
- cameraZoom: { type: Number, default: D.cameraZoom },
158
- defaultWidthScreenFactor: { type: Number, default: D.defaultWidthScreenFactor },
159
- defaultHeightScreenFactor: { type: Number, default: D.defaultHeightScreenFactor },
160
- devUi: { type: Boolean, default: D.devUi },
161
- // Empty array by default — colours must be configured per-instance.
162
- // toInstanceConfig() fills in CYBERIA_INSTANCE_CONF_DEFAULTS.colors when the array is empty.
163
- colors: { type: [ColorEntrySchema], default: [] },
127
+ // ── Tick model (authoritative simulation cadence) ─────────────────
128
+ tickRate: { type: Number, default: D.tickRate },
129
+ snapshotRate: { type: Number, default: D.snapshotRate },
164
130
 
165
131
  // ── World / AOI ─────────────────────────────────────────────────
166
132
  aoiRadius: { type: Number, default: D.aoiRadius },
@@ -205,7 +171,7 @@ const CyberiaInstanceConfSchema = new Schema(
205
171
 
206
172
  // ── Entity Status Indicators ────────────────────────────────────
207
173
  // Overhead icon mapping + per-status border colour.
208
- // See STATUS_ICONS in cyberia-instance-conf.defaults.js.
174
+ // See STATUS_ICONS in cyberia-server-defaults.js.
209
175
  statusIcons: { type: [StatusIconEntrySchema], default: D.statusIcons },
210
176
 
211
177
  // ── Skill system ─────────────────────────────────────────────────
@@ -4,24 +4,28 @@ import express from 'express';
4
4
 
5
5
  const logger = loggerFactory(import.meta);
6
6
 
7
- const CyberiaInstanceConfRouter = (options) => {
8
- const router = express.Router();
9
- const authMiddleware = options.authMiddleware;
10
- router.post(`/:id`, async (req, res) => await CyberiaInstanceConfController.post(req, res, options));
11
- router.post(`/`, async (req, res) => await CyberiaInstanceConfController.post(req, res, options));
12
- router.get(
13
- `/:id`,
14
- // authMiddleware,
15
- async (req, res) => await CyberiaInstanceConfController.get(req, res, options),
16
- );
17
- router.get(`/`, async (req, res) => await CyberiaInstanceConfController.get(req, res, options));
18
- router.put(`/:id`, async (req, res) => await CyberiaInstanceConfController.put(req, res, options));
19
- router.put(`/`, async (req, res) => await CyberiaInstanceConfController.put(req, res, options));
20
- router.delete(`/:id`, async (req, res) => await CyberiaInstanceConfController.delete(req, res, options));
21
- router.delete(`/`, async (req, res) => await CyberiaInstanceConfController.delete(req, res, options));
22
- return router;
23
- };
7
+ class CyberiaInstanceConfRouter {
8
+ /**
9
+ * @param {import('../types.js').RouterOptions} options
10
+ * @returns {import('express').Router}
11
+ */
12
+ static router(options) {
13
+ const router = express.Router();
14
+ router.post(`/:id`, async (req, res) => await CyberiaInstanceConfController.post(req, res, options));
15
+ router.post(`/`, async (req, res) => await CyberiaInstanceConfController.post(req, res, options));
16
+ router.get(`/:id`,
17
+ // options.authMiddleware,
18
+ async (req, res) => await CyberiaInstanceConfController.get(req, res, options),
19
+ );
20
+ router.get(`/`, async (req, res) => await CyberiaInstanceConfController.get(req, res, options));
21
+ router.put(`/:id`, async (req, res) => await CyberiaInstanceConfController.put(req, res, options));
22
+ router.put(`/`, async (req, res) => await CyberiaInstanceConfController.put(req, res, options));
23
+ router.delete(`/:id`, async (req, res) => await CyberiaInstanceConfController.delete(req, res, options));
24
+ router.delete(`/`, async (req, res) => await CyberiaInstanceConfController.delete(req, res, options));
25
+ return router;
26
+ }
27
+ }
24
28
 
25
- const ApiRouter = CyberiaInstanceConfRouter;
29
+ const ApiRouter = (options) => CyberiaInstanceConfRouter.router(options);
26
30
 
27
31
  export { ApiRouter, CyberiaInstanceConfRouter };
@@ -1,4 +1,4 @@
1
- import { DataBaseProvider } from '../../db/DataBaseProvider.js';
1
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
2
  import { loggerFactory } from '../../server/logger.js';
3
3
  import { DataQuery } from '../../server/data-query.js';
4
4
 
@@ -8,13 +8,13 @@ class CyberiaInstanceConfService {
8
8
  static post = async (req, res, options) => {
9
9
  /** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
10
10
  const CyberiaInstanceConf =
11
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
11
+ DataBaseProviderService.getModel("CyberiaInstanceConf", options);
12
12
  return await new CyberiaInstanceConf(req.body).save();
13
13
  };
14
14
  static get = async (req, res, options) => {
15
15
  /** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
16
16
  const CyberiaInstanceConf =
17
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
17
+ DataBaseProviderService.getModel("CyberiaInstanceConf", options);
18
18
  if (req.params.id) return await CyberiaInstanceConf.findById(req.params.id);
19
19
 
20
20
  // Parse query parameters using DataQuery helper
@@ -31,13 +31,13 @@ class CyberiaInstanceConfService {
31
31
  static put = async (req, res, options) => {
32
32
  /** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
33
33
  const CyberiaInstanceConf =
34
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
34
+ DataBaseProviderService.getModel("CyberiaInstanceConf", options);
35
35
  return await CyberiaInstanceConf.findByIdAndUpdate(req.params.id, req.body);
36
36
  };
37
37
  static delete = async (req, res, options) => {
38
38
  /** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
39
39
  const CyberiaInstanceConf =
40
- DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
40
+ DataBaseProviderService.getModel("CyberiaInstanceConf", options);
41
41
  if (req.params.id) return await CyberiaInstanceConf.findByIdAndDelete(req.params.id);
42
42
  else return await CyberiaInstanceConf.deleteMany();
43
43
  };
@@ -5,36 +5,41 @@ import express from 'express';
5
5
 
6
6
  const logger = loggerFactory(import.meta);
7
7
 
8
- const CyberiaMapRouter = (options) => {
9
- const router = express.Router();
10
- const authMiddleware = options.authMiddleware;
11
- router.post(
12
- `/:id`,
13
- authMiddleware,
14
- userGuard,
15
- async (req, res) => await CyberiaMapController.post(req, res, options),
16
- );
17
- router.post(`/`, authMiddleware, userGuard, async (req, res) => await CyberiaMapController.post(req, res, options));
18
- router.get(`/search-codes`, async (req, res) => await CyberiaMapController.get(req, res, options));
19
- router.get(`/:id`, async (req, res) => await CyberiaMapController.get(req, res, options));
20
- router.get(`/`, async (req, res) => await CyberiaMapController.get(req, res, options));
21
- router.put(`/:id`, authMiddleware, userGuard, async (req, res) => await CyberiaMapController.put(req, res, options));
22
- router.put(`/`, authMiddleware, userGuard, async (req, res) => await CyberiaMapController.put(req, res, options));
23
- router.delete(
24
- `/:id`,
25
- authMiddleware,
26
- userGuard,
27
- async (req, res) => await CyberiaMapController.delete(req, res, options),
28
- );
29
- router.delete(
30
- `/`,
31
- authMiddleware,
32
- adminGuard,
33
- async (req, res) => await CyberiaMapController.delete(req, res, options),
34
- );
35
- return router;
36
- };
8
+ class CyberiaMapRouter {
9
+ /**
10
+ * @param {import('../types.js').RouterOptions} options
11
+ * @returns {import('express').Router}
12
+ */
13
+ static router(options) {
14
+ const router = express.Router();
15
+ router.post(
16
+ `/:id`,
17
+ options.authMiddleware,
18
+ userGuard,
19
+ async (req, res) => await CyberiaMapController.post(req, res, options),
20
+ );
21
+ router.post(`/`, options.authMiddleware, userGuard, async (req, res) => await CyberiaMapController.post(req, res, options));
22
+ router.get(`/search-codes`, async (req, res) => await CyberiaMapController.get(req, res, options));
23
+ router.get(`/:id`, async (req, res) => await CyberiaMapController.get(req, res, options));
24
+ router.get(`/`, async (req, res) => await CyberiaMapController.get(req, res, options));
25
+ router.put(`/:id`, options.authMiddleware, userGuard, async (req, res) => await CyberiaMapController.put(req, res, options));
26
+ router.put(`/`, options.authMiddleware, userGuard, async (req, res) => await CyberiaMapController.put(req, res, options));
27
+ router.delete(
28
+ `/:id`,
29
+ options.authMiddleware,
30
+ userGuard,
31
+ async (req, res) => await CyberiaMapController.delete(req, res, options),
32
+ );
33
+ router.delete(
34
+ `/`,
35
+ options.authMiddleware,
36
+ adminGuard,
37
+ async (req, res) => await CyberiaMapController.delete(req, res, options),
38
+ );
39
+ return router;
40
+ }
41
+ }
37
42
 
38
- const ApiRouter = CyberiaMapRouter;
43
+ const ApiRouter = (options) => CyberiaMapRouter.router(options);
39
44
 
40
45
  export { ApiRouter, CyberiaMapRouter };
@@ -1,4 +1,4 @@
1
- import { DataBaseProvider } from '../../db/DataBaseProvider.js';
1
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
2
  import { loggerFactory } from '../../server/logger.js';
3
3
  import { DataQuery } from '../../server/data-query.js';
4
4
 
@@ -7,13 +7,13 @@ const logger = loggerFactory(import.meta);
7
7
  class CyberiaMapService {
8
8
  static post = async (req, res, options) => {
9
9
  /** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
10
- const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
10
+ const CyberiaMap = DataBaseProviderService.getModel("CyberiaMap", options);
11
11
  if (req.auth && req.auth.user) req.body.creator = req.auth.user._id;
12
12
  return await new CyberiaMap(req.body).save();
13
13
  };
14
14
  static get = async (req, res, options) => {
15
15
  /** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
16
- const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
16
+ const CyberiaMap = DataBaseProviderService.getModel("CyberiaMap", options);
17
17
  const populateCreator = { path: 'creator', model: 'User', select: '_id username' };
18
18
 
19
19
  // GET /search-codes?q=<partial> - Fast partial match search on code
@@ -43,27 +43,27 @@ class CyberiaMapService {
43
43
  };
44
44
  static put = async (req, res, options) => {
45
45
  /** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
46
- const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
46
+ const CyberiaMap = DataBaseProviderService.getModel("CyberiaMap", options);
47
47
  const map = await CyberiaMap.findById(req.params.id);
48
48
  if (!map) throw new Error('map not found');
49
49
  if (req.auth.user.role !== 'admin' && String(map.creator) !== String(req.auth.user._id))
50
50
  throw new Error('insufficient permission');
51
51
  if (req.body.thumbnail && map.thumbnail && String(req.body.thumbnail) !== String(map.thumbnail)) {
52
- const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
52
+ const File = DataBaseProviderService.getModel("File", options);
53
53
  await File.findByIdAndDelete(map.thumbnail);
54
54
  }
55
55
  return await CyberiaMap.findByIdAndUpdate(req.params.id, req.body, { returnDocument: 'after' });
56
56
  };
57
57
  static delete = async (req, res, options) => {
58
58
  /** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
59
- const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
59
+ const CyberiaMap = DataBaseProviderService.getModel("CyberiaMap", options);
60
60
  if (req.params.id) {
61
61
  const map = await CyberiaMap.findById(req.params.id);
62
62
  if (!map) throw new Error('map not found');
63
63
  if (req.auth.user.role !== 'admin' && String(map.creator) !== String(req.auth.user._id))
64
64
  throw new Error('insufficient permission');
65
65
  if (map.thumbnail) {
66
- const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
66
+ const File = DataBaseProviderService.getModel("File", options);
67
67
  await File.findByIdAndDelete(map.thumbnail);
68
68
  }
69
69
  return await CyberiaMap.findByIdAndDelete(req.params.id);
@@ -1,5 +1,5 @@
1
1
  import { Schema, model } from 'mongoose';
2
- import { QUEST_STEPS_TYPES } from '../../client/components/cyberia-portal/CommonCyberiaPortal.js';
2
+ import { QUEST_STEPS_TYPES } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
3
3
 
4
4
  // https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
5
5
 
@@ -4,24 +4,28 @@ import express from 'express';
4
4
 
5
5
  const logger = loggerFactory(import.meta);
6
6
 
7
- const CyberiaQuestRouter = (options) => {
8
- const router = express.Router();
9
- const authMiddleware = options.authMiddleware;
10
- router.post(`/:id`, async (req, res) => await CyberiaQuestController.post(req, res, options));
11
- router.post(`/`, async (req, res) => await CyberiaQuestController.post(req, res, options));
12
- router.get(
13
- `/:id`,
14
- // authMiddleware,
15
- async (req, res) => await CyberiaQuestController.get(req, res, options),
16
- );
17
- router.get(`/`, async (req, res) => await CyberiaQuestController.get(req, res, options));
18
- router.put(`/:id`, async (req, res) => await CyberiaQuestController.put(req, res, options));
19
- router.put(`/`, async (req, res) => await CyberiaQuestController.put(req, res, options));
20
- router.delete(`/:id`, async (req, res) => await CyberiaQuestController.delete(req, res, options));
21
- router.delete(`/`, async (req, res) => await CyberiaQuestController.delete(req, res, options));
22
- return router;
23
- };
7
+ class CyberiaQuestRouter {
8
+ /**
9
+ * @param {import('../types.js').RouterOptions} options
10
+ * @returns {import('express').Router}
11
+ */
12
+ static router(options) {
13
+ const router = express.Router();
14
+ router.post(`/:id`, async (req, res) => await CyberiaQuestController.post(req, res, options));
15
+ router.post(`/`, async (req, res) => await CyberiaQuestController.post(req, res, options));
16
+ router.get(`/:id`,
17
+ // options.authMiddleware,
18
+ async (req, res) => await CyberiaQuestController.get(req, res, options),
19
+ );
20
+ router.get(`/`, async (req, res) => await CyberiaQuestController.get(req, res, options));
21
+ router.put(`/:id`, async (req, res) => await CyberiaQuestController.put(req, res, options));
22
+ router.put(`/`, async (req, res) => await CyberiaQuestController.put(req, res, options));
23
+ router.delete(`/:id`, async (req, res) => await CyberiaQuestController.delete(req, res, options));
24
+ router.delete(`/`, async (req, res) => await CyberiaQuestController.delete(req, res, options));
25
+ return router;
26
+ }
27
+ }
24
28
 
25
- const ApiRouter = CyberiaQuestRouter;
29
+ const ApiRouter = (options) => CyberiaQuestRouter.router(options);
26
30
 
27
31
  export { ApiRouter, CyberiaQuestRouter };
@@ -1,4 +1,4 @@
1
- import { DataBaseProvider } from '../../db/DataBaseProvider.js';
1
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
2
2
  import { loggerFactory } from '../../server/logger.js';
3
3
  import { DataQuery } from '../../server/data-query.js';
4
4
 
@@ -7,12 +7,12 @@ const logger = loggerFactory(import.meta);
7
7
  class CyberiaQuestService {
8
8
  static post = async (req, res, options) => {
9
9
  /** @type {import('./cyberia-quest.model.js').CyberiaQuestModel} */
10
- const CyberiaQuest = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuest;
10
+ const CyberiaQuest = DataBaseProviderService.getModel("CyberiaQuest", options);
11
11
  return await new CyberiaQuest(req.body).save();
12
12
  };
13
13
  static get = async (req, res, options) => {
14
14
  /** @type {import('./cyberia-quest.model.js').CyberiaQuestModel} */
15
- const CyberiaQuest = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuest;
15
+ const CyberiaQuest = DataBaseProviderService.getModel("CyberiaQuest", options);
16
16
  if (req.params.id) return await CyberiaQuest.findById(req.params.id);
17
17
 
18
18
  // Parse query parameters using DataQuery helper
@@ -28,12 +28,12 @@ class CyberiaQuestService {
28
28
  };
29
29
  static put = async (req, res, options) => {
30
30
  /** @type {import('./cyberia-quest.model.js').CyberiaQuestModel} */
31
- const CyberiaQuest = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuest;
31
+ const CyberiaQuest = DataBaseProviderService.getModel("CyberiaQuest", options);
32
32
  return await CyberiaQuest.findByIdAndUpdate(req.params.id, req.body);
33
33
  };
34
34
  static delete = async (req, res, options) => {
35
35
  /** @type {import('./cyberia-quest.model.js').CyberiaQuestModel} */
36
- const CyberiaQuest = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaQuest;
36
+ const CyberiaQuest = DataBaseProviderService.getModel("CyberiaQuest", options);
37
37
  if (req.params.id) return await CyberiaQuest.findByIdAndDelete(req.params.id);
38
38
  else return await CyberiaQuest.deleteMany();
39
39
  };