cyberia 3.2.5 → 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 (381) hide show
  1. package/.github/workflows/engine-cyberia.cd.yml +8 -2
  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 +2 -2
  5. package/.vscode/extensions.json +9 -9
  6. package/.vscode/settings.json +20 -4
  7. package/CHANGELOG.md +563 -1
  8. package/CLI-HELP.md +130 -34
  9. package/Dockerfile +0 -4
  10. package/README.md +194 -607
  11. package/bin/build.js +42 -12
  12. package/bin/build.template.js +187 -0
  13. package/bin/cyberia.js +1367 -281
  14. package/bin/deploy.js +582 -3
  15. package/bin/index.js +1367 -281
  16. package/bump.config.js +26 -0
  17. package/conf.js +195 -111
  18. package/deployment.yaml +6 -222
  19. package/hardhat/package-lock.json +118 -149
  20. package/hardhat/package.json +5 -4
  21. package/jsconfig.json +1 -1
  22. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
  23. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +2 -2
  24. package/manifests/deployment/dd-cyberia-development/deployment.yaml +6 -222
  25. package/manifests/deployment/dd-cyberia-development/proxy.yaml +10 -118
  26. package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
  27. package/manifests/deployment/dd-test-development/deployment.yaml +138 -66
  28. package/manifests/deployment/dd-test-development/proxy.yaml +41 -5
  29. package/manifests/kind-config-dev.yaml +8 -0
  30. package/manifests/lxd/lxd-admin-profile.yaml +12 -3
  31. package/manifests/mongodb/pv-pvc.yaml +44 -8
  32. package/manifests/mongodb/statefulset.yaml +55 -68
  33. package/manifests/mongodb-4.4/headless-service.yaml +10 -0
  34. package/manifests/mongodb-4.4/kustomization.yaml +3 -1
  35. package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
  36. package/manifests/mongodb-4.4/pv-pvc.yaml +10 -14
  37. package/manifests/mongodb-4.4/statefulset.yaml +79 -0
  38. package/manifests/mongodb-4.4/storage-class.yaml +9 -0
  39. package/manifests/valkey/statefulset.yaml +1 -1
  40. package/manifests/valkey/valkey-nodeport.yaml +17 -0
  41. package/package.json +45 -24
  42. package/proxy.yaml +10 -118
  43. package/scripts/ipxe-setup.sh +52 -49
  44. package/scripts/k3s-node-setup.sh +83 -48
  45. package/scripts/lxd-vm-setup.sh +193 -8
  46. package/scripts/maas-nat-firewalld.sh +145 -0
  47. package/scripts/nat-iptables.sh +103 -18
  48. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +18 -18
  49. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +7 -14
  50. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +38 -33
  51. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +91 -36
  52. package/src/api/core/core.controller.js +10 -10
  53. package/src/api/core/core.router.js +19 -14
  54. package/src/api/core/core.service.js +15 -15
  55. package/src/api/crypto/crypto.controller.js +8 -8
  56. package/src/api/crypto/crypto.router.js +18 -12
  57. package/src/api/crypto/crypto.service.js +11 -11
  58. package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
  59. package/src/api/cyberia-action/cyberia-action.model.js +87 -0
  60. package/src/api/cyberia-action/cyberia-action.router.js +31 -0
  61. package/src/api/cyberia-action/cyberia-action.service.js +42 -0
  62. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +74 -0
  63. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +99 -0
  64. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +98 -0
  65. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +152 -0
  66. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +13 -13
  67. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +11 -11
  68. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +25 -20
  69. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +22 -22
  70. package/src/api/cyberia-entity/cyberia-entity.controller.js +10 -10
  71. package/src/api/cyberia-entity/cyberia-entity.router.js +22 -18
  72. package/src/api/cyberia-entity/cyberia-entity.service.js +15 -15
  73. package/src/api/cyberia-instance/cyberia-fallback-world.js +83 -198
  74. package/src/api/cyberia-instance/cyberia-instance.controller.js +14 -14
  75. package/src/api/cyberia-instance/cyberia-instance.model.js +3 -0
  76. package/src/api/cyberia-instance/cyberia-instance.router.js +57 -52
  77. package/src/api/cyberia-instance/cyberia-instance.service.js +32 -67
  78. package/src/api/cyberia-instance/cyberia-portal-connector.js +20 -246
  79. package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
  80. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +10 -10
  81. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +18 -49
  82. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +22 -18
  83. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +19 -15
  84. package/src/api/cyberia-map/cyberia-map.controller.js +10 -10
  85. package/src/api/cyberia-map/cyberia-map.router.js +35 -30
  86. package/src/api/cyberia-map/cyberia-map.service.js +17 -17
  87. package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
  88. package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
  89. package/src/api/cyberia-quest/cyberia-quest.router.js +31 -0
  90. package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
  91. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
  92. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
  93. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +31 -0
  94. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
  95. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +451 -0
  96. package/src/api/default/default.controller.js +10 -10
  97. package/src/api/default/default.router.js +22 -18
  98. package/src/api/default/default.service.js +15 -15
  99. package/src/api/document/document.controller.js +12 -12
  100. package/src/api/document/document.model.js +10 -16
  101. package/src/api/document/document.router.js +28 -23
  102. package/src/api/document/document.service.js +100 -23
  103. package/src/api/file/file.controller.js +8 -8
  104. package/src/api/file/file.model.js +10 -10
  105. package/src/api/file/file.router.js +19 -13
  106. package/src/api/file/file.service.js +45 -43
  107. package/src/api/instance/instance.controller.js +10 -10
  108. package/src/api/instance/instance.model.js +4 -10
  109. package/src/api/instance/instance.router.js +29 -24
  110. package/src/api/instance/instance.service.js +16 -16
  111. package/src/api/ipfs/ipfs.controller.js +12 -12
  112. package/src/api/ipfs/ipfs.model.js +4 -13
  113. package/src/api/ipfs/ipfs.router.js +21 -16
  114. package/src/api/ipfs/ipfs.service.js +22 -36
  115. package/src/api/object-layer/object-layer.controller.js +12 -12
  116. package/src/api/object-layer/object-layer.model.js +4 -17
  117. package/src/api/object-layer/object-layer.router.js +512 -507
  118. package/src/api/object-layer/object-layer.service.js +29 -26
  119. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
  120. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
  121. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +22 -18
  122. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +19 -15
  123. package/src/api/test/test.controller.js +8 -8
  124. package/src/api/test/test.router.js +17 -12
  125. package/src/api/test/test.service.js +8 -8
  126. package/src/api/types.js +24 -0
  127. package/src/api/user/guest.service.js +100 -0
  128. package/src/api/user/user.controller.js +6 -6
  129. package/src/api/user/user.model.js +8 -13
  130. package/src/api/user/user.router.js +297 -288
  131. package/src/api/user/user.service.js +103 -55
  132. package/src/cli/baremetal.js +132 -101
  133. package/src/cli/cluster.js +732 -217
  134. package/src/cli/db.js +106 -62
  135. package/src/cli/deploy.js +260 -149
  136. package/src/cli/fs.js +90 -9
  137. package/src/cli/image.js +43 -1
  138. package/src/cli/index.js +106 -16
  139. package/src/cli/ipfs.js +4 -6
  140. package/src/cli/kubectl.js +4 -1
  141. package/src/cli/lxd.js +1099 -223
  142. package/src/cli/monitor.js +9 -3
  143. package/src/cli/release.js +336 -86
  144. package/src/cli/repository.js +136 -53
  145. package/src/cli/run.js +599 -76
  146. package/src/cli/secrets.js +11 -2
  147. package/src/cli/ssh.js +1 -1
  148. package/src/cli/static.js +43 -115
  149. package/src/cli/test.js +9 -3
  150. package/src/client/Cryptokoyn.index.js +18 -21
  151. package/src/client/CyberiaPortal.index.js +19 -23
  152. package/src/client/Default.index.js +30 -36
  153. package/src/client/Itemledger.index.js +20 -26
  154. package/src/client/Underpost.index.js +19 -23
  155. package/src/client/components/core/404.js +4 -4
  156. package/src/client/components/core/500.js +4 -4
  157. package/src/client/components/core/Account.js +73 -60
  158. package/src/client/components/core/AgGrid.js +23 -33
  159. package/src/client/components/core/Alert.js +12 -13
  160. package/src/client/components/core/AppStore.js +1 -1
  161. package/src/client/components/core/Auth.js +40 -37
  162. package/src/client/components/core/Badge.js +7 -13
  163. package/src/client/components/core/BtnIcon.js +15 -17
  164. package/src/client/components/core/CalendarCore.js +42 -63
  165. package/src/client/components/core/Chat.js +13 -15
  166. package/src/client/components/core/ClientEvents.js +163 -0
  167. package/src/client/components/core/ColorPaletteElement.js +309 -0
  168. package/src/client/components/core/Content.js +17 -14
  169. package/src/client/components/core/Css.js +15 -71
  170. package/src/client/components/core/CssCore.js +12 -16
  171. package/src/client/components/core/D3Chart.js +4 -4
  172. package/src/client/components/core/Docs.js +64 -91
  173. package/src/client/components/core/DropDown.js +69 -91
  174. package/src/client/components/core/EventBus.js +96 -0
  175. package/src/client/components/core/EventsUI.js +14 -17
  176. package/src/client/components/core/FileExplorer.js +96 -228
  177. package/src/client/components/core/FullScreen.js +47 -75
  178. package/src/client/components/core/Input.js +24 -69
  179. package/src/client/components/core/Keyboard.js +25 -18
  180. package/src/client/components/core/KeyboardAvoidance.js +145 -0
  181. package/src/client/components/core/LoadingAnimation.js +25 -31
  182. package/src/client/components/core/LogIn.js +41 -41
  183. package/src/client/components/core/LogOut.js +23 -14
  184. package/src/client/components/core/Modal.js +544 -219
  185. package/src/client/components/core/NotificationManager.js +14 -18
  186. package/src/client/components/core/Panel.js +54 -50
  187. package/src/client/components/core/PanelForm.js +81 -177
  188. package/src/client/components/core/Polyhedron.js +110 -214
  189. package/src/client/components/core/PublicProfile.js +39 -32
  190. package/src/client/components/core/Recover.js +48 -44
  191. package/src/client/components/core/Responsive.js +88 -32
  192. package/src/client/components/core/RichText.js +9 -18
  193. package/src/client/components/core/Router.js +24 -3
  194. package/src/client/components/core/SearchBox.js +37 -37
  195. package/src/client/components/core/SignUp.js +39 -30
  196. package/src/client/components/core/SocketIo.js +31 -2
  197. package/src/client/components/core/SocketIoHandler.js +6 -6
  198. package/src/client/components/core/ToggleSwitch.js +8 -20
  199. package/src/client/components/core/ToolTip.js +5 -17
  200. package/src/client/components/core/Translate.js +56 -59
  201. package/src/client/components/core/Validator.js +26 -16
  202. package/src/client/components/core/Wallet.js +15 -26
  203. package/src/client/components/core/Worker.js +211 -276
  204. package/src/client/components/core/windowGetDimensions.js +7 -7
  205. package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +57 -57
  206. package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
  207. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +6 -4
  208. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +6 -4
  209. package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
  210. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
  211. package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
  212. package/src/client/components/cyberia/InstanceEngineCyberia.js +141 -60
  213. package/src/client/components/cyberia/MapEngineCyberia.js +691 -214
  214. package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
  215. package/src/client/components/cyberia/ObjectLayerEngineModal.js +1204 -94
  216. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +196 -298
  217. package/src/client/components/cyberia/SharedDefaultsCyberia.js +330 -0
  218. package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +102 -102
  219. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
  220. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +6 -4
  221. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +6 -4
  222. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
  223. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
  224. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
  225. package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
  226. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -4
  227. package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +87 -87
  228. package/src/client/components/default/CssDefault.js +12 -12
  229. package/src/client/components/default/LogInDefault.js +6 -4
  230. package/src/client/components/default/LogOutDefault.js +6 -4
  231. package/src/client/components/default/RouterDefault.js +47 -0
  232. package/src/client/components/default/SettingsDefault.js +4 -4
  233. package/src/client/components/default/SignUpDefault.js +6 -4
  234. package/src/client/components/default/TranslateDefault.js +3 -3
  235. package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +57 -57
  236. package/src/client/components/itemledger/CssItemledger.js +15 -15
  237. package/src/client/components/itemledger/LogInItemledger.js +6 -4
  238. package/src/client/components/itemledger/LogOutItemledger.js +6 -4
  239. package/src/client/components/itemledger/RouterItemledger.js +38 -0
  240. package/src/client/components/itemledger/SettingsItemledger.js +4 -4
  241. package/src/client/components/itemledger/SignUpItemledger.js +6 -4
  242. package/src/client/components/itemledger/TranslateItemledger.js +3 -3
  243. package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +88 -88
  244. package/src/client/components/underpost/CssUnderpost.js +14 -14
  245. package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
  246. package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
  247. package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
  248. package/src/client/components/underpost/LogInUnderpost.js +6 -4
  249. package/src/client/components/underpost/LogOutUnderpost.js +6 -4
  250. package/src/client/components/underpost/RouterUnderpost.js +45 -0
  251. package/src/client/components/underpost/SettingsUnderpost.js +4 -4
  252. package/src/client/components/underpost/SignUpUnderpost.js +6 -4
  253. package/src/client/components/underpost/TranslateUnderpost.js +4 -4
  254. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
  255. package/src/client/public/cyberia-docs/ARCHITECTURE.md +83 -0
  256. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +204 -0
  257. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +291 -0
  258. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +278 -0
  259. package/src/client/public/cyberia-docs/CYBERIA.md +259 -0
  260. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
  261. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
  262. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
  263. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
  264. package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
  265. package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +106 -0
  266. package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
  267. package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
  268. package/src/client/services/core/core.service.js +17 -49
  269. package/src/client/services/crypto/crypto.service.js +8 -13
  270. package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
  271. package/src/client/services/cyberia-client-hints/cyberia-client-hints.service.js +99 -0
  272. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +10 -16
  273. package/src/client/services/cyberia-entity/cyberia-entity.management.js +5 -5
  274. package/src/client/services/cyberia-entity/cyberia-entity.service.js +10 -16
  275. package/src/client/services/cyberia-instance/cyberia-instance.management.js +6 -6
  276. package/src/client/services/cyberia-instance/cyberia-instance.service.js +12 -18
  277. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +10 -16
  278. package/src/client/services/cyberia-map/cyberia-map.management.js +6 -6
  279. package/src/client/services/cyberia-map/cyberia-map.service.js +12 -18
  280. package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
  281. package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
  282. package/src/client/services/default/default.management.js +159 -267
  283. package/src/client/services/default/default.service.js +10 -16
  284. package/src/client/services/document/document.service.js +14 -19
  285. package/src/client/services/file/file.service.js +8 -13
  286. package/src/client/services/instance/instance.management.js +5 -5
  287. package/src/client/services/instance/instance.service.js +10 -15
  288. package/src/client/services/ipfs/ipfs.service.js +12 -18
  289. package/src/client/services/object-layer/object-layer.management.js +12 -12
  290. package/src/client/services/object-layer/object-layer.service.js +20 -26
  291. package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
  292. package/src/client/services/test/test.service.js +8 -13
  293. package/src/client/services/user/guest.service.js +86 -0
  294. package/src/client/services/user/user.management.js +5 -5
  295. package/src/client/services/user/user.service.js +14 -20
  296. package/src/client/ssr/body/404.js +3 -3
  297. package/src/client/ssr/body/500.js +3 -3
  298. package/src/client/ssr/body/CacheControl.js +5 -2
  299. package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
  300. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
  301. package/src/client/ssr/head/PwaItemledger.js +197 -60
  302. package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
  303. package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
  304. package/src/client/ssr/views/CyberiaServerMetrics.js +982 -0
  305. package/src/client/ssr/{offline → views}/Maintenance.js +12 -11
  306. package/src/client/ssr/{offline → views}/NoNetworkConnection.js +3 -3
  307. package/src/client/ssr/{pages → views}/Test.js +2 -2
  308. package/src/client/sw/core.sw.js +274 -0
  309. package/src/db/DataBaseProvider.js +115 -15
  310. package/src/db/mariadb/MariaDB.js +2 -1
  311. package/src/db/mongo/MongoBootstrap.js +657 -0
  312. package/src/db/mongo/MongooseDB.js +129 -21
  313. package/src/grpc/cyberia/grpc-server.js +185 -105
  314. package/src/index.js +1 -1
  315. package/src/runtime/cyberia-client/Dockerfile +101 -0
  316. package/src/runtime/cyberia-client/Dockerfile.dev +82 -0
  317. package/src/runtime/cyberia-server/Dockerfile +62 -0
  318. package/src/runtime/cyberia-server/Dockerfile.dev +71 -0
  319. package/src/runtime/express/Dockerfile +4 -4
  320. package/src/runtime/express/Express.js +2 -2
  321. package/src/runtime/lampp/Dockerfile +8 -7
  322. package/src/runtime/wp/Dockerfile +11 -17
  323. package/src/runtime/wp/Wp.js +8 -5
  324. package/src/server/atlas-sprite-sheet-generator.js +4 -2
  325. package/src/server/auth.js +2 -2
  326. package/src/server/client-build-docs.js +46 -47
  327. package/src/server/client-build.js +371 -132
  328. package/src/server/client-formatted.js +47 -16
  329. package/src/server/conf.js +91 -87
  330. package/src/server/data-query.js +32 -20
  331. package/src/server/dns.js +22 -0
  332. package/src/server/ipfs-client.js +232 -91
  333. package/src/server/object-layer.js +1 -6
  334. package/src/server/process.js +192 -45
  335. package/src/server/proxy.js +9 -2
  336. package/src/server/runtime.js +1 -1
  337. package/src/server/semantic-layer-generator-floor.js +11 -51
  338. package/src/server/semantic-layer-generator-resource.js +259 -0
  339. package/src/server/semantic-layer-generator-skin.js +41 -171
  340. package/src/server/semantic-layer-generator.js +122 -14
  341. package/src/server/shape-generator.js +108 -0
  342. package/src/server/start.js +34 -8
  343. package/src/server/valkey.js +143 -235
  344. package/src/ws/IoInterface.js +16 -16
  345. package/src/ws/core/channels/core.ws.chat.js +11 -11
  346. package/src/ws/core/channels/core.ws.mailer.js +29 -29
  347. package/src/ws/core/channels/core.ws.stream.js +19 -19
  348. package/src/ws/core/core.ws.connection.js +8 -8
  349. package/src/ws/core/core.ws.server.js +6 -5
  350. package/src/ws/default/channels/default.ws.main.js +10 -10
  351. package/src/ws/default/default.ws.connection.js +4 -4
  352. package/src/ws/default/default.ws.server.js +4 -3
  353. package/tsconfig.docs.json +15 -0
  354. package/typedoc.dd-cyberia.json +29 -0
  355. package/typedoc.json +29 -0
  356. package/WHITE-PAPER.md +0 -1540
  357. package/bin/file.js +0 -196
  358. package/bin/vs.js +0 -74
  359. package/bin/zed.js +0 -84
  360. package/hardhat/README.md +0 -531
  361. package/hardhat/WHITE-PAPER.md +0 -1540
  362. package/jsdoc.dd-cyberia.json +0 -68
  363. package/jsdoc.json +0 -68
  364. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +0 -413
  365. package/src/api/object-layer/README.md +0 -672
  366. package/src/client/components/core/ColorPalette.js +0 -5267
  367. package/src/client/components/core/JoyStick.js +0 -80
  368. package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
  369. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +0 -223
  370. package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -62
  371. package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
  372. package/src/client/components/default/RoutesDefault.js +0 -49
  373. package/src/client/components/itemledger/RoutesItemledger.js +0 -40
  374. package/src/client/components/underpost/RoutesUnderpost.js +0 -47
  375. package/src/client/ssr/email/DefaultRecoverEmail.js +0 -21
  376. package/src/client/ssr/email/DefaultVerifyEmail.js +0 -17
  377. package/src/client/ssr/pages/CyberiaServerMetrics.js +0 -461
  378. package/src/client/sw/default.sw.js +0 -127
  379. package/src/client/sw/template.sw.js +0 -84
  380. package/src/grpc/cyberia/OFF_CHAIN_ECONOMY.md +0 -305
  381. package/src/grpc/cyberia/README.md +0 -326
