cyberia 3.2.22 → 3.2.70
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/.env.example +127 -68
- package/.github/workflows/cyberia-client.cd.yml +40 -0
- package/.github/workflows/cyberia-server.cd.yml +40 -0
- package/.github/workflows/docker-image.cyberia-client.ci.yml +49 -0
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +48 -0
- package/.github/workflows/docker-image.cyberia-server.ci.yml +69 -0
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +69 -0
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +52 -0
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +52 -0
- package/.github/workflows/engine-cyberia.cd.yml +33 -24
- package/.github/workflows/engine-cyberia.ci.yml +13 -3
- package/.github/workflows/ghpkg.ci.yml +88 -1
- package/.github/workflows/gitlab.ci.yml +1 -1
- package/.github/workflows/hardhat.ci.yml +1 -1
- package/.github/workflows/npmpkg.ci.yml +10 -7
- package/.github/workflows/publish.ci.yml +2 -2
- package/.github/workflows/publish.cyberia.ci.yml +5 -16
- package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -8
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/CHANGELOG.md +301 -1
- package/CLI-HELP.md +71 -6
- package/Dockerfile +141 -43
- package/Dockerfile.dev +143 -0
- package/Dockerfile.test +165 -0
- package/README.md +1 -1
- package/baremetal/commission-workflows.json +1 -0
- package/bin/build.js +31 -0
- package/bin/cyberia.js +1080 -184
- package/bin/deploy.js +2 -2
- package/bin/index.js +1080 -184
- package/bump.config.js +1 -0
- package/compose.env +131 -0
- package/conf.js +18 -1
- package/deployment.yaml +2 -2
- package/docker-compose.yml +316 -0
- package/hardhat/hardhat.config.js +2 -2
- package/hardhat/package-lock.json +620 -2041
- package/hardhat/package.json +7 -5
- package/hardhat/scripts/deployObjectLayerToken.js +18 -18
- package/hardhat/test/ObjectLayerToken.js +378 -274
- package/ipfs/configure-ipfs.sh +13 -0
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-cyberia-development/grpc-service.yaml +17 -0
- package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +32 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/mongodb/entrypoint.sh +76 -0
- package/nginx.conf +87 -0
- package/package.json +31 -19
- package/pv-pvc.yaml +32 -0
- package/scripts/disk-clean.sh +85 -60
- package/scripts/kubeadm-node-setup.sh +317 -0
- package/scripts/rocky-kickstart.sh +877 -185
- package/scripts/rpmfusion-ffmpeg-setup.sh +26 -50
- package/scripts/test-monitor.sh +3 -5
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +43 -7
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +17 -25
- package/src/api/cyberia-action/cyberia-action.controller.js +19 -0
- package/src/api/cyberia-action/cyberia-action.model.js +21 -29
- package/src/api/cyberia-action/cyberia-action.router.js +42 -7
- package/src/api/cyberia-action/cyberia-action.service.js +20 -4
- package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +58 -57
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +37 -6
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +8 -2
- package/src/api/cyberia-entity/cyberia-entity.router.js +39 -7
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +74 -0
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +67 -0
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +63 -0
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +46 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +62 -10
- package/src/api/cyberia-instance/cyberia-instance.model.js +32 -2
- package/src/api/cyberia-instance/cyberia-instance.router.js +6 -6
- package/src/api/cyberia-instance/cyberia-world-generator.js +116 -3
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +3 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +39 -7
- package/src/api/cyberia-map/cyberia-map.router.js +21 -6
- package/src/api/cyberia-quest/cyberia-quest.controller.js +38 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +47 -7
- package/src/api/cyberia-quest/cyberia-quest.service.js +59 -4
- package/src/api/cyberia-saga/cyberia-saga.controller.js +74 -0
- package/src/api/cyberia-saga/cyberia-saga.model.js +59 -0
- package/src/api/cyberia-saga/cyberia-saga.router.js +63 -0
- package/src/api/cyberia-saga/cyberia-saga.service.js +42 -0
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +551 -129
- package/src/api/cyberia-skill/cyberia-skill.controller.js +74 -0
- package/src/api/cyberia-skill/cyberia-skill.model.js +50 -0
- package/src/api/cyberia-skill/cyberia-skill.router.js +63 -0
- package/src/api/cyberia-skill/cyberia-skill.service.js +42 -0
- package/src/api/ipfs/ipfs.service.js +28 -15
- package/src/api/object-layer/object-layer.router.js +25 -15
- package/src/api/object-layer/object-layer.service.js +15 -20
- package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +39 -7
- package/src/cli/baremetal.js +717 -16
- package/src/cli/cluster.js +80 -5
- package/src/cli/deploy.js +127 -11
- package/src/cli/docker-compose.js +648 -0
- package/src/cli/env.js +11 -2
- package/src/cli/fs.js +75 -30
- package/src/cli/image.js +129 -51
- package/src/cli/index.js +110 -6
- package/src/cli/kickstart.js +142 -20
- package/src/cli/release.js +46 -4
- package/src/cli/repository.js +238 -33
- package/src/cli/run.js +520 -114
- package/src/cli/secrets.js +82 -48
- package/src/cli/ssh.js +234 -0
- package/src/cli/static.js +2 -2
- package/src/client/components/cyberia/ActionEngineCyberia.js +1867 -0
- package/src/client/components/cyberia/EntityEngineCyberia.js +585 -0
- package/src/client/components/cyberia/InstanceEngineCyberia.js +219 -13
- package/src/client/components/cyberia/MapEngineCyberia.js +154 -71
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +40 -63
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +34 -20
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +195 -4
- package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +66 -0
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +8 -0
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -0
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +45 -27
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +3 -3
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +39 -22
- package/src/client/public/cyberia-docs/CYBERIA-LORE.md +88 -0
- package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +394 -0
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +8 -1
- package/src/client/public/cyberia-docs/CYBERIA.md +1 -1
- package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +5 -5
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
- package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +99 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +2 -2
- package/src/client/services/cyberia-map/cyberia-map.management.js +2 -2
- package/src/client/services/cyberia-saga/cyberia-saga.service.js +99 -0
- package/src/client/services/cyberia-skill/cyberia-skill.service.js +99 -0
- package/src/client/services/object-layer/object-layer.management.js +6 -6
- package/src/{server → client-builder}/client-build-docs.js +15 -5
- package/src/{server → client-builder}/client-build-live.js +3 -3
- package/src/{server → client-builder}/client-build.js +25 -22
- package/src/{server → client-builder}/client-dev-server.js +3 -3
- package/src/{server → client-builder}/client-icons.js +2 -2
- package/src/{server → client-builder}/ssr.js +5 -5
- package/src/client.build.js +1 -3
- package/src/client.dev.js +1 -1
- package/src/db/mongo/MongoBootstrap.js +12 -12
- package/src/grpc/cyberia/grpc-server.js +255 -70
- package/src/index.js +12 -1
- package/src/mailer/EmailRender.js +1 -1
- package/src/{server → projects/cyberia}/atlas-sprite-sheet-generator.js +2 -2
- package/src/{server → projects/cyberia}/besu-genesis-generator.js +3 -3
- package/src/projects/cyberia/catalog-cyberia.js +81 -0
- package/src/projects/cyberia/gemini-client.js +175 -0
- package/src/projects/cyberia/generate-saga.js +2107 -0
- package/src/{server → projects/cyberia}/ipfs-client.js +2 -2
- package/src/{server → projects/cyberia}/object-layer.js +12 -108
- package/src/{server → projects/cyberia}/semantic-layer-generator-floor.js +1 -1
- package/src/{server → projects/cyberia}/semantic-layer-generator-resource.js +1 -1
- package/src/{server → projects/cyberia}/semantic-layer-generator-skin.js +1 -1
- package/src/{server → projects/cyberia}/semantic-layer-generator.js +2 -2
- package/src/{server → projects/cyberia}/shape-generator.js +2 -2
- package/src/{server → projects/underpost}/catalog-underpost.js +1 -2
- package/src/runtime/cyberia-client/Dockerfile +27 -61
- package/src/runtime/cyberia-client/Dockerfile.dev +20 -12
- package/src/runtime/cyberia-server/Dockerfile +21 -20
- package/src/runtime/cyberia-server/Dockerfile.dev +17 -8
- package/src/runtime/engine-cyberia/Dockerfile +143 -0
- package/src/runtime/engine-cyberia/Dockerfile.dev +143 -0
- package/src/runtime/engine-cyberia/Dockerfile.test +165 -0
- package/src/runtime/engine-cyberia/compose.env +131 -0
- package/src/runtime/engine-cyberia/docker-compose.yml +316 -0
- package/src/runtime/engine-cyberia/ipfs/configure-ipfs.sh +13 -0
- package/src/runtime/engine-cyberia/mongodb/entrypoint.sh +76 -0
- package/src/runtime/engine-cyberia/nginx.conf +87 -0
- package/src/runtime/express/Express.js +2 -2
- package/src/runtime/nginx/Nginx.js +250 -0
- package/src/server/catalog.js +9 -14
- package/src/server/conf.js +3 -6
- package/src/server/runtime-status.js +18 -1
- package/src/server/start.js +12 -2
- package/src/server.js +6 -2
- package/test/cyberia-instance-conf-defaults.test.js +140 -0
- package/test/deploy-monitor.test.js +26 -10
- package/test/shape-generator.test.js +7 -1
- package/typedoc.dd-cyberia.json +3 -1
- package/typedoc.json +3 -1
- /package/src/client/ssr/{Render.js → RootDocument.js} +0 -0
- /package/src/{server → client-builder}/client-formatted.js +0 -0
|
@@ -17,11 +17,12 @@ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
|
|
|
17
17
|
import { loggerFactory } from '../../server/logger.js';
|
|
18
18
|
import {
|
|
19
19
|
CYBERIA_INSTANCE_CONF_DEFAULTS as FALLBACK_CONFIG_DEFAULTS,
|
|
20
|
+
DEFAULT_PLAYER_SPAWN,
|
|
20
21
|
ENTITY_TYPE_DEFAULTS,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// the AOI wire). Icon stems + border colours live in SharedDefaultsCyberia.
|
|
22
|
+
DefaultCyberiaActions,
|
|
23
|
+
DefaultCyberiaQuests,
|
|
24
24
|
} from '../../api/cyberia-server-defaults/cyberia-server-defaults.js';
|
|
25
|
+
import { DefaultCyberiaItems } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
|
|
25
26
|
import { generateFallbackWorld } from '../../api/cyberia-instance/cyberia-fallback-world.js';
|
|
26
27
|
|
|
27
28
|
const logger = loggerFactory(import.meta);
|
|
@@ -53,20 +54,6 @@ function getModels(dbKey) {
|
|
|
53
54
|
return bucket.models;
|
|
54
55
|
}
|
|
55
56
|
|
|
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
57
|
function normalizeEntityDefault(entityDefault = {}, canonical = {}) {
|
|
71
58
|
const defaultObjectLayers = entityDefault.defaultObjectLayers ?? canonical.defaultObjectLayers ?? [];
|
|
72
59
|
return {
|
|
@@ -79,68 +66,140 @@ function normalizeEntityDefault(entityDefault = {}, canonical = {}) {
|
|
|
79
66
|
active: !!ol.active,
|
|
80
67
|
quantity: ol.quantity || 0,
|
|
81
68
|
})),
|
|
69
|
+
behavior: entityDefault.behavior ?? canonical.behavior ?? '',
|
|
82
70
|
};
|
|
83
71
|
}
|
|
84
72
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
) {
|
|
107
|
-
bestLiveOverlapIndex = index;
|
|
108
|
-
bestLiveOverlap = liveOverlap;
|
|
109
|
-
bestLiveItemCount = canonical.liveItemIds?.length ?? 0;
|
|
73
|
+
// Merge instance-level itemIds flagged `defaultPlayerInventory` into the player
|
|
74
|
+
// entityDefault's defaultObjectLayers so cyberia-server seeds them into every new
|
|
75
|
+
// player's inventory (see handlers.go player spawn). Items are added inactive —
|
|
76
|
+
// present in the inventory, not auto-equipped — so they never violate the
|
|
77
|
+
// one-active-per-type equipment rule.
|
|
78
|
+
//
|
|
79
|
+
// Also **removes** items that are flagged `defaultPlayerInventory: false` from
|
|
80
|
+
// the player's defaultObjectLayers. This ensures the instance's explicit intent
|
|
81
|
+
// is honoured even when the conf's entityDefaults (e.g. from a backup/import)
|
|
82
|
+
// baked those items into the player layer list.
|
|
83
|
+
function applyInstanceDefaultPlayerInventory(config, instanceItemIds = []) {
|
|
84
|
+
const entries = instanceItemIds || [];
|
|
85
|
+
|
|
86
|
+
// ── 1. Remove items explicitly flagged as NOT default player inventory ─────
|
|
87
|
+
const removeIds = new Set(
|
|
88
|
+
entries.filter((entry) => entry && entry.defaultPlayerInventory === false && entry.id).map((entry) => entry.id),
|
|
89
|
+
);
|
|
90
|
+
if (removeIds.size > 0) {
|
|
91
|
+
for (const ed of config.entityDefaults || []) {
|
|
92
|
+
if (ed.defaultObjectLayers) {
|
|
93
|
+
ed.defaultObjectLayers = ed.defaultObjectLayers.filter((ol) => !removeIds.has(ol.itemId));
|
|
110
94
|
}
|
|
111
95
|
}
|
|
96
|
+
}
|
|
112
97
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return firstSameTypeIndex;
|
|
117
|
-
};
|
|
98
|
+
// ── 2. Add items flagged as default player inventory ──────────────────────
|
|
99
|
+
const addIds = entries.filter((entry) => entry && entry.defaultPlayerInventory && entry.id).map((entry) => entry.id);
|
|
100
|
+
if (addIds.length === 0) return config;
|
|
118
101
|
|
|
119
|
-
const
|
|
102
|
+
const playerDefault = (config.entityDefaults || []).find((d) => d.entityType === 'player');
|
|
103
|
+
if (!playerDefault) return config;
|
|
120
104
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
105
|
+
playerDefault.defaultObjectLayers = playerDefault.defaultObjectLayers || [];
|
|
106
|
+
const existing = new Set(playerDefault.defaultObjectLayers.map((ol) => ol.itemId));
|
|
107
|
+
for (const id of addIds) {
|
|
108
|
+
if (existing.has(id)) continue;
|
|
109
|
+
playerDefault.defaultObjectLayers.push({ itemId: id, active: false, quantity: 1 });
|
|
110
|
+
existing.add(id);
|
|
124
111
|
}
|
|
125
|
-
return
|
|
112
|
+
return config;
|
|
126
113
|
}
|
|
127
114
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
115
|
+
// Map CyberiaSkill collection docs to the proto skillConfig shape. The skill
|
|
116
|
+
// collection is the authoritative own-model source: it carries full skill
|
|
117
|
+
// metadata (summonedEntityItemId, name, description) that the instance-conf
|
|
118
|
+
// skillConfig schema deliberately does not store.
|
|
119
|
+
function skillDocsToConfig(skillDocs = []) {
|
|
120
|
+
return skillDocs
|
|
121
|
+
.filter((d) => d && d.triggerItemId)
|
|
122
|
+
.map((d) => ({
|
|
123
|
+
triggerItemId: d.triggerItemId,
|
|
124
|
+
skills: (d.skills || []).map((sk) => ({
|
|
125
|
+
logicEventId: sk.logicEventId || '',
|
|
126
|
+
name: sk.name || '',
|
|
127
|
+
description: sk.description || '',
|
|
128
|
+
summonedEntityItemId: sk.summonedEntityItemId || '',
|
|
129
|
+
})),
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Load authoritative skill configs from the CyberiaSkill collection. Returns []
|
|
134
|
+
// when the model is not loaded (api not mounted) or the collection is empty, so
|
|
135
|
+
// callers transparently keep the conf / fallback skillConfig.
|
|
136
|
+
async function loadSkillConfigDocs(models) {
|
|
137
|
+
if (!models.CyberiaSkill) return [];
|
|
138
|
+
return await models.CyberiaSkill.find({}).lean();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Map CyberiaEntityTypeDefault collection docs to the proto entityDefaults shape.
|
|
142
|
+
// This collection is the authoritative own-model source for per-entity-type item
|
|
143
|
+
// defaults (live/dead/drop + seed object layers). Resolution is by liveItemIds
|
|
144
|
+
// membership, so every variant (e.g. each resource skin) must travel as its own
|
|
145
|
+
// entry — never collapsed by entityType.
|
|
146
|
+
function entityTypeDefaultDocsToConfig(docs = []) {
|
|
147
|
+
return docs
|
|
148
|
+
.filter((d) => d && d.entityType)
|
|
149
|
+
.map((d) => ({
|
|
150
|
+
entityType: d.entityType,
|
|
151
|
+
liveItemIds: [...(d.liveItemIds || [])],
|
|
152
|
+
deadItemIds: [...(d.deadItemIds || [])],
|
|
153
|
+
dropItemIds: [...(d.dropItemIds || [])],
|
|
154
|
+
defaultObjectLayers: (d.defaultObjectLayers || []).map((ol) => ({
|
|
155
|
+
itemId: ol.itemId,
|
|
156
|
+
active: !!ol.active,
|
|
157
|
+
quantity: ol.quantity || 0,
|
|
158
|
+
})),
|
|
159
|
+
behavior: d.behavior || '',
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Load authoritative entity-type defaults from the CyberiaEntityTypeDefault
|
|
164
|
+
// collection. Returns [] when the model is not mounted or empty, so callers
|
|
165
|
+
// transparently keep the conf / canonical entityDefaults.
|
|
166
|
+
async function loadEntityTypeDefaultDocs(models) {
|
|
167
|
+
if (!models.CyberiaEntityTypeDefault) return [];
|
|
168
|
+
return await models.CyberiaEntityTypeDefault.find({}).lean();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Feed every live/dead/drop and default-object-layer item id from the collection
|
|
172
|
+
// defaults into the atlas id set so the Go server resolves their sprites even
|
|
173
|
+
// when the entity appears in no map (e.g. a new resource skin).
|
|
174
|
+
function addEntityDefaultAtlasIds(entityDefaults, atlasItemIds) {
|
|
175
|
+
for (const d of entityDefaults || []) {
|
|
176
|
+
for (const id of d.liveItemIds || []) if (id) atlasItemIds.add(id);
|
|
177
|
+
for (const id of d.deadItemIds || []) if (id) atlasItemIds.add(id);
|
|
178
|
+
for (const id of d.dropItemIds || []) if (id) atlasItemIds.add(id);
|
|
179
|
+
for (const ol of d.defaultObjectLayers || []) if (ol.itemId) atlasItemIds.add(ol.itemId);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
138
182
|
|
|
139
|
-
|
|
140
|
-
|
|
183
|
+
// Feed skill trigger items and every concrete summoned-entity id into the atlas
|
|
184
|
+
// id set so the Go server resolves their sprites even when the entity appears in
|
|
185
|
+
// no map. Runtime placeholders ('$active_skin', …) are excluded.
|
|
186
|
+
function addSkillAtlasIds(skillDocs, atlasItemIds) {
|
|
187
|
+
for (const d of skillDocs || []) {
|
|
188
|
+
if (d.triggerItemId) atlasItemIds.add(d.triggerItemId);
|
|
189
|
+
for (const sk of d.skills || []) {
|
|
190
|
+
const id = sk.summonedEntityItemId;
|
|
191
|
+
if (id && !id.startsWith('$')) atlasItemIds.add(id);
|
|
192
|
+
}
|
|
141
193
|
}
|
|
194
|
+
}
|
|
142
195
|
|
|
143
|
-
|
|
196
|
+
function mergeEntityDefaults(entityDefaults = []) {
|
|
197
|
+
const merged = entityDefaults.map((entityDefault) => normalizeEntityDefault(entityDefault));
|
|
198
|
+
const coveredTypes = new Set(merged.map((entityDefault) => entityDefault.entityType));
|
|
199
|
+
for (const canonical of ENTITY_TYPE_DEFAULTS) {
|
|
200
|
+
if (!coveredTypes.has(canonical.entityType)) merged.push(normalizeEntityDefault(canonical, canonical));
|
|
201
|
+
}
|
|
202
|
+
return merged;
|
|
144
203
|
}
|
|
145
204
|
|
|
146
205
|
// ── Mongoose doc → protobuf message converters ───────────────────
|
|
@@ -248,6 +307,52 @@ function toInstanceMsg(doc) {
|
|
|
248
307
|
})),
|
|
249
308
|
topologyMode: doc.topologyMode || 'hybrid',
|
|
250
309
|
seed: doc.seed || '',
|
|
310
|
+
playerSpawn: {
|
|
311
|
+
sourceMapCode: doc.playerSpawn?.sourceMapCode || '',
|
|
312
|
+
sourceCellX: doc.playerSpawn?.sourceCellX || 0,
|
|
313
|
+
sourceCellY: doc.playerSpawn?.sourceCellY || 0,
|
|
314
|
+
random: !!doc.playerSpawn?.random,
|
|
315
|
+
},
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// CyberiaAction → CyberiaActionMessage (proto camelCase fields).
|
|
320
|
+
function toActionMsg(a) {
|
|
321
|
+
return {
|
|
322
|
+
code: a.code || '',
|
|
323
|
+
label: a.label || '',
|
|
324
|
+
sourceMapCode: a.sourceMapCode || '',
|
|
325
|
+
sourceCellX: a.sourceCellX || 0,
|
|
326
|
+
sourceCellY: a.sourceCellY || 0,
|
|
327
|
+
dialogCode: a.dialogCode || '',
|
|
328
|
+
questDialogueCodes: (a.questDialogueCodes || []).map((qd) => ({
|
|
329
|
+
questCode: qd.questCode || '',
|
|
330
|
+
dialogCode: qd.dialogCode || '',
|
|
331
|
+
})),
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// CyberiaQuest → CyberiaQuestMessage.
|
|
336
|
+
function toQuestMsg(q) {
|
|
337
|
+
return {
|
|
338
|
+
code: q.code || '',
|
|
339
|
+
title: q.title || '',
|
|
340
|
+
description: q.description || '',
|
|
341
|
+
unlocksQuestCodes: q.unlocksQuestCodes || [],
|
|
342
|
+
prerequisiteCodes: q.prerequisiteCodes || [],
|
|
343
|
+
sourceMapCode: q.sourceMapCode || '',
|
|
344
|
+
sourceCellX: q.sourceCellX || 0,
|
|
345
|
+
sourceCellY: q.sourceCellY || 0,
|
|
346
|
+
steps: (q.steps || []).map((s) => ({
|
|
347
|
+
id: s.id || '',
|
|
348
|
+
description: s.description || '',
|
|
349
|
+
objectives: (s.objectives || []).map((o) => ({
|
|
350
|
+
type: o.type || '',
|
|
351
|
+
itemId: o.itemId || '',
|
|
352
|
+
quantity: o.quantity || 1,
|
|
353
|
+
})),
|
|
354
|
+
})),
|
|
355
|
+
rewards: (q.rewards || []).map((r) => ({ itemId: r.itemId || '', quantity: r.quantity || 1 })),
|
|
251
356
|
};
|
|
252
357
|
}
|
|
253
358
|
|
|
@@ -445,11 +550,34 @@ function buildHandlers(dbKey) {
|
|
|
445
550
|
if (ol.itemId) fallbackItemIds.add(ol.itemId);
|
|
446
551
|
}
|
|
447
552
|
}
|
|
553
|
+
// Include every canonical item so the Go server can resolve the type
|
|
554
|
+
// of anything a player may pick up or equip (quest rewards like
|
|
555
|
+
// hatchet, alt weapons, etc.) — required for the one-per-type
|
|
556
|
+
// equipment rule, which silently no-ops when item type is unknown.
|
|
557
|
+
for (const it of DefaultCyberiaItems || []) {
|
|
558
|
+
if (it?.item?.id) fallbackItemIds.add(it.item.id);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Own-model skills (if seeded) override the fallback skillConfig; their
|
|
562
|
+
// summoned-entity atlases are resolved alongside the world's.
|
|
563
|
+
const fallbackSkillDocs = await loadSkillConfigDocs(models);
|
|
564
|
+
addSkillAtlasIds(fallbackSkillDocs, fallbackItemIds);
|
|
565
|
+
|
|
566
|
+
// Own-model entity defaults (if seeded) override the fallback
|
|
567
|
+
// entityDefaults; their live/dead/drop atlases resolve alongside.
|
|
568
|
+
const fallbackEntityDefaultDocs = await loadEntityTypeDefaultDocs(models);
|
|
569
|
+
const fallbackEntityDefaultsConfig = entityTypeDefaultDocsToConfig(fallbackEntityDefaultDocs);
|
|
570
|
+
addEntityDefaultAtlasIds(fallbackEntityDefaultsConfig, fallbackItemIds);
|
|
448
571
|
|
|
449
572
|
const fallbackOlDocs = fallbackItemIds.size
|
|
450
573
|
? await models.ObjectLayer.find({ 'data.item.id': { $in: [...fallbackItemIds] } }).lean()
|
|
451
574
|
: [];
|
|
452
575
|
|
|
576
|
+
const fallbackConfig = toInstanceConfig(fallbackConf);
|
|
577
|
+
if (fallbackEntityDefaultsConfig.length)
|
|
578
|
+
fallbackConfig.entityDefaults = mergeEntityDefaults(fallbackEntityDefaultsConfig);
|
|
579
|
+
if (fallbackSkillDocs.length) fallbackConfig.skillConfig = skillDocsToConfig(fallbackSkillDocs);
|
|
580
|
+
|
|
453
581
|
callback(null, {
|
|
454
582
|
instance: toInstanceMsg({
|
|
455
583
|
_id: '',
|
|
@@ -461,6 +589,7 @@ function buildHandlers(dbKey) {
|
|
|
461
589
|
portals: world.portals,
|
|
462
590
|
topologyMode: 'procedural',
|
|
463
591
|
seed: instanceCode,
|
|
592
|
+
playerSpawn: world.instance.playerSpawn,
|
|
464
593
|
}),
|
|
465
594
|
maps: world.maps.map((m) => ({
|
|
466
595
|
mongoId: '',
|
|
@@ -473,8 +602,12 @@ function buildHandlers(dbKey) {
|
|
|
473
602
|
entities: (m.entities || []).map(toEntityMsg),
|
|
474
603
|
})),
|
|
475
604
|
objectLayers: fallbackOlDocs.map(toObjectLayerMsg),
|
|
476
|
-
config:
|
|
605
|
+
config: fallbackConfig,
|
|
477
606
|
version: 'fallback',
|
|
607
|
+
// Mission content for the procedural fallback comes straight from
|
|
608
|
+
// the canonical defaults — no DB, fully self-contained.
|
|
609
|
+
actions: DefaultCyberiaActions.map(toActionMsg),
|
|
610
|
+
quests: DefaultCyberiaQuests.map(toQuestMsg),
|
|
478
611
|
});
|
|
479
612
|
return;
|
|
480
613
|
}
|
|
@@ -506,9 +639,23 @@ function buildHandlers(dbKey) {
|
|
|
506
639
|
}
|
|
507
640
|
}
|
|
508
641
|
|
|
509
|
-
//
|
|
510
|
-
//
|
|
511
|
-
// the
|
|
642
|
+
// Instance-level itemIds (e.g. default-player-inventory items) may not
|
|
643
|
+
// appear in any map entity — include them so their atlases resolve.
|
|
644
|
+
// Tolerate legacy flat-string entries alongside the { id, … } shape.
|
|
645
|
+
for (const entry of inst.itemIds || []) {
|
|
646
|
+
const id = typeof entry === 'string' ? entry : entry?.id;
|
|
647
|
+
if (id) itemIds.add(id);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// Authoritative per-entity-type defaults come from the
|
|
651
|
+
// CyberiaEntityTypeDefault collection (own model); empty collection leaves
|
|
652
|
+
// the conf/canonical defaults in place.
|
|
653
|
+
const entityDefaultDocs = await loadEntityTypeDefaultDocs(models);
|
|
654
|
+
const entityDefaultsConfig = entityTypeDefaultDocsToConfig(entityDefaultDocs);
|
|
655
|
+
|
|
656
|
+
// Include system OL items from canonical ENTITY_TYPE_DEFAULTS, the DB conf,
|
|
657
|
+
// AND the collection so the Go server always caches every default atlas
|
|
658
|
+
// even when an entity (e.g. a new resource skin) appears in no map.
|
|
512
659
|
for (const d of [...ENTITY_TYPE_DEFAULTS, ...(conf.entityDefaults || [])]) {
|
|
513
660
|
for (const id of d.liveItemIds || []) itemIds.add(id);
|
|
514
661
|
for (const id of d.deadItemIds || []) itemIds.add(id);
|
|
@@ -517,6 +664,12 @@ function buildHandlers(dbKey) {
|
|
|
517
664
|
if (ol.itemId) itemIds.add(ol.itemId);
|
|
518
665
|
}
|
|
519
666
|
}
|
|
667
|
+
addEntityDefaultAtlasIds(entityDefaultsConfig, itemIds);
|
|
668
|
+
|
|
669
|
+
// Authoritative skills come from the CyberiaSkill collection (own model);
|
|
670
|
+
// resolve their atlases before the OL query so summoned entities render.
|
|
671
|
+
const skillDocs = await loadSkillConfigDocs(models);
|
|
672
|
+
addSkillAtlasIds(skillDocs, itemIds);
|
|
520
673
|
|
|
521
674
|
const olDocs = itemIds.size
|
|
522
675
|
? await models.ObjectLayer.find({ 'data.item.id': { $in: [...itemIds] } }).lean()
|
|
@@ -527,14 +680,46 @@ function buildHandlers(dbKey) {
|
|
|
527
680
|
const versionParts = [String(inst.updatedAt || inst._id)];
|
|
528
681
|
for (const m of mapDocs) versionParts.push(String(m.updatedAt || m._id));
|
|
529
682
|
if (conf.updatedAt) versionParts.push(String(conf.updatedAt));
|
|
683
|
+
// Skill edits live in their own collection — fold them in so a skill
|
|
684
|
+
// change triggers a Go-side world rebuild instead of serving stale skills.
|
|
685
|
+
for (const sk of skillDocs) versionParts.push(String(sk.updatedAt || sk._id));
|
|
686
|
+
// Entity-type-default edits live in their own collection too — fold them
|
|
687
|
+
// in so adding/editing a default (e.g. a new resource) rebuilds the world.
|
|
688
|
+
for (const ed of entityDefaultDocs) versionParts.push(String(ed.updatedAt || ed._id));
|
|
530
689
|
const version = crypto.createHash('sha256').update(versionParts.join('|')).digest('hex');
|
|
531
690
|
|
|
691
|
+
// Mission content for this instance: actions and quests bound to its
|
|
692
|
+
// maps (by sourceMapCode). Delivered with the world so the Go server
|
|
693
|
+
// never opens a separate REST channel, and never receives content from
|
|
694
|
+
// other instances' maps.
|
|
695
|
+
const actionDocs =
|
|
696
|
+
mapCodes.length && models.CyberiaAction
|
|
697
|
+
? await models.CyberiaAction.find({ sourceMapCode: { $in: mapCodes } }).lean()
|
|
698
|
+
: [];
|
|
699
|
+
const questDocs =
|
|
700
|
+
mapCodes.length && models.CyberiaQuest
|
|
701
|
+
? await models.CyberiaQuest.find({ sourceMapCode: { $in: mapCodes } }).lean()
|
|
702
|
+
: [];
|
|
703
|
+
|
|
704
|
+
const baseConfig = toInstanceConfig(conf);
|
|
705
|
+
// Own-model entity defaults win over the conf's entityDefaults (overlaid on
|
|
706
|
+
// canonical via mergeEntityDefaults), so every collection variant — e.g.
|
|
707
|
+
// each resource skin — reaches the Go runtime keyed by liveItemIds. Applied
|
|
708
|
+
// BEFORE default-player-inventory so the player layer additions survive.
|
|
709
|
+
if (entityDefaultsConfig.length) baseConfig.entityDefaults = mergeEntityDefaults(entityDefaultsConfig);
|
|
710
|
+
const config = applyInstanceDefaultPlayerInventory(baseConfig, inst.itemIds);
|
|
711
|
+
// Own-model skills win over the conf's stripped skillConfig (which lacks
|
|
712
|
+
// summonedEntityItemId); empty collection leaves the conf/fallback as-is.
|
|
713
|
+
if (skillDocs.length) config.skillConfig = skillDocsToConfig(skillDocs);
|
|
714
|
+
|
|
532
715
|
callback(null, {
|
|
533
716
|
instance: toInstanceMsg(inst),
|
|
534
717
|
maps: mapDocs.map(toMapMsg),
|
|
535
718
|
objectLayers: olDocs.map(toObjectLayerMsg),
|
|
536
|
-
config
|
|
719
|
+
config,
|
|
537
720
|
version,
|
|
721
|
+
actions: actionDocs.map(toActionMsg),
|
|
722
|
+
quests: questDocs.map(toQuestMsg),
|
|
538
723
|
});
|
|
539
724
|
} catch (err) {
|
|
540
725
|
logger.error('getFullInstance:', err);
|
package/src/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import UnderpostKickStart from './cli/kickstart.js';
|
|
|
10
10
|
import UnderpostCluster from './cli/cluster.js';
|
|
11
11
|
import UnderpostDB from './cli/db.js';
|
|
12
12
|
import UnderpostDeploy from './cli/deploy.js';
|
|
13
|
+
import UnderpostDockerCompose from './cli/docker-compose.js';
|
|
13
14
|
import UnderpostKubectl from './cli/kubectl.js';
|
|
14
15
|
import UnderpostRootEnv from './cli/env.js';
|
|
15
16
|
import UnderpostFileStorage from './cli/fs.js';
|
|
@@ -44,7 +45,7 @@ class Underpost {
|
|
|
44
45
|
* @type {String}
|
|
45
46
|
* @memberof Underpost
|
|
46
47
|
*/
|
|
47
|
-
static version = 'v3.2.
|
|
48
|
+
static version = 'v3.2.70';
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
51
|
* Required Node.js major version
|
|
@@ -146,6 +147,15 @@ class Underpost {
|
|
|
146
147
|
static get deploy() {
|
|
147
148
|
return UnderpostDeploy.API;
|
|
148
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* Docker Compose pipeline cli API
|
|
152
|
+
* @static
|
|
153
|
+
* @type {UnderpostDockerCompose.API}
|
|
154
|
+
* @memberof Underpost
|
|
155
|
+
*/
|
|
156
|
+
static get dockerCompose() {
|
|
157
|
+
return UnderpostDockerCompose.API;
|
|
158
|
+
}
|
|
149
159
|
/**
|
|
150
160
|
* File Storage cli API
|
|
151
161
|
* @static
|
|
@@ -321,6 +331,7 @@ export {
|
|
|
321
331
|
UnderpostCluster,
|
|
322
332
|
UnderpostDB,
|
|
323
333
|
UnderpostDeploy,
|
|
334
|
+
UnderpostDockerCompose,
|
|
324
335
|
UnderpostKubectl,
|
|
325
336
|
UnderpostRootEnv,
|
|
326
337
|
UnderpostFileStorage,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Atlas Sprite Sheet Generator for Cyberia Online.
|
|
3
3
|
* Consolidates all object layer frames (8 directions, multiple modes) into a single PNG atlas.
|
|
4
|
-
* @module src/
|
|
4
|
+
* @module src/projects/cyberia/atlas-sprite-sheet-generator.js
|
|
5
5
|
* @namespace CyberiaAtlasSpriteSheetGenerator
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ import fs from 'fs-extra';
|
|
|
9
9
|
import path from 'path';
|
|
10
10
|
import sharp from 'sharp';
|
|
11
11
|
import { Jimp, rgbaToInt } from 'jimp';
|
|
12
|
-
import { loggerFactory } from '
|
|
12
|
+
import { loggerFactory } from '../../server/logger.js';
|
|
13
13
|
|
|
14
14
|
const logger = loggerFactory(import.meta);
|
|
15
15
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* This eliminates hardcoded keys/hashes in manifests/besu/ and ensures every
|
|
10
10
|
* new deployment gets a clean, unique chain identity.
|
|
11
11
|
*
|
|
12
|
-
* @module src/
|
|
12
|
+
* @module src/projects/cyberia/besu-genesis-generator.js
|
|
13
13
|
* @namespace BesuGenesisGenerator
|
|
14
14
|
*/
|
|
15
15
|
|
|
@@ -17,8 +17,8 @@ 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 '
|
|
21
|
-
import { shellExec } from '
|
|
20
|
+
import { loggerFactory } from '../../server/logger.js';
|
|
21
|
+
import { shellExec } from '../../server/process.js';
|
|
22
22
|
|
|
23
23
|
const logger = loggerFactory(import.meta);
|
|
24
24
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cyberia CLI content catalog.
|
|
3
|
+
*
|
|
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
|
|
6
|
+
* statically depend on it. Exports the uniform product-catalog shape:
|
|
7
|
+
*
|
|
8
|
+
* - `sourceMoves` — public `[src, dest]` pairs moved into the engine tree before a build.
|
|
9
|
+
* - `privateConfPaths` — extra payloads synced into the deploy's private repo.
|
|
10
|
+
* - `templatePaths` — engine paths packaged into the standalone product CLI template.
|
|
11
|
+
* - `stripPaths` — paths removed from the base `pwa-microservices-template`.
|
|
12
|
+
* - `moves` — `[src, dest]` pairs moved into the template during assembly (like sourceMoves but into the template target).
|
|
13
|
+
* - `copies` — `[src, dest]` pairs copied into the template during assembly (like moves but copied instead of moved).
|
|
14
|
+
* - `keywords` — npm keywords for the standalone product CLI package.
|
|
15
|
+
* - `description` — npm description for the standalone product CLI package.
|
|
16
|
+
*
|
|
17
|
+
* @module src/projects/cyberia/catalog-cyberia.js
|
|
18
|
+
* @namespace CyberiaCatalog
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export default {
|
|
22
|
+
sourceMoves: [],
|
|
23
|
+
privateConfPaths: ['cyberia-instances/amethyst-strata-expansion'],
|
|
24
|
+
templatePaths: [
|
|
25
|
+
'/src/grpc/cyberia',
|
|
26
|
+
'/src/client/ssr/views/CyberiaServerMetrics.js',
|
|
27
|
+
'/test/cyberia-instance-conf-defaults.test.js',
|
|
28
|
+
'/test/shape-generator.test.js',
|
|
29
|
+
'/src/projects/cyberia',
|
|
30
|
+
'/src/runtime/cyberia-server',
|
|
31
|
+
'/src/runtime/cyberia-client',
|
|
32
|
+
'/src/runtime/engine-cyberia',
|
|
33
|
+
'/.github/workflows/hardhat.ci.yml',
|
|
34
|
+
'/src/client/public/cyberia-docs',
|
|
35
|
+
'/src/api/cyberia-server-defaults',
|
|
36
|
+
'/.github/workflows/docker-image.cyberia-client.ci.yml',
|
|
37
|
+
'/.github/workflows/docker-image.cyberia-client.dev.ci.yml',
|
|
38
|
+
'/.github/workflows/docker-image.cyberia-server.ci.yml',
|
|
39
|
+
'/.github/workflows/docker-image.cyberia-server.dev.ci.yml',
|
|
40
|
+
'/.github/workflows/cyberia-client.cd.yml',
|
|
41
|
+
'/.github/workflows/cyberia-server.cd.yml',
|
|
42
|
+
],
|
|
43
|
+
stripPaths: [
|
|
44
|
+
'./src/projects/cyberia',
|
|
45
|
+
'./src/grpc/cyberia',
|
|
46
|
+
'./src/runtime/cyberia-server',
|
|
47
|
+
'./src/runtime/cyberia-client',
|
|
48
|
+
'./src/runtime/engine-cyberia',
|
|
49
|
+
'./test/cyberia-instance-conf-defaults.test.js',
|
|
50
|
+
'./test/shape-generator.test.js',
|
|
51
|
+
'./src/client/public/cyberia-docs',
|
|
52
|
+
'bin/cyberia.js',
|
|
53
|
+
'./hardhat',
|
|
54
|
+
],
|
|
55
|
+
moves: [],
|
|
56
|
+
copies: [
|
|
57
|
+
['./src/runtime/engine-cyberia/docker-compose.yml', './docker-compose.yml'],
|
|
58
|
+
['./src/runtime/engine-cyberia/compose.env', './.env.example'],
|
|
59
|
+
['./src/runtime/engine-cyberia/.', './'],
|
|
60
|
+
],
|
|
61
|
+
keywords: [
|
|
62
|
+
'cyberia',
|
|
63
|
+
'cyberia-cli',
|
|
64
|
+
'engine-cyberia',
|
|
65
|
+
'sidecar',
|
|
66
|
+
'data-layer',
|
|
67
|
+
'object-layer',
|
|
68
|
+
'atlas-sprite-sheet',
|
|
69
|
+
'ipfs',
|
|
70
|
+
'erc-1155',
|
|
71
|
+
'object-layer-token',
|
|
72
|
+
'hardhat',
|
|
73
|
+
'hyperledger-besu',
|
|
74
|
+
'blockchain',
|
|
75
|
+
'web3',
|
|
76
|
+
'underpost-platform',
|
|
77
|
+
'mmorpg',
|
|
78
|
+
],
|
|
79
|
+
description:
|
|
80
|
+
'Cyberia CLI — toolchain for the Cyberia MMO data layer, content pipeline, persistence, gRPC services, and ERC-1155 lifecycle on Hyperledger Besu.',
|
|
81
|
+
};
|