@underpostnet/cyberia 3.3.0 → 3.3.76
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.
- package/.dockerignore +1 -0
- package/.env.example +17 -5
- package/.github/workflows/coverall.cyberia.ci.yml +39 -14
- package/.github/workflows/cyberia-client.cd.yml +5 -0
- package/.github/workflows/cyberia-server.cd.yml +5 -0
- package/.github/workflows/docker-image.cyberia-client.ci.yml +8 -5
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +8 -3
- package/.github/workflows/docker-image.cyberia-server.ci.yml +8 -5
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +8 -5
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +15 -1
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +15 -1
- package/.github/workflows/engine-cyberia.cd.yml +3 -0
- package/.github/workflows/engine-cyberia.ci.yml +4 -5
- package/.github/workflows/ghpkg.ci.yml +35 -20
- package/.github/workflows/hardhat.ci.yml +12 -11
- package/.github/workflows/npmpkg.ci.yml +17 -15
- package/.github/workflows/publish.cyberia.ci.yml +44 -0
- package/.github/workflows/pwa-microservices-template-test.ci.yml +2 -2
- package/.github/workflows/release.cd.yml +1 -0
- package/.prettierignore +1 -0
- package/AGENTS.md +96 -0
- package/CHANGELOG.md +653 -2513
- package/CLI-HELP.md +323 -157
- package/Dockerfile +25 -9
- package/Dockerfile.dev +25 -9
- package/Dockerfile.test +5 -5
- package/README.md +48 -28
- package/bin/build.js +86 -41
- package/bin/build.template.js +8 -3
- package/bin/cyberia.js +1494 -1403
- package/bin/deploy.js +18 -104
- package/bin/index.js +1494 -1403
- package/compose.env +17 -5
- package/conf.js +98 -7
- package/deploy/cyberia-client/deploy.sh +46 -0
- package/deploy/cyberia-client/package.sh +17 -0
- package/deploy/cyberia-client/state.sh +15 -0
- package/deploy/cyberia-server/deploy.sh +46 -0
- package/deploy/cyberia-server/package.sh +17 -0
- package/deploy/cyberia-server/state.sh +15 -0
- package/deploy/dd-cyberia/deploy.sh +9 -29
- package/deploy/dd-cyberia/init.sh +38 -45
- package/deploy/dd-cyberia/package.sh +16 -0
- package/deploy/dd-cyberia/state.sh +14 -0
- package/deploy/dd-cyberia/sync-deploy.sh +133 -147
- package/deploy/lib/config.sh +29 -0
- package/deploy/lib/github-actions-logging.sh +610 -0
- package/deploy/lib/host.sh +194 -0
- package/deploy/lib/state.sh +65 -0
- package/deploy/pwa-microservices-template/deploy.sh +17 -42
- package/deploy/release/deploy.sh +9 -41
- package/deployment.yaml +7 -2
- package/docker-compose.yml +23 -17
- package/examples/static-page/README.md +19 -19
- package/examples/static-page/ssr-components/CustomPage.js +2 -2
- package/hardhat/hardhat.config.js +1 -6
- package/hardhat/package-lock.json +101 -40
- package/hardhat/package.json +2 -2
- package/manifests/alertmanager/deployment.yaml +81 -0
- package/manifests/blackbox-exporter/deployment.yaml +75 -0
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +32 -7
- package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +32 -7
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +7 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/mongo-express/deployment.yaml +46 -27
- package/manifests/deployment/mongo-express/kustomization.yaml +9 -0
- package/manifests/deployment/mongo-express/mongo-express-nodeport.yaml +18 -0
- package/manifests/deployment/mongo-express/service.yaml +16 -0
- package/manifests/deployment/mongo-express-no-auth/disable-mongodb-auth.yaml +16 -0
- package/manifests/deployment/mongo-express-no-auth/kustomization.yaml +16 -0
- package/manifests/grafana/deployment.yaml +26 -7
- package/manifests/grafana/kustomization.yaml +1 -0
- package/manifests/grafana/service.yaml +6 -1
- package/manifests/mariadb/pv.yaml +1 -0
- package/manifests/mongodb/statefulset.yaml +9 -2
- package/manifests/mysql/pv-pvc.yaml +14 -1
- package/manifests/postgresql/pv.yaml +12 -1
- package/manifests/postgresql/pvc.yaml +1 -0
- package/manifests/prometheus/deployment.yaml +18 -22
- package/package.json +87 -12
- package/scripts/event-monitor.sh +56 -0
- package/scripts/k3s-node-setup.sh +27 -14
- package/scripts/kubeadm-node-setup.sh +31 -11
- package/scripts/maas-setup.sh +8 -8
- package/scripts/selinux-normalize.sh +907 -0
- package/scripts/shutdown-machine.sh +843 -0
- package/scripts/test-monitor.sh +5 -5
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +15 -10
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +36 -5
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +7 -2
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +90 -186
- package/src/api/core/core.controller.js +1 -1
- package/src/api/core/core.router.js +2 -2
- package/src/api/core/core.service.js +2 -2
- package/src/api/crypto/crypto.controller.js +1 -1
- package/src/api/crypto/crypto.service.js +1 -1
- package/src/api/cyberia-action/cyberia-action.controller.js +1 -1
- package/src/api/cyberia-action/cyberia-action.router.js +3 -3
- package/src/api/cyberia-action/cyberia-action.service.js +5 -6
- package/src/api/cyberia-audio/cyberia-audio.controller.js +6 -0
- package/src/api/cyberia-audio/cyberia-audio.model.js +61 -0
- package/src/api/cyberia-audio/cyberia-audio.router.js +21 -0
- package/src/api/cyberia-audio/cyberia-audio.service.js +220 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +2 -4
- package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +10 -19
- package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +13 -35
- package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +17 -34
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +2 -2
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +2 -2
- package/src/api/cyberia-entity/cyberia-entity.controller.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.model.js +2 -0
- package/src/api/cyberia-entity/cyberia-entity.router.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.service.js +3 -3
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +8 -2
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +31 -20
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +17 -2
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +468 -5
- package/src/api/cyberia-instance/cyberia-fallback-capture.js +502 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +29 -40
- package/src/api/cyberia-instance/cyberia-instance-boot.service.js +5 -5
- package/src/api/cyberia-instance/cyberia-instance-items.js +98 -0
- package/src/api/cyberia-instance/cyberia-instance-map.service.js +35 -142
- package/src/api/cyberia-instance/cyberia-instance.controller.js +2 -5
- package/src/api/cyberia-instance/cyberia-instance.model.js +0 -14
- package/src/api/cyberia-instance/cyberia-instance.router.js +5 -18
- package/src/api/cyberia-instance/cyberia-instance.service.js +5 -45
- package/src/api/cyberia-instance/cyberia-world-generator.js +8 -13
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +1 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +49 -75
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +1 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +76 -3
- package/src/api/cyberia-map/cyberia-map.controller.js +1 -1
- package/src/api/cyberia-map/cyberia-map.router.js +1 -1
- package/src/api/cyberia-map/cyberia-map.service.js +8 -4
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.controller.js +31 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.model.js +56 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.router.js +33 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +189 -0
- package/src/api/cyberia-quest/cyberia-quest.controller.js +1 -1
- package/src/api/cyberia-quest/cyberia-quest.router.js +4 -4
- package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +2 -2
- package/src/api/cyberia-saga/cyberia-saga.controller.js +1 -1
- package/src/api/cyberia-saga/cyberia-saga.router.js +1 -1
- package/src/api/cyberia-saga/cyberia-saga.service.js +2 -2
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +403 -214
- package/src/api/cyberia-skill/cyberia-skill.controller.js +1 -1
- package/src/api/cyberia-skill/cyberia-skill.model.js +6 -6
- package/src/api/cyberia-skill/cyberia-skill.router.js +1 -1
- package/src/api/cyberia-skill/cyberia-skill.service.js +2 -2
- package/src/api/default/default.controller.js +1 -1
- package/src/api/default/default.router.js +1 -1
- package/src/api/default/default.service.js +2 -2
- package/src/api/document/document.controller.js +1 -1
- package/src/api/document/document.router.js +1 -1
- package/src/api/document/document.service.js +2 -2
- package/src/api/file/file.controller.js +1 -1
- package/src/api/file/file.ref.js +153 -0
- package/src/api/file/file.ref.json +11 -2
- package/src/api/file/file.router.js +1 -1
- package/src/api/file/file.service.js +2 -2
- package/src/api/instance/instance.controller.js +1 -1
- package/src/api/instance/instance.router.js +1 -1
- package/src/api/instance/instance.service.js +2 -2
- package/src/api/ipfs/ipfs.controller.js +1 -1
- package/src/api/ipfs/ipfs.router.js +2 -2
- package/src/api/ipfs/ipfs.service.js +2 -2
- package/src/api/object-layer/object-layer.controller.js +1 -1
- package/src/api/object-layer/object-layer.model.js +47 -12
- package/src/api/object-layer/object-layer.router.js +12 -5
- package/src/api/object-layer/object-layer.service.js +116 -123
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +1 -1
- package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +1 -1
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +2 -2
- package/src/api/test/test.controller.js +1 -1
- package/src/api/test/test.service.js +1 -1
- package/src/api/user/guest.service.js +3 -3
- package/src/api/user/user.controller.js +1 -1
- package/src/api/user/user.router.js +2 -2
- package/src/api/user/user.service.js +4 -4
- package/src/api.js +5 -9
- package/src/cli/app.js +402 -0
- package/src/cli/baremetal.js +30 -35
- package/src/cli/client.js +306 -0
- package/src/cli/cloud-init.js +3 -3
- package/src/cli/cluster.js +191 -82
- package/src/cli/db.js +120 -68
- package/src/cli/deploy.js +157 -75
- package/src/cli/docker-compose.js +5 -5
- package/src/cli/domains.js +184 -0
- package/src/cli/dotenv-store.js +143 -0
- package/src/cli/event.js +2281 -0
- package/src/cli/fs-selection.js +115 -0
- package/src/cli/fs.js +159 -343
- package/src/cli/host.js +672 -0
- package/src/cli/image.js +4 -6
- package/src/cli/index.js +343 -151
- package/src/cli/ipfs.js +34 -30
- package/src/cli/kickstart.js +1 -1
- package/src/cli/kubectl.js +218 -41
- package/src/cli/lxd.js +3 -3
- package/src/cli/monitor.js +1359 -26
- package/src/cli/package.js +90 -0
- package/src/cli/release.js +16 -12
- package/src/cli/repository.js +586 -363
- package/src/cli/run.js +398 -843
- package/src/cli/secrets.js +2158 -964
- package/src/cli/ssh.js +478 -279
- package/src/cli/state.js +394 -0
- package/src/cli/static.js +2 -2
- package/src/cli/system.js +1 -1
- package/src/cli/test.js +203 -125
- package/src/cli/vultr.js +61 -21
- package/src/cli/wireguard.js +1112 -306
- package/src/client/components/core/CalendarCore.js +53 -96
- package/src/client/components/core/Docs.js +327 -303
- package/src/client/components/core/FileExplorer.js +0 -21
- package/src/client/components/core/Modal.js +56 -1
- package/src/client/components/core/PanelForm.js +4 -4
- package/src/client/components/core/Repository.js +56 -0
- package/src/client/components/core/Translate.js +7 -0
- package/src/client/components/core/{FullScreen.js → ViewModeController.js} +42 -39
- package/src/client/components/core/Wallet.js +0 -11
- package/src/client/components/core/Worker.js +7 -1
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +2 -2
- package/src/client/components/cyberia/ActionEngineCyberia.js +12 -36
- package/src/client/components/cyberia/EntityEngineCyberia.js +492 -121
- package/src/client/components/cyberia/InstanceEngineCyberia.js +129 -160
- package/src/client/components/cyberia/InstanceSelectionView.js +7 -1
- package/src/client/components/cyberia/MapEngineCyberia.js +175 -69
- package/src/client/components/cyberia/ObjectLayerEngine.js +1011 -97
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +81 -155
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +113 -98
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +215 -56
- package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +2 -35
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +1 -1
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +712 -76
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +2 -2
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +0 -4
- package/src/client/components/default/AppShellDefault.js +1 -1
- package/src/client/components/default/SettingsDefault.js +2 -2
- package/src/client/components/itemledger/SettingsItemledger.js +2 -2
- package/src/client/components/underpost/AppShellUnderpost.js +3 -2
- package/src/client/components/underpost/SettingsUnderpost.js +2 -2
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +15 -15
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +313 -30
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +51 -29
- package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +52 -53
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +16 -11
- package/src/client/public/cyberia-docs/CYBERIA.md +48 -28
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +11 -5
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +23 -6
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/STATS-PROGRESSION.md +217 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +20 -12
- package/src/client/public/default/android-chrome-144x144.png +0 -0
- package/src/client/public/default/android-chrome-192x192.png +0 -0
- package/src/client/public/default/android-chrome-256x256.png +0 -0
- package/src/client/public/default/android-chrome-36x36.png +0 -0
- package/src/client/public/default/android-chrome-384x384.png +0 -0
- package/src/client/public/default/android-chrome-48x48.png +0 -0
- package/src/client/public/default/android-chrome-512x512.png +0 -0
- package/src/client/public/default/android-chrome-72x72.png +0 -0
- package/src/client/public/default/android-chrome-96x96.png +0 -0
- package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
- package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
- package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
- package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
- package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
- package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
- package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
- package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
- package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
- package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
- package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
- package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
- package/src/client/public/default/assets/background/white.jpg +0 -0
- package/src/client/public/default/browserconfig.xml +1 -1
- package/src/client/public/default/favicon-16x16.png +0 -0
- package/src/client/public/default/favicon-32x32.png +0 -0
- package/src/client/public/default/favicon-48x48.png +0 -0
- package/src/client/public/default/favicon.ico +0 -0
- package/src/client/public/default/manifest.webmanifest +5 -5
- package/src/client/public/default/mstile-144x144.png +0 -0
- package/src/client/public/default/mstile-150x150.png +0 -0
- package/src/client/public/default/mstile-310x150.png +0 -0
- package/src/client/public/default/mstile-310x310.png +0 -0
- package/src/client/public/default/mstile-70x70.png +0 -0
- package/src/client/public/default/yandex-browser-50x50.png +0 -0
- package/src/client/public/default/yandex-browser-manifest.json +1 -1
- package/src/client/services/cyberia-audio/cyberia-audio.service.js +99 -0
- package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +38 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +5 -4
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +0 -40
- package/src/client/services/cyberia-map/cyberia-map.management.js +5 -4
- package/src/client/services/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +138 -0
- package/src/client/services/object-layer/object-layer.management.js +6 -10
- package/src/client/services/object-layer/object-layer.service.js +3 -1
- package/src/client/ssr/RootDocument.js +1 -1
- package/src/client/ssr/body/404.js +1 -1
- package/src/client/ssr/body/500.js +1 -1
- package/src/client/ssr/body/CacheControl.js +1 -1
- package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +1 -1
- package/src/client/ssr/body/DefaultSplashScreen.js +1 -1
- package/src/client/ssr/body/SwaggerDarkMode.js +1 -1
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +1 -1
- package/src/client/ssr/head/CryptokoynScripts.js +1 -1
- package/src/client/ssr/head/Css.js +1 -1
- package/src/client/ssr/head/CyberiaPortalScripts.js +1 -1
- package/src/client/ssr/head/DefaultScripts.js +1 -1
- package/src/client/ssr/head/ItemledgerScripts.js +1 -1
- package/src/client/ssr/head/Microdata.js +1 -1
- package/src/client/ssr/head/Production.js +1 -1
- package/src/client/ssr/head/Pwa.js +1 -1
- package/src/client/ssr/head/PwaItemledger.js +1 -1
- package/src/client/ssr/head/Seo.js +1 -1
- package/src/client/ssr/head/UnderpostScripts.js +1 -1
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +1 -1
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +1 -1
- package/src/client/ssr/views/Cyberia404.js +7 -5
- package/src/client/ssr/views/CyberiaServerMetrics.js +1 -1
- package/src/client/ssr/views/Maintenance.js +1 -1
- package/src/client/ssr/views/NoNetworkConnection.js +1 -1
- package/src/client/ssr/views/Test.js +1 -1
- package/src/client/sw/core.sw.js +20 -14
- package/src/client-builder/client-build-docs.js +92 -77
- package/src/client-builder/client-build-live.js +2 -2
- package/src/client-builder/client-build.js +105 -74
- package/src/client-builder/client-bundle.js +347 -0
- package/src/client-builder/client-dev-server.js +3 -3
- package/src/client-builder/client-icons.js +2 -2
- package/src/client-builder/ssr.js +3 -3
- package/src/client.build.js +3 -6
- package/src/client.dev.js +3 -6
- package/src/db/DataBaseProvider.js +186 -3
- package/src/db/mariadb/MariaDB.js +3 -2
- package/src/db/mongo/MongoBootstrap.js +273 -101
- package/src/db/mongo/MongoExpress.js +187 -0
- package/src/db/mongo/MongooseDB.js +7 -8
- package/src/{server/valkey.js → db/valkey/Valkey.js} +5 -4
- package/src/grpc/cyberia/grpc-server.js +6 -8
- package/src/index.js +79 -23
- package/src/mailer/EmailRender.js +2 -2
- package/src/mailer/MailerInterceptor.js +87 -0
- package/src/mailer/MailerProvider.js +50 -6
- package/src/projects/cyberia/atlas-sprite-sheet-generator.js +144 -147
- package/src/projects/cyberia/atlas-sprite-sheet-store.js +391 -0
- package/src/projects/cyberia/besu-genesis-generator.js +8 -17
- package/src/projects/cyberia/boot-contract-fixtures.js +32 -0
- package/src/projects/cyberia/catalog-cyberia.js +54 -10
- package/src/projects/cyberia/gemini-client.js +4 -4
- package/src/projects/cyberia/generate-saga.js +5 -12
- package/src/projects/cyberia/hot-reload-trigger.js +18 -29
- package/src/projects/cyberia/instance-backup.js +210 -0
- package/src/projects/cyberia/instance-data.js +178 -258
- package/src/projects/cyberia/ipfs-client.js +4 -4
- package/src/projects/cyberia/map-preview-generator.js +33 -69
- package/src/projects/cyberia/object-layer.js +153 -320
- package/src/projects/cyberia/seed-audio.js +139 -0
- package/src/projects/cyberia/semantic-layer-generator-skin.js +2 -8
- package/src/projects/cyberia/semantic-layer-generator.js +3 -19
- package/src/projects/cyberia/stat-balance.js +81 -0
- package/src/projects/cyberia/stat-commands.js +23 -0
- package/src/projects/cyberia/stat-contract-generator.js +101 -0
- package/src/projects/underpost/catalog-underpost.js +9 -1
- package/src/proxy.js +4 -7
- package/src/runtime/cyberia-client/Dockerfile +17 -8
- package/src/runtime/cyberia-client/Dockerfile.dev +13 -4
- package/src/runtime/cyberia-server/Dockerfile +18 -6
- package/src/runtime/cyberia-server/Dockerfile.dev +16 -3
- package/src/runtime/engine-cyberia/Dockerfile +25 -9
- package/src/runtime/engine-cyberia/Dockerfile.dev +25 -9
- package/src/runtime/engine-cyberia/Dockerfile.test +5 -5
- package/src/runtime/engine-cyberia/compose.env +17 -5
- package/src/runtime/engine-cyberia/docker-compose.yml +23 -17
- package/src/runtime/express/Express.js +32 -27
- package/src/runtime/lampp/Lampp.js +22 -70
- package/src/runtime/nginx/Nginx.js +1 -1
- package/src/runtime/wp/Wp.js +16 -48
- package/src/server/{catalog.js → build/catalog.js} +15 -5
- package/src/server/build/coverage.js +188 -0
- package/src/server/build/execution.js +402 -0
- package/src/server/build/package.js +508 -0
- package/src/server/build/testing.js +578 -0
- package/src/server/{dns.js → network/dns.js} +144 -11
- package/src/server/{forward-proxy.js → network/forward-proxy.js} +10 -18
- package/src/server/{middlewares.js → network/middlewares.js} +11 -5
- package/src/server/network/node-capability.js +98 -0
- package/src/server/{peer.js → network/peer.js} +3 -3
- package/src/server/{proxy.js → network/proxy.js} +7 -13
- package/src/server/network/router.js +356 -0
- package/src/server/{tls.js → network/tls.js} +2 -2
- package/src/server/{underpost-compression.js → network/underpost-compression.js} +1 -1
- package/src/server/{underpost-gateway.js → network/underpost-gateway.js} +7 -7
- package/src/server/{underpost-ingress.js → network/underpost-ingress.js} +2 -2
- package/src/server/{cri.js → ops/cri.js} +2 -2
- package/src/server/{cron.js → ops/cron.js} +349 -74
- package/src/server/ops/event-notification.js +284 -0
- package/src/server/{logger.js → ops/logger.js} +143 -23
- package/src/server/ops/monitoring.js +1724 -0
- package/src/server/{systemd.js → ops/systemd.js} +55 -1
- package/src/server/{conf.js → runtime/conf.js} +516 -423
- package/src/server/runtime/config-scope.js +215 -0
- package/src/server/runtime/environment.js +149 -0
- package/src/server/{process.js → runtime/process.js} +153 -12
- package/src/server/{runtime-status.js → runtime/runtime-status.js} +155 -16
- package/src/server/{runtime.js → runtime/runtime.js} +12 -8
- package/src/server/{start.js → runtime/start.js} +128 -39
- package/src/server/{auth.js → security/auth.js} +7 -8
- package/src/server/security/container-storage.js +382 -0
- package/src/server/{crypto.js → security/crypto.js} +1 -1
- package/src/server/{selinux.js → security/selinux.js} +1 -1
- package/src/server/{backup.js → storage/backup.js} +17 -8
- package/src/server/{data-query.js → storage/data-query.js} +17 -1
- package/src/server/storage/downloader.js +121 -0
- package/src/server/storage/repository.js +68 -0
- package/src/server/storage/zip.js +153 -0
- package/src/server.js +4 -7
- package/src/ws/IoInterface.js +1 -1
- package/src/ws/IoServer.js +1 -1
- package/src/ws/core/core.ws.connection.js +1 -1
- package/src/ws/core/core.ws.emit.js +1 -1
- package/src/ws/core/core.ws.server.js +1 -1
- package/src/ws/default/default.ws.connection.js +1 -1
- package/src/ws/default/default.ws.emit.js +1 -1
- package/src/ws/default/default.ws.server.js +1 -1
- package/test/e2e/event-e2e-public-ingress-down.js +45 -0
- package/test/e2e/event-e2e-wireguard-server-down.js +38 -0
- package/test/e2e/event-e2e-wireguard-spoke-down.js +40 -0
- package/test/{api.test.js → integration/app/api.test.js} +33 -14
- package/test/integration/app/cyberia/atlas-sprite-sheet-store.test.js +402 -0
- package/test/integration/app/cyberia/atlas-sprite-sheet.test.js +86 -0
- package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +64 -0
- package/test/integration/app/cyberia/cyberia-entity-type-default.test.js +842 -0
- package/test/integration/app/cyberia/cyberia-instance-conf-coerce.test.js +53 -0
- package/test/{cyberia-instance-conf-defaults.test.js → integration/app/cyberia/cyberia-instance-conf-defaults.test.js} +17 -23
- package/test/integration/app/cyberia/cyberia-instance-items.test.js +90 -0
- package/test/integration/app/cyberia/cyberia-load.test.js +466 -0
- package/test/integration/app/cyberia/cyberia-map-audio-conf.test.js +256 -0
- package/test/integration/app/cyberia/cyberia-stats.test.js +150 -0
- package/test/integration/app/cyberia/fallback-world-capture.test.js +338 -0
- package/test/integration/app/cyberia/object-layer-item-id.test.js +327 -0
- package/test/integration/app/cyberia/object-layer-item-selection.test.js +56 -0
- package/test/integration/app/cyberia/object-layer-natural-key.test.js +32 -0
- package/test/integration/app/cyberia/seed-audio.test.js +275 -0
- package/test/{shape-generator.test.js → integration/app/cyberia/shape-generator.test.js} +1 -1
- package/test/integration/infra/1-security/config-scope.test.js +305 -0
- package/test/integration/infra/1-security/container-storage.test.js +356 -0
- package/test/integration/infra/1-security/in-pod-cli-surface.test.js +86 -0
- package/test/integration/infra/1-security/secret-onboarding.test.js +930 -0
- package/test/{selinux.test.js → integration/infra/1-security/selinux.test.js} +2 -4
- package/test/{sops-secret-store.test.js → integration/infra/1-security/sops-secret-store.test.js} +415 -61
- package/test/integration/infra/1-security/systemd-service.test.js +70 -0
- package/test/integration/infra/1-security/underpost-config-secret.test.js +367 -0
- package/test/integration/infra/2-network/dns-firewall.test.js +566 -0
- package/test/integration/infra/2-network/node-capability.test.js +182 -0
- package/test/integration/infra/2-network/wireguard-cli.test.js +1187 -0
- package/test/{wireguard-edge.test.js → integration/infra/2-network/wireguard-edge.test.js} +649 -55
- package/test/{cluster-instances.test.js → integration/infra/3-cluster/cluster-instances.test.js} +11 -15
- package/test/{deploy-node-placement.test.js → integration/infra/3-cluster/deploy-node-placement.test.js} +3 -3
- package/test/integration/infra/3-cluster/docker-compose-stack.test.js +313 -0
- package/test/integration/infra/3-cluster/mongo-express-deploy.test.js +156 -0
- package/test/integration/infra/4-ingress/api-cross-origin.test.js +79 -0
- package/test/integration/infra/4-ingress/deploy-routes.test.js +379 -0
- package/test/integration/infra/4-ingress/gateway-static-assets.test.js +453 -0
- package/test/{instance-traffic-plan.test.js → integration/infra/4-ingress/instance-traffic-plan.test.js} +10 -6
- package/test/{underpost-gateway.test.js → integration/infra/4-ingress/underpost-gateway.test.js} +6 -6
- package/test/{underpost-ingress.test.js → integration/infra/4-ingress/underpost-ingress.test.js} +4 -4
- package/test/integration/infra/5-observability/cron-jobs.test.js +652 -0
- package/test/{deploy-monitor.test.js → integration/infra/5-observability/deploy-monitor.test.js} +29 -31
- package/test/integration/infra/5-observability/event-notification.test.js +197 -0
- package/test/integration/infra/5-observability/event-remediation.test.js +502 -0
- package/test/integration/infra/5-observability/event-targets.test.js +1174 -0
- package/test/integration/infra/5-observability/monitoring-stack.test.js +902 -0
- package/test/support/shell-harness.js +73 -0
- package/test/unit/build-template.test.js +97 -0
- package/test/unit/build-workflow-offline.test.js +132 -0
- package/test/unit/catalog.test.js +71 -0
- package/test/unit/client-build-docs.test.js +361 -0
- package/test/unit/client-bundle.test.js +313 -0
- package/test/unit/conf-loading.test.js +303 -0
- package/test/unit/conf-resolution.test.js +996 -0
- package/test/unit/coverage-artifact.test.js +221 -0
- package/test/{crypto.test.js → unit/crypto.test.js} +1 -1
- package/test/unit/cyberia/instance-backup.test.js +183 -0
- package/test/unit/cyberia/instance-object-layer-items.test.js +46 -0
- package/test/unit/cyberia/publish-workflow.test.js +22 -0
- package/test/unit/cyberia/stat-balance.test.js +69 -0
- package/test/unit/deploy-env-resolution.test.js +38 -0
- package/test/unit/deploy-log-table.test.js +518 -0
- package/test/unit/downloader-integrity.test.js +98 -0
- package/test/unit/execution-profiles.test.js +219 -0
- package/test/unit/file-reference-registry.test.js +141 -0
- package/test/unit/fleet-sync-source.test.js +149 -0
- package/test/unit/fs-storage-paths.test.js +596 -0
- package/test/unit/logger-redaction.test.js +141 -0
- package/test/unit/package.test.js +457 -0
- package/test/unit/prepare-host.test.js +382 -0
- package/test/unit/process-environment.test.js +18 -0
- package/test/unit/propagation-message.test.js +78 -0
- package/test/unit/redeploy-plan.test.js +24 -0
- package/test/unit/release-bump.test.js +474 -0
- package/test/unit/ssh-output-redaction.test.js +28 -0
- package/test/unit/start-options.test.js +46 -0
- package/test/unit/test-tiers.test.js +220 -0
- package/test/unit/zip-archive.test.js +142 -0
- package/vitest.config.js +66 -0
- package/.nycrc +0 -9
- package/deploy/lib/logging.sh +0 -96
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +0 -48
- package/manifests/mongodb/pv-pvc.yaml +0 -59
- package/scripts/coverall-test-cyberia.sh +0 -24
- package/scripts/coverall-test.sh +0 -24
- package/scripts/link-local-underpost-cli.sh +0 -6
- package/src/api/cyberia-instance/cyberia-fallback-default-items.js +0 -63
- package/src/api/user/user.build.js +0 -16
- package/src/cli/env.js +0 -177
- package/src/client/components/core/Blockchain.js +0 -41
- package/src/client/components/core/Blog.js +0 -9
- package/src/client/components/core/KeyboardAvoidance.js +0 -145
- package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +0 -368
- package/src/client/public/default/assets/background/dark.jpg +0 -0
- package/src/client/public/default/assets/background/white0-min.jpg +0 -0
- package/src/client/public/default/assets/background/white0.jpg +0 -0
- package/src/client/public/doc/favicon.ico +0 -0
- package/src/client/public/doc/sitemap +0 -148
- package/src/server/downloader.js +0 -73
- package/src/server/environment.js +0 -98
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence for the atlas sprite sheet of one object layer item.
|
|
3
|
+
*
|
|
4
|
+
* Owns the AtlasSpriteSheet document, the File blobs it points at, and the
|
|
5
|
+
* IPFS pins of the atlas PNG and its metadata. Every writer — the REST service
|
|
6
|
+
* and the Cyberia CLI — goes through here, so one item key always resolves to
|
|
7
|
+
* one atlas.
|
|
8
|
+
*
|
|
9
|
+
* @module src/projects/cyberia/atlas-sprite-sheet-store.js
|
|
10
|
+
* @namespace CyberiaAtlasSpriteSheetStore
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import crypto from 'crypto';
|
|
14
|
+
import { Types } from 'mongoose';
|
|
15
|
+
import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
|
|
16
|
+
import { loggerFactory } from '../../server/ops/logger.js';
|
|
17
|
+
import { createPinRecord } from '../../api/ipfs/ipfs.service.js';
|
|
18
|
+
import { FileFactory } from '../../api/file/file.service.js';
|
|
19
|
+
import { deleteOwnedFiles, documentFileIds, fileRefFields } from '../../api/file/file.ref.js';
|
|
20
|
+
import { AtlasSpriteSheetGenerator, DEFAULT_ATLAS_UPSCALE_FACTOR } from './atlas-sprite-sheet-generator.js';
|
|
21
|
+
import { IpfsClient } from './ipfs-client.js';
|
|
22
|
+
|
|
23
|
+
const logger = loggerFactory(import.meta);
|
|
24
|
+
|
|
25
|
+
/** The File-referencing fields of this model, read from the registry that owns that mapping. */
|
|
26
|
+
export const ATLAS_FILE_FIELDS = fileRefFields('atlas-sprite-sheet');
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The File `name` an atlas render is written under, as {@link upsertRenderFile} spells it.
|
|
30
|
+
* A prune reads it to recognise a render whose atlas is already gone.
|
|
31
|
+
* @constant {RegExp}
|
|
32
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
33
|
+
*/
|
|
34
|
+
const ATLAS_RENDER_NAME = /-(atlas|minify|idle)\.png$/;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* MFS paths of the IPFS content an item key owns.
|
|
38
|
+
* @param {string} itemKey - Object layer item id.
|
|
39
|
+
* @returns {{ png: string, metadata: string }}
|
|
40
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
41
|
+
*/
|
|
42
|
+
export const atlasMfsPaths = (itemKey) => ({
|
|
43
|
+
png: `/object-layer/${itemKey}/${itemKey}_atlas_sprite_sheet.png`,
|
|
44
|
+
metadata: `/object-layer/${itemKey}/${itemKey}_atlas_sprite_sheet_metadata.json`,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The File `_id` a render resolves through, derived from the item key, the render
|
|
49
|
+
* role and the bytes themselves.
|
|
50
|
+
*
|
|
51
|
+
* Content-addressed on purpose: identical bytes re-derive the same id, which makes
|
|
52
|
+
* a rerun a no-op instead of a churn of File documents. Changed bytes land on a new
|
|
53
|
+
* id, and the writer deletes the one it replaced.
|
|
54
|
+
*
|
|
55
|
+
* @param {string} itemKey - Object layer item id.
|
|
56
|
+
* @param {string} role - Render role: `atlas`, `minify` or `idle`.
|
|
57
|
+
* @param {string} md5 - Hex MD5 of the PNG bytes.
|
|
58
|
+
* @returns {import('mongoose').Types.ObjectId}
|
|
59
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
60
|
+
*/
|
|
61
|
+
const atlasFileId = (itemKey, role, md5) =>
|
|
62
|
+
new Types.ObjectId(crypto.createHash('sha256').update(`atlas:${itemKey}:${role}:${md5}`).digest('hex').slice(0, 24));
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Writes a PNG render to the File collection under its content-addressed id.
|
|
66
|
+
* Re-writing the same bytes returns the stored document untouched.
|
|
67
|
+
*
|
|
68
|
+
* @param {Object} File - Mongoose File model.
|
|
69
|
+
* @param {string} itemKey - Object layer item id.
|
|
70
|
+
* @param {string} role - Render role: `atlas`, `minify` or `idle`.
|
|
71
|
+
* @param {Buffer} buffer - PNG bytes.
|
|
72
|
+
* @returns {Promise<import('mongoose').Types.ObjectId>} The File id.
|
|
73
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
74
|
+
*/
|
|
75
|
+
const upsertRenderFile = async (File, itemKey, role, buffer) => {
|
|
76
|
+
const payload = FileFactory.create(buffer, `${itemKey}-${role}.png`);
|
|
77
|
+
const _id = atlasFileId(itemKey, role, payload.md5);
|
|
78
|
+
await File.updateOne({ _id }, { $setOnInsert: { ...payload, _id } }, { upsert: true });
|
|
79
|
+
return _id;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Writes the idle-preview still cut from a human-resolution render, or returns null
|
|
84
|
+
* for an atlas with no frame to cut.
|
|
85
|
+
*
|
|
86
|
+
* @param {Object} File - Mongoose File model.
|
|
87
|
+
* @param {string} itemKey - Object layer item id.
|
|
88
|
+
* @param {Buffer} buffer - PNG bytes of the human-resolution render.
|
|
89
|
+
* @param {Object} metadata - Atlas metadata describing that render's layout.
|
|
90
|
+
* @returns {Promise<import('mongoose').Types.ObjectId|null>}
|
|
91
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
92
|
+
*/
|
|
93
|
+
const upsertIdlePreview = async (File, itemKey, buffer, metadata) => {
|
|
94
|
+
const still = await AtlasSpriteSheetGenerator.idlePreviewFromAtlas(buffer, metadata);
|
|
95
|
+
return still ? await upsertRenderFile(File, itemKey, 'idle', still) : null;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Deletes the File documents an atlas no longer points at.
|
|
100
|
+
*
|
|
101
|
+
* @param {Object} File - Mongoose File model.
|
|
102
|
+
* @param {Array<import('mongoose').Types.ObjectId>} previousIds - File ids held before the write.
|
|
103
|
+
* @param {Array<import('mongoose').Types.ObjectId>} currentIds - File ids held after the write.
|
|
104
|
+
* @returns {Promise<void>}
|
|
105
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
106
|
+
*/
|
|
107
|
+
const deleteReplacedFiles = async (File, previousIds, currentIds) => {
|
|
108
|
+
const kept = new Set(currentIds.filter(Boolean).map(String));
|
|
109
|
+
const replaced = [...new Set(previousIds.filter(Boolean).map(String))].filter((id) => !kept.has(id));
|
|
110
|
+
if (replaced.length === 0) return;
|
|
111
|
+
await File.deleteMany({ _id: { $in: replaced } });
|
|
112
|
+
logger.info(`Removed ${replaced.length} replaced atlas File document(s)`);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Pins a payload to IPFS and records it in the registry. A failure is logged and
|
|
117
|
+
* yields an empty CID, so a missing IPFS node never blocks a write.
|
|
118
|
+
*
|
|
119
|
+
* @param {Object} params
|
|
120
|
+
* @param {function(): Promise<{cid: string}|null>} params.add - The IpfsClient call.
|
|
121
|
+
* @param {string} params.resourceType - Registry category.
|
|
122
|
+
* @param {string} params.mfsPath - MFS path of the payload.
|
|
123
|
+
* @param {Object} [params.options] - Router options ({ host, path }).
|
|
124
|
+
* @returns {Promise<string>} The CID, or an empty string.
|
|
125
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
126
|
+
*/
|
|
127
|
+
const pin = async ({ add, resourceType, mfsPath, options }) => {
|
|
128
|
+
try {
|
|
129
|
+
const result = await add();
|
|
130
|
+
if (!result) return '';
|
|
131
|
+
await createPinRecord({ cid: result.cid, resourceType, mfsPath, options });
|
|
132
|
+
logger.info(`Pinned ${resourceType} – CID: ${result.cid}`);
|
|
133
|
+
return result.cid;
|
|
134
|
+
} catch (error) {
|
|
135
|
+
logger.warn(`Failed to pin ${resourceType}: ${error.message}`);
|
|
136
|
+
return '';
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Tells whether two atlas layouts place every frame at the same cell.
|
|
142
|
+
*
|
|
143
|
+
* @param {Object} left - Atlas metadata.
|
|
144
|
+
* @param {Object} right - Atlas metadata.
|
|
145
|
+
* @returns {boolean}
|
|
146
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
147
|
+
*/
|
|
148
|
+
const sameLayout = (left, right) => {
|
|
149
|
+
if (left.atlasWidth !== right.atlasWidth || left.atlasHeight !== right.atlasHeight) return false;
|
|
150
|
+
const box = (frame) => (frame ? `${frame.x},${frame.y},${frame.width},${frame.height}` : '');
|
|
151
|
+
const directions = new Set([...Object.keys(left.frames ?? {}), ...Object.keys(right.frames ?? {})]);
|
|
152
|
+
for (const direction of directions) {
|
|
153
|
+
const leftFrames = left.frames?.[direction] ?? [];
|
|
154
|
+
const rightFrames = right.frames?.[direction] ?? [];
|
|
155
|
+
if (leftFrames.length !== rightFrames.length) return false;
|
|
156
|
+
for (let index = 0; index < leftFrames.length; index++) {
|
|
157
|
+
if (box(leftFrames[index]) !== box(rightFrames[index])) return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return true;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Atlas sprite sheet persistence, keyed by object layer item id.
|
|
165
|
+
* @class AtlasSpriteSheetStore
|
|
166
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
167
|
+
*/
|
|
168
|
+
export class AtlasSpriteSheetStore {
|
|
169
|
+
/**
|
|
170
|
+
* Generates both renders of an item's atlas and stores them.
|
|
171
|
+
*
|
|
172
|
+
* The write is keyed by `metadata.itemKey`, so a rerun updates the same
|
|
173
|
+
* document. Renders whose bytes did not change keep their File documents;
|
|
174
|
+
* renders that changed replace them and the old ones are deleted.
|
|
175
|
+
*
|
|
176
|
+
* @static
|
|
177
|
+
* @param {Object} params
|
|
178
|
+
* @param {string} params.itemKey - Object layer item id.
|
|
179
|
+
* @param {Object} params.objectLayerRenderFrames - Render frames, document or plain object.
|
|
180
|
+
* @param {number} [params.upscaleFactor=DEFAULT_ATLAS_UPSCALE_FACTOR] - Pixels per cell of the human-resolution render.
|
|
181
|
+
* @param {number} [params.maxAtlasDim=null] - Maximum atlas dimension, auto-calculated when null.
|
|
182
|
+
* @param {Object} [params.options] - Router options ({ host, path }) for model lookup.
|
|
183
|
+
* @returns {Promise<{atlasDoc: Object, metadata: Object, atlasCid: string, atlasMetadataCid: string}>}
|
|
184
|
+
* `metadata` is the plain generated layout, free of the document wrapper a caller would have to unwrap.
|
|
185
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
186
|
+
*/
|
|
187
|
+
static async persist({
|
|
188
|
+
itemKey,
|
|
189
|
+
objectLayerRenderFrames,
|
|
190
|
+
upscaleFactor = DEFAULT_ATLAS_UPSCALE_FACTOR,
|
|
191
|
+
maxAtlasDim = null,
|
|
192
|
+
options,
|
|
193
|
+
}) {
|
|
194
|
+
const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
|
|
195
|
+
const File = DataBaseProviderService.getModel('File', options);
|
|
196
|
+
|
|
197
|
+
const { buffer, minifyBuffer, metadata } = await AtlasSpriteSheetGenerator.generateAtlas(
|
|
198
|
+
objectLayerRenderFrames,
|
|
199
|
+
itemKey,
|
|
200
|
+
upscaleFactor,
|
|
201
|
+
maxAtlasDim,
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
const fileId = await upsertRenderFile(File, itemKey, 'atlas', buffer);
|
|
205
|
+
const minifyFileId = await upsertRenderFile(File, itemKey, 'minify', minifyBuffer);
|
|
206
|
+
const idlePreviewFileId = await upsertIdlePreview(File, itemKey, buffer, metadata);
|
|
207
|
+
|
|
208
|
+
const mfsPaths = atlasMfsPaths(itemKey);
|
|
209
|
+
const atlasCid = await pin({
|
|
210
|
+
add: () => IpfsClient.addBufferToIpfs(buffer, `${itemKey}_atlas_sprite_sheet.png`, mfsPaths.png),
|
|
211
|
+
resourceType: 'atlas-sprite-sheet',
|
|
212
|
+
mfsPath: mfsPaths.png,
|
|
213
|
+
options,
|
|
214
|
+
});
|
|
215
|
+
const atlasMetadataCid = await pin({
|
|
216
|
+
add: () => IpfsClient.addJsonToIpfs(metadata, `${itemKey}_atlas_sprite_sheet_metadata.json`, mfsPaths.metadata),
|
|
217
|
+
resourceType: 'atlas-metadata',
|
|
218
|
+
mfsPath: mfsPaths.metadata,
|
|
219
|
+
options,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
let atlasDoc = await AtlasSpriteSheet.findOne({ 'metadata.itemKey': itemKey });
|
|
223
|
+
const previousFileIds = atlasDoc ? ATLAS_FILE_FIELDS.map((field) => atlasDoc[field]) : [];
|
|
224
|
+
|
|
225
|
+
const renders = { fileId, minifyFileId, idlePreviewFileId };
|
|
226
|
+
if (atlasDoc) {
|
|
227
|
+
atlasDoc.set({ ...renders, cid: atlasCid, metadata });
|
|
228
|
+
await atlasDoc.save();
|
|
229
|
+
} else {
|
|
230
|
+
atlasDoc = await new AtlasSpriteSheet({ ...renders, cid: atlasCid, metadata }).save();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
await deleteReplacedFiles(File, previousFileIds, Object.values(renders));
|
|
234
|
+
|
|
235
|
+
return { atlasDoc, metadata, atlasCid, atlasMetadataCid };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Removes atlases and everything they own: every File render they point at, and
|
|
240
|
+
* the documents themselves.
|
|
241
|
+
*
|
|
242
|
+
* The one place a caller deletes an atlas, because an atlas owns more than its
|
|
243
|
+
* document: a drop that took `fileId` and left `minifyFileId` behind is what put
|
|
244
|
+
* unreachable renders in the File collection. Rerunnable — a second call finds
|
|
245
|
+
* nothing and reports zeros.
|
|
246
|
+
*
|
|
247
|
+
* @static
|
|
248
|
+
* @param {Object} params
|
|
249
|
+
* @param {string[]} [params.itemKeys] - Item keys to purge.
|
|
250
|
+
* @param {Array<*>} [params.atlasIds] - Atlas document ids to purge, for a caller holding the link rather than the key.
|
|
251
|
+
* @param {boolean} [params.all=false] - Purge the whole collection, ignoring both selectors.
|
|
252
|
+
* @param {Object} [params.options] - Router options ({ host, path }) for model lookup.
|
|
253
|
+
* @returns {Promise<{atlases: number, files: number, cids: string[]}>} What was removed, and the CIDs the caller still has to unpin.
|
|
254
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
255
|
+
*/
|
|
256
|
+
static async purge({ itemKeys = [], atlasIds = [], all = false, options }) {
|
|
257
|
+
const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
|
|
258
|
+
const File = DataBaseProviderService.getModel('File', options);
|
|
259
|
+
|
|
260
|
+
const clauses = [];
|
|
261
|
+
if (itemKeys.length > 0) clauses.push({ 'metadata.itemKey': { $in: itemKeys } });
|
|
262
|
+
if (atlasIds.length > 0) clauses.push({ _id: { $in: atlasIds } });
|
|
263
|
+
if (!all && clauses.length === 0) return { atlases: 0, files: 0, cids: [] };
|
|
264
|
+
const selector = all ? {} : clauses.length === 1 ? clauses[0] : { $or: clauses };
|
|
265
|
+
|
|
266
|
+
const docs = await AtlasSpriteSheet.find(
|
|
267
|
+
selector,
|
|
268
|
+
Object.fromEntries([...ATLAS_FILE_FIELDS, 'cid'].map((field) => [field, 1])),
|
|
269
|
+
).lean();
|
|
270
|
+
if (docs.length === 0) return { atlases: 0, files: 0, cids: [] };
|
|
271
|
+
|
|
272
|
+
const fileIds = documentFileIds(docs, ATLAS_FILE_FIELDS);
|
|
273
|
+
const cids = [...new Set(docs.map((doc) => doc.cid).filter(Boolean))];
|
|
274
|
+
|
|
275
|
+
// Documents first: the survivors this reads decide which renders are still
|
|
276
|
+
// reachable, so the ones being dropped must already be gone.
|
|
277
|
+
const { deletedCount } = await AtlasSpriteSheet.deleteMany({ _id: { $in: docs.map((doc) => doc._id) } });
|
|
278
|
+
const files = await deleteOwnedFiles({ File, Owner: AtlasSpriteSheet, fields: ATLAS_FILE_FIELDS, ids: fileIds });
|
|
279
|
+
|
|
280
|
+
return { atlases: deletedCount ?? 0, files, cids };
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Deletes atlas renders no atlas document points at any more.
|
|
285
|
+
*
|
|
286
|
+
* The repair for what an earlier drop left behind: candidates are recognised by
|
|
287
|
+
* the name the writer gives a render, and a candidate a live atlas still holds
|
|
288
|
+
* is kept. Idempotent, and a no-op on a collection that never leaked.
|
|
289
|
+
*
|
|
290
|
+
* @static
|
|
291
|
+
* @param {Object} params
|
|
292
|
+
* @param {Object} [params.options] - Router options ({ host, path }) for model lookup.
|
|
293
|
+
* @returns {Promise<number>} How many orphaned renders were removed.
|
|
294
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
295
|
+
*/
|
|
296
|
+
static async pruneOrphanRenders({ options } = {}) {
|
|
297
|
+
const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
|
|
298
|
+
const File = DataBaseProviderService.getModel('File', options);
|
|
299
|
+
|
|
300
|
+
const candidates = await File.find({ name: { $regex: ATLAS_RENDER_NAME } }, { _id: 1 }).lean();
|
|
301
|
+
if (candidates.length === 0) return 0;
|
|
302
|
+
|
|
303
|
+
const removed = await deleteOwnedFiles({
|
|
304
|
+
File,
|
|
305
|
+
Owner: AtlasSpriteSheet,
|
|
306
|
+
fields: ATLAS_FILE_FIELDS,
|
|
307
|
+
ids: candidates.map((doc) => doc._id),
|
|
308
|
+
});
|
|
309
|
+
if (removed > 0) logger.info(`Removed ${removed} orphaned atlas File document(s)`);
|
|
310
|
+
return removed;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Refreshes only the minified render of a stored atlas.
|
|
315
|
+
*
|
|
316
|
+
* The layout must still match the stored metadata, because the client runtime
|
|
317
|
+
* pairs `GET /blob/:itemKey` with `GET /metadata/:itemKey`. A layout that moved
|
|
318
|
+
* means the render frames changed after the atlas was generated, so the item is
|
|
319
|
+
* reported as stale instead of written.
|
|
320
|
+
*
|
|
321
|
+
* @static
|
|
322
|
+
* @param {Object} params
|
|
323
|
+
* @param {string} params.itemKey - Object layer item id.
|
|
324
|
+
* @param {Object} params.objectLayerRenderFrames - Render frames, document or plain object.
|
|
325
|
+
* @param {Object} [params.options] - Router options ({ host, path }) for model lookup.
|
|
326
|
+
* @returns {Promise<{ status: 'updated'|'unchanged'|'missing'|'stale', minifyFileId?: import('mongoose').Types.ObjectId }>}
|
|
327
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
328
|
+
*/
|
|
329
|
+
static async syncMinifyRender({ itemKey, objectLayerRenderFrames, options }) {
|
|
330
|
+
const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
|
|
331
|
+
const File = DataBaseProviderService.getModel('File', options);
|
|
332
|
+
|
|
333
|
+
const atlasDoc = await AtlasSpriteSheet.findOne({ 'metadata.itemKey': itemKey });
|
|
334
|
+
if (!atlasDoc) return { status: 'missing' };
|
|
335
|
+
|
|
336
|
+
// Only the minified render is wanted here, so ask for no upscaled second render.
|
|
337
|
+
const { minifyBuffer, metadata } = await AtlasSpriteSheetGenerator.generateAtlas(
|
|
338
|
+
objectLayerRenderFrames,
|
|
339
|
+
itemKey,
|
|
340
|
+
1,
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
if (!sameLayout(metadata, atlasDoc.metadata.toObject ? atlasDoc.metadata.toObject() : atlasDoc.metadata)) {
|
|
344
|
+
return { status: 'stale' };
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const previousId = atlasDoc.minifyFileId;
|
|
348
|
+
const minifyFileId = await upsertRenderFile(File, itemKey, 'minify', minifyBuffer);
|
|
349
|
+
if (previousId && String(previousId) === String(minifyFileId)) {
|
|
350
|
+
return { status: 'unchanged', minifyFileId };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
await AtlasSpriteSheet.updateOne({ _id: atlasDoc._id }, { $set: { minifyFileId } });
|
|
354
|
+
await deleteReplacedFiles(File, [previousId], [minifyFileId]);
|
|
355
|
+
|
|
356
|
+
return { status: 'updated', minifyFileId };
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Fills or refreshes the idle-preview still of a stored atlas from the render it already
|
|
361
|
+
* holds, so an atlas written before the still existed gains one without a regeneration.
|
|
362
|
+
*
|
|
363
|
+
* @static
|
|
364
|
+
* @param {Object} params
|
|
365
|
+
* @param {string} params.itemKey - Object layer item id.
|
|
366
|
+
* @param {Object} [params.options] - Router options ({ host, path }) for model lookup.
|
|
367
|
+
* @returns {Promise<{ status: 'updated'|'unchanged'|'missing', idlePreviewFileId?: import('mongoose').Types.ObjectId }>}
|
|
368
|
+
* @memberof CyberiaAtlasSpriteSheetStore
|
|
369
|
+
*/
|
|
370
|
+
static async syncIdlePreview({ itemKey, options }) {
|
|
371
|
+
const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
|
|
372
|
+
const File = DataBaseProviderService.getModel('File', options);
|
|
373
|
+
|
|
374
|
+
const atlasDoc = await AtlasSpriteSheet.findOne({ 'metadata.itemKey': itemKey });
|
|
375
|
+
// Hydrated, not lean: a lean read hands back a BSON Binary the decoder cannot open.
|
|
376
|
+
const render = atlasDoc?.fileId ? await File.findById(atlasDoc.fileId) : null;
|
|
377
|
+
if (!render?.data) return { status: 'missing' };
|
|
378
|
+
|
|
379
|
+
const metadata = atlasDoc.metadata.toObject ? atlasDoc.metadata.toObject() : atlasDoc.metadata;
|
|
380
|
+
const previousId = atlasDoc.idlePreviewFileId;
|
|
381
|
+
const idlePreviewFileId = await upsertIdlePreview(File, itemKey, Buffer.from(render.data), metadata);
|
|
382
|
+
if (previousId && String(previousId) === String(idlePreviewFileId)) {
|
|
383
|
+
return { status: 'unchanged', idlePreviewFileId };
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
await AtlasSpriteSheet.updateOne({ _id: atlasDoc._id }, { $set: { idlePreviewFileId } });
|
|
387
|
+
await deleteReplacedFiles(File, [previousId], [idlePreviewFileId]);
|
|
388
|
+
|
|
389
|
+
return { status: 'updated', idlePreviewFileId };
|
|
390
|
+
}
|
|
391
|
+
}
|
|
@@ -17,9 +17,9 @@ import crypto from 'crypto';
|
|
|
17
17
|
import fs from 'fs-extra';
|
|
18
18
|
import path from 'path';
|
|
19
19
|
import { keccak256 as ethersKeccak256 } from 'ethers';
|
|
20
|
-
import { loggerFactory } from '../../server/logger.js';
|
|
21
|
-
import { shellExec } from '../../server/process.js';
|
|
22
|
-
import { crictlCommandFactory } from '../../server/cri.js';
|
|
20
|
+
import { loggerFactory } from '../../server/ops/logger.js';
|
|
21
|
+
import { shellExec } from '../../server/runtime/process.js';
|
|
22
|
+
import { crictlCommandFactory } from '../../server/ops/cri.js';
|
|
23
23
|
|
|
24
24
|
const logger = loggerFactory(import.meta);
|
|
25
25
|
|
|
@@ -61,26 +61,17 @@ function derivePublicKey(privateKeyHex) {
|
|
|
61
61
|
* (uncompressed, sans 04 prefix) public key bytes:
|
|
62
62
|
* `address = keccak256(pubKeyBytes)[12..31]`
|
|
63
63
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* produces **wrong** addresses. We use `ethers.keccak256` which bundles
|
|
68
|
-
* a correct Keccak-256 implementation.
|
|
64
|
+
* Ethereum uses the original Keccak-256, not NIST SHA3-256. NIST added other
|
|
65
|
+
* domain-separation padding, so `crypto.createHash('sha3-256')` gives wrong
|
|
66
|
+
* addresses. `ethers.keccak256` carries a correct Keccak-256.
|
|
69
67
|
*
|
|
70
68
|
* @param {string} publicKeyHex - 128-char hex public key (no 0x prefix).
|
|
71
69
|
* @returns {string} 40-char lowercase hex Ethereum address (no 0x prefix).
|
|
72
70
|
* @memberof BesuGenesisGenerator
|
|
73
71
|
*/
|
|
74
72
|
function publicKeyToAddress(publicKeyHex) {
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
// so crypto.createHash('sha3-256') produces WRONG addresses.
|
|
78
|
-
//
|
|
79
|
-
// Node.js's OpenSSL does not expose the original Keccak-256, so we use ethers
|
|
80
|
-
// which bundles a correct implementation.
|
|
81
|
-
//
|
|
82
|
-
// ethersKeccak256 expects a 0x-prefixed hex string or Uint8Array and returns
|
|
83
|
-
// a 0x-prefixed 64-char hex hash. The Ethereum address is the last 20 bytes.
|
|
73
|
+
// ethersKeccak256 takes 0x-prefixed hex or a Uint8Array and returns a
|
|
74
|
+
// 0x-prefixed 64-char hash. The address is its last 20 bytes.
|
|
84
75
|
const hash = ethersKeccak256(Buffer.from(publicKeyHex, 'hex')); // 0x-prefixed 64-char hex
|
|
85
76
|
return hash.slice(26); // skip '0x' + first 24 hex chars → last 40 hex chars (20 bytes)
|
|
86
77
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { STAT_DEFAULTS } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
|
|
2
|
+
import { DefaultCyberiaActions, DefaultCyberiaQuests } from '../../api/cyberia-server-defaults/cyberia-server-defaults.js';
|
|
3
|
+
import { toInstanceConfig, toMapMsg, toInstanceMsg, toObjectLayerMsg, toActionMsg, toQuestMsg } from './instance-data.js';
|
|
4
|
+
|
|
5
|
+
export function buildBootContractArtifacts() {
|
|
6
|
+
const layer = toObjectLayerMsg({
|
|
7
|
+
_id: 'contract-layer', sha256: 'abc',
|
|
8
|
+
data: { stats: { ...STAT_DEFAULTS, effect: -100, resistance: 100 }, item: { id: 'sword', type: 'weapon' } },
|
|
9
|
+
});
|
|
10
|
+
const full = {
|
|
11
|
+
instance: toInstanceMsg({ _id: 'contract-instance', code: 'contract-test', cyberiaMapCodes: ['contract-map'] }),
|
|
12
|
+
maps: [toMapMsg({
|
|
13
|
+
_id: 'contract-map', code: 'contract-map', gridX: 16, gridY: 16,
|
|
14
|
+
entities: [{ entityType: 'bot', level: 7, objectLayerItemIds: ['sword'] }],
|
|
15
|
+
})],
|
|
16
|
+
objectLayers: [layer],
|
|
17
|
+
config: toInstanceConfig({}),
|
|
18
|
+
version: 'contract-fixture',
|
|
19
|
+
actions: DefaultCyberiaActions.slice(0, 1).map(toActionMsg),
|
|
20
|
+
quests: DefaultCyberiaQuests.slice(0, 1).map(toQuestMsg),
|
|
21
|
+
};
|
|
22
|
+
const payloads = {
|
|
23
|
+
boot_full_instance: full,
|
|
24
|
+
boot_object_layer: layer,
|
|
25
|
+
boot_manifest: { entries: [{ itemId: 'sword', sha256: 'abc' }] },
|
|
26
|
+
boot_ping: { serverTimeMs: 1000 },
|
|
27
|
+
};
|
|
28
|
+
return Object.fromEntries(Object.entries(payloads).map(([name, data]) => [
|
|
29
|
+
'cyberia-server/engine_client/testdata/' + name + '.json',
|
|
30
|
+
JSON.stringify({ status: 'success', data }, null, 2) + '\n',
|
|
31
|
+
]));
|
|
32
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Cyberia CLI content catalog.
|
|
3
3
|
*
|
|
4
4
|
* A per-deploy product catalog: pure data, loaded dynamically by deploy id via
|
|
5
|
-
* {@link module:src/server/catalog} so the base build and template assembly never
|
|
5
|
+
* {@link module:src/server/build/catalog.js} so the base build and template assembly never
|
|
6
6
|
* statically depend on it. Exports the uniform product-catalog shape:
|
|
7
7
|
*
|
|
8
8
|
* - `sourceMoves` — public `[src, dest]` pairs moved into the engine tree before a build.
|
|
@@ -13,12 +13,50 @@
|
|
|
13
13
|
* - `copies` — `[src, dest]` pairs copied into the template during assembly (like moves but copied instead of moved).
|
|
14
14
|
* - `keywords` — npm keywords for the standalone product CLI package.
|
|
15
15
|
* - `description` — npm description for the standalone product CLI package.
|
|
16
|
+
* - `packageName` — npm name of the product package; the deploy id without `dd-` otherwise.
|
|
17
|
+
* - `packageBin` — bin map of the standalone product CLI.
|
|
18
|
+
* - `packageDependencies` — runtime dependencies this product adds to the engine's.
|
|
19
|
+
* - `packageScripts` — npm scripts this product adds to the engine's.
|
|
20
|
+
*
|
|
21
|
+
* The `package*` fields are the single declaration of what this product's manifests carry:
|
|
22
|
+
* every generated manifest — the deploy's `engine-private/conf/<id>/package.json`, the product
|
|
23
|
+
* repository's, and the published instance copy — is built from them by
|
|
24
|
+
* {@link module:src/server/build/package.js}. Nothing else may name them.
|
|
16
25
|
*
|
|
17
26
|
* @module src/projects/cyberia/catalog-cyberia.js
|
|
18
27
|
* @namespace CyberiaCatalog
|
|
19
28
|
*/
|
|
20
29
|
|
|
30
|
+
const DEPLOY_ID = 'dd-cyberia';
|
|
31
|
+
const DOCKER_COMPOSE_ID = 'cyberia';
|
|
32
|
+
|
|
33
|
+
const dockerScript = (action, flags = '') =>
|
|
34
|
+
`node bin docker-compose --${action}${flags} --deploy-id ${DEPLOY_ID} --docker-compose-id ${DOCKER_COMPOSE_ID}`;
|
|
35
|
+
|
|
21
36
|
export default {
|
|
37
|
+
packageName: 'cyberia',
|
|
38
|
+
// Pod bootstraps link this product checkout over the image CLI before continuing.
|
|
39
|
+
packageBin: { cyberia: 'bin/index.js', underpost: 'bin/index.js' },
|
|
40
|
+
// Native-dependency pin list: versions stay reproducible across CI and production deploys.
|
|
41
|
+
packageDependencies: {
|
|
42
|
+
'maxrects-packer': '^2.7.3',
|
|
43
|
+
pngjs: '^7.0.0',
|
|
44
|
+
jimp: '^1.6.0',
|
|
45
|
+
sharp: '^0.35.4',
|
|
46
|
+
ethers: '~6.16.0',
|
|
47
|
+
},
|
|
48
|
+
packageScripts: {
|
|
49
|
+
'docker:generate': dockerScript('generate'),
|
|
50
|
+
'docker:up': dockerScript('up'),
|
|
51
|
+
'docker:up:build': dockerScript('up', ' --build'),
|
|
52
|
+
'docker:down': dockerScript('down'),
|
|
53
|
+
'docker:down:volumes': dockerScript('down', ' --volumes'),
|
|
54
|
+
'docker:restart': dockerScript('restart'),
|
|
55
|
+
'docker:pull': dockerScript('pull'),
|
|
56
|
+
'docker:logs': dockerScript('logs'),
|
|
57
|
+
'docker:status': dockerScript('status'),
|
|
58
|
+
'docker:reset': dockerScript('reset'),
|
|
59
|
+
},
|
|
22
60
|
sourceMoves: [],
|
|
23
61
|
privateConfPaths: [
|
|
24
62
|
/** INSTANCE_CODES */
|
|
@@ -26,6 +64,7 @@ export default {
|
|
|
26
64
|
'cyberia-instances/amethyst-strata-expansion',
|
|
27
65
|
'cyberia-sagas/amethyst-strata-expansion.json',
|
|
28
66
|
'cyberia-instances/FOREST',
|
|
67
|
+
'cyberia-instances/TEST',
|
|
29
68
|
|
|
30
69
|
/** INSTANCE_CODES */
|
|
31
70
|
],
|
|
@@ -33,8 +72,8 @@ export default {
|
|
|
33
72
|
'/src/grpc/cyberia',
|
|
34
73
|
'/src/client/ssr/views/CyberiaServerMetrics.js',
|
|
35
74
|
'/src/client/ssr/views/Cyberia404.js',
|
|
36
|
-
'/test/cyberia
|
|
37
|
-
'/test/
|
|
75
|
+
'/test/unit/cyberia',
|
|
76
|
+
'/test/integration/app/cyberia',
|
|
38
77
|
'/src/projects/cyberia',
|
|
39
78
|
'/src/runtime/cyberia-server',
|
|
40
79
|
'/src/runtime/cyberia-client',
|
|
@@ -49,7 +88,13 @@ export default {
|
|
|
49
88
|
'/.github/workflows/cyberia-client.cd.yml',
|
|
50
89
|
'/.github/workflows/cyberia-server.cd.yml',
|
|
51
90
|
'/.github/workflows/coverall.cyberia.ci.yml',
|
|
52
|
-
'/
|
|
91
|
+
'/bin/cyberia.js',
|
|
92
|
+
'/hardhat',
|
|
93
|
+
// The deploy scripts `run-workflow build-manifest` mirrors into each generated instance
|
|
94
|
+
// repository. The base template drops the whole `deploy/` tree, so the product CLI only has
|
|
95
|
+
// them if it packages them here.
|
|
96
|
+
'/deploy/cyberia-client',
|
|
97
|
+
'/deploy/cyberia-server',
|
|
53
98
|
],
|
|
54
99
|
stripPaths: [
|
|
55
100
|
'./src/projects/cyberia',
|
|
@@ -57,14 +102,13 @@ export default {
|
|
|
57
102
|
'./src/runtime/cyberia-server',
|
|
58
103
|
'./src/runtime/cyberia-client',
|
|
59
104
|
'./src/runtime/engine-cyberia',
|
|
60
|
-
'./test/cyberia
|
|
61
|
-
'./test/cyberia
|
|
62
|
-
'./test/object-layer-item-id.test.js',
|
|
63
|
-
'./test/shape-generator.test.js',
|
|
105
|
+
'./test/unit/cyberia',
|
|
106
|
+
'./test/integration/app/cyberia',
|
|
64
107
|
'./src/client/public/cyberia-docs',
|
|
65
|
-
'./
|
|
66
|
-
'bin/cyberia.js',
|
|
108
|
+
'./bin/cyberia.js',
|
|
67
109
|
'./hardhat',
|
|
110
|
+
'./deploy/cyberia-client',
|
|
111
|
+
'./deploy/cyberia-server',
|
|
68
112
|
],
|
|
69
113
|
moves: [],
|
|
70
114
|
copies: [
|
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
* Top-Down PCG saga generator. No streaming, no tool-calls — the saga
|
|
6
6
|
* orchestration only needs one structured JSON payload per request.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Only the `:generateContent` endpoint is wired, matching the Gemma model
|
|
9
|
+
* family (e.g. `gemma-4-26b-a4b-it`). Authentication uses the `x-goog-api-key`
|
|
10
|
+
* header from `GEMINI_API_KEY`.
|
|
11
11
|
*
|
|
12
12
|
* @module src/projects/cyberia/gemini-client.js
|
|
13
13
|
* @namespace GeminiClient
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import axios from 'axios';
|
|
17
|
-
import { loggerFactory } from '../../server/logger.js';
|
|
17
|
+
import { loggerFactory } from '../../server/ops/logger.js';
|
|
18
18
|
|
|
19
19
|
const logger = loggerFactory(import.meta);
|
|
20
20
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validateStats } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
|
|
1
2
|
/**
|
|
2
3
|
* Top-Down Procedural Generation guided by LLMs (Semantic Reverse-Engineering).
|
|
3
4
|
*
|
|
@@ -18,7 +19,7 @@ import fs from 'fs-extra';
|
|
|
18
19
|
import nodePath from 'path';
|
|
19
20
|
import crypto from 'crypto';
|
|
20
21
|
import { GeminiClient } from './gemini-client.js';
|
|
21
|
-
import { loggerFactory } from '../../server/logger.js';
|
|
22
|
+
import { loggerFactory } from '../../server/ops/logger.js';
|
|
22
23
|
|
|
23
24
|
const logger = loggerFactory(import.meta);
|
|
24
25
|
|
|
@@ -1089,9 +1090,10 @@ const STAGE_PROMPTS = {
|
|
|
1089
1090
|
'STAGE: foundation. Return ONE JSON object: { "saga": {...}, "objectLayers": [...] }.',
|
|
1090
1091
|
'saga: { code, name, description, mapCodes:[] } (leave mapCodes an empty array).',
|
|
1091
1092
|
'objectLayers[]: { stats:{ effect, resistance, agility, range, intelligence, utility },',
|
|
1093
|
+
'- Stats are integer modifiers from -100 to +100. Zero is neutral. Level and XP belong to entities.',
|
|
1092
1094
|
' item:{ id, type, description, activable }, render:null }',
|
|
1093
1095
|
' item.type is one of: skin, breastplate, weapon, skill, coin, floor, obstacle, portal,',
|
|
1094
|
-
' foreground, resource; every stat is an integer
|
|
1096
|
+
' foreground, resource; every stat is an integer -100..+100, with 0 neutral.',
|
|
1095
1097
|
'Produce 5-10 object-layer items including at least one "coin" currency item AND at least two',
|
|
1096
1098
|
'"skin" items that represent NAMED NPC characters players can speak to (these back "talk" quests).',
|
|
1097
1099
|
].join('\n'),
|
|
@@ -1536,14 +1538,7 @@ function normalizeSagaPayload(raw, { theme }) {
|
|
|
1536
1538
|
const objectLayers = asArray(raw.objectLayers).map((ol) => {
|
|
1537
1539
|
const stats = ol.stats || {};
|
|
1538
1540
|
return {
|
|
1539
|
-
stats:
|
|
1540
|
-
effect: Number(stats.effect) || 0,
|
|
1541
|
-
resistance: Number(stats.resistance) || 0,
|
|
1542
|
-
agility: Number(stats.agility) || 0,
|
|
1543
|
-
range: Number(stats.range) || 0,
|
|
1544
|
-
intelligence: Number(stats.intelligence) || 0,
|
|
1545
|
-
utility: Number(stats.utility) || 0,
|
|
1546
|
-
},
|
|
1541
|
+
stats: validateStats(stats),
|
|
1547
1542
|
item: {
|
|
1548
1543
|
id: slugify(ol.item?.id),
|
|
1549
1544
|
type: ol.item?.type || 'skin',
|
|
@@ -1621,7 +1616,6 @@ function normalizeSagaPayload(raw, { theme }) {
|
|
|
1621
1616
|
description: saga.description,
|
|
1622
1617
|
tags: ['saga', 'generated'],
|
|
1623
1618
|
cyberiaMapCodes: [...saga.mapCodes],
|
|
1624
|
-
itemIds: saga.itemIds.map((id) => ({ id, defaultPlayerInventory: false })),
|
|
1625
1619
|
portals: [],
|
|
1626
1620
|
topologyMode: 'procedural',
|
|
1627
1621
|
};
|
|
@@ -1687,7 +1681,6 @@ async function persistInstance({ instance, CyberiaInstance }) {
|
|
|
1687
1681
|
description: instance.description,
|
|
1688
1682
|
tags: instance.tags,
|
|
1689
1683
|
cyberiaMapCodes: instance.cyberiaMapCodes,
|
|
1690
|
-
itemIds: instance.itemIds,
|
|
1691
1684
|
topologyMode: instance.topologyMode,
|
|
1692
1685
|
},
|
|
1693
1686
|
$setOnInsert: { code: instance.code, portals: instance.portals || [] },
|