@@ -1,6 +1,6 @@
1
1
  import mongoose from 'mongoose';
2
- import { loggerFactory } from '../../server/logger.js';
3
2
  import { getCapVariableName } from '../../client/components/core/CommonJs.js';
3
+ import { loggerFactory } from '../../server/logger.js';
4
4
 
5
5
  /**
6
6
  * Module for connecting to and loading models for a MongoDB database using Mongoose.
@@ -10,6 +10,32 @@ import { getCapVariableName } from '../../client/components/core/CommonJs.js';
10
10
 
11
11
  const logger = loggerFactory(import.meta);
12
12
 
13
+ const MONGODB_SERVICE_NAME = 'mongodb-service';
14
+ const MONGODB_STATEFULSET_NAME = 'mongodb';
15
+ const MONGODB_DEFAULT_AUTH_SOURCE = 'admin';
16
+ const MONGODB_DEFAULT_REPLICA_SET = 'rs0';
17
+ const MONGODB_DEFAULT_REPLICA_COUNT = 3;
18
+
19
+ /**
20
+ * Resolves MongoDB replica hosts from explicit input or StatefulSet defaults.
21
+ * @param {{hostList?: string, replicaCount?: number}} [options] - Host resolution options.
22
+ * @returns {Array<string>} Normalized host:port entries.
23
+ */
24
+ const resolveMongoReplicaHosts = ({ hostList = '', replicaCount = MONGODB_DEFAULT_REPLICA_COUNT }) => {
25
+ if (hostList) {
26
+ return hostList
27
+ .split(',')
28
+ .map((host) => host.trim())
29
+ .filter(Boolean)
30
+ .map((host) => (host.includes(':') ? host : `${host}:27017`));
31
+ }
32
+
33
+ return Array.from(
34
+ { length: replicaCount },
35
+ (_, index) => `${MONGODB_STATEFULSET_NAME}-${index}.${MONGODB_SERVICE_NAME}:27017`,
36
+ );
37
+ };
38
+
13
39
  /**
14
40
  * @class
15
41
  * @alias MongooseDBService
@@ -23,35 +49,109 @@ const logger = loggerFactory(import.meta);
23
49
  * 3. No built-in defaults — both `host` and `name` are required from the caller or environment.
24
50
  */
