cyberia 3.0.3 → 3.2.5
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.production → .env.example} +20 -4
- package/.github/workflows/engine-cyberia.cd.yml +43 -10
- package/.github/workflows/engine-cyberia.ci.yml +48 -26
- package/.github/workflows/ghpkg.ci.yml +5 -5
- package/.github/workflows/gitlab.ci.yml +1 -1
- package/.github/workflows/hardhat.ci.yml +82 -0
- package/.github/workflows/npmpkg.ci.yml +60 -14
- package/.github/workflows/publish.ci.yml +26 -7
- package/.github/workflows/publish.cyberia.ci.yml +5 -5
- package/.github/workflows/pwa-microservices-template-page.cd.yml +6 -7
- package/.github/workflows/pwa-microservices-template-test.ci.yml +4 -4
- package/.github/workflows/release.cd.yml +14 -8
- package/.vscode/extensions.json +9 -8
- package/.vscode/settings.json +3 -2
- package/CHANGELOG.md +643 -1
- package/CLI-HELP.md +132 -57
- package/Dockerfile +4 -2
- package/README.md +347 -22
- package/WHITE-PAPER.md +1540 -0
- package/bin/build.js +21 -12
- package/bin/cyberia.js +2640 -106
- package/bin/deploy.js +258 -372
- package/bin/file.js +5 -1
- package/bin/index.js +2640 -106
- package/bin/vs.js +3 -3
- package/conf.js +169 -105
- package/deployment.yaml +236 -20
- package/hardhat/.env.example +31 -0
- package/hardhat/README.md +531 -0
- package/hardhat/WHITE-PAPER.md +1540 -0
- package/hardhat/contracts/ObjectLayerToken.sol +391 -0
- package/hardhat/deployments/.gitkeep +0 -0
- package/hardhat/deployments/hardhat-ObjectLayerToken.json +11 -0
- package/hardhat/hardhat.config.js +136 -0
- package/hardhat/ignition/modules/ObjectLayerToken.js +21 -0
- package/hardhat/networks/besu-object-layer.network.json +138 -0
- package/hardhat/package-lock.json +4323 -0
- package/hardhat/package.json +36 -0
- package/hardhat/scripts/deployObjectLayerToken.js +98 -0
- package/hardhat/test/ObjectLayerToken.js +592 -0
- package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
- package/hardhat/types/ethers-contracts/common.ts +92 -0
- package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
- package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
- package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
- package/hardhat/types/ethers-contracts/index.ts +6 -0
- package/jsdoc.dd-cyberia.json +68 -0
- package/jsdoc.json +65 -49
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +5 -4
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +5 -4
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +562 -0
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +297 -0
- package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +132 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +88 -74
- package/manifests/deployment/dd-test-development/proxy.yaml +13 -4
- package/manifests/deployment/playwright/deployment.yaml +1 -1
- package/manifests/pv-pvc-dd.yaml +1 -1
- package/nodemon.json +1 -1
- package/package.json +60 -48
- package/proxy.yaml +118 -10
- package/pv-pvc.yaml +132 -0
- package/scripts/k3s-node-setup.sh +1 -1
- package/scripts/ports-ls.sh +2 -0
- package/scripts/rhel-grpc-setup.sh +56 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +47 -1
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +17 -2
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +80 -7
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
- package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
- package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
- package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
- package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +368 -0
- package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
- package/src/api/cyberia-instance/cyberia-instance.model.js +84 -0
- package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +191 -0
- package/src/api/cyberia-instance/cyberia-portal-connector.js +486 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +413 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +228 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +42 -0
- package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
- package/src/api/cyberia-map/cyberia-map.model.js +30 -0
- package/src/api/cyberia-map/cyberia-map.router.js +40 -0
- package/src/api/cyberia-map/cyberia-map.service.js +74 -0
- package/src/api/document/document.service.js +1 -1
- package/src/api/file/file.controller.js +3 -1
- package/src/api/file/file.ref.json +18 -0
- package/src/api/file/file.service.js +28 -5
- package/src/api/ipfs/ipfs.controller.js +4 -25
- package/src/api/ipfs/ipfs.model.js +43 -34
- package/src/api/ipfs/ipfs.router.js +8 -13
- package/src/api/ipfs/ipfs.service.js +56 -104
- package/src/api/object-layer/README.md +347 -22
- package/src/api/object-layer/object-layer.controller.js +6 -2
- package/src/api/object-layer/object-layer.model.js +12 -8
- package/src/api/object-layer/object-layer.router.js +698 -42
- package/src/api/object-layer/object-layer.service.js +119 -37
- package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +1 -2
- package/src/api/user/user.router.js +10 -5
- package/src/api/user/user.service.js +15 -14
- package/src/cli/baremetal.js +6 -10
- package/src/cli/cloud-init.js +0 -3
- package/src/cli/cluster.js +7 -7
- package/src/cli/db.js +723 -857
- package/src/cli/deploy.js +215 -105
- package/src/cli/env.js +34 -5
- package/src/cli/fs.js +5 -4
- package/src/cli/image.js +0 -3
- package/src/cli/index.js +83 -15
- package/src/cli/kubectl.js +211 -0
- package/src/cli/monitor.js +5 -6
- package/src/cli/release.js +284 -0
- package/src/cli/repository.js +708 -62
- package/src/cli/run.js +371 -151
- package/src/cli/secrets.js +73 -2
- package/src/cli/ssh.js +1 -1
- package/src/cli/test.js +3 -3
- package/src/client/Cryptokoyn.index.js +3 -4
- package/src/client/CyberiaPortal.index.js +3 -4
- package/src/client/Default.index.js +3 -4
- package/src/client/Itemledger.index.js +4 -963
- package/src/client/Underpost.index.js +3 -4
- package/src/client/components/core/AgGrid.js +20 -5
- package/src/client/components/core/Alert.js +2 -2
- package/src/client/components/core/AppStore.js +69 -0
- package/src/client/components/core/CalendarCore.js +2 -2
- package/src/client/components/core/Content.js +22 -3
- package/src/client/components/core/Docs.js +30 -6
- package/src/client/components/core/DropDown.js +137 -17
- package/src/client/components/core/FileExplorer.js +71 -4
- package/src/client/components/core/Input.js +1 -1
- package/src/client/components/core/Keyboard.js +2 -2
- package/src/client/components/core/LogIn.js +2 -2
- package/src/client/components/core/LogOut.js +2 -2
- package/src/client/components/core/Modal.js +20 -7
- package/src/client/components/core/Panel.js +0 -1
- package/src/client/components/core/PanelForm.js +19 -19
- package/src/client/components/core/RichText.js +1 -2
- package/src/client/components/core/SocketIo.js +82 -29
- package/src/client/components/core/SocketIoHandler.js +75 -0
- package/src/client/components/core/Stream.js +143 -95
- package/src/client/components/core/Webhook.js +40 -7
- package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
- package/src/client/components/cryptokoyn/LogInCryptokoyn.js +3 -3
- package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +2 -2
- package/src/client/components/cryptokoyn/MenuCryptokoyn.js +3 -3
- package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
- package/src/client/components/cyberia/InstanceEngineCyberia.js +700 -0
- package/src/client/components/cyberia/MapEngineCyberia.js +1359 -2
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +17 -6
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +92 -54
- package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +217 -30
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +44 -2
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +3 -4
- package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +2 -2
- package/src/client/components/cyberia-portal/MenuCyberiaPortal.js +104 -9
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +5 -0
- package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -0
- package/src/client/components/default/AppStoreDefault.js +5 -0
- package/src/client/components/default/LogInDefault.js +3 -3
- package/src/client/components/default/LogOutDefault.js +2 -2
- package/src/client/components/default/MenuDefault.js +5 -5
- package/src/client/components/default/SocketIoDefault.js +3 -51
- package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
- package/src/client/components/itemledger/LogInItemledger.js +3 -3
- package/src/client/components/itemledger/LogOutItemledger.js +2 -2
- package/src/client/components/itemledger/MenuItemledger.js +3 -3
- package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
- package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
- package/src/client/components/underpost/CssUnderpost.js +59 -0
- package/src/client/components/underpost/LogInUnderpost.js +6 -3
- package/src/client/components/underpost/LogOutUnderpost.js +4 -2
- package/src/client/components/underpost/MenuUnderpost.js +104 -18
- package/src/client/components/underpost/RoutesUnderpost.js +2 -0
- package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
- package/src/client/public/cryptokoyn/assets/logo/base-icon.png +0 -0
- package/src/client/public/cryptokoyn/browserconfig.xml +12 -0
- package/src/client/public/cryptokoyn/microdata.json +85 -0
- package/src/client/public/cryptokoyn/site.webmanifest +57 -0
- package/src/client/public/cryptokoyn/sitemap +3 -3
- package/src/client/public/default/sitemap +3 -3
- package/src/client/public/itemledger/browserconfig.xml +2 -2
- package/src/client/public/itemledger/manifest.webmanifest +4 -4
- package/src/client/public/itemledger/microdata.json +71 -0
- package/src/client/public/itemledger/sitemap +3 -3
- package/src/client/public/itemledger/yandex-browser-manifest.json +2 -2
- package/src/client/public/test/sitemap +3 -3
- package/src/client/services/core/core.service.js +20 -8
- package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +105 -0
- package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
- package/src/client/services/cyberia-entity/cyberia-entity.service.js +105 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +122 -0
- package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +105 -0
- package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
- package/src/client/services/cyberia-map/cyberia-map.service.js +126 -0
- package/src/client/services/instance/instance.management.js +2 -2
- package/src/client/services/ipfs/ipfs.service.js +3 -23
- package/src/client/services/object-layer/object-layer.management.js +3 -3
- package/src/client/services/object-layer/object-layer.service.js +21 -0
- package/src/client/services/user/user.management.js +2 -2
- package/src/client/ssr/body/404.js +15 -11
- package/src/client/ssr/body/500.js +15 -11
- package/src/client/ssr/body/SwaggerDarkMode.js +285 -0
- package/src/client/ssr/head/PwaItemledger.js +60 -0
- package/src/client/ssr/offline/NoNetworkConnection.js +11 -10
- package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
- package/src/client/ssr/pages/Test.js +11 -10
- package/src/client.build.js +0 -3
- package/src/client.dev.js +0 -3
- package/src/db/DataBaseProvider.js +17 -2
- package/src/db/mariadb/MariaDB.js +14 -9
- package/src/db/mongo/MongooseDB.js +17 -1
- package/src/grpc/cyberia/OFF_CHAIN_ECONOMY.md +305 -0
- package/src/grpc/cyberia/README.md +326 -0
- package/src/grpc/cyberia/grpc-server.js +530 -0
- package/src/index.js +24 -1
- package/src/proxy.js +0 -3
- package/src/runtime/express/Dockerfile +4 -0
- package/src/runtime/express/Express.js +33 -10
- package/src/runtime/lampp/Dockerfile +13 -2
- package/src/runtime/lampp/Lampp.js +33 -17
- package/src/runtime/wp/Dockerfile +68 -0
- package/src/runtime/wp/Wp.js +639 -0
- package/src/server/auth.js +36 -15
- package/src/server/backup.js +39 -12
- package/src/server/besu-genesis-generator.js +1630 -0
- package/src/server/client-build-docs.js +133 -17
- package/src/server/client-build-live.js +9 -18
- package/src/server/client-build.js +229 -101
- package/src/server/client-dev-server.js +14 -13
- package/src/server/client-formatted.js +109 -57
- package/src/server/conf.js +391 -164
- package/src/server/cron.js +27 -24
- package/src/server/dns.js +29 -12
- package/src/server/downloader.js +0 -2
- package/src/server/ipfs-client.js +24 -1
- package/src/server/logger.js +27 -9
- package/src/server/object-layer.js +217 -103
- package/src/server/peer.js +8 -2
- package/src/server/process.js +1 -50
- package/src/server/proxy.js +4 -8
- package/src/server/runtime.js +30 -9
- package/src/server/semantic-layer-generator-floor.js +359 -0
- package/src/server/semantic-layer-generator-skin.js +1294 -0
- package/src/server/semantic-layer-generator.js +116 -555
- package/src/server/ssr.js +0 -3
- package/src/server/start.js +19 -12
- package/src/server/tls.js +0 -2
- package/src/server.js +0 -4
- package/src/ws/IoInterface.js +1 -10
- package/src/ws/IoServer.js +14 -33
- package/src/ws/core/channels/core.ws.chat.js +65 -20
- package/src/ws/core/channels/core.ws.mailer.js +113 -32
- package/src/ws/core/channels/core.ws.stream.js +90 -31
- package/src/ws/core/core.ws.connection.js +12 -33
- package/src/ws/core/core.ws.emit.js +10 -26
- package/src/ws/core/core.ws.server.js +25 -58
- package/src/ws/default/channels/default.ws.main.js +53 -12
- package/src/ws/default/default.ws.connection.js +26 -13
- package/src/ws/default/default.ws.server.js +30 -12
- package/.env.development +0 -43
- package/.env.test +0 -43
- package/hardhat/contracts/CryptoKoyn.sol +0 -59
- package/hardhat/contracts/ItemLedger.sol +0 -73
- package/hardhat/contracts/Lock.sol +0 -34
- package/hardhat/hardhat.config.cjs +0 -45
- package/hardhat/ignition/modules/Lock.js +0 -18
- package/hardhat/networks/cryptokoyn-itemledger.network.json +0 -29
- package/hardhat/scripts/deployCryptokoyn.cjs +0 -25
- package/hardhat/scripts/deployItemledger.cjs +0 -25
- package/hardhat/test/Lock.js +0 -126
- package/hardhat/white-paper.md +0 -581
- package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
- package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
- package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
- package/src/client/components/default/ElementsDefault.js +0 -38
- package/src/client/components/itemledger/CommonItemledger.js +0 -29
- package/src/client/components/itemledger/ElementsItemledger.js +0 -38
- package/src/client/components/underpost/CommonUnderpost.js +0 -29
- package/src/client/components/underpost/ElementsUnderpost.js +0 -38
- package/src/ws/core/management/core.ws.chat.js +0 -8
- package/src/ws/core/management/core.ws.mailer.js +0 -16
- package/src/ws/core/management/core.ws.stream.js +0 -8
- package/src/ws/default/management/default.ws.main.js +0 -8
- package/white-paper.md +0 -581
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { Schema, model } from 'mongoose';
|
|
2
|
+
import { CYBERIA_INSTANCE_CONF_DEFAULTS as D } from './cyberia-instance-conf.defaults.js';
|
|
3
|
+
|
|
4
|
+
const ColorEntrySchema = new Schema(
|
|
5
|
+
{
|
|
6
|
+
key: { type: String, required: true },
|
|
7
|
+
r: { type: Number, default: 0 },
|
|
8
|
+
g: { type: Number, default: 0 },
|
|
9
|
+
b: { type: Number, default: 0 },
|
|
10
|
+
a: { type: Number, default: 255 },
|
|
11
|
+
},
|
|
12
|
+
{ _id: false },
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
// ObjectLayer inventory slot: itemId + whether it starts active + initial quantity.
|
|
16
|
+
// Used by EntityDefaultSchema.defaultObjectLayers.
|
|
17
|
+
const ObjectLayerSlotSchema = new Schema(
|
|
18
|
+
{
|
|
19
|
+
itemId: { type: String, required: true },
|
|
20
|
+
active: { type: Boolean, default: false },
|
|
21
|
+
quantity: { type: Number, default: 1 },
|
|
22
|
+
},
|
|
23
|
+
{ _id: false },
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const EntityDefaultSchema = new Schema(
|
|
27
|
+
{
|
|
28
|
+
// Entity category string (matches entity_type_str / bot Behavior in game engine)
|
|
29
|
+
entityType: { type: String, required: true },
|
|
30
|
+
// Default ObjectLayer item IDs when the entity is alive and carries no assigned items.
|
|
31
|
+
liveItemIds: { type: [String], default: [] },
|
|
32
|
+
// Default ObjectLayer item IDs for the dead / ghost / respawning state.
|
|
33
|
+
// Empty array = use liveItemIds solid fill color.
|
|
34
|
+
deadItemIds: { type: [String], default: [] },
|
|
35
|
+
// Palette key for solid-color fallback when no OL items are assigned.
|
|
36
|
+
colorKey: { type: String, default: '' },
|
|
37
|
+
// Full default ObjectLayer inventory for this entity type.
|
|
38
|
+
// Each entry specifies itemId, whether it starts active, and its initial quantity.
|
|
39
|
+
// The coin slot must always have active:false — coins are non-activable.
|
|
40
|
+
// When non-empty this supersedes liveItemIds for inventory initialization.
|
|
41
|
+
defaultObjectLayers: { type: [ObjectLayerSlotSchema], default: [] },
|
|
42
|
+
},
|
|
43
|
+
{ _id: false },
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const SkillConfigEntrySchema = new Schema(
|
|
47
|
+
{
|
|
48
|
+
triggerItemId: { type: String, required: true },
|
|
49
|
+
logicEventIds: { type: [String], default: [] },
|
|
50
|
+
},
|
|
51
|
+
{ _id: false },
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
// ── StatusIconEntrySchema ────────────────────────────────────────────────────
|
|
55
|
+
// Maps a u8 status ID to an overhead icon and a border colour used by the
|
|
56
|
+
// interaction bubble / interact overlay on the C/WASM client.
|
|
57
|
+
// See STATUS_ICONS in cyberia-instance-conf.defaults.js.
|
|
58
|
+
const StatusIconBorderColorSchema = new Schema(
|
|
59
|
+
{
|
|
60
|
+
r: { type: Number, default: 100 },
|
|
61
|
+
g: { type: Number, default: 100 },
|
|
62
|
+
b: { type: Number, default: 100 },
|
|
63
|
+
a: { type: Number, default: 200 },
|
|
64
|
+
},
|
|
65
|
+
{ _id: false },
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const StatusIconEntrySchema = new Schema(
|
|
69
|
+
{
|
|
70
|
+
id: { type: Number, required: true },
|
|
71
|
+
name: { type: String, default: '' },
|
|
72
|
+
iconId: { type: String, default: null },
|
|
73
|
+
bounce: { type: Boolean, default: false },
|
|
74
|
+
borderColor: { type: StatusIconBorderColorSchema },
|
|
75
|
+
description: { type: String, default: '' },
|
|
76
|
+
},
|
|
77
|
+
{ _id: false },
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
// ── EconomyRulesSchema ───────────────────────────────────────────────────────
|
|
81
|
+
// Mirrors the EconomyRules proto message and the economyRules sub-document in
|
|
82
|
+
// cyberia-instance-conf.defaults.js. All fields default from those canonical
|
|
83
|
+
// values so a freshly created document is immediately playable.
|
|
84
|
+
// See OFF_CHAIN_ECONOMY.md for the full Fountain & Sink architecture.
|
|
85
|
+
const EconomyRulesSchema = new Schema(
|
|
86
|
+
{
|
|
87
|
+
// ── Fountains ───────────────────────────────────────────────────────────
|
|
88
|
+
botSpawnCoins: { type: Number, default: D.economyRules.botSpawnCoins },
|
|
89
|
+
playerSpawnCoins: { type: Number, default: D.economyRules.playerSpawnCoins },
|
|
90
|
+
// ── Kill Transfer ───────────────────────────────────────────────────────
|
|
91
|
+
coinKillPercentVsBot: { type: Number, default: D.economyRules.coinKillPercentVsBot },
|
|
92
|
+
coinKillPercentVsPlayer: { type: Number, default: D.economyRules.coinKillPercentVsPlayer },
|
|
93
|
+
coinKillMinAmount: { type: Number, default: D.economyRules.coinKillMinAmount },
|
|
94
|
+
// ── Sinks ───────────────────────────────────────────────────────────────
|
|
95
|
+
respawnCostPercent: { type: Number, default: D.economyRules.respawnCostPercent },
|
|
96
|
+
portalFee: { type: Number, default: D.economyRules.portalFee },
|
|
97
|
+
craftingFeePercent: { type: Number, default: D.economyRules.craftingFeePercent },
|
|
98
|
+
},
|
|
99
|
+
{ _id: false },
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// ── EquipmentRulesSchema ─────────────────────────────────────────────────────
|
|
103
|
+
// Governs which ObjectLayer item types can be simultaneously active on a
|
|
104
|
+
// character entity and enforces the one-active-per-type constraint.
|
|
105
|
+
// See EQUIPMENT_RULES_DEFAULTS in cyberia-instance-conf.defaults.js.
|
|
106
|
+
const EquipmentRulesSchema = new Schema(
|
|
107
|
+
{
|
|
108
|
+
// Item types that players are allowed to activate (equip).
|
|
109
|
+
// Types not in this list are non-activable (coins, floors, etc.).
|
|
110
|
+
activeItemTypes: { type: [String], default: D.equipmentRules.activeItemTypes },
|
|
111
|
+
// Enforce at most one active item per item type.
|
|
112
|
+
onePerType: { type: Boolean, default: D.equipmentRules.onePerType },
|
|
113
|
+
// Require at least one active skin when the player owns any skin.
|
|
114
|
+
requireSkin: { type: Boolean, default: D.equipmentRules.requireSkin },
|
|
115
|
+
},
|
|
116
|
+
{ _id: false },
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const SkillRulesSchema = new Schema(
|
|
120
|
+
{
|
|
121
|
+
projectileSpawnChance: { type: Number, default: D.skillRules.projectileSpawnChance },
|
|
122
|
+
projectileLifetimeMs: { type: Number, default: D.skillRules.projectileLifetimeMs },
|
|
123
|
+
projectileWidth: { type: Number, default: D.skillRules.projectileWidth },
|
|
124
|
+
projectileHeight: { type: Number, default: D.skillRules.projectileHeight },
|
|
125
|
+
projectileSpeedMultiplier: { type: Number, default: D.skillRules.projectileSpeedMultiplier },
|
|
126
|
+
doppelgangerSpawnChance: { type: Number, default: D.skillRules.doppelgangerSpawnChance },
|
|
127
|
+
doppelgangerLifetimeMs: { type: Number, default: D.skillRules.doppelgangerLifetimeMs },
|
|
128
|
+
doppelgangerSpawnRadius: { type: Number, default: D.skillRules.doppelgangerSpawnRadius },
|
|
129
|
+
doppelgangerInitialLifeFraction: { type: Number, default: D.skillRules.doppelgangerInitialLifeFraction },
|
|
130
|
+
},
|
|
131
|
+
{ _id: false },
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Game server configuration for a Cyberia instance.
|
|
136
|
+
* Separated from CyberiaInstance so the GUI never overwrites live server parameters
|
|
137
|
+
* when editing instance identity / map-graph fields.
|
|
138
|
+
*
|
|
139
|
+
* Linked from CyberiaInstance.conf (ObjectId ref).
|
|
140
|
+
* Looked up by instanceCode for CLI / gRPC use.
|
|
141
|
+
*/
|
|
142
|
+
const CyberiaInstanceConfSchema = new Schema(
|
|
143
|
+
{
|
|
144
|
+
// Back-reference to the owning instance (indexed for fast lookup by code).
|
|
145
|
+
instanceCode: { type: String, required: true, unique: true, trim: true },
|
|
146
|
+
|
|
147
|
+
// ── Rendering / camera ──────────────────────────────────────────
|
|
148
|
+
cellSize: { type: Number, default: D.cellSize },
|
|
149
|
+
fps: { type: Number, default: D.fps },
|
|
150
|
+
interpolationMs: { type: Number, default: D.interpolationMs },
|
|
151
|
+
defaultObjWidth: { type: Number, default: D.defaultObjWidth },
|
|
152
|
+
defaultObjHeight: { type: Number, default: D.defaultObjHeight },
|
|
153
|
+
cameraSmoothing: { type: Number, default: D.cameraSmoothing },
|
|
154
|
+
cameraZoom: { type: Number, default: D.cameraZoom },
|
|
155
|
+
defaultWidthScreenFactor: { type: Number, default: D.defaultWidthScreenFactor },
|
|
156
|
+
defaultHeightScreenFactor: { type: Number, default: D.defaultHeightScreenFactor },
|
|
157
|
+
devUi: { type: Boolean, default: D.devUi },
|
|
158
|
+
// Empty array by default — colours must be configured per-instance.
|
|
159
|
+
// toInstanceConfig() fills in CYBERIA_INSTANCE_CONF_DEFAULTS.colors when the array is empty.
|
|
160
|
+
colors: { type: [ColorEntrySchema], default: [] },
|
|
161
|
+
|
|
162
|
+
// ── World / AOI ─────────────────────────────────────────────────
|
|
163
|
+
aoiRadius: { type: Number, default: D.aoiRadius },
|
|
164
|
+
portalHoldTimeMs: { type: Number, default: D.portalHoldTimeMs },
|
|
165
|
+
portalSpawnRadius: { type: Number, default: D.portalSpawnRadius },
|
|
166
|
+
|
|
167
|
+
// ── Entity base stats ────────────────────────────────────────────
|
|
168
|
+
entityBaseSpeed: { type: Number, default: D.entityBaseSpeed },
|
|
169
|
+
entityBaseMaxLife: { type: Number, default: D.entityBaseMaxLife },
|
|
170
|
+
entityBaseActionCooldownMs: { type: Number, default: D.entityBaseActionCooldownMs },
|
|
171
|
+
entityBaseMinActionCooldownMs: { type: Number, default: D.entityBaseMinActionCooldownMs },
|
|
172
|
+
|
|
173
|
+
// ── Bot defaults ─────────────────────────────────────────────────
|
|
174
|
+
botAggroRange: { type: Number, default: D.botAggroRange },
|
|
175
|
+
|
|
176
|
+
// ── Player defaults ──────────────────────────────────────────────
|
|
177
|
+
defaultPlayerWidth: { type: Number, default: D.defaultPlayerWidth },
|
|
178
|
+
defaultPlayerHeight: { type: Number, default: D.defaultPlayerHeight },
|
|
179
|
+
playerBaseLifeRegenMin: { type: Number, default: D.playerBaseLifeRegenMin },
|
|
180
|
+
playerBaseLifeRegenMax: { type: Number, default: D.playerBaseLifeRegenMax },
|
|
181
|
+
sumStatsLimit: { type: Number, default: D.sumStatsLimit },
|
|
182
|
+
maxActiveLayers: { type: Number, default: D.maxActiveLayers },
|
|
183
|
+
initialLifeFraction: { type: Number, default: D.initialLifeFraction },
|
|
184
|
+
|
|
185
|
+
// ── Combat / death ───────────────────────────────────────────────
|
|
186
|
+
respawnDurationMs: { type: Number, default: D.respawnDurationMs },
|
|
187
|
+
collisionLifeLoss: { type: Number, default: D.collisionLifeLoss },
|
|
188
|
+
|
|
189
|
+
// ── Economy ──────────────────────────────────────────────────────
|
|
190
|
+
// Fountain & Sink parameters. See EconomyRulesSchema and OFF_CHAIN_ECONOMY.md.
|
|
191
|
+
economyRules: { type: EconomyRulesSchema },
|
|
192
|
+
|
|
193
|
+
// ── Regen ────────────────────────────────────────────────────────
|
|
194
|
+
lifeRegenChance: { type: Number, default: D.lifeRegenChance },
|
|
195
|
+
maxChance: { type: Number, default: D.maxChance },
|
|
196
|
+
|
|
197
|
+
// ── Entity type rendering defaults ───────────────────────────────
|
|
198
|
+
// Replaces flat fields: userDefaultItemId, botDefaultItemId, ghostItemId,
|
|
199
|
+
// coinItemId, defaultFloorItemId, weaponDefaultItemId.
|
|
200
|
+
// Each entry: { entityType, liveItemIds, deadItemIds, colorKey }.
|
|
201
|
+
entityDefaults: { type: [EntityDefaultSchema], default: D.entityDefaults },
|
|
202
|
+
|
|
203
|
+
// ── Entity Status Indicators ────────────────────────────────────
|
|
204
|
+
// Overhead icon mapping + per-status border colour.
|
|
205
|
+
// See STATUS_ICONS in cyberia-instance-conf.defaults.js.
|
|
206
|
+
statusIcons: { type: [StatusIconEntrySchema], default: D.statusIcons },
|
|
207
|
+
|
|
208
|
+
// ── Skill system ─────────────────────────────────────────────────
|
|
209
|
+
// Each entry maps a trigger item to an ordered list of logic handler keys.
|
|
210
|
+
// Spawning entities (e.g. projectiles) is handled inside the logic handler itself.
|
|
211
|
+
skillConfig: { type: [SkillConfigEntrySchema], default: [] },
|
|
212
|
+
|
|
213
|
+
// Numeric tuning parameters for each skill archetype.
|
|
214
|
+
skillRules: { type: SkillRulesSchema },
|
|
215
|
+
|
|
216
|
+
// ── Equipment rules ──────────────────────────────────────────────
|
|
217
|
+
// Governs which item types can be simultaneously active and enforces
|
|
218
|
+
// the one-active-per-type constraint. See EQUIPMENT_RULES_DEFAULTS.
|
|
219
|
+
equipmentRules: { type: EquipmentRulesSchema },
|
|
220
|
+
},
|
|
221
|
+
{ timestamps: true },
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const CyberiaInstanceConfModel = model('CyberiaInstanceConf', CyberiaInstanceConfSchema);
|
|
225
|
+
|
|
226
|
+
const ProviderSchema = CyberiaInstanceConfSchema;
|
|
227
|
+
|
|
228
|
+
export { CyberiaInstanceConfSchema, CyberiaInstanceConfModel, ProviderSchema };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { loggerFactory } from '../../server/logger.js';
|
|
2
|
+
import { CyberiaInstanceConfController } from './cyberia-instance-conf.controller.js';
|
|
3
|
+
import express from 'express';
|
|
4
|
+
|
|
5
|
+
const logger = loggerFactory(import.meta);
|
|
6
|
+
|
|
7
|
+
const CyberiaInstanceConfRouter = (options) => {
|
|
8
|
+
const router = express.Router();
|
|
9
|
+
const authMiddleware = options.authMiddleware;
|
|
10
|
+
router.post(`/:id`, async (req, res) => await CyberiaInstanceConfController.post(req, res, options));
|
|
11
|
+
router.post(`/`, async (req, res) => await CyberiaInstanceConfController.post(req, res, options));
|
|
12
|
+
router.get(
|
|
13
|
+
`/:id`,
|
|
14
|
+
// authMiddleware,
|
|
15
|
+
async (req, res) => await CyberiaInstanceConfController.get(req, res, options),
|
|
16
|
+
);
|
|
17
|
+
router.get(`/`, async (req, res) => await CyberiaInstanceConfController.get(req, res, options));
|
|
18
|
+
router.put(`/:id`, async (req, res) => await CyberiaInstanceConfController.put(req, res, options));
|
|
19
|
+
router.put(`/`, async (req, res) => await CyberiaInstanceConfController.put(req, res, options));
|
|
20
|
+
router.delete(`/:id`, async (req, res) => await CyberiaInstanceConfController.delete(req, res, options));
|
|
21
|
+
router.delete(`/`, async (req, res) => await CyberiaInstanceConfController.delete(req, res, options));
|
|
22
|
+
return router;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const ApiRouter = CyberiaInstanceConfRouter;
|
|
26
|
+
|
|
27
|
+
export { ApiRouter, CyberiaInstanceConfRouter };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DataBaseProvider } from '../../db/DataBaseProvider.js';
|
|
2
|
+
import { loggerFactory } from '../../server/logger.js';
|
|
3
|
+
import { DataQuery } from '../../server/data-query.js';
|
|
4
|
+
|
|
5
|
+
const logger = loggerFactory(import.meta);
|
|
6
|
+
|
|
7
|
+
const CyberiaInstanceConfService = {
|
|
8
|
+
post: async (req, res, options) => {
|
|
9
|
+
/** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
|
|
10
|
+
const CyberiaInstanceConf = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
|
|
11
|
+
return await new CyberiaInstanceConf(req.body).save();
|
|
12
|
+
},
|
|
13
|
+
get: async (req, res, options) => {
|
|
14
|
+
/** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
|
|
15
|
+
const CyberiaInstanceConf = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
|
|
16
|
+
if (req.params.id) return await CyberiaInstanceConf.findById(req.params.id);
|
|
17
|
+
|
|
18
|
+
// Parse query parameters using DataQuery helper
|
|
19
|
+
const { query, sort, skip, limit, page } = DataQuery.parse(req.query);
|
|
20
|
+
|
|
21
|
+
const [data, total] = await Promise.all([
|
|
22
|
+
CyberiaInstanceConf.find(query).sort(sort).limit(limit).skip(skip),
|
|
23
|
+
CyberiaInstanceConf.countDocuments(query),
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
const totalPages = Math.ceil(total / limit);
|
|
27
|
+
return { data, total, page, totalPages };
|
|
28
|
+
},
|
|
29
|
+
put: async (req, res, options) => {
|
|
30
|
+
/** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
|
|
31
|
+
const CyberiaInstanceConf = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
|
|
32
|
+
return await CyberiaInstanceConf.findByIdAndUpdate(req.params.id, req.body);
|
|
33
|
+
},
|
|
34
|
+
delete: async (req, res, options) => {
|
|
35
|
+
/** @type {import('./cyberia-instance-conf.model.js').CyberiaInstanceConfModel} */
|
|
36
|
+
const CyberiaInstanceConf = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaInstanceConf;
|
|
37
|
+
if (req.params.id) return await CyberiaInstanceConf.findByIdAndDelete(req.params.id);
|
|
38
|
+
else return await CyberiaInstanceConf.deleteMany();
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { CyberiaInstanceConfService };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { loggerFactory } from '../../server/logger.js';
|
|
2
|
+
import { CyberiaMapService } from './cyberia-map.service.js';
|
|
3
|
+
|
|
4
|
+
const logger = loggerFactory(import.meta);
|
|
5
|
+
|
|
6
|
+
const CyberiaMapController = {
|
|
7
|
+
post: async (req, res, options) => {
|
|
8
|
+
try {
|
|
9
|
+
const result = await CyberiaMapService.post(req, res, options);
|
|
10
|
+
return res.status(200).json({
|
|
11
|
+
status: 'success',
|
|
12
|
+
data: result,
|
|
13
|
+
});
|
|
14
|
+
} catch (error) {
|
|
15
|
+
logger.error(error, error.stack);
|
|
16
|
+
return res.status(400).json({
|
|
17
|
+
status: 'error',
|
|
18
|
+
message: error.message,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
get: async (req, res, options) => {
|
|
23
|
+
try {
|
|
24
|
+
const { page, limit } = req.query;
|
|
25
|
+
const result = await CyberiaMapService.get(
|
|
26
|
+
{
|
|
27
|
+
...req,
|
|
28
|
+
path: req.path,
|
|
29
|
+
params: req.params,
|
|
30
|
+
query: { ...req.query, page: parseInt(page), limit: parseInt(limit) },
|
|
31
|
+
},
|
|
32
|
+
res,
|
|
33
|
+
options,
|
|
34
|
+
);
|
|
35
|
+
return res.status(200).json({
|
|
36
|
+
status: 'success',
|
|
37
|
+
data: result,
|
|
38
|
+
});
|
|
39
|
+
} catch (error) {
|
|
40
|
+
logger.error(error, error.stack);
|
|
41
|
+
return res.status(400).json({
|
|
42
|
+
status: 'error',
|
|
43
|
+
message: error.message,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
put: async (req, res, options) => {
|
|
48
|
+
try {
|
|
49
|
+
const result = await CyberiaMapService.put(req, res, options);
|
|
50
|
+
return res.status(200).json({
|
|
51
|
+
status: 'success',
|
|
52
|
+
data: result,
|
|
53
|
+
});
|
|
54
|
+
} catch (error) {
|
|
55
|
+
logger.error(error, error.stack);
|
|
56
|
+
return res.status(400).json({
|
|
57
|
+
status: 'error',
|
|
58
|
+
message: error.message,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
delete: async (req, res, options) => {
|
|
63
|
+
try {
|
|
64
|
+
const result = await CyberiaMapService.delete(req, res, options);
|
|
65
|
+
return res.status(200).json({
|
|
66
|
+
status: 'success',
|
|
67
|
+
data: result,
|
|
68
|
+
});
|
|
69
|
+
} catch (error) {
|
|
70
|
+
logger.error(error, error.stack);
|
|
71
|
+
return res.status(400).json({
|
|
72
|
+
status: 'error',
|
|
73
|
+
message: error.message,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export { CyberiaMapController };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Schema, model, Types } from 'mongoose';
|
|
2
|
+
import { CyberiaEntitySchema } from '../cyberia-entity/cyberia-entity.model.js';
|
|
3
|
+
|
|
4
|
+
// https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
|
|
5
|
+
|
|
6
|
+
const CyberiaMapSchema = new Schema(
|
|
7
|
+
{
|
|
8
|
+
code: { type: String, default: '', unique: true },
|
|
9
|
+
name: { type: String, default: '' },
|
|
10
|
+
description: { type: String, default: '' },
|
|
11
|
+
entities: { type: [CyberiaEntitySchema], default: [] },
|
|
12
|
+
tags: { type: [String], default: [] },
|
|
13
|
+
creator: { type: Schema.Types.ObjectId, ref: 'User' },
|
|
14
|
+
status: { type: String, default: 'unlisted' },
|
|
15
|
+
thumbnail: { type: Schema.Types.ObjectId, ref: 'File' },
|
|
16
|
+
gridX: { type: Number, default: 16 },
|
|
17
|
+
gridY: { type: Number, default: 16 },
|
|
18
|
+
cellWidth: { type: Number, default: 32 },
|
|
19
|
+
cellHeight: { type: Number, default: 32 },
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
timestamps: true,
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const CyberiaMapModel = model('CyberiaMap', CyberiaMapSchema);
|
|
27
|
+
|
|
28
|
+
const ProviderSchema = CyberiaMapSchema;
|
|
29
|
+
|
|
30
|
+
export { CyberiaMapSchema, CyberiaMapModel, ProviderSchema };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { loggerFactory } from '../../server/logger.js';
|
|
2
|
+
import { CyberiaMapController } from './cyberia-map.controller.js';
|
|
3
|
+
import { userGuard, adminGuard } from '../../server/auth.js';
|
|
4
|
+
import express from 'express';
|
|
5
|
+
|
|
6
|
+
const logger = loggerFactory(import.meta);
|
|
7
|
+
|
|
8
|
+
const CyberiaMapRouter = (options) => {
|
|
9
|
+
const router = express.Router();
|
|
10
|
+
const authMiddleware = options.authMiddleware;
|
|
11
|
+
router.post(
|
|
12
|
+
`/:id`,
|
|
13
|
+
authMiddleware,
|
|
14
|
+
userGuard,
|
|
15
|
+
async (req, res) => await CyberiaMapController.post(req, res, options),
|
|
16
|
+
);
|
|
17
|
+
router.post(`/`, authMiddleware, userGuard, async (req, res) => await CyberiaMapController.post(req, res, options));
|
|
18
|
+
router.get(`/search-codes`, async (req, res) => await CyberiaMapController.get(req, res, options));
|
|
19
|
+
router.get(`/:id`, async (req, res) => await CyberiaMapController.get(req, res, options));
|
|
20
|
+
router.get(`/`, async (req, res) => await CyberiaMapController.get(req, res, options));
|
|
21
|
+
router.put(`/:id`, authMiddleware, userGuard, async (req, res) => await CyberiaMapController.put(req, res, options));
|
|
22
|
+
router.put(`/`, authMiddleware, userGuard, async (req, res) => await CyberiaMapController.put(req, res, options));
|
|
23
|
+
router.delete(
|
|
24
|
+
`/:id`,
|
|
25
|
+
authMiddleware,
|
|
26
|
+
userGuard,
|
|
27
|
+
async (req, res) => await CyberiaMapController.delete(req, res, options),
|
|
28
|
+
);
|
|
29
|
+
router.delete(
|
|
30
|
+
`/`,
|
|
31
|
+
authMiddleware,
|
|
32
|
+
adminGuard,
|
|
33
|
+
async (req, res) => await CyberiaMapController.delete(req, res, options),
|
|
34
|
+
);
|
|
35
|
+
return router;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const ApiRouter = CyberiaMapRouter;
|
|
39
|
+
|
|
40
|
+
export { ApiRouter, CyberiaMapRouter };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { DataBaseProvider } from '../../db/DataBaseProvider.js';
|
|
2
|
+
import { loggerFactory } from '../../server/logger.js';
|
|
3
|
+
import { DataQuery } from '../../server/data-query.js';
|
|
4
|
+
|
|
5
|
+
const logger = loggerFactory(import.meta);
|
|
6
|
+
|
|
7
|
+
const CyberiaMapService = {
|
|
8
|
+
post: async (req, res, options) => {
|
|
9
|
+
/** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
|
|
10
|
+
const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
|
|
11
|
+
if (req.auth && req.auth.user) req.body.creator = req.auth.user._id;
|
|
12
|
+
return await new CyberiaMap(req.body).save();
|
|
13
|
+
},
|
|
14
|
+
get: async (req, res, options) => {
|
|
15
|
+
/** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
|
|
16
|
+
const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
|
|
17
|
+
const populateCreator = { path: 'creator', model: 'User', select: '_id username' };
|
|
18
|
+
|
|
19
|
+
// GET /search-codes?q=<partial> - Fast partial match search on code
|
|
20
|
+
if (req.path?.startsWith('/search-codes')) {
|
|
21
|
+
const q = (req.query.q || '').trim();
|
|
22
|
+
if (!q) return { codes: [] };
|
|
23
|
+
const escaped = q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
24
|
+
const results = await CyberiaMap.find({ code: { $regex: escaped, $options: 'i' } }, { code: 1, _id: 0 })
|
|
25
|
+
.limit(20)
|
|
26
|
+
.lean();
|
|
27
|
+
const codes = [...new Set(results.map((r) => r.code).filter(Boolean))];
|
|
28
|
+
return { codes };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (req.params.id) return await CyberiaMap.findById(req.params.id).populate(populateCreator);
|
|
32
|
+
|
|
33
|
+
// Parse query parameters using DataQuery helper
|
|
34
|
+
const { query, sort, skip, limit, page } = DataQuery.parse(req.query);
|
|
35
|
+
|
|
36
|
+
const [data, total] = await Promise.all([
|
|
37
|
+
CyberiaMap.find(query).sort(sort).limit(limit).skip(skip).populate(populateCreator),
|
|
38
|
+
CyberiaMap.countDocuments(query),
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
const totalPages = Math.ceil(total / limit);
|
|
42
|
+
return { data, total, page, totalPages };
|
|
43
|
+
},
|
|
44
|
+
put: async (req, res, options) => {
|
|
45
|
+
/** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
|
|
46
|
+
const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
|
|
47
|
+
const map = await CyberiaMap.findById(req.params.id);
|
|
48
|
+
if (!map) throw new Error('map not found');
|
|
49
|
+
if (req.auth.user.role !== 'admin' && String(map.creator) !== String(req.auth.user._id))
|
|
50
|
+
throw new Error('insufficient permission');
|
|
51
|
+
if (req.body.thumbnail && map.thumbnail && String(req.body.thumbnail) !== String(map.thumbnail)) {
|
|
52
|
+
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
|
|
53
|
+
await File.findByIdAndDelete(map.thumbnail);
|
|
54
|
+
}
|
|
55
|
+
return await CyberiaMap.findByIdAndUpdate(req.params.id, req.body, { returnDocument: 'after' });
|
|
56
|
+
},
|
|
57
|
+
delete: async (req, res, options) => {
|
|
58
|
+
/** @type {import('./cyberia-map.model.js').CyberiaMapModel} */
|
|
59
|
+
const CyberiaMap = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.CyberiaMap;
|
|
60
|
+
if (req.params.id) {
|
|
61
|
+
const map = await CyberiaMap.findById(req.params.id);
|
|
62
|
+
if (!map) throw new Error('map not found');
|
|
63
|
+
if (req.auth.user.role !== 'admin' && String(map.creator) !== String(req.auth.user._id))
|
|
64
|
+
throw new Error('insufficient permission');
|
|
65
|
+
if (map.thumbnail) {
|
|
66
|
+
const File = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.File;
|
|
67
|
+
await File.findByIdAndDelete(map.thumbnail);
|
|
68
|
+
}
|
|
69
|
+
return await CyberiaMap.findByIdAndDelete(req.params.id);
|
|
70
|
+
} else return await CyberiaMap.deleteMany();
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export { CyberiaMapService };
|
|
@@ -497,7 +497,7 @@ const DocumentService = {
|
|
|
497
497
|
req.body.isPublic = isPublic;
|
|
498
498
|
req.body.tags = tags;
|
|
499
499
|
|
|
500
|
-
return await Document.findByIdAndUpdate(req.params.id, req.body, {
|
|
500
|
+
return await Document.findByIdAndUpdate(req.params.id, req.body, { returnDocument: 'after' });
|
|
501
501
|
}
|
|
502
502
|
}
|
|
503
503
|
},
|
|
@@ -19,7 +19,9 @@ const FileController = {
|
|
|
19
19
|
},
|
|
20
20
|
get: async (req, res, options) => {
|
|
21
21
|
try {
|
|
22
|
-
|
|
22
|
+
if (req && req.headers && req.headers.origin) {
|
|
23
|
+
res.set('Access-Control-Allow-Origin', req.headers.origin);
|
|
24
|
+
} else res.setHeader('Access-Control-Allow-Origin', '*');
|
|
23
25
|
res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
|
|
24
26
|
const result = await FileService.get(req, res, options);
|
|
25
27
|
if (result instanceof Buffer) {
|
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"api": "atlas-sprite-sheet",
|
|
4
|
+
"model": {
|
|
5
|
+
"fileId": true
|
|
6
|
+
}
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"api": "company",
|
|
4
10
|
"model": {
|
|
5
11
|
"logo": true
|
|
6
12
|
}
|
|
7
13
|
},
|
|
14
|
+
{
|
|
15
|
+
"api": "cyberia-instance",
|
|
16
|
+
"model": {
|
|
17
|
+
"thumbnail": true
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"api": "cyberia-map",
|
|
22
|
+
"model": {
|
|
23
|
+
"thumbnail": true
|
|
24
|
+
}
|
|
25
|
+
},
|
|
8
26
|
{
|
|
9
27
|
"api": "document",
|
|
10
28
|
"model": {
|
|
@@ -387,12 +387,35 @@ const FileService = {
|
|
|
387
387
|
if (doc.isPublic) return true;
|
|
388
388
|
|
|
389
389
|
// Otherwise, user must be authenticated and own the document
|
|
390
|
+
// Try bearer token first
|
|
390
391
|
const token = getBearerToken(req);
|
|
391
|
-
if (
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
392
|
+
if (token) {
|
|
393
|
+
try {
|
|
394
|
+
const payload = jwtVerify(token, options);
|
|
395
|
+
const user = await User.findOne({ _id: payload._id }).lean();
|
|
396
|
+
if (user && String(doc.userId) === String(user._id)) return true;
|
|
397
|
+
} catch (bearerErr) {
|
|
398
|
+
logger.warn('Bearer token verification failed, trying cookie session fallback:', bearerErr.message);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Fallback: check cookie-based session (refreshToken cookie)
|
|
403
|
+
const refreshToken = req.cookies?.refreshToken;
|
|
404
|
+
if (refreshToken) {
|
|
405
|
+
try {
|
|
406
|
+
const user = await User.findOne({ 'activeSessions.tokenHash': refreshToken }).lean();
|
|
407
|
+
if (user) {
|
|
408
|
+
const session = user.activeSessions.find((s) => s.tokenHash === refreshToken);
|
|
409
|
+
if (session && (!session.expiresAt || session.expiresAt >= new Date())) {
|
|
410
|
+
return String(doc.userId) === String(user._id);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
} catch (cookieErr) {
|
|
414
|
+
logger.warn('Cookie session verification failed:', cookieErr.message);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return false;
|
|
396
419
|
} catch (err) {
|
|
397
420
|
console.log(err);
|
|
398
421
|
logger.error('Authorization check failed:', err);
|
|
@@ -69,34 +69,13 @@ const IpfsController = {
|
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
|
-
|
|
72
|
+
verify: async (req, res, options) => {
|
|
73
73
|
try {
|
|
74
|
-
const result = await IpfsService.
|
|
75
|
-
return res.status(200).json({
|
|
76
|
-
status: 'success',
|
|
77
|
-
data: result,
|
|
78
|
-
});
|
|
74
|
+
const result = await IpfsService.verify(req, res, options);
|
|
75
|
+
return res.status(200).json({ status: 'success', data: result });
|
|
79
76
|
} catch (error) {
|
|
80
77
|
logger.error(error, error.stack);
|
|
81
|
-
return res.status(400).json({
|
|
82
|
-
status: 'error',
|
|
83
|
-
message: error.message,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
unpin: async (req, res, options) => {
|
|
88
|
-
try {
|
|
89
|
-
const result = await IpfsService.unpin(req, res, options);
|
|
90
|
-
return res.status(200).json({
|
|
91
|
-
status: 'success',
|
|
92
|
-
data: result,
|
|
93
|
-
});
|
|
94
|
-
} catch (error) {
|
|
95
|
-
logger.error(error, error.stack);
|
|
96
|
-
return res.status(400).json({
|
|
97
|
-
status: 'error',
|
|
98
|
-
message: error.message,
|
|
99
|
-
});
|
|
78
|
+
return res.status(400).json({ status: 'error', message: error.message });
|
|
100
79
|
}
|
|
101
80
|
},
|
|
102
81
|
};
|