25
51
  class MongooseDBService {
52
+ /**
53
+ * Normalizes Mongo host inputs into plain host:port entries.
54
+ * @param {Array<string>|string} hosts - Host input as list or comma-separated string.
55
+ * @returns {Array<string>} Normalized host:port entries.
56
+ */
57
+ normalizeHosts(hosts) {
58
+ const hostEntries = Array.isArray(hosts) ? hosts : `${hosts || ''}`.split(',');
59
+
60
+ return hostEntries
61
+ .map((entry) => `${entry || ''}`.trim())
62
+ .filter(Boolean)
63
+ .map((entry) => entry.replace(/^mongodb:\/\//, '').replace(/\/.*$/, ''));
64
+ }
65
+
66
+ /**
67
+ * Normalizes connection config from object or legacy host/name signature.
68
+ * @param {object|string} configOrHost - Connection config object or host string.
69
+ * @param {string} [name] - Legacy DB name when using host string input.
70
+ * @returns {{authSource: string, dbName: string, directConnection: boolean, hosts: Array<string>, password: string, replicaSet: string, user: string}} Normalized config.
71
+ */
72
+ normalizeConfig(configOrHost, name) {
73
+ const config =
74
+ typeof configOrHost === 'object' && configOrHost !== null ? { ...configOrHost } : { host: configOrHost, name };
75
+
76
+ const rawHosts = config.host || process.env.DB_HOST;
77
+ const hosts = this.normalizeHosts(rawHosts);
78
+ const dbName = config.name || process.env.DB_NAME;
79
+
80
+ if (!hosts.length || !dbName) {
81
+ const missing = [!hosts.length && 'host (db.host|DB_HOST)', !dbName && 'name (db.name|DB_NAME)']
82
+ .filter(Boolean)
83
+ .join(', ');
84
+ throw new Error(`MongooseDBService.connect: missing required parameter(s): ${missing}`);
85
+ }
86
+
87
+ const user = config.user || process.env.DB_USER || '';
88
+ const password = config.password || process.env.DB_PASSWORD || '';
89
+ const directConnection = hosts.length === 1;
90
+ const replicaSet = directConnection
91
+ ? ''
92
+ : config.replicaSet || process.env.DB_REPLICA_SET || MONGODB_DEFAULT_REPLICA_SET;
93
+ const authSource = config.authSource || process.env.DB_AUTH_SOURCE || (user ? MONGODB_DEFAULT_AUTH_SOURCE : '');
94
+
95
+ return {
96
+ authSource,
97
+ dbName,
98
+ directConnection,
99
+ hosts,
100
+ password,
101
+ replicaSet,
102
+ user,
103
+ };
104
+ }
105
+
106
+ /**
107
+ * Builds a MongoDB URI from normalized config options.
108
+ * @param {object|string} configOrHost - Connection config object or host string.
109
+ * @param {string} [name] - Legacy DB name when using host string input.
110
+ * @returns {string} MongoDB connection URI.
111
+ */
112
+ buildUri(configOrHost, name) {
113
+ const config = this.normalizeConfig(configOrHost, name);
114
+ const credentials =
115
+ config.user && config.password
116
+ ? `${encodeURIComponent(config.user)}:${encodeURIComponent(config.password)}@`
117
+ : '';
118
+ const query = new URLSearchParams();
119
+
120
+ if (config.directConnection) query.set('directConnection', 'true');
121
+ else if (config.replicaSet) query.set('replicaSet', config.replicaSet);
122
+ if (config.authSource) query.set('authSource', config.authSource);
123
+
124
+ return `mongodb://${credentials}${config.hosts.join(',')}/${config.dbName}${query.size ? `?${query.toString()}` : ''}`;
125
+ }
126
+
26
127
  /**
27
128
  * Establishes a Mongoose connection to the specified MongoDB instance.
28
129
  *
29
130
  * @async
30
- * @param {string} host - The MongoDB host URI (e.g., `'mongodb://localhost:27017'`).
31
- * Falls back to `process.env.DB_HOST` when not provided.
32
- * @param {string} name - The database name.
33
- * Falls back to `process.env.DB_NAME` when not provided.
131
+ * @param {object|string} configOrHost - Either a db config object or a legacy host string.
132
+ * @param {string} [configOrHost.host] - Legacy single host or comma-separated host list.
133
+ * @param {string} [configOrHost.name] - The database name.
134
+ * @param {string} [configOrHost.replicaSet] - The MongoDB replica set name.
135
+ * @param {string} [configOrHost.authSource] - The authentication database.
136
+ * @param {string} [configOrHost.user] - The MongoDB username.
137
+ * @param {string} [configOrHost.password] - The MongoDB password.
138
+ * @param {string} [name] - Legacy database name when a host string is passed.
34
139
  * @returns {Promise<mongoose.Connection>} A promise that resolves to the established Mongoose connection object.
35
140
  * @throws {Error} If neither the argument nor the corresponding environment variable supplies a value.
36
141
  */
37
- async connect(host, name) {
38
- host = host || process.env.DB_HOST;
39
- name = name || process.env.DB_NAME;
40
-
41
- if (!host || !name) {
42
- const missing = [!host && 'host (DB_HOST)', !name && 'name (DB_NAME)'].filter(Boolean).join(', ');
43
- throw new Error(`MongooseDBService.connect: missing required parameter(s): ${missing}`);
44
- }
45
-
46
- const uri = `${host}/${name}`;
47
- // logger.info('MongooseDB connect', { host, name, uri });
142
+ async connect(configOrHost, name) {
143
+ const uri = this.buildUri(configOrHost, name);
144
+ if (process.env.NODE_ENV === 'development') logger.info(`Connecting to MongoDB with URI`, uri);
48
145
  return await mongoose
49
146
  .createConnection(uri, {
147
+ autoIndex: process.env.NODE_ENV !== 'production',
148
+ heartbeatFrequencyMS: 10000,
149
+ maxPoolSize: 20,
150
+ minPoolSize: 2,
151
+ retryReads: true,
152
+ retryWrites: true,
50
153
  serverSelectionTimeoutMS: 5000,
51
- // readPreference: 'primary',
52
- // directConnection: true,
53
- // useNewUrlParser: true,
54
- // useUnifiedTopology: true,
154
+ socketTimeoutMS: 45000,
55
155
  })
56
156
  .asPromise();
57
157
  }
@@ -87,4 +187,12 @@ class MongooseDBService {
87
187
  */
88
188
  const MongooseDB = new MongooseDBService();
89
189
 
90
- export { MongooseDB, MongooseDBService as MongooseDBClass };
190
+ export {
191
+ MongooseDB,
192
+ MongooseDBService as MongooseDBClass,
193
+ MONGODB_DEFAULT_REPLICA_COUNT,
194
+ MONGODB_DEFAULT_REPLICA_SET,
195
+ MONGODB_SERVICE_NAME,
196
+ MONGODB_STATEFULSET_NAME,
197
+ resolveMongoReplicaHosts,
198
+ };
@@ -10,15 +10,18 @@
10
10
 
11
11
  import * as grpc from '@grpc/grpc-js';
12
12
  import * as protoLoader from '@grpc/proto-loader';
13
+ import crypto from 'crypto';
13
14
  import path from 'path';
14
15
  import { fileURLToPath } from 'url';
15
- import { DataBaseProvider } from '../../db/DataBaseProvider.js';
16
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
16
17
  import { loggerFactory } from '../../server/logger.js';
17
18
  import {
18
19
  CYBERIA_INSTANCE_CONF_DEFAULTS as FALLBACK_CONFIG_DEFAULTS,
19
20
  ENTITY_TYPE_DEFAULTS,
20
- STATUS_ICONS,
21
- } from '../../api/cyberia-instance-conf/cyberia-instance-conf.defaults.js';
21
+ // STATUS_ICONS deliberately not imported here — see toInstanceConfig.
22
+ // Server simulation only cares about the numeric u8 IDs (which travel on
23
+ // the AOI wire). Icon stems + border colours live in SharedDefaultsCyberia.
24
+ } from '../../api/cyberia-server-defaults/cyberia-server-defaults.js';
22
25
  import { generateFallbackWorld } from '../../api/cyberia-instance/cyberia-fallback-world.js';
23
26
 
24
27
  const logger = loggerFactory(import.meta);
@@ -26,7 +29,7 @@ const logger = loggerFactory(import.meta);
26
29
  const __filename = fileURLToPath(import.meta.url);
27
30
  const __dirname = path.dirname(__filename);
28
31
 
29
- const PROTO_PATH = path.resolve(__dirname, '../../../cyberia-server/proto/cyberia.proto');
32
+ const PROTO_PATH = path.resolve(__dirname, '../../../cyberia-server/gen/proto/cyberia.proto');
30
33
 
31
34
  const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
32
35
  keepCase: false,
@@ -43,11 +46,101 @@ const proto = grpc.loadPackageDefinition(packageDefinition).cyberia;
43
46
  // ═══════════════════════════════════════════════════════════════════
44
47
 
45
48
  function getModels(dbKey) {
46
- const bucket = DataBaseProvider.instance[dbKey];
47
- if (!bucket || !bucket.mongoose || !bucket.mongoose.models) {
48
- throw new Error(`DataBaseProvider not loaded for key "${dbKey}"`);
49
+ const bucket = DataBaseProviderService.getProvider(dbKey, 'mongoose');
50
+ if (!bucket || !bucket.models) {
51
+ throw new Error(`DataBaseProviderService not loaded for key "${dbKey}"`);
49
52
  }
50
- return bucket.mongoose.models;
53
+ return bucket.models;
54
+ }
55
+
56
+ function countSharedItemIds(source = [], target = []) {
57
+ if (!Array.isArray(source) || source.length === 0 || !Array.isArray(target) || target.length === 0) {
58
+ return 0;
59
+ }
60
+ const targetSet = new Set(target.filter(Boolean));
61
+ let count = 0;
62
+ for (const itemId of source) {
63
+ if (targetSet.has(itemId)) {
64
+ count += 1;
65
+ }
66
+ }
67
+ return count;
68
+ }
69
+
70
+ function normalizeEntityDefault(entityDefault = {}, canonical = {}) {
71
+ const defaultObjectLayers = entityDefault.defaultObjectLayers ?? canonical.defaultObjectLayers ?? [];
72
+ return {
73
+ entityType: entityDefault.entityType ?? canonical.entityType ?? '',
74
+ liveItemIds: [...(entityDefault.liveItemIds ?? canonical.liveItemIds ?? [])],
75
+ deadItemIds: [...(entityDefault.deadItemIds ?? canonical.deadItemIds ?? [])],
76
+ dropItemIds: [...(entityDefault.dropItemIds ?? canonical.dropItemIds ?? [])],
77
+ defaultObjectLayers: defaultObjectLayers.map((ol) => ({
78
+ itemId: ol.itemId || '',
79
+ active: !!ol.active,
80
+ quantity: ol.quantity || 0,
81
+ })),
82
+ };
83
+ }
84
+
85
+ function selectCanonicalEntityDefaultIndex(entityDefault, canonicalDefaults, usedIndexes) {
86
+ const pickBestIndex = (candidateIndexes) => {
87
+ let firstSameTypeIndex = -1;
88
+ let bestLiveOverlapIndex = -1;
89
+ let bestLiveOverlap = 0;
90
+ let bestLiveItemCount = Number.POSITIVE_INFINITY;
91
+
92
+ for (const index of candidateIndexes) {
93
+ const canonical = canonicalDefaults[index];
94
+ if (canonical.entityType !== entityDefault.entityType) {
95
+ continue;
96
+ }
97
+ if (firstSameTypeIndex === -1) {
98
+ firstSameTypeIndex = index;
99
+ }
100
+ const liveOverlap = countSharedItemIds(entityDefault.liveItemIds, canonical.liveItemIds);
101
+ if (
102
+ liveOverlap > 0 &&
103
+ (bestLiveOverlapIndex === -1 ||
104
+ liveOverlap > bestLiveOverlap ||
105
+ (liveOverlap === bestLiveOverlap && (canonical.liveItemIds?.length ?? 0) < bestLiveItemCount))
106
+ ) {
107
+ bestLiveOverlapIndex = index;
108
+ bestLiveOverlap = liveOverlap;
109
+ bestLiveItemCount = canonical.liveItemIds?.length ?? 0;
110
+ }
111
+ }
112
+
113
+ if (bestLiveOverlapIndex !== -1) {
114
+ return bestLiveOverlapIndex;
115
+ }
116
+ return firstSameTypeIndex;
117
+ };
118
+
119
+ const unusedCandidateIndexes = canonicalDefaults.map((_, index) => index).filter((index) => !usedIndexes.has(index));
120
+
121
+ const preferredIndex = pickBestIndex(unusedCandidateIndexes);
122
+ if (preferredIndex !== -1) {
123
+ return preferredIndex;
124
+ }
125
+ return pickBestIndex(canonicalDefaults.map((_, index) => index));
126
+ }
127
+
128
+ function mergeEntityDefaults(entityDefaults = []) {
129
+ const mergedDefaults = ENTITY_TYPE_DEFAULTS.map((canonical) => normalizeEntityDefault(canonical, canonical));
130
+ const usedCanonicalIndexes = new Set();
131
+
132
+ for (const entityDefault of entityDefaults) {
133
+ const canonicalIndex = selectCanonicalEntityDefaultIndex(entityDefault, ENTITY_TYPE_DEFAULTS, usedCanonicalIndexes);
134
+ if (canonicalIndex === -1) {
135
+ mergedDefaults.push(normalizeEntityDefault(entityDefault));
136
+ continue;
137
+ }
138
+
139
+ mergedDefaults[canonicalIndex] = normalizeEntityDefault(entityDefault, ENTITY_TYPE_DEFAULTS[canonicalIndex]);
140
+ usedCanonicalIndexes.add(canonicalIndex);
141
+ }
142
+
143
+ return mergedDefaults;
51
144
  }
52
145
 
53
146
  // ── Mongoose doc → protobuf message converters ───────────────────
@@ -58,13 +151,6 @@ function toObjectLayerMsg(doc) {
58
151
  const stats = d.stats || {};
59
152
  const ledger = d.ledger || {};
60
153
  const render = d.render || {};
61
- const rf = doc.objectLayerRenderFramesId;
62
- let frameDuration = 250;
63
- let isStateless = false;
64
- if (rf && typeof rf === 'object') {
65
- if (rf.frame_duration != null) frameDuration = rf.frame_duration;
66
- if (rf.is_stateless != null) isStateless = rf.is_stateless;
67
- }
68
154
  return {
69
155
  mongoId: String(doc._id),
70
156
  stats: {
@@ -92,12 +178,24 @@ function toObjectLayerMsg(doc) {
92
178
  },
93
179
  sha256: doc.sha256 || '',
94
180
  cid: doc.cid || '',
95
- frameDuration,
96
- isStateless,
97
181
  };
98
182
  }
99
183
 
184
+ /**
185
+ * Parse a CSS rgba() colour string into {r, g, b, a} integer components.
186
+ * Returns {r:0, g:0, b:0, a:0} (transparent) when the string is absent or malformed.
187
+ */
188
+ function parseRgba(str) {
189
+ if (!str) return { r: 0, g: 0, b: 0, a: 0 };
190
+ const m = str.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/);
191
+ if (!m) return { r: 0, g: 0, b: 0, a: 0 };
192
+ // CSS alpha is 0-1 (float); proto uses 0-255 (int).
193
+ const cssAlpha = m[4] !== undefined ? parseFloat(m[4]) : 1;
194
+ return { r: Number(m[1]), g: Number(m[2]), b: Number(m[3]), a: Math.round(cssAlpha * 255) };
195
+ }
196
+
100
197
  function toEntityMsg(ent) {
198
+ const rgba = parseRgba(ent.color);
101
199
  return {
102
200
  entityType: ent.entityType || 'floor',
103
201
  initCellX: ent.initCellX || 0,
@@ -111,6 +209,10 @@ function toEntityMsg(ent) {
111
209
  maxLife: ent.maxLife || 0,
112
210
  lifeRegen: ent.lifeRegen || 0,
113
211
  portalSubtype: ent.portalSubtype || '',
212
+ colorR: rgba.r,
213
+ colorG: rgba.g,
214
+ colorB: rgba.b,
215
+ colorA: rgba.a,
114
216
  };
115
217
  }
116
218
 
@@ -159,49 +261,24 @@ function toInstanceConfig(gc) {
159
261
  const fb = FALLBACK_CONFIG_DEFAULTS;
160
262
  if (!gc) return buildFallbackConfig();
161
263
 
162
- const colors =
163
- gc.colors && gc.colors.length > 0
164
- ? gc.colors.map((c) => ({
165
- key: c.key || '',
166
- r: c.r ?? 0,
167
- g: c.g ?? 0,
168
- b: c.b ?? 0,
169
- a: c.a ?? 255,
170
- }))
171
- : fb.colors.map((c) => ({ ...c }));
172
-
173
- // Merge entity defaults: use canonical ENTITY_TYPE_DEFAULTS as base, overlay with
174
- // any instance-specific overrides stored in gc.entityDefaults.
264
+ // STRICT BOUNDARY — this function produces the *simulation* config for
265
+ // cyberia-server only. Every presentation concern is excluded:
266
+ //
267
+ // - palette (colors), camera tunings, screen factors, devUi,
268
+ // interpolationMs, status-icon visuals, entityDefaults[].colorKey,
269
+ // cellSize, defaultObj* all of these reach the client through
270
+ // /api/cyberia-client-hints, never through gRPC.
271
+ //
272
+ // The Go simulation does not need any of them to advance world state;
273
+ // the C/WASM cyberia-client owns its own render policy. See
274
+ // src/client/components/cyberia/SharedDefaultsCyberia.js.
275
+
175
276
  const gcDefaults = gc.entityDefaults && gc.entityDefaults.length > 0 ? gc.entityDefaults : [];
176
- const gcDefaultsMap = Object.fromEntries(gcDefaults.map((d) => [d.entityType, d]));
177
- const entityDefaults = ENTITY_TYPE_DEFAULTS.map((canonical) => {
178
- const override = gcDefaultsMap[canonical.entityType] ?? {};
179
- const dols = override.defaultObjectLayers ?? canonical.defaultObjectLayers ?? [];
180
- return {
181
- entityType: canonical.entityType,
182
- liveItemIds: override.liveItemIds ?? canonical.liveItemIds,
183
- deadItemIds: override.deadItemIds ?? canonical.deadItemIds,
184
- colorKey: override.colorKey ?? canonical.colorKey,
185
- defaultObjectLayers: dols.map((ol) => ({
186
- itemId: ol.itemId || '',
187
- active: !!ol.active,
188
- quantity: ol.quantity || 0,
189
- })),
190
- };
191
- });
277
+ const entityDefaults = mergeEntityDefaults(gcDefaults);
192
278
 
193
279
  return {
194
- cellSize: gc.cellSize ?? fb.cellSize,
195
- fps: gc.fps ?? fb.fps,
196
- interpolationMs: gc.interpolationMs ?? fb.interpolationMs,
197
- defaultObjWidth: gc.defaultObjWidth ?? fb.defaultObjWidth,
198
- defaultObjHeight: gc.defaultObjHeight ?? fb.defaultObjHeight,
199
- cameraSmoothing: gc.cameraSmoothing ?? fb.cameraSmoothing,
200
- cameraZoom: gc.cameraZoom ?? fb.cameraZoom,
201
- defaultWidthScreenFactor: gc.defaultWidthScreenFactor ?? fb.defaultWidthScreenFactor,
202
- defaultHeightScreenFactor: gc.defaultHeightScreenFactor ?? fb.defaultHeightScreenFactor,
203
- devUi: gc.devUi ?? fb.devUi,
204
- colors,
280
+ tickRate: gc.tickRate ?? fb.tickRate,
281
+ snapshotRate: gc.snapshotRate ?? fb.snapshotRate,
205
282
  aoiRadius: gc.aoiRadius ?? fb.aoiRadius,
206
283
  portalHoldTimeMs: gc.portalHoldTimeMs ?? fb.portalHoldTimeMs,
207
284
  portalSpawnRadius: gc.portalSpawnRadius ?? fb.portalSpawnRadius,
@@ -233,9 +310,14 @@ function toInstanceConfig(gc) {
233
310
  lifeRegenChance: gc.lifeRegenChance ?? fb.lifeRegenChance,
234
311
  maxChance: gc.maxChance ?? fb.maxChance,
235
312
  entityDefaults,
236
- skillConfig: (gc.skillConfig || []).map((sc) => ({
313
+ skillConfig: (gc.skillConfig && gc.skillConfig.length > 0 ? gc.skillConfig : fb.skillConfig).map((sc) => ({
237
314
  triggerItemId: sc.triggerItemId || '',
238
- logicEventIds: sc.logicEventIds || [],
315
+ skills: (sc.skills || []).map((sk) => ({
316
+ logicEventId: sk.logicEventId || '',
317
+ name: sk.name || '',
318
+ description: sk.description || '',
319
+ summonedEntityItemId: sk.summonedEntityItemId || '',
320
+ })),
239
321
  })),
240
322
  skillRules: {
241
323
  projectileSpawnChance: gc.skillRules?.projectileSpawnChance ?? fb.skillRules.projectileSpawnChance,
@@ -255,23 +337,6 @@ function toInstanceConfig(gc) {
255
337
  onePerType: gc.equipmentRules?.onePerType ?? fb.equipmentRules.onePerType,
256
338
  requireSkin: gc.equipmentRules?.requireSkin ?? fb.equipmentRules.requireSkin,
257
339
  },
258
- // Status icon mapping — u8 ID → icon filename stem + border colour.
259
- // Border colours come from the frozen STATUS_ICONS constant (canonical
260
- // source of truth). DB entries may override iconId but borderColor is
261
- // always canonical — the DB schema defaults are generic grey, not the
262
- // actual per-status colours.
263
- statusIcons: STATUS_ICONS.map((canon) => {
264
- const dbEntry = (gc.statusIcons || []).find((s) => s.id === canon.id);
265
- const bc = canon.borderColor || {};
266
- return {
267
- id: canon.id,
268
- iconId: (dbEntry && dbEntry.iconId) || canon.iconId || '',
269
- borderColorR: bc.r ?? 100,
270
- borderColorG: bc.g ?? 100,
271
- borderColorB: bc.b ?? 100,
272
- borderColorA: bc.a ?? 200,
273
- };
274
- }),
275
340
  };
276
341
  }
277
342
 
@@ -302,10 +367,7 @@ function buildHandlers(dbKey) {
302
367
  if (call.request.itemTypeFilter) {
303
368
  filter['data.item.type'] = call.request.itemTypeFilter;
304
369
  }
305
- const cursor = models.ObjectLayer.find(filter)
306
- .populate('objectLayerRenderFramesId', { _id: 1, frame_duration: 1, is_stateless: 1 })
307
- .lean()
308
- .cursor();
370
+ const cursor = models.ObjectLayer.find(filter).lean().cursor();
309
371
  for await (const doc of cursor) {
310
372
  call.write(toObjectLayerMsg(doc));
311
373
  }
@@ -319,9 +381,7 @@ function buildHandlers(dbKey) {
319
381
  async getObjectLayer(call, callback) {
320
382
  try {
321
383
  const models = getModels(dbKey);
322
- const doc = await models.ObjectLayer.findOne({ 'data.item.id': call.request.itemId })
323
- .populate('objectLayerRenderFramesId', { _id: 1, frame_duration: 1, is_stateless: 1 })
324
- .lean();
384
+ const doc = await models.ObjectLayer.findOne({ 'data.item.id': call.request.itemId }).lean();
325
385
  if (!doc)
326
386
  return callback({ code: grpc.status.NOT_FOUND, message: `ObjectLayer "${call.request.itemId}" not found` });
327
387
  callback(null, toObjectLayerMsg(doc));
@@ -344,7 +404,7 @@ function buildHandlers(dbKey) {
344
404
  models.GlobalMapCodeRegistry.findOneAndUpdate(
345
405
  { mapCode },
346
406
  { instanceCode, status: 'active' },
347
- { upsert: true, new: true, timestamps: true },
407
+ { upsert: true, returnDocument: 'after', timestamps: true },
348
408
  ).catch((err) => logger.warn('getMapData registry update failed:', err.message));
349
409
  }
350
410
 
@@ -380,15 +440,14 @@ function buildHandlers(dbKey) {
380
440
  for (const d of fallbackConf.entityDefaults || []) {
381
441
  for (const id of d.liveItemIds || []) fallbackItemIds.add(id);
382
442
  for (const id of d.deadItemIds || []) fallbackItemIds.add(id);
443
+ for (const id of d.dropItemIds || []) fallbackItemIds.add(id);
383
444
  for (const ol of d.defaultObjectLayers || []) {
384
445
  if (ol.itemId) fallbackItemIds.add(ol.itemId);
385
446
  }
386
447
  }
387
448
 
388
449
  const fallbackOlDocs = fallbackItemIds.size
389
- ? await models.ObjectLayer.find({ 'data.item.id': { $in: [...fallbackItemIds] } })
390
- .populate('objectLayerRenderFramesId', { _id: 1, frame_duration: 1, is_stateless: 1 })
391
- .lean()
450
+ ? await models.ObjectLayer.find({ 'data.item.id': { $in: [...fallbackItemIds] } }).lean()
392
451
  : [];
393
452
 
394
453
  callback(null, {
@@ -415,12 +474,27 @@ function buildHandlers(dbKey) {
415
474
  })),
416
475
  objectLayers: fallbackOlDocs.map(toObjectLayerMsg),
417
476
  config: toInstanceConfig(fallbackConf),
477
+ version: 'fallback',
418
478
  });
419
479
  return;
420
480
  }
421
481
 
422
482
  // ── Instance found — load maps + entity OLs + config default OLs ──────
423
- const conf = inst.conf || {};
483
+ // `populate('conf')` returns null when the ObjectId ref is missing or
484
+ // orphaned (e.g. after a --conf import that preserved a stale _id).
485
+ // Fall back to a direct instanceCode lookup so aoiRadius and all other
486
+ // tuning fields are always read from the database, never silently
487
+ // replaced by FALLBACK_CONFIG_DEFAULTS.
488
+ let conf = inst.conf;
489
+ if (!conf) {
490
+ conf = await models.CyberiaInstanceConf.findOne({ instanceCode }).lean();
491
+ if (conf) {
492
+ logger.warn(
493
+ `getFullInstance: conf ref missing on instance "${instanceCode}" — resolved by instanceCode lookup`,
494
+ );
495
+ }
496
+ }
497
+ conf = conf || {};
424
498
  const mapCodes = inst.cyberiaMapCodes || [];
425
499
  const mapDocs = mapCodes.length ? await models.CyberiaMap.find({ code: { $in: mapCodes } }).lean() : [];
426
500
 
@@ -432,29 +506,35 @@ function buildHandlers(dbKey) {
432
506
  }
433
507
  }
434
508
 
435
- // Also include "system" item IDs from the instance config so the
436
- // Go server has their OL data cached without extra round trips:
437
- // Include OL item IDs from entityDefaults so the Go server has all
438
- // default atlas data cached at startup without needing extra round trips.
439
- for (const d of conf.entityDefaults || []) {
509
+ // Include system OL items from BOTH canonical ENTITY_TYPE_DEFAULTS AND
510
+ // the DB conf so the Go server always caches all default atlases even if
511
+ // the DB doc has incomplete entityDefaults.
512
+ for (const d of [...ENTITY_TYPE_DEFAULTS, ...(conf.entityDefaults || [])]) {
440
513
  for (const id of d.liveItemIds || []) itemIds.add(id);
441
514
  for (const id of d.deadItemIds || []) itemIds.add(id);
515
+ for (const id of d.dropItemIds || []) itemIds.add(id);
442
516
  for (const ol of d.defaultObjectLayers || []) {
443
517
  if (ol.itemId) itemIds.add(ol.itemId);
444
518
  }
445
519
  }
446
520
 
447
521
  const olDocs = itemIds.size
448
- ? await models.ObjectLayer.find({ 'data.item.id': { $in: [...itemIds] } })
449
- .populate('objectLayerRenderFramesId', { _id: 1, frame_duration: 1, is_stateless: 1 })
450
- .lean()
522
+ ? await models.ObjectLayer.find({ 'data.item.id': { $in: [...itemIds] } }).lean()
451
523
  : [];
452
524
 
525
+ // Opaque version string from updatedAt timestamps — the Go server
526
+ // compares this to skip full world rebuilds when nothing changed.
527
+ const versionParts = [String(inst.updatedAt || inst._id)];
528
+ for (const m of mapDocs) versionParts.push(String(m.updatedAt || m._id));
529
+ if (conf.updatedAt) versionParts.push(String(conf.updatedAt));
530
+ const version = crypto.createHash('sha256').update(versionParts.join('|')).digest('hex');
531
+
453
532
  callback(null, {
454
533
  instance: toInstanceMsg(inst),
455
534
  maps: mapDocs.map(toMapMsg),
456
535
  objectLayers: olDocs.map(toObjectLayerMsg),
457
536
  config: toInstanceConfig(conf),
537
+ version,
458
538
  });
459
539
  } catch (err) {
460
540
  logger.error('getFullInstance:', err);
@@ -481,16 +561,16 @@ function buildHandlers(dbKey) {
481
561
  // Server lifecycle
482
562
  // ═══════════════════════════════════════════════════════════════════
483
563
 
484
- const GrpcServer = {
485
- _server: null,
564
+ class GrpcServer {
565
+ static _server = null;
486
566
 
487
567
  /**
488
568
  * @param {Object} opts
489
- * @param {string} opts.host - DataBaseProvider host key
490
- * @param {string} opts.path - DataBaseProvider path key
569
+ * @param {string} opts.host - DataBaseProviderService host key
570
+ * @param {string} opts.path - DataBaseProviderService path key
491
571
  * @param {number} [opts.port=50051]
492
572
  */
493
- async start({ host, path: dbPath, port = 50051 } = {}) {
573
+ static async start({ host, path: dbPath, port = 50051 } = {}) {
494
574
  const dbKey = `${host}${dbPath}`;
495
575
  const server = new grpc.Server({
496
576
  'grpc.max_send_message_length': 64 * 1024 * 1024,
@@ -513,9 +593,9 @@ const GrpcServer = {
513
593
  resolve(server);
514
594
  });
515
595
  });
516
- },
596
+ }
517
597
 
518
- async stop() {
598
+ static async stop() {
519
599
  if (!GrpcServer._server) return;
520
600
  return new Promise((resolve) => {
521
601
  GrpcServer._server.tryShutdown(() => {
@@ -524,7 +604,7 @@ const GrpcServer = {
524
604
  resolve();
525
605
  });
526
606
  });
527
- },
528
- };
607
+ }
608
+ }
529
609
 
530
610
  export { GrpcServer };
package/src/index.js CHANGED
@@ -44,7 +44,7 @@ class Underpost {
44
44
  * @type {String}
45
45
  * @memberof Underpost
46
46
  */
47
- static version = 'v3.2.5';
47
+ static version = 'v3.2.12';
48
48
 
49
49
  /**
50
50
  * Required Node.js major version