├── .dockerignore
├── .github
├── CODEOWNERS
├── dependabot.yml
└── workflows
│ ├── test.yml
│ └── validate.yml
├── .gitignore
├── LICENSE
├── README.md
├── build.cjs
├── demo
└── index.html
├── dev.Dockerfile
├── dist
├── uasset-reader.js
└── uasset-reader.min.js
├── docker-bake.hcl
├── eslint.config.js
├── jsdoc.conf.json
├── package-lock.json
├── package.json
├── src
└── js
│ ├── _namespace_.js
│ ├── enums
│ └── enums.js
│ └── main.js
└── tests
├── datacases.json
├── main.test.js
└── uassets
└── ue50
├── BP_Actor_Simple.json
├── BP_Actor_Simple.uasset
└── BP_Actor_Simple.utxt
/.dockerignore:
--------------------------------------------------------------------------------
1 | /coverage
2 | /node_modules
3 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @rancoud
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "npm"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 | time: "08:00"
8 | timezone: "Europe/Paris"
9 | - package-ecosystem: "github-actions"
10 | directory: "/"
11 | schedule:
12 | interval: "daily"
13 | time: "08:00"
14 | timezone: "Europe/Paris"
15 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: test
2 |
3 | permissions:
4 | contents: read
5 |
6 | concurrency:
7 | group: ${{ github.workflow }}-${{ github.ref }}
8 | cancel-in-progress: true
9 |
10 | on:
11 | push:
12 | branches:
13 | - 'main'
14 | pull_request:
15 |
16 | jobs:
17 | test:
18 | runs-on: ubuntu-latest
19 | steps:
20 | -
21 | name: Checkout
22 | uses: actions/checkout@v4
23 | -
24 | name: Test
25 | uses: docker/bake-action@v6
26 | with:
27 | source: .
28 | targets: test
29 | -
30 | name: Upload coverage
31 | uses: codecov/codecov-action@v5
32 | with:
33 | files: ./coverage/lcov.info
34 | token: ${{ secrets.CODECOV_TOKEN }}
35 |
--------------------------------------------------------------------------------
/.github/workflows/validate.yml:
--------------------------------------------------------------------------------
1 | name: validate
2 |
3 | permissions:
4 | contents: read
5 |
6 | concurrency:
7 | group: ${{ github.workflow }}-${{ github.ref }}
8 | cancel-in-progress: true
9 |
10 | on:
11 | push:
12 | branches:
13 | - 'main'
14 | pull_request:
15 |
16 | jobs:
17 | prepare:
18 | runs-on: ubuntu-latest
19 | outputs:
20 | targets: ${{ steps.targets.outputs.matrix }}
21 | steps:
22 | -
23 | name: Checkout
24 | uses: actions/checkout@v4
25 | -
26 | name: Targets matrix
27 | id: targets
28 | run: |
29 | echo "matrix=$(docker buildx bake validate --print | jq -cr '.group.validate.targets')" >> $GITHUB_OUTPUT
30 |
31 | validate:
32 | runs-on: ubuntu-latest
33 | needs:
34 | - prepare
35 | strategy:
36 | fail-fast: false
37 | matrix:
38 | target: ${{ fromJson(needs.prepare.outputs.targets) }}
39 | steps:
40 | -
41 | name: Checkout
42 | uses: actions/checkout@v4
43 | -
44 | name: Validate
45 | uses: docker/bake-action@v6
46 | with:
47 | source: .
48 | targets: ${{ matrix.target }}
49 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # IntelliJ
2 | .idea
3 | *.iml
4 |
5 | # Node modules
6 | node_modules
7 |
8 | # System files
9 | .DS_Store
10 |
11 | # Jest
12 | coverage
13 |
14 | # JSDoc
15 | jsdoc
16 |
17 | # eslint
18 | eslint_out.html
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 blueprintUE
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Uasset Reader JS
2 | Read and extract informations of `.uasset` files from Unreal Engine in javascript.
3 | [Here a Live Demo.](https://blueprintue.com/tools/uasset-reader.html)
4 |
5 | ## How to use
6 | First you need to import `uasset-reader.min.js` in your page.
7 | ```js
8 | const file = document.getElementById("file-input").files[0];
9 | const buffer = await file.arrayBuffer();
10 | const bytes = new Uint8Array(buffer);
11 | new window.blueprintUE.uasset.ReaderUasset().analyze(bytes);
12 | ```
13 |
14 | ### Main Methods
15 | #### analyze([bytes: Uint8Array]): Uasset
16 | This method read each byte to extract data from current `.uasset` file.
17 |
18 | ## How to Dev
19 | `npm test` or `docker buildx bake test` to test and coverage
20 | `npm run build` or `docker buildx bake build` to create dist js file minified
21 | `npm run jsdoc` or `docker buildx bake jsdoc` to generate documentation
22 | `npm run eslint` or `docker buildx bake lint` to run eslint
23 | `npm run eslint:fix` to run eslint and fix files
24 |
--------------------------------------------------------------------------------
/build.cjs:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const path = require("path");
3 | const babel = require("@babel/core");
4 |
5 | // region JS
6 |
7 | function generateJS() {
8 | // list of JS files to concat
9 | const inputJSFiles = [
10 | path.join(__dirname, 'src/js/_namespace_.js'),
11 | path.join(__dirname, 'src/js/enums/enums.js'),
12 | path.join(__dirname, 'src/js/main.js')
13 | ];
14 |
15 | // output JS file
16 | const outputJSFilename = "dist/uasset-reader.js";
17 |
18 | let outputJSFileContent = concatJSFiles(inputJSFiles);
19 | outputJSFileContent = removeLines(outputJSFileContent);
20 | outputJSFileContent = removeDebug(outputJSFileContent);
21 | outputJSFileContent = addHeaderAndLicense(outputJSFileContent);
22 | saveFile(outputJSFilename, outputJSFileContent);
23 | }
24 |
25 | function concatJSFiles(files) {
26 | let outputFileContent = ["(function () {"];
27 | outputFileContent.push('"use strict";' + "\n");
28 |
29 | for(let idxFiles = 0, maxFiles = files.length; idxFiles < maxFiles; ++idxFiles) {
30 | outputFileContent.push(fs.readFileSync(files[idxFiles]).toString("utf8"));
31 | }
32 |
33 | outputFileContent.push("})();");
34 |
35 | return outputFileContent.join("\n");
36 | }
37 |
38 | function removeLines(content) {
39 | const lines = content.split(/\r\n|\r|\n/g);
40 | let idxLines = 0;
41 | let maxLines = lines.length;
42 | let newLines = [];
43 |
44 | for (; idxLines < maxLines; ++idxLines) {
45 | if (lines[idxLines].match("BUILD REMOVE LINE")) {
46 | continue;
47 | }
48 |
49 | newLines.push(lines[idxLines]);
50 | }
51 |
52 | return newLines.join("\n");
53 | }
54 |
55 | function removeDebug(content) {
56 | function getNode(node) {
57 | if (node.isMemberExpression()) {
58 | const object = node.get("object");
59 | if (object.isIdentifier() && node.has("property")) {
60 | return node.get("property");
61 | }
62 | }
63 |
64 | return node;
65 | }
66 |
67 | function isConsole(nodePath) {
68 | const callee = nodePath.get("callee");
69 |
70 | if (!callee.isMemberExpression()) {
71 | return;
72 | }
73 |
74 | return getNode(callee.get("object")).isIdentifier({name: "console"}) && callee.has("property");
75 | }
76 |
77 | function isAlert(nodePath) {
78 | return getNode(nodePath.get("callee")).isIdentifier({name: "alert"});
79 | }
80 |
81 | return babel.transformSync(content, {
82 | retainLines: true,
83 | plugins:[{
84 | visitor: {
85 | DebuggerStatement(nodePath) {
86 | nodePath.remove();
87 | },
88 | CallExpression(nodePath) {
89 | if (isConsole(nodePath) || isAlert(nodePath)) {
90 | nodePath.remove();
91 | }
92 | }
93 | },
94 | }]
95 | }).code;
96 | }
97 |
98 | generateJS();
99 |
100 | // endregion
101 |
102 | function addHeaderAndLicense(content) {
103 | const license = fs.readFileSync("./LICENSE", "utf8");
104 | const pkg = require("./package.json");
105 |
106 | let header = pkg.name + " (v" + pkg.version + ")\n" + pkg.homepage + "\n\n" + license;
107 |
108 | const lines = header.split("\n");
109 | for (let idx = 0, max = lines.length; idx < max; ++idx) {
110 | if (idx + 1 !== max) {
111 | lines[idx] = " * " + lines[idx];
112 | } else {
113 | lines[idx] = " */" + lines[idx];
114 | }
115 | }
116 |
117 | return "/**\n" + lines.join("\n") + "\n" + content;
118 | }
119 |
120 | function saveFile(filename, content) {
121 | fs.writeFileSync(filename, content);
122 | }
123 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Read .uasset dev file from Unreal Engine 5 in javascript
6 |
197 |
198 |
199 | .uasset reader dev file from Unreal Engine 5
200 |
201 |
Drop your .uasset dev file from Unreal Engine 5 here or click on the input file below.
202 |
203 |
204 |
205 | ERROR:
206 |
207 | LOADING
208 |
209 |
210 |
Legend
211 |
212 |
00 uint16
213 |
00 int16
214 |
00 uint32
215 |
00 int32
216 |
00 int64
217 |
00 uint64
218 |
00 fguidSlot
219 |
00 fguidString
220 |
00 fstring
221 |
00 data
222 |
223 |
224 |
225 |
226 |
227 |
.uasset hex values
228 |
229 |
230 |
231 |
.uasset explorer
232 |
233 |
.uasset resources
234 |
235 |
236 |
237 |
238 |
239 |
545 |
546 |
--------------------------------------------------------------------------------
/dev.Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1
2 |
3 | FROM node:alpine AS base
4 | RUN apk add --no-cache cpio findutils git
5 | WORKDIR /src
6 |
7 | FROM base AS deps
8 | RUN --mount=type=bind,target=.,rw \
9 | --mount=type=cache,target=/src/node_modules \
10 | npm install && mkdir /vendor && cp package-lock.json /vendor
11 |
12 | FROM scratch AS vendor-update
13 | COPY --from=deps /vendor /
14 |
15 | FROM deps AS vendor-validate
16 | RUN --mount=type=bind,target=.,rw <&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor-update"'
22 | git status --porcelain -- package-lock.json
23 | exit 1
24 | fi
25 | EOT
26 |
27 | FROM deps AS build
28 | RUN --mount=type=bind,target=.,rw \
29 | --mount=type=cache,target=/src/node_modules \
30 | npm run build && mkdir /out && cp -Rf dist /out/
31 |
32 | FROM scratch AS build-update
33 | COPY --from=build /out /
34 |
35 | FROM build AS build-validate
36 | RUN --mount=type=bind,target=.,rw <&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
42 | git status --porcelain -- dist
43 | exit 1
44 | fi
45 | EOT
46 |
47 | FROM deps AS format
48 | RUN --mount=type=bind,target=.,rw \
49 | --mount=type=cache,target=/src/node_modules \
50 | npm run eslint:fix \
51 | && mkdir /out && find . -name '*.js' -not -path './node_modules/*' | cpio -pdm /out
52 |
53 | FROM scratch AS format-update
54 | COPY --from=format /out /
55 |
56 | FROM deps AS lint
57 | RUN --mount=type=bind,target=.,rw \
58 | --mount=type=cache,target=/src/node_modules \
59 | npm run eslint
60 |
61 | FROM deps AS test
62 | RUN --mount=type=bind,target=.,rw \
63 | --mount=type=cache,target=/src/node_modules \
64 | npm test && cp -r ./coverage /tmp
65 |
66 | FROM scratch AS test-coverage
67 | COPY --from=test /tmp/coverage /
68 |
69 | FROM deps AS jsdoc
70 | RUN --mount=type=bind,target=.,rw \
71 | --mount=type=cache,target=/src/node_modules \
72 | npm run jsdoc && cp -r ./jsdoc /tmp
73 |
74 | FROM scratch AS jsdoc-update
75 | COPY --from=jsdoc /tmp/jsdoc /
76 |
--------------------------------------------------------------------------------
/dist/uasset-reader.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * uasset-reader-js (v1.1.2)
3 | * https://github.com/blueprintue/uasset-reader-js
4 | *
5 | * MIT License
6 | *
7 | * Copyright (c) 2023 blueprintUE
8 | *
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy
10 | * of this software and associated documentation files (the "Software"), to deal
11 | * in the Software without restriction, including without limitation the rights
12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | * copies of the Software, and to permit persons to whom the Software is
14 | * furnished to do so, subject to the following conditions:
15 | *
16 | * The above copyright notice and this permission notice shall be included in all
17 | * copies or substantial portions of the Software.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | * SOFTWARE.
26 | */
27 | !function(){"use strict";function e(){this.currentIdx=0,this.bytes=[],this.uasset={hexView:[],header:{},names:[],gatherableTextData:[],imports:{},exports:[],depends:{},softPackageReferences:{},searchableNames:{},thumbnails:{Index:[],Thumbnails:[]},assetRegistryData:{},preloadDependency:{},bulkDataStart:{}}}void 0===window.blueprintUE&&(window.blueprintUE={}),void 0===window.blueprintUE.uasset&&(window.blueprintUE.uasset={}),e.prototype.uint16=function(e){var t=this.readCountBytes(2),t=new DataView(new Uint8Array(t).buffer).getUint16(0,this.useLittleEndian);return this.addHexView(e,"uint16",t,this.currentIdx-2,this.currentIdx-1),t},e.prototype.int32=function(e){var t=this.readCountBytes(4),t=new DataView(new Uint8Array(t).buffer).getInt32(0,this.useLittleEndian);return this.addHexView(e,"int32",t,this.currentIdx-4,this.currentIdx-1),t},e.prototype.uint32=function(e){var t=this.readCountBytes(4),t=new DataView(new Uint8Array(t).buffer).getUint32(0,this.useLittleEndian);return this.addHexView(e,"uint32",t,this.currentIdx-4,this.currentIdx-1),t},e.prototype.int64=function(e){var t=this.readCountBytes(8),t=new DataView(new Uint8Array(t).buffer).getBigInt64(0,this.useLittleEndian);return this.addHexView(e,"int64",t,this.currentIdx-8,this.currentIdx-1),t},e.prototype.uint64=function(e){var t=this.readCountBytes(8),t=new DataView(new Uint8Array(t).buffer).getBigUint64(0,this.useLittleEndian);return this.addHexView(e,"uint64",t,this.currentIdx-8,this.currentIdx-1),t},e.prototype.fguidSlot=function(e){for(var t,s="",a="",i="",r="",n=3,h=this.readCountBytes(16);0<=n;--n)s+=h[n].toString(16).padStart(2,"0"),a+=h[n+4].toString(16).padStart(2,"0"),i+=h[n+8].toString(16).padStart(2,"0"),r+=h[n+12].toString(16).padStart(2,"0");return t=(s+a+i+r).toUpperCase(),this.addHexView(e,"fguidSlot",t,this.currentIdx-16,this.currentIdx-1),t},e.prototype.fguidString=function(e){for(var t,s="",a=0,i=this.readCountBytes(16);a<16;++a)s+=i[a].toString(16).padStart(2,"0");return t=s.toUpperCase(),this.addHexView(e,"fguidString",t,this.currentIdx-16,this.currentIdx-1),t},e.prototype.fstring=function(e){var t,s,a,i,r,n,h="",o=0,u=[],d=this.int32(e+" (fstring length)");if(0===d)return"";if(n=this.currentIdx,0>"], "int32Hint": true}],
65 | "no-caller": "error",
66 | "no-case-declarations": "error",
67 | "no-class-assign": "error",
68 | "no-compare-neg-zero": "error",
69 | "no-cond-assign": ["error", "always"],
70 | "no-console": "error",
71 | "no-const-assign": "error",
72 | "no-constant-binary-expression": "error",
73 | "no-constant-condition": ["error", {"checkLoops": "all"}],
74 | "no-constructor-return": "error",
75 | "no-continue": "off",
76 | "no-control-regex": "error",
77 | "no-debugger": "error",
78 | "no-delete-var": "error",
79 | "no-div-regex": "error",
80 | "no-dupe-args": "error",
81 | "no-dupe-class-members": "error",
82 | "no-dupe-else-if": "error",
83 | "no-dupe-keys": "error",
84 | "no-duplicate-case": "error",
85 | "no-duplicate-imports": "error",
86 | "no-else-return": "error",
87 | "no-empty": "error",
88 | "no-empty-character-class": "error",
89 | "no-empty-function": "error",
90 | "no-empty-pattern": "error",
91 | "no-empty-static-block": "error",
92 | "no-eq-null": "error",
93 | "no-eval": "error",
94 | "no-ex-assign": "error",
95 | "no-extend-native": "error",
96 | "no-extra-bind": "error",
97 | "no-extra-boolean-cast": ["error", {"enforceForLogicalOperands": true}],
98 | "no-extra-label": "error",
99 | "no-fallthrough": "error",
100 | "no-func-assign": "error",
101 | "no-global-assign": "error",
102 | "no-implicit-coercion": "error",
103 | "no-implicit-globals": "off",
104 | "no-implied-eval": "error",
105 | "no-import-assign": "error",
106 | "no-inline-comments": ["error", {"ignorePattern": "BUILD REMOVE LINE"}],
107 | "no-inner-declarations": ["error", "functions", {"blockScopedFunctions": "disallow"}],
108 | "no-invalid-regexp": "error",
109 | "no-invalid-this": "error",
110 | "no-irregular-whitespace": "error",
111 | "no-iterator": "error",
112 | "no-label-var": "error",
113 | "no-labels": "error",
114 | "no-lone-blocks": "error",
115 | "no-lonely-if": "error",
116 | "no-loop-func": "error",
117 | "no-loss-of-precision": "error",
118 | "no-magic-numbers": ["error", {"ignore": [0, 1, -1, 2, 4, 8, 12, 16], "ignoreArrayIndexes": true, "ignoreDefaultValues": true}],
119 | "no-misleading-character-class": "error",
120 | "no-multi-assign": "error",
121 | "no-multi-str": "error",
122 | "no-negated-condition": "error",
123 | "no-nested-ternary": "error",
124 | "no-new": "error",
125 | "no-new-func": "error",
126 | "no-new-native-nonconstructor": "error",
127 | "no-new-wrappers": "error",
128 | "no-nonoctal-decimal-escape": "error",
129 | "no-obj-calls": "error",
130 | "no-object-constructor": "error",
131 | "no-octal": "error",
132 | "no-octal-escape": "error",
133 | "no-param-reassign": "error",
134 | "no-plusplus": ["error", {"allowForLoopAfterthoughts": true}],
135 | "no-promise-executor-return": "error",
136 | "no-proto": "error",
137 | "no-prototype-builtins": "error",
138 | "no-redeclare": "error",
139 | "no-regex-spaces": "error",
140 | "no-restricted-exports": "error",
141 | "no-restricted-globals": "error",
142 | "no-restricted-imports": "error",
143 | "no-restricted-properties": "error",
144 | "no-restricted-syntax": "error",
145 | "no-return-assign": "error",
146 | "no-script-url": "error",
147 | "no-self-assign": "error",
148 | "no-self-compare": "error",
149 | "no-sequences": "error",
150 | "no-setter-return": "error",
151 | "no-shadow": "error",
152 | "no-shadow-restricted-names": "error",
153 | "no-sparse-arrays": "error",
154 | "no-template-curly-in-string": "error",
155 | "no-ternary": "error",
156 | "no-this-before-super": "error",
157 | "no-throw-literal": "error",
158 | "no-undef": "error",
159 | "no-undef-init": "error",
160 | "no-undefined": "off",
161 | "no-underscore-dangle": "error",
162 | "no-unexpected-multiline": "error",
163 | "no-unmodified-loop-condition": "error",
164 | "no-unneeded-ternary": "error",
165 | "no-unreachable": "error",
166 | "no-unreachable-loop": "error",
167 | "no-unsafe-finally": "error",
168 | "no-unsafe-negation": "error",
169 | "no-unsafe-optional-chaining": "error",
170 | "no-unused-expressions": "error",
171 | "no-unused-labels": "error",
172 | "no-unused-private-class-members": "error",
173 | "no-unused-vars": "error",
174 | "no-use-before-define": ["error", {"functions": false, "classes": true, "variables": true}],
175 | "no-useless-assignment": "error",
176 | "no-useless-backreference": "error",
177 | "no-useless-call": "error",
178 | "no-useless-catch": "error",
179 | "no-useless-computed-key": "error",
180 | "no-useless-concat": "error",
181 | "no-useless-constructor": "error",
182 | "no-useless-escape": "error",
183 | "no-useless-rename": "error",
184 | "no-useless-return": "error",
185 | "no-var": "off",
186 | "no-void": "error",
187 | "no-warning-comments": "error",
188 | "no-with": "error",
189 | "object-shorthand": ["error", "never"],
190 | "one-var": ["error", "never"],
191 | "operator-assignment": ["error", "never"],
192 | "prefer-arrow-callback": "off",
193 | "prefer-const": "off",
194 | "prefer-destructuring": "off",
195 | "prefer-exponentiation-operator": "off",
196 | "prefer-named-capture-group": "off",
197 | "prefer-numeric-literals": "error",
198 | "prefer-object-has-own": "off",
199 | "prefer-object-spread": "off",
200 | "prefer-promise-reject-errors": "off",
201 | "prefer-regex-literals": "error",
202 | "prefer-rest-params": "off",
203 | "prefer-spread": "off",
204 | "prefer-template": "off",
205 | "radix": ["error", "always"],
206 | "require-atomic-updates": "error",
207 | "require-await": "error",
208 | "require-unicode-regexp": "off",
209 | "require-yield": "error",
210 | "sort-imports": "error",
211 | "sort-keys": ["off"],
212 | "sort-vars": ["off"],
213 | "strict": "off",
214 | "symbol-description": "off",
215 | "unicode-bom": ["error", "never"],
216 | "use-isnan": "error",
217 | "valid-typeof": "error",
218 | "vars-on-top": "error",
219 | "yoda": "error",
220 | // eslint-stylistic:all
221 | "stylistic/array-bracket-newline": ["error", "consistent"],
222 | "stylistic/array-bracket-spacing": ["error", "never"],
223 | "stylistic/array-element-newline": ["error", "consistent"],
224 | "stylistic/arrow-parens": ["error", "always"],
225 | "stylistic/arrow-spacing": ["error", {"before": true, "after": true}],
226 | "stylistic/block-spacing": ["error", "always"],
227 | "stylistic/brace-style": ["error", "1tbs", {"allowSingleLine": false}],
228 | "stylistic/comma-dangle": ["error", "never"],
229 | "stylistic/comma-spacing": ["error", {"before": false, "after": true}],
230 | "stylistic/comma-style": ["error", "last"],
231 | "stylistic/computed-property-spacing": ["error", "never"],
232 | "stylistic/dot-location": ["error", "object"],
233 | "stylistic/eol-last": ["error", "always"],
234 | "stylistic/function-call-argument-newline": ["error", "consistent"],
235 | "stylistic/function-call-spacing": ["error", "never"],
236 | "stylistic/function-paren-newline": ["error", "consistent"],
237 | "stylistic/generator-star-spacing": ["error",
238 | {
239 | "before": false,
240 | "after": true,
241 | "anonymous": {"before": false, "after": true},
242 | "method": {"before": true, "after": false}
243 | }
244 | ],
245 | "stylistic/implicit-arrow-linebreak": ["error", "beside"],
246 | "stylistic/indent": ["error", 4],
247 | "stylistic/indent-binary-ops": ["error", 4],
248 | "stylistic/key-spacing": ["error",
249 | {
250 | "beforeColon": false,
251 | "afterColon": true,
252 | "mode": "minimum",
253 | align: {
254 | "beforeColon": false,
255 | "afterColon": true,
256 | "on": "colon",
257 | "mode": "minimum"
258 | }
259 | }
260 | ],
261 | "stylistic/keyword-spacing": ["error", {"before": true, "after": true}],
262 | "stylistic/line-comment-position": ["error", {"position": "above", "ignorePattern": "BUILD REMOVE LINE"}],
263 | "stylistic/linebreak-style": ["error", "unix"],
264 | "stylistic/lines-around-comment": ["error",
265 | {
266 | "beforeBlockComment": true,
267 | "afterBlockComment": false,
268 | "beforeLineComment": true,
269 | "afterLineComment": false,
270 | "allowBlockStart": true,
271 | "allowBlockEnd": false,
272 | "allowClassStart": true,
273 | "allowClassEnd": false,
274 | "allowObjectStart": true,
275 | "allowObjectEnd": false,
276 | "allowArrayStart": true,
277 | "allowArrayEnd": false,
278 | "ignorePattern": "region|endregion|type"
279 | }
280 | ],
281 | "stylistic/lines-between-class-members": ["error", "always"],
282 | "stylistic/max-len": ["error",
283 | {
284 | "code": 180,
285 | "comments": 180,
286 | "ignorePattern": "global",
287 | "ignoreRegExpLiterals": true,
288 | "ignoreStrings": true,
289 | "ignoreTemplateLiterals": true,
290 | "ignoreTrailingComments": true,
291 | "ignoreUrls": true
292 | }
293 | ],
294 | "stylistic/max-statements-per-line": ["error", {"max": 1}],
295 | "stylistic/member-delimiter-style": ["error",
296 | {
297 | "multiline": {
298 | "delimiter": "comma",
299 | "requireLast": false
300 | },
301 | "singleline": {
302 | "delimiter": "comma",
303 | "requireLast": false
304 | },
305 | }
306 | ],
307 | "stylistic/multiline-comment-style": ["error", "starred-block"],
308 | "stylistic/multiline-ternary": ["error", "always-multiline"],
309 | "stylistic/new-parens": ["error", "always"],
310 | "stylistic/newline-per-chained-call": ["error", {"ignoreChainWithDepth": 5}],
311 | "stylistic/no-confusing-arrow": ["error", {"allowParens": false, "onlyOneSimpleParam": false}],
312 | "stylistic/no-extra-parens": "off",
313 | "stylistic/no-extra-semi": "error",
314 | "stylistic/no-floating-decimal": "error",
315 | "stylistic/no-mixed-operators": ["error", {"allowSamePrecedence": false}],
316 | "stylistic/no-mixed-spaces-and-tabs": "error",
317 | "stylistic/no-multi-spaces": ["error", {"ignoreEOLComments": false, "exceptions": {"Property": true}}],
318 | "stylistic/no-multiple-empty-lines": ["error", {"max": 1, "maxBOF": 0, "maxEOF": 1}],
319 | "stylistic/no-tabs": ["error", {"allowIndentationTabs": false}],
320 | "stylistic/no-trailing-spaces": ["error", {"ignoreComments": false, "skipBlankLines": false}],
321 | "stylistic/no-whitespace-before-property": "error",
322 | "stylistic/nonblock-statement-body-position": ["error", "below"],
323 | "stylistic/object-curly-newline": ["error", {"consistent": true}],
324 | "stylistic/object-curly-spacing": ["error", "never"],
325 | "stylistic/object-property-newline": ["error", {"allowAllPropertiesOnSameLine": true}],
326 | "stylistic/one-var-declaration-per-line": ["error", "always"],
327 | "stylistic/operator-linebreak": ["error", "after"],
328 | "stylistic/padded-blocks": ["error", "never"],
329 | "stylistic/padding-line-between-statements": ["error"],
330 | "stylistic/quote-props": ["error", "consistent-as-needed", {"keywords": true, "numbers": true}],
331 | "stylistic/quotes": ["error", "double"],
332 | "stylistic/rest-spread-spacing": ["error", "never"],
333 | "stylistic/semi": ["error", "always"],
334 | "stylistic/semi-spacing": ["error", {"before": false, "after": true}],
335 | "stylistic/semi-style": ["error", "last"],
336 | "stylistic/space-before-blocks": ["error"],
337 | "stylistic/space-before-function-paren": ["error", "never"],
338 | "stylistic/space-in-parens": ["error", "never"],
339 | "stylistic/space-infix-ops": ["error", {"int32Hint": false}],
340 | "stylistic/space-unary-ops": ["error"],
341 | "stylistic/spaced-comment": ["error", "always"],
342 | "stylistic/switch-colon-spacing": ["error", {"after": true, "before": false}],
343 | "stylistic/template-curly-spacing": ["error", "never"],
344 | "stylistic/template-tag-spacing": ["error", "never"],
345 | "stylistic/wrap-iife": ["error", "outside"],
346 | "stylistic/wrap-regex": "error",
347 | "stylistic/yield-star-spacing": ["error", {"before": false, "after": true}],
348 | // jsdoc:all
349 | "jsdoc/check-access": "error",
350 | "jsdoc/check-alignment": "error",
351 | "jsdoc/check-examples": "off",
352 | "jsdoc/check-indentation": "off",
353 | "jsdoc/check-line-alignment": ["error", "always", {"tags": ["param", "property"]}],
354 | "jsdoc/check-param-names": ["error", {"enableFixer": true, "checkDestructured": true, "useDefaultObjectProperties": true, "disableExtraPropertyReporting": true}],
355 | "jsdoc/check-property-names": ["error", {"enableFixer": true}],
356 | "jsdoc/check-syntax": "error",
357 | "jsdoc/check-tag-names": "error",
358 | "jsdoc/check-types": "error",
359 | "jsdoc/check-values": ["error"],
360 | "jsdoc/empty-tags": "error",
361 | "jsdoc/implements-on-classes": "error",
362 | "jsdoc/imports-as-dependencies": "error",
363 | "jsdoc/match-description": "error",
364 | "jsdoc/match-name": "off",
365 | "jsdoc/multiline-blocks": "error",
366 | "jsdoc/no-bad-blocks": "error",
367 | "jsdoc/no-blank-block-descriptions": "error",
368 | "jsdoc/no-blank-blocks": "error",
369 | "jsdoc/no-defaults": "error",
370 | "jsdoc/no-missing-syntax": "off",
371 | "jsdoc/no-multi-asterisks": "error",
372 | "jsdoc/no-restricted-syntax": "off",
373 | "jsdoc/no-types": "off",
374 | "jsdoc/no-undefined-types": "error",
375 | "jsdoc/require-asterisk-prefix": ["error", "always"],
376 | "jsdoc/require-description": "error",
377 | "jsdoc/require-description-complete-sentence": "off",
378 | "jsdoc/require-example": "off",
379 | "jsdoc/require-file-overview": "off",
380 | "jsdoc/require-hyphen-before-param-description": ["error", "always"],
381 | "jsdoc/require-jsdoc": "error",
382 | "jsdoc/require-param": "error",
383 | "jsdoc/require-param-description": "error",
384 | "jsdoc/require-param-name": "error",
385 | "jsdoc/require-param-type": "error",
386 | "jsdoc/require-property": "error",
387 | "jsdoc/require-property-description": "error",
388 | "jsdoc/require-property-name": "error",
389 | "jsdoc/require-property-type": "error",
390 | "jsdoc/require-returns": "error",
391 | "jsdoc/require-returns-check": "error",
392 | "jsdoc/require-returns-description": "off",
393 | "jsdoc/require-returns-type": "error",
394 | "jsdoc/require-throws": "error",
395 | "jsdoc/require-yields": "error",
396 | "jsdoc/require-yields-check": "error",
397 | "jsdoc/sort-tags": ["error", {"tagSequence": [
398 | {tags: [
399 | // Brief descriptions
400 | "summary",
401 | "typeSummary",
402 |
403 | // Module/file-level
404 | "module",
405 | "exports",
406 | "file",
407 | "fileoverview",
408 | "overview",
409 | "import",
410 |
411 | // Identifying (name, type)
412 | "typedef",
413 | "interface",
414 | "record",
415 | "template",
416 | "name",
417 | "kind",
418 | "type",
419 | "alias",
420 | "external",
421 | "host",
422 | "callback",
423 | "func",
424 | "function",
425 | "method",
426 | "class",
427 | "constructor",
428 |
429 | // Relationships
430 | "modifies",
431 | "mixes",
432 | "mixin",
433 | "mixinClass",
434 | "mixinFunction",
435 | "namespace",
436 | "borrows",
437 | "constructs",
438 | "lends",
439 | "implements",
440 | "requires",
441 |
442 | // Long descriptions
443 | "desc",
444 | "description",
445 | "classdesc",
446 | "tutorial",
447 | "copyright",
448 | "license",
449 |
450 | // Simple annotations
451 | "const",
452 | "constant",
453 | "final",
454 | "global",
455 | "readonly",
456 | "abstract",
457 | "virtual",
458 | "var",
459 | "member",
460 | "memberof",
461 | "memberof!",
462 | "inner",
463 | "instance",
464 | "inheritdoc",
465 | "inheritDoc",
466 | "override",
467 | "hideconstructor",
468 |
469 | // Core function/object info
470 | "param",
471 | "arg",
472 | "argument",
473 | "prop",
474 | "property",
475 | "return",
476 | "returns",
477 |
478 | // Important behavior details
479 | "async",
480 | "generator",
481 | "default",
482 | "defaultvalue",
483 | "enum",
484 | "augments",
485 | "extends",
486 | "throws",
487 | "exception",
488 | "yield",
489 | "yields",
490 | "event",
491 | "fires",
492 | "emits",
493 | "listens",
494 | "this",
495 |
496 | // Access
497 | "static",
498 | "private",
499 | "protected",
500 | "public",
501 | "access",
502 | "package",
503 |
504 | "-other",
505 |
506 | // Supplementary descriptions
507 | "see",
508 | "example",
509 |
510 | // METADATA
511 |
512 | // Other Closure (undocumented) metadata
513 | "closurePrimitive",
514 | "customElement",
515 | "expose",
516 | "hidden",
517 | "idGenerator",
518 | "meaning",
519 | "ngInject",
520 | "owner",
521 | "wizaction",
522 |
523 | // Other Closure (documented) metadata
524 | "define",
525 | "dict",
526 | "export",
527 | "externs",
528 | "implicitCast",
529 | "noalias",
530 | "nocollapse",
531 | "nocompile",
532 | "noinline",
533 | "nosideeffects",
534 | "polymer",
535 | "polymerBehavior",
536 | "preserve",
537 | "struct",
538 | "suppress",
539 | "unrestricted",
540 |
541 | // @homer0/prettier-plugin-jsdoc metadata
542 | "category",
543 |
544 | // Non-Closure metadata
545 | "ignore",
546 | "author",
547 | "version",
548 | "variation",
549 | "since",
550 | "deprecated",
551 | "todo",
552 | ]}
553 | ]}],
554 | "jsdoc/tag-lines": ["error", "any", {"startLines": 1}],
555 | "jsdoc/text-escaping": "off",
556 | "jsdoc/valid-types": "off"
557 | },
558 | },
559 | {
560 | files: ["tests/*.js"],
561 | languageOptions: {
562 | ecmaVersion: "latest",
563 | globals: {
564 | ...globals.browser,
565 | ...globals.jest,
566 | ...globals.es2015,
567 | ...globals.node,
568 | Promise: "off",
569 | },
570 | },
571 | plugins: {
572 | jest: jest,
573 | stylistic: stylistic,
574 | },
575 | rules: {
576 | // eslint:recommended
577 | "constructor-super": "error",
578 | "for-direction": "error",
579 | "getter-return": "error",
580 | "no-async-promise-executor": "error",
581 | "no-case-declarations": "error",
582 | "no-class-assign": "error",
583 | "no-compare-neg-zero": "error",
584 | "no-cond-assign": "error",
585 | "no-const-assign": "error",
586 | "no-constant-binary-expression": "error",
587 | "no-constant-condition": "error",
588 | "no-control-regex": "error",
589 | "no-debugger": "error",
590 | "no-delete-var": "error",
591 | "no-dupe-args": "error",
592 | "no-dupe-class-members": "error",
593 | "no-dupe-else-if": "error",
594 | "no-dupe-keys": "error",
595 | "no-duplicate-case": "error",
596 | "no-empty": "error",
597 | "no-empty-character-class": "error",
598 | "no-empty-pattern": "error",
599 | "no-empty-static-block": "error",
600 | "no-ex-assign": "error",
601 | "no-extra-boolean-cast": "error",
602 | "no-fallthrough": "error",
603 | "no-func-assign": "error",
604 | "no-global-assign": "error",
605 | "no-import-assign": "error",
606 | "no-invalid-regexp": "error",
607 | "no-irregular-whitespace": "error",
608 | "no-loss-of-precision": "error",
609 | "no-misleading-character-class": "error",
610 | "no-new-native-nonconstructor": "error",
611 | "no-nonoctal-decimal-escape": "error",
612 | "no-obj-calls": "error",
613 | "no-octal": "error",
614 | "no-prototype-builtins": "error",
615 | "no-redeclare": "error",
616 | "no-regex-spaces": "error",
617 | "no-self-assign": "error",
618 | "no-setter-return": "error",
619 | "no-shadow-restricted-names": "error",
620 | "no-sparse-arrays": "error",
621 | "no-this-before-super": "error",
622 | "no-undef": "error",
623 | "no-unexpected-multiline": "error",
624 | "no-unreachable": "error",
625 | "no-unsafe-finally": "error",
626 | "no-unsafe-negation": "error",
627 | "no-unsafe-optional-chaining": "error",
628 | "no-unused-labels": "error",
629 | "no-unused-private-class-members": "error",
630 | "no-unused-vars": "error",
631 | "no-useless-backreference": "error",
632 | "no-useless-catch": "error",
633 | "no-useless-escape": "error",
634 | "no-with": "error",
635 | "require-yield": "error",
636 | "use-isnan": "error",
637 | "valid-typeof": "error",
638 | // eslint-stylistic:recommended
639 | "stylistic/array-bracket-spacing": ["error", "never"],
640 | "stylistic/arrow-parens": ["error", "always"],
641 | "stylistic/arrow-spacing": ["error", {"before": true, "after": true}],
642 | "stylistic/block-spacing": ["error", "always"],
643 | "stylistic/brace-style": ["error", "1tbs", {"allowSingleLine": true}],
644 | "stylistic/comma-dangle": ["error", "never"],
645 | "stylistic/comma-spacing": ["error", {"before": false, "after": true}],
646 | "stylistic/comma-style": ["error", "last"],
647 | "stylistic/computed-property-spacing": ["error", "never"],
648 | "stylistic/dot-location": ["error", "object"],
649 | "stylistic/eol-last": ["error", "always"],
650 | "stylistic/indent": ["error", 4],
651 | "stylistic/indent-binary-ops": ["error", 4],
652 | "stylistic/key-spacing": ["error",
653 | {
654 | "beforeColon": false,
655 | "afterColon": true,
656 | "mode": "minimum",
657 | align: {
658 | "beforeColon": false,
659 | "afterColon": true,
660 | "on": "colon",
661 | "mode": "minimum"
662 | }
663 | }
664 | ],
665 | "stylistic/keyword-spacing": ["error", {"before": true, "after": true}],
666 | "stylistic/lines-between-class-members": ["error", "always"],
667 | "stylistic/max-statements-per-line": ["error", {"max": 1}],
668 | "stylistic/member-delimiter-style": ["error",
669 | {
670 | "multiline": {
671 | "delimiter": "comma",
672 | "requireLast": false
673 | },
674 | "singleline": {
675 | "delimiter": "comma",
676 | "requireLast": false
677 | },
678 | }
679 | ],
680 | "stylistic/multiline-ternary": ["error", "always-multiline"],
681 | "stylistic/new-parens": ["error", "always"],
682 | "stylistic/no-extra-parens": "off",
683 | "stylistic/no-floating-decimal": "error",
684 | "stylistic/no-mixed-operators": ["error", {"allowSamePrecedence": false}],
685 | "stylistic/no-mixed-spaces-and-tabs": "error",
686 | "stylistic/no-multi-spaces": ["error", {"ignoreEOLComments": false, "exceptions": {"Property": true}}],
687 | "stylistic/no-multiple-empty-lines": ["error", {"max": 1, "maxBOF": 0, "maxEOF": 1}],
688 | "stylistic/no-tabs": ["error", {"allowIndentationTabs": false}],
689 | "stylistic/no-trailing-spaces": ["error", {"ignoreComments": false, "skipBlankLines": false}],
690 | "stylistic/no-whitespace-before-property": "error",
691 | "stylistic/object-curly-spacing": ["error", "never"],
692 | "stylistic/operator-linebreak": ["error", "after"],
693 | "stylistic/padded-blocks": ["error", "never"],
694 | "stylistic/quote-props": ["error", "consistent-as-needed", {"keywords": true, "numbers": true}],
695 | "stylistic/quotes": ["error", "double", {"allowTemplateLiterals": true}],
696 | "stylistic/rest-spread-spacing": ["error", "never"],
697 | "stylistic/semi": ["error", "always"],
698 | "stylistic/semi-spacing": ["error", {"before": false, "after": true}],
699 | "stylistic/space-before-blocks": ["error"],
700 | "stylistic/space-before-function-paren": ["error", "never"],
701 | "stylistic/space-in-parens": ["error", "never"],
702 | "stylistic/space-infix-ops": ["error", {"int32Hint": false}],
703 | "stylistic/space-unary-ops": ["error"],
704 | "stylistic/spaced-comment": ["error", "always"],
705 | "stylistic/template-curly-spacing": ["error", "never"],
706 | "stylistic/template-tag-spacing": ["error", "never"],
707 | "stylistic/wrap-iife": ["error", "outside"],
708 | "stylistic/yield-star-spacing": ["error", {"before": false, "after": true}],
709 | // jest:recommended
710 | "jest/expect-expect": "warn",
711 | "jest/no-alias-methods": "error",
712 | "jest/no-commented-out-tests": "warn",
713 | "jest/no-conditional-expect": "error",
714 | "jest/no-deprecated-functions": "error",
715 | "jest/no-disabled-tests": "warn",
716 | "jest/no-done-callback": "error",
717 | "jest/no-export": "error",
718 | "jest/no-focused-tests": "error",
719 | "jest/no-identical-title": "error",
720 | "jest/no-interpolation-in-snapshots": "error",
721 | "jest/no-jasmine-globals": "error",
722 | "jest/no-mocks-import": "error",
723 | "jest/no-standalone-expect": "error",
724 | "jest/no-test-prefixes": "error",
725 | "jest/valid-describe-callback": "error",
726 | "jest/valid-expect": "error",
727 | "jest/valid-expect-in-promise": "error",
728 | "jest/valid-title": "error"
729 | },
730 | }
731 | ];
732 |
--------------------------------------------------------------------------------
/jsdoc.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "opts": {
3 | "encoding": "utf8",
4 | "destination": "./jsdoc/",
5 | "pedantic": true,
6 | "private": true,
7 | "recurse": true
8 | },
9 | "plugins": [],
10 | "recurseDepth": 5,
11 | "source": {
12 | "include": [
13 | "./src/js"
14 | ],
15 | "includePattern": ".js$",
16 | "excludePattern": "",
17 | "exclude": [
18 | "node_modules",
19 | "dist",
20 | "demo",
21 | "tests",
22 | "coverage"
23 | ]
24 | },
25 | "sourceType": "module",
26 | "tags": {
27 | "allowUnknownTags": false,
28 | "dictionaries": ["jsdoc","closure"]
29 | },
30 | "templates": {
31 | "cleverLinks": true,
32 | "monospaceLinks": true,
33 | "default": {
34 | "outputSourceFiles": false
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "uasset-reader-js",
3 | "version": "1.1.2",
4 | "description": "Read .uasset files from Unreal Engine in javascript",
5 | "scripts": {
6 | "test": "jest --coverage --coverageDirectory=./coverage -- tests/main.test.js",
7 | "build": "node build.cjs && uglifyjs dist/uasset-reader.js --mangle --webkit --compress \"drop_console=true,module=false,passes=5\" --comments \"/MIT License/\" -o dist/uasset-reader.min.js && jest",
8 | "jsdoc": "jsdoc -c jsdoc.conf.json",
9 | "eslint": "eslint --max-warnings=0 src/**/*.js tests/*.js",
10 | "eslint:fix": "eslint --fix src/**/*.js tests/*.js"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/blueprintue/uasset-reader-js.git"
15 | },
16 | "author": "Sébastien Rancoud ",
17 | "license": "MIT",
18 | "bugs": {
19 | "url": "https://github.com/blueprintue/uasset-reader-js/issues"
20 | },
21 | "homepage": "https://github.com/blueprintue/uasset-reader-js",
22 | "devDependencies": {
23 | "@babel/core": "^7.27.4",
24 | "@stylistic/eslint-plugin": "^4.4.1",
25 | "@types/jest": "^29.5.14",
26 | "eslint": "^9.28.0",
27 | "eslint-plugin-jest": "^28.13.0",
28 | "eslint-plugin-jsdoc": "^50.7.1",
29 | "globals": "^16.2.0",
30 | "jest": "^29.7.0",
31 | "jest-environment-jsdom": "^29.7.0",
32 | "jsdoc": "^4.0.4",
33 | "uglify-js": "^3.19.3"
34 | },
35 | "type": "module",
36 | "engines": {
37 | "npm": ">=10.7.0",
38 | "node": ">=22.1.0"
39 | },
40 | "jest": {
41 | "testEnvironment": "jsdom"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/js/_namespace_.js:
--------------------------------------------------------------------------------
1 | /* istanbul ignore else */
2 | if (window.blueprintUE === undefined) {
3 | /**
4 | * This namespace is attached to `window`.
5 | * It's the main namespace leading to another namespace called `render`.
6 | *
7 | * @namespace
8 | */
9 | window.blueprintUE = {};
10 | }
11 | /* istanbul ignore else */
12 | if (window.blueprintUE.uasset === undefined) {
13 | /**
14 | * This namespace is attached to `window.blueprintUE`.
15 | * It will only expose the `Main` class.
16 | *
17 | * @namespace
18 | */
19 | window.blueprintUE.uasset = {};
20 | }
21 |
22 | /**
23 | * Uasset structure.
24 | *
25 | * @typedef Uasset
26 | * @property {HexView[]} hexView - list of bytes read with position and type in file
27 | * @property {object} header - header file
28 | * @property {Name[]} names - to fill
29 | * @property {GatherableTextData[]} gatherableTextData - to fill
30 | * @property {object} imports - to fill
31 | * @property {object} exports - to fill
32 | * @property {object} depends - to fill
33 | * @property {object} softPackageReferences - to fill
34 | * @property {object} searchableNames - to fill
35 | * @property {Thumbnails} thumbnails - to fill
36 | * @property {object} assetRegistryData - to fill
37 | * @property {object} preloadDependency - to fill
38 | * @property {object} bulkDataStart - to fill
39 | */
40 |
41 | /**
42 | * HexView structure.
43 | *
44 | * @typedef HexView
45 | * @property {string} key - name of what we read
46 | * @property {string} type - type name of what we read (int16, int32, etc...)
47 | * @property {string} value - value read
48 | * @property {number} start - start position in the file
49 | * @property {number} stop - stop position in the file
50 | */
51 |
52 | /**
53 | * Name structure.
54 | *
55 | * @typedef Name
56 | * @property {string} Name - value
57 | * @property {number} NonCasePreservingHash - hash of value with case non preserved (upper)
58 | * @property {number} CasePreservingHash - hash of value with case preserved
59 | */
60 |
61 | // region GatherableTextData
62 | /**
63 | * GatherableTextData Structure.
64 | *
65 | * @typedef GatherableTextData
66 | * @property {string} NamespaceName - to fill
67 | * @property {SourceData} SourceData - to fill
68 | * @property {SourceSiteContexts[]} SourceSiteContexts - to fill
69 | */
70 |
71 | /**
72 | * SourceData Structure.
73 | *
74 | * @typedef SourceData
75 | * @property {string} SourceString - to fill
76 | * @property {GatherableTextDataMetadata} SourceStringMetaData - to fill
77 | */
78 |
79 | /**
80 | * SourceSiteContexts Structure.
81 | *
82 | * @typedef SourceSiteContexts
83 | * @property {string} KeyName - to fill
84 | * @property {string} SiteDescription - to fill
85 | * @property {number} IsEditorOnly - to fill
86 | * @property {number} IsOptional - to fill
87 | * @property {GatherableTextDataMetadata} InfoMetaData - to fill
88 | * @property {GatherableTextDataMetadata} KeyMetaData - to fill
89 | */
90 |
91 | /**
92 | * GatherableTextDataMetadata Structure.
93 | *
94 | * @typedef GatherableTextDataMetadata
95 | * @property {number} ValueCount - to fill
96 | * @property {any[]} Values - to fill
97 | */
98 | // endregion
99 |
100 | // region Thumbnails
101 | /**
102 | * Thumbnails Structure.
103 | *
104 | * @typedef Thumbnails
105 | * @property {ThumbnailsIndex[]} Index - index
106 | * @property {ThumbnailsThumbnails[]} Thumbnails - thumbnails
107 | */
108 |
109 | /**
110 | * Thumbnails Index Structure
111 | *
112 | * @typedef ThumbnailsIndex
113 | * @property {string} AssetClassName - class name
114 | * @property {string} ObjectPathWithoutPackageName - path
115 | * @property {number} FileOffset - position in file
116 | */
117 |
118 | /**
119 | * Thumbnails Thumbnails Structure
120 | *
121 | * @typedef ThumbnailsThumbnails
122 | * @property {number} ImageWidth - width
123 | * @property {number} ImageHeight - height
124 | * @property {string} ImageFormat - format (PNG or JPEG)
125 | * @property {number} ImageSizeData - how many bytes used in file
126 | * @property {number[]} ImageData - raw data
127 | */
128 | // endregion
129 |
--------------------------------------------------------------------------------
/src/js/main.js:
--------------------------------------------------------------------------------
1 | /* global DataView, EPackageFileTag, EUnrealEngineObjectUE4Version, EUnrealEngineObjectUE5Version, GatherableTextData, SourceSiteContexts, Uasset, Uint8Array */
2 | /**
3 | * Main public entry point.
4 | *
5 | * @class ReaderUasset
6 | */
7 | function ReaderUasset() {
8 | this.currentIdx = 0;
9 | this.bytes = [];
10 |
11 | /** @type {Uasset} */
12 | this.uasset = {
13 | hexView : [],
14 | header : {},
15 | names : [],
16 | gatherableTextData : [],
17 | imports : {},
18 | exports : [],
19 | depends : {},
20 | softPackageReferences: {},
21 | searchableNames : {},
22 | thumbnails : {Index: [], Thumbnails: []},
23 | assetRegistryData : {},
24 | preloadDependency : {},
25 | bulkDataStart : {}
26 | };
27 | }
28 |
29 | // region helpers
30 | /**
31 | * Read 2 bytes, save in hex view and return value as uint16 en littleEndian.
32 | *
33 | * @function ReaderUasset#uint16
34 | * @param {string} key - name of what we read
35 | * @returns {number}
36 | * @private
37 | */
38 | ReaderUasset.prototype.uint16 = function uint16(key) {
39 | /** @type {number} */
40 | var val;
41 | /** @type {number[]} */
42 | var bytes = this.readCountBytes(2);
43 |
44 | val = new DataView(new Uint8Array(bytes).buffer).getUint16(0, this.useLittleEndian);
45 |
46 | this.addHexView(key, "uint16", val, this.currentIdx - 2, this.currentIdx - 1);
47 |
48 | return val;
49 | };
50 |
51 | /**
52 | * Read 4 bytes, save in hex view and return value as int32 en littleEndian.
53 | *
54 | * @function ReaderUasset#int32
55 | * @param {string} key - name of what we read
56 | * @returns {number}
57 | * @private
58 | */
59 | ReaderUasset.prototype.int32 = function int32(key) {
60 | /** @type {number} */
61 | var val;
62 | /** @type {number[]} */
63 | var bytes = this.readCountBytes(4);
64 |
65 | val = new DataView(new Uint8Array(bytes).buffer).getInt32(0, this.useLittleEndian);
66 |
67 | this.addHexView(key, "int32", val, this.currentIdx - 4, this.currentIdx - 1);
68 |
69 | return val;
70 | };
71 |
72 | /**
73 | * Read 4 bytes, save in hex view and return value as uint32 en littleEndian.
74 | *
75 | * @function ReaderUasset#uint32
76 | * @param {string} key - name of what we read
77 | * @returns {number}
78 | * @private
79 | */
80 | ReaderUasset.prototype.uint32 = function uint32(key) {
81 | /** @type {number} */
82 | var val;
83 | /** @type {number[]} */
84 | var bytes = this.readCountBytes(4);
85 |
86 | val = new DataView(new Uint8Array(bytes).buffer).getUint32(0, this.useLittleEndian);
87 |
88 | this.addHexView(key, "uint32", val, this.currentIdx - 4, this.currentIdx - 1);
89 |
90 | return val;
91 | };
92 |
93 | /**
94 | * Read 8 bytes, save in hex view and return value as int64 en littleEndian.
95 | *
96 | * @function ReaderUasset#int64
97 | * @param {string} key - name of what we read
98 | * @returns {number}
99 | * @private
100 | */
101 | ReaderUasset.prototype.int64 = function int64(key) {
102 | /** @type {bigint} */
103 | var val;
104 | /** @type {number[]} */
105 | var bytes = this.readCountBytes(8);
106 |
107 | val = new DataView(new Uint8Array(bytes).buffer).getBigInt64(0, this.useLittleEndian);
108 |
109 | this.addHexView(key, "int64", val, this.currentIdx - 8, this.currentIdx - 1);
110 |
111 | return val;
112 | };
113 |
114 | /**
115 | * Read 8 bytes, save in hex view and return value as uint64 en littleEndian.
116 | *
117 | * @function ReaderUasset#uint64
118 | * @param {string} key - name of what we read
119 | * @returns {number}
120 | * @private
121 | */
122 | ReaderUasset.prototype.uint64 = function uint64(key) {
123 | /** @type {bigint} */
124 | var val;
125 | /** @type {number[]} */
126 | var bytes = this.readCountBytes(8);
127 |
128 | val = new DataView(new Uint8Array(bytes).buffer).getBigUint64(0, this.useLittleEndian);
129 |
130 | this.addHexView(key, "uint64", val, this.currentIdx - 8, this.currentIdx - 1);
131 |
132 | return val;
133 | };
134 |
135 | /**
136 | * Read 16 bytes, save in hex view and return value as string.
137 | *
138 | * @function ReaderUasset#fguidSlot
139 | * @param {string} key - name of what we read
140 | * @returns {string}
141 | * @private
142 | */
143 | ReaderUasset.prototype.fguidSlot = function fguidSlot(key) {
144 | /** @type {string} */
145 | var val;
146 | /** @type {string} */
147 | var str1 = "";
148 | /** @type {string} */
149 | var str2 = "";
150 | /** @type {string} */
151 | var str3 = "";
152 | /** @type {string} */
153 | var str4 = "";
154 | /** @type {number} */
155 | var idx = 3;
156 | /** @type {number[]} */
157 | var bytes = this.readCountBytes(16);
158 |
159 | for (; idx >= 0; --idx) {
160 | str1 = str1 + bytes[idx].toString(16).padStart(2, "0");
161 | str2 = str2 + bytes[idx + 4].toString(16).padStart(2, "0");
162 | str3 = str3 + bytes[idx + 8].toString(16).padStart(2, "0");
163 | str4 = str4 + bytes[idx + 12].toString(16).padStart(2, "0");
164 | }
165 |
166 | val = (str1 + str2 + str3 + str4).toUpperCase();
167 |
168 | this.addHexView(key, "fguidSlot", val, this.currentIdx - 16, this.currentIdx - 1);
169 |
170 | return val;
171 | };
172 |
173 | /**
174 | * Read 16 bytes, save in hex view and return value as string.
175 | *
176 | * @function ReaderUasset#fguidString
177 | * @param {string} key - name of what we read
178 | * @returns {string}
179 | * @private
180 | */
181 | ReaderUasset.prototype.fguidString = function fguidString(key) {
182 | /** @type {string} */
183 | var val;
184 | /** @type {string} */
185 | var str = "";
186 | /** @type {number} */
187 | var idx = 0;
188 | /** @type {number[]} */
189 | var bytes = this.readCountBytes(16);
190 |
191 | for (; idx < 16; ++idx) {
192 | str = str + bytes[idx].toString(16).padStart(2, "0");
193 | }
194 |
195 | val = str.toUpperCase();
196 |
197 | this.addHexView(key, "fguidString", val, this.currentIdx - 16, this.currentIdx - 1);
198 |
199 | return val;
200 | };
201 |
202 | /**
203 | * Read 16 bytes, save in hex view and return value as string.
204 | *
205 | * @function ReaderUasset#fstring
206 | * @param {string} key - name of what we read
207 | * @returns {string}
208 | * @private
209 | */
210 | ReaderUasset.prototype.fstring = function fstring(key) {
211 | /** @type {string} */
212 | var val;
213 | /** @type {number[]} */
214 | var bytes;
215 | /** @type {string} */
216 | var str = "";
217 | /** @type {number} */
218 | var counter = 0;
219 | /** @type {number[]} */
220 | var output = [];
221 | /** @type {string} */
222 | var value;
223 | /** @type {string} */
224 | var extra;
225 | /** @type {number} */
226 | var idx;
227 | /** @type {number} */
228 | var startPosition;
229 |
230 | var length = this.int32(key + " (fstring length)");
231 | if (length === 0) {
232 | return "";
233 | }
234 |
235 | startPosition = this.currentIdx;
236 |
237 | if (length > 0) {
238 | bytes = this.readCountBytes(length);
239 | for (idx = 0; idx < bytes.length - 1; ++idx) {
240 | str = str + String.fromCharCode(bytes[idx]);
241 | }
242 |
243 | val = str;
244 |
245 | this.addHexView(key, "fstring", val, startPosition, this.currentIdx - 1);
246 |
247 | return str;
248 | }
249 |
250 | /* eslint-disable */
251 | length = length * -1 * 2;
252 | bytes = this.readCountBytes(length);
253 | while (counter < bytes.length) {
254 | value = String.fromCharCode(bytes[counter++]);
255 | if (value >= 0xD800 && value <= 0xDBFF && counter < bytes.length) {
256 | extra = String.fromCharCode(bytes[counter++]);
257 | if ((extra & 0xFC00) === 0xDC00) {
258 | output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
259 | } else {
260 | output.push(value);
261 | counter--;
262 | }
263 | } else {
264 | output.push(value);
265 | }
266 | }
267 | /* eslint-enable */
268 |
269 | val = output.join("");
270 |
271 | this.addHexView(key, "fstring", val, startPosition, this.currentIdx - 1);
272 |
273 | return val;
274 | };
275 |
276 | /**
277 | * Read n bytes.
278 | *
279 | * @function ReaderUasset#readCountBytes
280 | * @param {number} count - number of bytes to read.
281 | * @returns {number[]}
282 | * @private
283 | */
284 | ReaderUasset.prototype.readCountBytes = function readCountBytes(count) {
285 | var bytes = [];
286 | var idx = 0;
287 |
288 | for (; idx < count; ++idx) {
289 | bytes.push(this.bytes[this.currentIdx]);
290 | this.currentIdx = this.currentIdx + 1;
291 | }
292 |
293 | return bytes;
294 | };
295 |
296 | /**
297 | * Add informations in HexView struct.
298 | *
299 | * @function ReaderUasset#addHexView
300 | * @param {string} key - name of what we read
301 | * @param {string} type - type name of what we read (int16, int32, etc...)
302 | * @param {string} value - value read
303 | * @param {number} startPosition - start position in the file
304 | * @param {number} stopPosition - stop position in the file
305 | * @returns {undefined}
306 | * @private
307 | */
308 | ReaderUasset.prototype.addHexView = function addHexView(key, type, value, startPosition, stopPosition) { /* eslint-disable-line max-params */
309 | if (this.saveHexView === false) {
310 | return;
311 | }
312 |
313 | this.uasset.hexView.push({
314 | key : key,
315 | type : type,
316 | value: value,
317 | start: startPosition,
318 | stop : stopPosition
319 | });
320 | };
321 |
322 | /**
323 | * Resolve FName.
324 | *
325 | * @function ReaderUasset#resolveFName
326 | * @param {number} idx - name of what we read
327 | * @returns {string}
328 | * @private
329 | */
330 | ReaderUasset.prototype.resolveFName = function resolveFName(idx) {
331 | if (this.uasset.names[idx]) {
332 | return this.uasset.names[idx].Name;
333 | }
334 |
335 | return "";
336 | };
337 | // endregion
338 |
339 | /**
340 | * Read Header.
341 | *
342 | * @function ReaderUasset#readHeader
343 | * @returns {(Error|undefined)}
344 | * @private
345 | * @see https://github.com/EpicGames/UnrealEngine/blob/5.0/Engine/Source/Runtime/CoreUObject/Private/UObject/PackageFileSummary.cpp#L48
346 | */
347 | /* eslint-disable-next-line max-lines-per-function,max-statements,complexity */
348 | ReaderUasset.prototype.readHeader = function readHeader() {
349 | /** @type {number} */
350 | var idx;
351 | /** @type {number} */
352 | var count;
353 |
354 | // Check file is uasset
355 | this.uasset.header.EPackageFileTag = this.uint32("EPackageFileTag");
356 | if (this.uasset.header.EPackageFileTag === EPackageFileTag.PACKAGE_FILE_TAG_SWAPPED) {
357 | // The package has been stored in a separate endianness
358 | this.useLittleEndian = false;
359 | }
360 |
361 | if (this.uasset.header.EPackageFileTag !== EPackageFileTag.PACKAGE_FILE_TAG &&
362 | this.uasset.header.EPackageFileTag !== EPackageFileTag.PACKAGE_FILE_TAG_SWAPPED) {
363 | return new Error("invalid uasset");
364 | }
365 |
366 | /**
367 | * Check file is not UE3
368 | *
369 | * The package file version number when this package was saved.
370 | *
371 | * Lower 16 bits stores the UE3 engine version
372 | * Upper 16 bits stores the UE licensee version
373 | * For newer packages this is -7:
374 | * -2 indicates presence of enum-based custom versions
375 | * -3 indicates guid-based custom versions
376 | * -4 indicates removal of the UE3 version. Packages saved with this ID cannot be loaded in older engine versions
377 | * -5 indicates the replacement of writing out the "UE3 version" so older versions of engine can gracefully fail to open newer packages
378 | * -6 indicates optimizations to how custom versions are being serialized
379 | * -7 indicates the texture allocation info has been removed from the summary
380 | * -8 indicates that the UE5 version has been added to the summary
381 | */
382 | this.uasset.header.LegacyFileVersion = this.int32("LegacyFileVersion");
383 | /* eslint-disable-next-line no-magic-numbers */
384 | if (this.uasset.header.LegacyFileVersion !== -6 && this.uasset.header.LegacyFileVersion !== -7 && this.uasset.header.LegacyFileVersion !== -8) {
385 | return new Error("unsupported version");
386 | }
387 |
388 | /**
389 | * Next bytes is for UE3
390 | * No need to check because it will always be different of -4
391 | */
392 | this.uasset.header.LegacyUE3Version = this.int32("LegacyUE3Version");
393 |
394 | // Check file is valid UE4
395 | this.uasset.header.FileVersionUE4 = this.int32("FileVersionUE4");
396 |
397 | // Check valid UE5
398 | /* eslint-disable-next-line no-magic-numbers */
399 | if (this.uasset.header.LegacyFileVersion <= -8) {
400 | this.uasset.header.FileVersionUE5 = this.int32("FileVersionUE5");
401 | }
402 |
403 | this.uasset.header.FileVersionLicenseeUE4 = this.int32("FileVersionLicenseeUE4");
404 | if (this.uasset.header.FileVersionUE4 === 0 && this.uasset.header.FileVersionLicenseeUE4 === 0 && this.uasset.header.FileVersionUE5 === 0) {
405 | return new Error("asset unversioned");
406 | }
407 |
408 | count = this.int32("CustomVersions Count");
409 | this.uasset.header.CustomVersions = [];
410 | for (idx = 0; idx < count; ++idx) {
411 | this.uasset.header.CustomVersions.push({
412 | key : this.fguidSlot("CustomVersions #" + idx + ": key"),
413 | version: this.int32("CustomVersions #" + idx + ": version")
414 | });
415 | }
416 |
417 | this.uasset.header.TotalHeaderSize = this.int32("TotalHeaderSize");
418 |
419 | this.uasset.header.FolderName = this.fstring("FolderName");
420 |
421 | this.uasset.header.PackageFlags = this.uint32("PackageFlags");
422 |
423 | this.uasset.header.NameCount = this.int32("NameCount");
424 | this.uasset.header.NameOffset = this.int32("NameOffset");
425 |
426 | if (this.uasset.header.FileVersionUE5 >= EUnrealEngineObjectUE5Version.VER_UE5_ADD_SOFTOBJECTPATH_LIST.value) {
427 | this.uasset.header.SoftObjectPathsCount = this.uint32("SoftObjectPathsCount");
428 | this.uasset.header.SoftObjectPathsOffset = this.uint32("SoftObjectPathsOffset");
429 | }
430 |
431 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_ADDED_PACKAGE_SUMMARY_LOCALIZATION_ID.value) {
432 | this.uasset.header.LocalizationId = this.fstring("LocalizationId");
433 | }
434 |
435 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_SERIALIZE_TEXT_IN_PACKAGES.value) {
436 | this.uasset.header.GatherableTextDataCount = this.int32("GatherableTextDataCount");
437 | this.uasset.header.GatherableTextDataOffset = this.int32("GatherableTextDataOffset");
438 | }
439 |
440 | this.uasset.header.ExportCount = this.int32("ExportCount");
441 | this.uasset.header.ExportOffset = this.int32("ExportOffset");
442 |
443 | this.uasset.header.ImportCount = this.int32("ImportCount");
444 | this.uasset.header.ImportOffset = this.int32("ImportOffset");
445 |
446 | this.uasset.header.DependsOffset = this.int32("DependsOffset");
447 |
448 | if (this.uasset.header.FileVersionUE4 < EUnrealEngineObjectUE4Version.VER_UE4_OLDEST_LOADABLE_PACKAGE.value) {
449 | return new Error("asset too old");
450 | }
451 |
452 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_ADD_STRING_ASSET_REFERENCES_MAP.value) {
453 | this.uasset.header.SoftPackageReferencesCount = this.int32("SoftPackageReferencesCount");
454 | this.uasset.header.SoftPackageReferencesOffset = this.int32("SoftPackageReferencesOffset");
455 | }
456 |
457 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_ADDED_SEARCHABLE_NAMES.value) {
458 | this.uasset.header.SearchableNamesOffset = this.int32("SearchableNamesOffset");
459 | }
460 |
461 | this.uasset.header.ThumbnailTableOffset = this.int32("ThumbnailTableOffset");
462 |
463 | this.uasset.header.Guid = this.fguidString("Guid");
464 |
465 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_ADDED_PACKAGE_OWNER.value) {
466 | this.uasset.header.PersistentGuid = this.fguidString("PersistentGuid");
467 | }
468 |
469 | // eslint-disable-next-line stylistic/max-len
470 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_ADDED_PACKAGE_OWNER.value && this.uasset.header.FileVersionUE4 < EUnrealEngineObjectUE4Version.VER_UE4_NON_OUTER_PACKAGE_IMPORT.value) {
471 | this.uasset.header.OwnerPersistentGuid = this.fguidString("OwnerPersistentGuid");
472 | }
473 |
474 | count = this.int32("Generations Count");
475 | this.uasset.header.Generations = [];
476 | for (idx = 0; idx < count; ++idx) {
477 | this.uasset.header.Generations.push({
478 | exportCount: this.int32("Generations #" + idx + ": export count"),
479 | nameCount : this.int32("Generations #" + idx + ": name count)")
480 | });
481 | }
482 |
483 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_ENGINE_VERSION_OBJECT.value) {
484 | this.uasset.header.SavedByEngineVersion = String(this.uint16("SavedByEngineVersion Major"));
485 | this.uasset.header.SavedByEngineVersion = this.uasset.header.SavedByEngineVersion + "." + this.uint16("SavedByEngineVersion Minor");
486 | this.uasset.header.SavedByEngineVersion = this.uasset.header.SavedByEngineVersion + "." + this.uint16("SavedByEngineVersion Patch");
487 | this.uasset.header.SavedByEngineVersion = this.uasset.header.SavedByEngineVersion + "-" + this.uint32("SavedByEngineVersion Changelist");
488 | this.uasset.header.SavedByEngineVersion = this.uasset.header.SavedByEngineVersion + "+" + this.fstring("SavedByEngineVersion Branch");
489 | } else {
490 | this.uasset.header.EngineChangelist = this.int32("EngineChangelist");
491 | }
492 |
493 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_PACKAGE_SUMMARY_HAS_COMPATIBLE_ENGINE_VERSION.value) {
494 | this.uasset.header.CompatibleWithEngineVersion = String(this.uint16("CompatibleWithEngineVersion Major"));
495 | this.uasset.header.CompatibleWithEngineVersion = this.uasset.header.CompatibleWithEngineVersion + "." + this.uint16("CompatibleWithEngineVersion Minor");
496 | this.uasset.header.CompatibleWithEngineVersion = this.uasset.header.CompatibleWithEngineVersion + "." + this.uint16("CompatibleWithEngineVersion Patch");
497 | this.uasset.header.CompatibleWithEngineVersion = this.uasset.header.CompatibleWithEngineVersion + "-" + this.uint32("CompatibleWithEngineVersion Changelist");
498 | this.uasset.header.CompatibleWithEngineVersion = this.uasset.header.CompatibleWithEngineVersion + "+" + this.fstring("CompatibleWithEngineVersion Branch");
499 | } else {
500 | this.uasset.header.CompatibleWithEngineVersion = this.uasset.header.SavedByEngineVersion;
501 | }
502 |
503 | this.uasset.header.CompressionFlags = this.uint32("CompressionFlags");
504 |
505 | count = this.int32("CompressedChunks Count");
506 | if (count > 0) {
507 | return new Error("asset compressed");
508 | }
509 |
510 | this.uasset.header.PackageSource = this.uint32("PackageSource");
511 |
512 | count = this.uint32("AdditionalPackagesToCook Count");
513 | this.uasset.header.AdditionalPackagesToCook = [];
514 | if (count > 0) {
515 | return new Error("AdditionalPackagesToCook has items");
516 | }
517 |
518 | /* eslint-disable-next-line no-magic-numbers */
519 | if (this.uasset.header.LegacyFileVersion > -7) {
520 | this.uasset.header.NumTextureAllocations = this.int32("NumTextureAllocations");
521 | }
522 |
523 | this.uasset.header.AssetRegistryDataOffset = this.int32("AssetRegistryDataOffset");
524 | this.uasset.header.BulkDataStartOffset = this.int64("BulkDataStartOffset");
525 |
526 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_WORLD_LEVEL_INFO.value) {
527 | this.uasset.header.WorldTileInfoDataOffset = this.int32("WorldTileInfoDataOffset");
528 | }
529 |
530 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_CHANGED_CHUNKID_TO_BE_AN_ARRAY_OF_CHUNKIDS.value) {
531 | count = this.int32("ChunkIDs Count");
532 | this.uasset.header.ChunkIDs = [];
533 | if (count > 0) {
534 | return new Error("ChunkIDs has items");
535 | }
536 | } else if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_ADDED_CHUNKID_TO_ASSETDATA_AND_UPACKAGE.value) {
537 | this.uasset.header.ChunkID = this.int32("ChunkID");
538 | }
539 |
540 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_PRELOAD_DEPENDENCIES_IN_COOKED_EXPORTS.value) {
541 | this.uasset.header.PreloadDependencyCount = this.int32("PreloadDependencyCount");
542 | this.uasset.header.PreloadDependencyOffset = this.int32("PreloadDependencyOffset");
543 | } else {
544 | this.uasset.header.PreloadDependencyCount = -1;
545 | this.uasset.header.PreloadDependencyOffset = 0;
546 | }
547 |
548 | if (this.uasset.header.FileVersionUE5 >= EUnrealEngineObjectUE5Version.VER_UE5_NAMES_REFERENCED_FROM_EXPORT_DATA.value) {
549 | this.uasset.header.NamesReferencedFromExportDataCount = this.int32("NamesReferencedFromExportDataCount");
550 | }
551 |
552 | if (this.uasset.header.FileVersionUE5 >= EUnrealEngineObjectUE5Version.VER_UE5_PAYLOAD_TOC.value) {
553 | this.uasset.header.PayloadTocOffset = this.int64("PayloadTocOffset");
554 | } else {
555 | this.uasset.header.PayloadTocOffset = -1;
556 | }
557 |
558 | if (this.uasset.header.FileVersionUE5 >= EUnrealEngineObjectUE5Version.VER_UE5_DATA_RESOURCES.value) {
559 | this.uasset.header.DataResourceOffset = this.int32("DataResourceOffset");
560 | }
561 |
562 | return undefined;
563 | };
564 |
565 | /**
566 | * Read Names.
567 | *
568 | * @function ReaderUasset#readNames
569 | * @returns {undefined}
570 | * @private
571 | * @see https://github.com/EpicGames/UnrealEngine/blob/5.0/Engine/Source/Runtime/Core/Private/UObject/UnrealNames.cpp#L2736
572 | */
573 | ReaderUasset.prototype.readNames = function readNames() {
574 | var idx = 0;
575 | var count = this.uasset.header.NameCount;
576 | this.currentIdx = this.uasset.header.NameOffset;
577 |
578 | /**
579 | * Hashes: These are not used anymore but recalculated on save to maintain serialization format
580 | * GetRawNonCasePreservingHash -> return FCrc::Strihash_DEPRECATED(Source) & 0xFFFF;
581 | * GetRawCasePreservingHash -> return FCrc::StrCrc32(Source) & 0xFFFF;
582 | */
583 |
584 | for (; idx < count; ++idx) {
585 | this.uasset.names.push({
586 | Name : this.fstring("Name #" + (idx + 1) + ": string"),
587 | NonCasePreservingHash: this.uint16("Name #" + (idx + 1) + ": NonCasePreservingHash"),
588 | CasePreservingHash : this.uint16("Name #" + (idx + 1) + ": CasePreservingHash")
589 | });
590 | }
591 | };
592 |
593 | /**
594 | * Read Gatherable Text Data.
595 | *
596 | * @function ReaderUasset#readGatherableTextData
597 | * @returns {Error|undefined}
598 | * @private
599 | * @see https://github.com/EpicGames/UnrealEngine/blob/5.0/Engine/Source/Runtime/Core/Private/Internationalization/GatherableTextData.cpp
600 | */
601 | ReaderUasset.prototype.readGatherableTextData = function readGatherableTextData() {
602 | /** @type {GatherableTextData} */
603 | var gatherableTextData;
604 | /** @type {SourceSiteContexts} */
605 | var sourceSiteContexts;
606 | /** @type {number} */
607 | var countSourceSiteContexts;
608 | /** @type {number} */
609 | var idxSourceSiteContexts;
610 | /** @type {number} */
611 | var idx = 0;
612 | /** @type {number} */
613 | var count = this.uasset.header.GatherableTextDataCount;
614 |
615 | this.currentIdx = this.uasset.header.GatherableTextDataOffset;
616 |
617 | this.uasset.gatherableTextData = [];
618 | for (; idx < count; ++idx) {
619 | gatherableTextData = {};
620 |
621 | gatherableTextData.NamespaceName = this.fstring("GatherableTextData #" + (idx + 1) + ": NamespaceName");
622 |
623 | gatherableTextData.SourceData = {
624 | SourceString : this.fstring("GatherableTextData #" + (idx + 1) + ": SourceData.SourceString"),
625 | SourceStringMetaData: {
626 | ValueCount: this.int32("GatherableTextData #" + (idx + 1) + ": SourceData.CountSourceStringMetaData"),
627 | Values : []
628 | }
629 | };
630 |
631 | if (gatherableTextData.SourceData.SourceStringMetaData.ValueCount > 0) {
632 | return new Error("unsupported SourceStringMetaData from readGatherableTextData");
633 | }
634 |
635 | gatherableTextData.SourceSiteContexts = [];
636 | countSourceSiteContexts = this.int32("GatherableTextData #" + (idx + 1) + ": CountSourceSiteContexts");
637 | for (idxSourceSiteContexts = 0; idxSourceSiteContexts < countSourceSiteContexts; ++idxSourceSiteContexts) {
638 | sourceSiteContexts = {};
639 | sourceSiteContexts.KeyName = this.fstring("GatherableTextData #" + (idx + 1) + " - SourceSiteContexts #" + (idxSourceSiteContexts + 1) + ": KeyName");
640 | sourceSiteContexts.SiteDescription = this.fstring("GatherableTextData #" + (idx + 1) + " - SourceSiteContexts #" + (idxSourceSiteContexts + 1) + ": SiteDescription");
641 | sourceSiteContexts.IsEditorOnly = this.uint32("GatherableTextData #" + (idx + 1) + " - SourceSiteContexts #" + (idxSourceSiteContexts + 1) + ": IsEditorOnly");
642 | sourceSiteContexts.IsOptional = this.uint32("GatherableTextData #" + (idx + 1) + " - SourceSiteContexts #" + (idxSourceSiteContexts + 1) + ": IsOptional");
643 |
644 | sourceSiteContexts.InfoMetaData = {
645 | ValueCount: this.int32("GatherableTextData #" + (idx + 1) + " - SourceSiteContexts #" + (idxSourceSiteContexts + 1) + ": CountInfoMetaData"),
646 | Values : []
647 | };
648 |
649 | if (sourceSiteContexts.InfoMetaData.ValueCount > 0) {
650 | return new Error("unsupported SourceSiteContexts.InfoMetaData from readGatherableTextData");
651 | }
652 |
653 | sourceSiteContexts.KeyMetaData = {
654 | ValueCount: this.int32("GatherableTextData #" + (idx + 1) + " - SourceSiteContexts #" + (idxSourceSiteContexts + 1) + ": CountKeyMetaData"),
655 | Values : []
656 | };
657 |
658 | if (sourceSiteContexts.KeyMetaData.ValueCount > 0) {
659 | return new Error("unsupported SourceSiteContexts.KeyMetaData from readGatherableTextData");
660 | }
661 |
662 | gatherableTextData.SourceSiteContexts.push(sourceSiteContexts);
663 | }
664 |
665 | this.uasset.gatherableTextData.push(gatherableTextData);
666 | }
667 |
668 | return undefined;
669 | };
670 |
671 | /**
672 | * Read Imports.
673 | *
674 | * @function ReaderUasset#readImports
675 | * @returns {undefined}
676 | * @private
677 | * @see https://github.com/EpicGames/UnrealEngine/blob/5.0/Engine/Source/Runtime/CoreUObject/Private/UObject/ObjectResource.cpp#L302
678 | */
679 | ReaderUasset.prototype.readImports = function readImports() {
680 | var idx = 0;
681 | /** @type {number} */
682 | var classPackage;
683 | /** @type {number} */
684 | var className;
685 | /** @type {number} */
686 | var outerIndex;
687 | /** @type {number} */
688 | var objectName;
689 | /** @type {number} */
690 | var packageName = 0;
691 | /** @type {number} */
692 | var bImportOptional = 0;
693 | /** @type {number} */
694 | var count = this.uasset.header.ImportCount;
695 |
696 | this.currentIdx = this.uasset.header.ImportOffset;
697 |
698 | this.uasset.imports.Imports = [];
699 | for (; idx < count; ++idx) {
700 | classPackage = this.uint64("Import #" + (idx + 1) + ": classPackage");
701 | className = this.uint64("Import #" + (idx + 1) + ": className");
702 | outerIndex = this.int32("Import #" + (idx + 1) + ": outerIndex");
703 | objectName = this.uint64("Import #" + (idx + 1) + ": objectName");
704 |
705 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_NON_OUTER_PACKAGE_IMPORT.value) {
706 | packageName = this.uint64("Import #" + (idx + 1) + ": packageName");
707 | }
708 |
709 | if (this.uasset.header.FileVersionUE5 >= EUnrealEngineObjectUE5Version.VER_UE5_OPTIONAL_RESOURCES.value) {
710 | bImportOptional = this.int32("Import #" + (idx + 1) + ": importOptional");
711 | }
712 |
713 | this.uasset.imports.Imports.push({
714 | classPackage : this.resolveFName(classPackage),
715 | className : this.resolveFName(className),
716 | outerIndex : outerIndex,
717 | objectName : this.resolveFName(objectName),
718 | packageName : this.resolveFName(packageName),
719 | bImportOptional: bImportOptional
720 | });
721 | }
722 | };
723 |
724 | /**
725 | * Read Exports.
726 | *
727 | * @function ReaderUasset#readExports
728 | * @returns {undefined}
729 | * @private
730 | * @see https://github.com/EpicGames/UnrealEngine/blob/5.0/Engine/Source/Runtime/CoreUObject/Private/UObject/ObjectResource.cpp#L113
731 | * @todo Data are HERE, need to find how to read that
732 | */
733 | /* eslint-disable-next-line max-statements */
734 | ReaderUasset.prototype.readExports = function readExports() {
735 | /** @type {number} */
736 | var idx = 0;
737 | /** @type {number} */
738 | var count;
739 | /** @type {number} */
740 | var nodeNameRef;
741 | /** @type {number} */
742 | var classIndex;
743 | /** @type {number} */
744 | var superIndex;
745 | /** @type {number} */
746 | var templateIndex = 0;
747 | /** @type {number} */
748 | var outerIndex;
749 | /** @type {number} */
750 | var objectName;
751 | /** @type {number} */
752 | var objectFlags;
753 | /** @type {number} */
754 | var serialSize;
755 | /** @type {number} */
756 | var serialOffset;
757 | /** @type {number} */
758 | var bForcedExport;
759 | /** @type {number} */
760 | var bNotForClient;
761 | /** @type {number} */
762 | var bNotForServer;
763 | /** @type {string} */
764 | var packageGuid;
765 | /** @type {number} */
766 | var packageFlags;
767 | /** @type {number} */
768 | var bNotAlwaysLoadedForEditorGame = 0;
769 | /** @type {number} */
770 | var bIsAsset = 0;
771 | /** @type {number} */
772 | var bGeneratePublicHash = 0;
773 | /** @type {number} */
774 | var firstExportDependency = 0;
775 | /** @type {number} */
776 | var serializationBeforeSerializationDependencies = 0;
777 | /** @type {number} */
778 | var createBeforeSerializationDependencies = 0;
779 | /** @type {number} */
780 | var serializationBeforeCreateDependencies = 0;
781 | /** @type {number} */
782 | var createBeforeCreateDependencies = 0;
783 |
784 | this.currentIdx = this.uasset.header.ExportOffset;
785 |
786 | count = this.uasset.header.ExportCount;
787 | this.uasset.exports = [];
788 | for (; idx < count; ++idx) {
789 | classIndex = this.int32("Export #" + (idx + 1) + ": classIndex");
790 | superIndex = this.int32("Export #" + (idx + 1) + ": superIndex");
791 |
792 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_TEMPLATEINDEX_IN_COOKED_EXPORTS.value) {
793 | templateIndex = this.int32("Export #" + (idx + 1) + ": templateIndex");
794 | }
795 |
796 | outerIndex = this.int32("Export #" + (idx + 1) + ": outerIndex");
797 | objectName = this.uint64("Export #" + (idx + 1) + ": objectName");
798 | objectFlags = this.uint32("Export #" + (idx + 1) + ": objectFlags");
799 | serialSize = this.int64("Export #" + (idx + 1) + ": serialSize");
800 | serialOffset = this.int64("Export #" + (idx + 1) + ": serialOffset");
801 | bForcedExport = this.int32("Export #" + (idx + 1) + ": bForcedExport");
802 | bNotForClient = this.int32("Export #" + (idx + 1) + ": bNotForClient");
803 | bNotForServer = this.int32("Export #" + (idx + 1) + ": bNotForServer");
804 | packageGuid = this.fguidString("Export #" + (idx + 1) + ": packageGuid");
805 | packageFlags = this.uint32("Export #" + (idx + 1) + ": packageFlags");
806 |
807 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_LOAD_FOR_EDITOR_GAME.value) {
808 | bNotAlwaysLoadedForEditorGame = this.int32("Export #" + (idx + 1) + ": bNotAlwaysLoadedForEditorGame");
809 | }
810 |
811 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_COOKED_ASSETS_IN_EDITOR_SUPPORT.value) {
812 | bIsAsset = this.int32("Export #" + (idx + 1) + ": bIsAsset");
813 | }
814 |
815 | if (this.uasset.header.FileVersionUE5 >= EUnrealEngineObjectUE5Version.VER_UE5_OPTIONAL_RESOURCES.value) {
816 | bGeneratePublicHash = this.int32("Export #" + (idx + 1) + ": bGeneratePublicHash");
817 | }
818 |
819 | if (this.uasset.header.FileVersionUE4 >= EUnrealEngineObjectUE4Version.VER_UE4_PRELOAD_DEPENDENCIES_IN_COOKED_EXPORTS.value) {
820 | firstExportDependency = this.int32("Export #" + (idx + 1) + ": firstExportDependency");
821 | serializationBeforeSerializationDependencies = this.int32("Export #" + (idx + 1) + ": serializationBeforeSerializationDependencies");
822 | createBeforeSerializationDependencies = this.int32("Export #" + (idx + 1) + ": createBeforeSerializationDependencies");
823 | serializationBeforeCreateDependencies = this.int32("Export #" + (idx + 1) + ": serializationBeforeCreateDependencies");
824 | createBeforeCreateDependencies = this.int32("Export #" + (idx + 1) + ": createBeforeCreateDependencies");
825 | }
826 |
827 | this.uasset.exports.push({
828 | classIndex : classIndex,
829 | superIndex : superIndex,
830 | templateIndex : templateIndex,
831 | outerIndex : outerIndex,
832 | objectName : this.resolveFName(objectName),
833 | objectFlags : objectFlags,
834 | serialSize : serialSize,
835 | serialOffset : serialOffset,
836 | bForcedExport : bForcedExport,
837 | bNotForClient : bNotForClient,
838 | bNotForServer : bNotForServer,
839 | packageGuid : packageGuid,
840 | packageFlags : packageFlags,
841 | bNotAlwaysLoadedForEditorGame : bNotAlwaysLoadedForEditorGame,
842 | bIsAsset : bIsAsset,
843 | bGeneratePublicHash : bGeneratePublicHash,
844 | firstExportDependency : firstExportDependency,
845 | serializationBeforeSerializationDependencies: serializationBeforeSerializationDependencies,
846 | createBeforeSerializationDependencies : createBeforeSerializationDependencies,
847 | serializationBeforeCreateDependencies : serializationBeforeCreateDependencies,
848 | createBeforeCreateDependencies : createBeforeCreateDependencies,
849 | data : []
850 | });
851 | }
852 |
853 | for (idx = 0; idx < count; ++idx) {
854 | if (this.uasset.exports[idx].serialSize <= 0) {
855 | continue;
856 | }
857 |
858 | this.currentIdx = Number(this.uasset.exports[idx].serialOffset);
859 |
860 | // Data are HERE, need to find how to read that
861 |
862 | nodeNameRef = this.uint64("Exports #" + (idx + 1) + ": data");
863 | this.uasset.exports[idx].data.push(this.resolveFName(nodeNameRef));
864 | this.uasset.exports[idx].data.push(this.uint32("flags"));
865 | }
866 | };
867 |
868 | /**
869 | * Read Depends.
870 | *
871 | * @function ReaderUasset#readDepends
872 | * @returns {undefined}
873 | * @private
874 | */
875 | ReaderUasset.prototype.readDepends = function readDepends() {
876 | /** @type {number} */
877 | var idx = 0;
878 | /** @type {number} */
879 | var count;
880 |
881 | this.currentIdx = this.uasset.header.DependsOffset;
882 |
883 | count = this.int32("Depends Count");
884 | this.uasset.depends.Depends = [];
885 | for (; idx < count; ++idx) {
886 | this.uasset.depends.Depends.push({
887 | FPackageIndex: this.int32("Depend #" + (idx + 1) + ": FPackageIndex")
888 | });
889 | }
890 | };
891 |
892 | /**
893 | * Read Soft Package References.
894 | *
895 | * @function ReaderUasset#readSoftPackageReferences
896 | * @returns {undefined}
897 | * @private
898 | */
899 | ReaderUasset.prototype.readSoftPackageReferences = function readSoftPackageReferences() {
900 | /** @type {number} */
901 | var nameIndex;
902 | /** @type {number} */
903 | var idx = 0;
904 | /** @type {number} */
905 | var count;
906 |
907 | this.currentIdx = this.uasset.header.SoftPackageReferencesOffset;
908 |
909 | count = this.uasset.header.SoftPackageReferencesCount;
910 | this.uasset.softPackageReferences = [];
911 | for (; idx < count; ++idx) {
912 | nameIndex = this.uint64("SoftPackageReferences #" + (idx + 1) + ": SoftPackageReferences");
913 | this.uasset.softPackageReferences.push({
914 | assetPathName: this.resolveFName(nameIndex)
915 | });
916 | }
917 | };
918 |
919 | /**
920 | * Read Searchable Names.
921 | *
922 | * @function ReaderUasset#readSearchableNames
923 | * @returns {undefined}
924 | * @private
925 | */
926 | ReaderUasset.prototype.readSearchableNames = function readSearchableNames() {
927 | this.currentIdx = this.uasset.header.SearchableNamesOffset;
928 |
929 | this.int32("CountSearchableNames");
930 | this.uasset.searchableNames = [];
931 | };
932 |
933 | /**
934 | * Read Thumbnails.
935 | *
936 | * @function ReaderUasset#readThumbnails
937 | * @returns {undefined}
938 | * @private
939 | * @see https://github.com/EpicGames/UnrealEngine/blob/5.0/Engine/Source/Runtime/Core/Private/Misc/ObjectThumbnail.cpp#L42
940 | */
941 | ReaderUasset.prototype.readThumbnails = function readThumbnails() {
942 | /** @type {number} */
943 | var pos;
944 | /** @type {number} */
945 | var idx = 0;
946 | /** @type {number} */
947 | var count;
948 | /** @type {number} */
949 | var imageWidth;
950 | /** @type {number} */
951 | var imageHeight;
952 | /** @type {string} */
953 | var imageFormat;
954 | /** @type {number} */
955 | var imageSizeData;
956 | /** @type {number[]} */
957 | var imageData;
958 |
959 | this.currentIdx = this.uasset.header.ThumbnailTableOffset;
960 |
961 | count = this.int32("Thumbnails Count");
962 | this.uasset.thumbnails.Index = [];
963 | this.uasset.thumbnails.Thumbnails = [];
964 | for (; idx < count; ++idx) {
965 | this.uasset.thumbnails.Index.push({
966 | AssetClassName : this.fstring("Thumbnails #" + (idx + 1) + ": assetClassName"),
967 | ObjectPathWithoutPackageName: this.fstring("Thumbnails #" + (idx + 1) + ": objectPathWithoutPackageName"),
968 | FileOffset : this.int32("Thumbnails #" + (idx + 1) + ": fileOffset")
969 | });
970 | }
971 |
972 | for (idx = 0; idx < count; ++idx) {
973 | this.currentIdx = this.uasset.thumbnails.Index[idx].FileOffset;
974 |
975 | imageWidth = this.int32("Thumbnails #" + (idx + 1) + ": imageWidth");
976 | imageHeight = this.int32("Thumbnails #" + (idx + 1) + ": imageHeight");
977 | imageFormat = "PNG";
978 |
979 | if (imageHeight < 0) {
980 | imageFormat = "JPEG";
981 | imageHeight = imageHeight * -1;
982 | }
983 |
984 | imageData = [];
985 | imageSizeData = this.int32("Thumbnails #" + (idx + 1) + ": imageSizeData");
986 | if (imageSizeData > 0) {
987 | pos = this.currentIdx;
988 | imageData = this.readCountBytes(imageSizeData);
989 | this.addHexView("Thumbnails #" + (idx + 1) + ": imageData", "data", imageData.join(""), pos, this.currentIdx - 1);
990 | }
991 |
992 | this.uasset.thumbnails.Thumbnails.push({
993 | ImageWidth : imageWidth,
994 | ImageHeight : imageHeight,
995 | ImageFormat : imageFormat,
996 | ImageSizeData: imageSizeData,
997 | ImageData : imageData
998 | });
999 | }
1000 | };
1001 |
1002 | /**
1003 | * Read Asset Registry Data.
1004 | *
1005 | * @function ReaderUasset#readAssetRegistryData
1006 | * @returns {undefined}
1007 | * @private
1008 | */
1009 | ReaderUasset.prototype.readAssetRegistryData = function readAssetRegistryData() {
1010 | /** @type {number} */
1011 | var idx;
1012 | /** @type {number} */
1013 | var count;
1014 | /** @type {number} */
1015 | var idxTag;
1016 | /** @type {number} */
1017 | var countTag;
1018 | /** @type {number} */
1019 | var nextOffset = this.uasset.header.TotalHeaderSize;
1020 |
1021 | this.currentIdx = this.uasset.header.AssetRegistryDataOffset;
1022 |
1023 | if (this.uasset.header.WorldTileInfoDataOffset > 0) {
1024 | nextOffset = this.uasset.header.WorldTileInfoDataOffset;
1025 | }
1026 |
1027 | this.uasset.assetRegistryData.size = nextOffset - this.uasset.header.AssetRegistryDataOffset;
1028 |
1029 | this.uasset.assetRegistryData.DependencyDataOffset = this.int64("DependencyDataOffset");
1030 |
1031 | this.uasset.assetRegistryData.data = [];
1032 | count = this.int32("AssetRegistryData Count");
1033 | for (idx = 0; idx < count; ++idx) {
1034 | this.uasset.assetRegistryData.data.push({
1035 | ObjectPath : this.fstring("ObjectPath"),
1036 | ObjectClassName: this.fstring("ObjectClassName"),
1037 | Tags : []
1038 | });
1039 |
1040 | countTag = this.int32("AssetRegistryData Tag Count");
1041 | for (idxTag = 0; idxTag < countTag; ++idxTag) {
1042 | this.uasset.assetRegistryData.data[idx].Tags.push({
1043 | Key : this.fstring("key"),
1044 | Value: this.fstring("value")
1045 | });
1046 | }
1047 | }
1048 | };
1049 |
1050 | /**
1051 | * Read Preload Dependency.
1052 | *
1053 | * @function ReaderUasset#readPreloadDependency
1054 | * @returns {undefined}
1055 | * @private
1056 | */
1057 | ReaderUasset.prototype.readPreloadDependency = function readPreloadDependency() {
1058 | this.currentIdx = this.uasset.header.PreloadDependencyOffset;
1059 | };
1060 |
1061 | /**
1062 | * Read Bulk Data Start.
1063 | *
1064 | * @function ReaderUasset#readBulkDataStart
1065 | * @returns {undefined}
1066 | * @private
1067 | */
1068 | ReaderUasset.prototype.readBulkDataStart = function readBulkDataStart() {
1069 | this.currentIdx = Number(this.uasset.header.BulkDataStartOffset);
1070 | };
1071 |
1072 | /**
1073 | * Analyze Uasset.
1074 | *
1075 | * @function ReaderUasset#analyze
1076 | * @param {Uint8Array} bytes - bytes read from file
1077 | * @param {boolean} saveHexView - if true save all informations to debug
1078 | * @returns {(Error|Uasset)}
1079 | * @public
1080 | */
1081 | ReaderUasset.prototype.analyze = function analyze(bytes, saveHexView) {
1082 | /** @type {(Error|undefined)} */
1083 | var err;
1084 |
1085 | this.currentIdx = 0;
1086 | this.bytes = bytes;
1087 | this.saveHexView = saveHexView || false;
1088 | this.useLittleEndian = true;
1089 |
1090 | err = this.readHeader();
1091 | if (err !== undefined) {
1092 | return err;
1093 | }
1094 |
1095 | this.readNames();
1096 |
1097 | err = this.readGatherableTextData();
1098 | if (err !== undefined) {
1099 | return err;
1100 | }
1101 |
1102 | this.readImports();
1103 | this.readExports();
1104 | this.readDepends();
1105 | this.readSoftPackageReferences();
1106 | this.readSearchableNames();
1107 | this.readThumbnails();
1108 | this.readAssetRegistryData();
1109 | this.readPreloadDependency();
1110 | this.readBulkDataStart();
1111 |
1112 | this.uasset.hexView.sort(function sortHexView(left, right) {
1113 | return left.start - right.start;
1114 | });
1115 |
1116 | return this.uasset;
1117 | };
1118 |
1119 | // Freeze prototype for security issue about prototype pollution.
1120 | Object.freeze(ReaderUasset.prototype);
1121 | Object.freeze(ReaderUasset);
1122 |
1123 | window.blueprintUE.uasset.ReaderUasset = ReaderUasset;
1124 |
--------------------------------------------------------------------------------
/tests/datacases.json:
--------------------------------------------------------------------------------
1 | {
2 | "simple": {
3 | "ue50": [
4 | {
5 | "name": "BP_Actor_Simple",
6 | "input": "uassets/ue50/BP_Actor_Simple.uasset",
7 | "expected": "uassets/ue50/BP_Actor_Simple.json"
8 | }
9 | ]
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/main.test.js:
--------------------------------------------------------------------------------
1 | require("../src/js/_namespace_");
2 | require("../src/js/enums/enums");
3 | require("../src/js/main");
4 | const fs = require("fs");
5 | const path = require("path");
6 | const datacases = require("./datacases.json");
7 |
8 | function parseBigIntPayload(key, value) {
9 | if (["PayloadTocOffset", "BulkDataStartOffset"].indexOf(key) !== -1) {
10 | value = value.replace("n", "");
11 | value = BigInt(value);
12 | }
13 |
14 | return value;
15 | }
16 |
17 | describe("main", function() {
18 | // region constructor
19 | it("should be defined", () => {
20 | expect(window.blueprintUE.uasset.ReaderUasset).toBeDefined();
21 | });
22 | // endregion
23 |
24 | describe("datacases", function() {
25 | describe("simple", function() {
26 | describe("UE 5.0", function() {
27 | /* eslint-disable-next-line no-unused-vars */
28 | it.each(datacases.simple.ue50)(`$name`, ({name, input, expected}) => {
29 | const bytesInput = new Uint8Array(fs.readFileSync(path.resolve(__dirname, input)));
30 | const bytesOutput = JSON.parse(fs.readFileSync(path.resolve(__dirname, expected)).toString(), parseBigIntPayload);
31 |
32 | const uasset = new window.blueprintUE.uasset.ReaderUasset().analyze(bytesInput, false);
33 |
34 | expect(uasset.header).toStrictEqual(bytesOutput.header);
35 | expect(uasset.names).toStrictEqual(bytesOutput.names);
36 | expect(uasset.gatherableTextData).toStrictEqual(bytesOutput.gatherableTextData);
37 | });
38 | });
39 | });
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/tests/uassets/ue50/BP_Actor_Simple.json:
--------------------------------------------------------------------------------
1 | {
2 | "header": {
3 | "AdditionalPackagesToCook": [],
4 | "AssetRegistryDataOffset": 5620,
5 | "BulkDataStartOffset": "20574n",
6 | "ChunkIDs": [],
7 | "CompatibleWithEngineVersion": "5.0.0-19505902+++UE5+Release-5.0",
8 | "CompressionFlags": 0,
9 | "CustomVersions": [
10 | {
11 | "key": "29E575DDE0A346279D10D276232CDCEA",
12 | "version": 17
13 | },
14 | {
15 | "key": "375EC13C06E448FBB50084F0262A717E",
16 | "version": 4
17 | },
18 | {
19 | "key": "59DA5D5212324948B878597870B8E98B",
20 | "version": 8
21 | },
22 | {
23 | "key": "601D1886AC644F84AA16D3DE0DEAC7D6",
24 | "version": 59
25 | },
26 | {
27 | "key": "697DD581E64F41ABAA4A51ECBEB7B628",
28 | "version": 59
29 | },
30 | {
31 | "key": "9C54D522A8264FBE9421074661B482D0",
32 | "version": 44
33 | },
34 | {
35 | "key": "B0D832E41F894F0DACCF7EB736FD4AA2",
36 | "version": 10
37 | },
38 | {
39 | "key": "CFFC743F43B04480939114DF171D2073",
40 | "version": 37
41 | },
42 | {
43 | "key": "D89B5E4224BD4D468412ACA8DF641779",
44 | "version": 36
45 | },
46 | {
47 | "key": "E4B068EDF49442E9A231DA0B2E46BB41",
48 | "version": 40
49 | }
50 | ],
51 | "DependsOffset": 5352,
52 | "EPackageFileTag": 2653586369,
53 | "ExportCount": 14,
54 | "ExportOffset": 3840,
55 | "FileVersionLicenseeUE4": 0,
56 | "FileVersionUE4": 522,
57 | "FileVersionUE5": 1004,
58 | "FolderName": "None",
59 | "GatherableTextDataCount": 1,
60 | "GatherableTextDataOffset": 2969,
61 | "Generations": [
62 | {
63 | "exportCount": 14,
64 | "nameCount": 107
65 | }
66 | ],
67 | "Guid":"06318DB10D38BC46A951670107952FF5",
68 | "ImportCount": 18,
69 | "ImportOffset": 3120,
70 | "LegacyFileVersion": -8,
71 | "LegacyUE3Version": 864,
72 | "LocalizationId": "50B4947A4816F182AF72CC889D9D0EB8",
73 | "NameCount": 107,
74 | "NameOffset": 498,
75 | "NamesReferencedFromExportDataCount": 81,
76 | "PackageFlags": 262144,
77 | "PackageSource": 81731590,
78 | "PayloadTocOffset": "-1n",
79 | "PersistentGuid": "496FAA46B66D61499D3C93D6872762C1",
80 | "PreloadDependencyCount": -1,
81 | "PreloadDependencyOffset": 14650,
82 | "SavedByEngineVersion": "5.0.3-20979098+++UE5+Release-5.0",
83 | "SearchableNamesOffset": 5496,
84 | "SoftPackageReferencesCount": 1,
85 | "SoftPackageReferencesOffset": 5488,
86 | "ThumbnailTableOffset": 5524,
87 | "TotalHeaderSize": 14650,
88 | "WorldTileInfoDataOffset": 0
89 | },
90 | "names": [
91 | {
92 | "Name": "/Game/BP_Actor_Simple.BP_Actor_Simple",
93 | "NonCasePreservingHash": 29338,
94 | "CasePreservingHash": 60561
95 | },
96 | {
97 | "Name": "/Game/BP_Actor_Simple.BP_Actor_Simple_C",
98 | "NonCasePreservingHash": 12397,
99 | "CasePreservingHash": 33577
100 | },
101 | {
102 | "Name": "AllNodes",
103 | "NonCasePreservingHash": 5631,
104 | "CasePreservingHash": 17127
105 | },
106 | {
107 | "Name": "ArrayProperty",
108 | "NonCasePreservingHash": 45129,
109 | "CasePreservingHash": 27107
110 | },
111 | {
112 | "Name": "bAllowDeletion",
113 | "NonCasePreservingHash": 61951,
114 | "CasePreservingHash": 60174
115 | },
116 | {
117 | "Name": "bCommentBubblePinned",
118 | "NonCasePreservingHash": 11889,
119 | "CasePreservingHash": 19493
120 | },
121 | {
122 | "Name": "bCommentBubbleVisible",
123 | "NonCasePreservingHash": 9297,
124 | "CasePreservingHash": 15420
125 | },
126 | {
127 | "Name": "bLegacyNeedToPurgeSkelRefs",
128 | "NonCasePreservingHash": 44431,
129 | "CasePreservingHash": 15196
130 | },
131 | {
132 | "Name": "BlueprintGuid",
133 | "NonCasePreservingHash": 1999,
134 | "CasePreservingHash": 21786
135 | },
136 | {
137 | "Name": "BlueprintInternalUseOnly",
138 | "NonCasePreservingHash": 57478,
139 | "CasePreservingHash": 20896
140 | },
141 | {
142 | "Name": "BlueprintSystemVersion",
143 | "NonCasePreservingHash": 29825,
144 | "CasePreservingHash": 11017
145 | },
146 | {
147 | "Name": "BlueprintType",
148 | "NonCasePreservingHash": 4364,
149 | "CasePreservingHash": 57234
150 | },
151 | {
152 | "Name": "BoolProperty",
153 | "NonCasePreservingHash": 1040,
154 | "CasePreservingHash": 35504
155 | },
156 | {
157 | "Name": "bOverrideFunction",
158 | "NonCasePreservingHash": 62992,
159 | "CasePreservingHash": 23440
160 | },
161 | {
162 | "Name": "bVisualizeComponent",
163 | "NonCasePreservingHash": 34731,
164 | "CasePreservingHash": 55862
165 | },
166 | {
167 | "Name": "Category",
168 | "NonCasePreservingHash": 32503,
169 | "CasePreservingHash": 50580
170 | },
171 | {
172 | "Name": "CategoryName",
173 | "NonCasePreservingHash": 13966,
174 | "CasePreservingHash": 3160
175 | },
176 | {
177 | "Name": "Comment",
178 | "NonCasePreservingHash": 6602,
179 | "CasePreservingHash": 40892
180 | },
181 | {
182 | "Name": "ComponentClass",
183 | "NonCasePreservingHash": 65073,
184 | "CasePreservingHash": 22006
185 | },
186 | {
187 | "Name": "ComponentTemplate",
188 | "NonCasePreservingHash": 43732,
189 | "CasePreservingHash": 49698
190 | },
191 | {
192 | "Name": "DefaultGraphNode",
193 | "NonCasePreservingHash": 58036,
194 | "CasePreservingHash": 30438
195 | },
196 | {
197 | "Name": "DefaultSceneRoot",
198 | "NonCasePreservingHash": 36028,
199 | "CasePreservingHash": 1438
200 | },
201 | {
202 | "Name": "DefaultSceneRootNode",
203 | "NonCasePreservingHash": 20538,
204 | "CasePreservingHash": 58813
205 | },
206 | {
207 | "Name": "delegate",
208 | "NonCasePreservingHash": 64503,
209 | "CasePreservingHash": 36762
210 | },
211 | {
212 | "Name": "DeltaSeconds",
213 | "NonCasePreservingHash": 21698,
214 | "CasePreservingHash": 891
215 | },
216 | {
217 | "Name": "DisplayName",
218 | "NonCasePreservingHash": 38266,
219 | "CasePreservingHash": 17126
220 | },
221 | {
222 | "Name": "EditedDocumentInfo",
223 | "NonCasePreservingHash": 24507,
224 | "CasePreservingHash": 64272
225 | },
226 | {
227 | "Name": "EditedObjectPath",
228 | "NonCasePreservingHash": 16846,
229 | "CasePreservingHash": 32927
230 | },
231 | {
232 | "Name": "EnabledState",
233 | "NonCasePreservingHash": 9665,
234 | "CasePreservingHash": 56654
235 | },
236 | {
237 | "Name": "Engine",
238 | "NonCasePreservingHash": 439,
239 | "CasePreservingHash": 58948
240 | },
241 | {
242 | "Name": "ENodeEnabledState",
243 | "NonCasePreservingHash": 16518,
244 | "CasePreservingHash": 62427
245 | },
246 | {
247 | "Name": "ENodeEnabledState::Disabled",
248 | "NonCasePreservingHash": 43953,
249 | "CasePreservingHash": 54526
250 | },
251 | {
252 | "Name": "EnumProperty",
253 | "NonCasePreservingHash": 55121,
254 | "CasePreservingHash": 16541
255 | },
256 | {
257 | "Name": "EventReference",
258 | "NonCasePreservingHash": 41639,
259 | "CasePreservingHash": 44001
260 | },
261 | {
262 | "Name": "exec",
263 | "NonCasePreservingHash": 60028,
264 | "CasePreservingHash": 6908
265 | },
266 | {
267 | "Name": "float",
268 | "NonCasePreservingHash": 30996,
269 | "CasePreservingHash": 52381
270 | },
271 | {
272 | "Name": "FloatProperty",
273 | "NonCasePreservingHash": 43003,
274 | "CasePreservingHash": 64990
275 | },
276 | {
277 | "Name": "FunctionGraphs",
278 | "NonCasePreservingHash": 10564,
279 | "CasePreservingHash": 15656
280 | },
281 | {
282 | "Name": "FunctionReference",
283 | "NonCasePreservingHash": 23205,
284 | "CasePreservingHash": 5628
285 | },
286 | {
287 | "Name": "GeneratedClass",
288 | "NonCasePreservingHash": 2182,
289 | "CasePreservingHash": 21592
290 | },
291 | {
292 | "Name": "GraphGuid",
293 | "NonCasePreservingHash": 33442,
294 | "CasePreservingHash": 30411
295 | },
296 | {
297 | "Name": "Guid",
298 | "NonCasePreservingHash": 20547,
299 | "CasePreservingHash": 26874
300 | },
301 | {
302 | "Name": "InternalVariableName",
303 | "NonCasePreservingHash": 65341,
304 | "CasePreservingHash": 64778
305 | },
306 | {
307 | "Name": "IntProperty",
308 | "NonCasePreservingHash": 54181,
309 | "CasePreservingHash": 18998
310 | },
311 | {
312 | "Name": "LastEditedDocuments",
313 | "NonCasePreservingHash": 7692,
314 | "CasePreservingHash": 53250
315 | },
316 | {
317 | "Name": "MemberName",
318 | "NonCasePreservingHash": 8076,
319 | "CasePreservingHash": 46771
320 | },
321 | {
322 | "Name": "MemberParent",
323 | "NonCasePreservingHash": 59774,
324 | "CasePreservingHash": 15485
325 | },
326 | {
327 | "Name": "MemberReference",
328 | "NonCasePreservingHash": 46718,
329 | "CasePreservingHash": 16313
330 | },
331 | {
332 | "Name": "ModuleRelativePath",
333 | "NonCasePreservingHash": 8816,
334 | "CasePreservingHash": 24971
335 | },
336 | {
337 | "Name": "NameProperty",
338 | "NonCasePreservingHash": 62082,
339 | "CasePreservingHash": 18952
340 | },
341 | {
342 | "Name": "NodeComment",
343 | "NonCasePreservingHash": 9312,
344 | "CasePreservingHash": 62303
345 | },
346 | {
347 | "Name": "NodeGuid",
348 | "NonCasePreservingHash": 44241,
349 | "CasePreservingHash": 43780
350 | },
351 | {
352 | "Name": "NodePosY",
353 | "NonCasePreservingHash": 18034,
354 | "CasePreservingHash": 26093
355 | },
356 | {
357 | "Name": "Nodes",
358 | "NonCasePreservingHash": 65209,
359 | "CasePreservingHash": 27803
360 | },
361 | {
362 | "Name": "None",
363 | "NonCasePreservingHash": 1012,
364 | "CasePreservingHash": 3525
365 | },
366 | {
367 | "Name": "object",
368 | "NonCasePreservingHash": 19301,
369 | "CasePreservingHash": 65431
370 | },
371 | {
372 | "Name": "ObjectProperty",
373 | "NonCasePreservingHash": 56129,
374 | "CasePreservingHash": 60083
375 | },
376 | {
377 | "Name": "OtherActor",
378 | "NonCasePreservingHash": 60607,
379 | "CasePreservingHash": 64347
380 | },
381 | {
382 | "Name": "OutputDelegate",
383 | "NonCasePreservingHash": 27916,
384 | "CasePreservingHash": 19858
385 | },
386 | {
387 | "Name": "PackageLocalizationNamespace",
388 | "NonCasePreservingHash": 29714,
389 | "CasePreservingHash": 34937
390 | },
391 | {
392 | "Name": "ParentClass",
393 | "NonCasePreservingHash": 56600,
394 | "CasePreservingHash": 23461
395 | },
396 | {
397 | "Name": "real",
398 | "NonCasePreservingHash": 51542,
399 | "CasePreservingHash": 11945
400 | },
401 | {
402 | "Name": "ReceiveActorBeginOverlap",
403 | "NonCasePreservingHash": 62953,
404 | "CasePreservingHash": 47985
405 | },
406 | {
407 | "Name": "ReceiveBeginPlay",
408 | "NonCasePreservingHash": 32129,
409 | "CasePreservingHash": 51810
410 | },
411 | {
412 | "Name": "ReceiveTick",
413 | "NonCasePreservingHash": 20811,
414 | "CasePreservingHash": 52988
415 | },
416 | {
417 | "Name": "RootNodes",
418 | "NonCasePreservingHash": 3095,
419 | "CasePreservingHash": 22343
420 | },
421 | {
422 | "Name": "SavedViewOffset",
423 | "NonCasePreservingHash": 51324,
424 | "CasePreservingHash": 17644
425 | },
426 | {
427 | "Name": "SavedZoomAmount",
428 | "NonCasePreservingHash": 5727,
429 | "CasePreservingHash": 51597
430 | },
431 | {
432 | "Name": "Schema",
433 | "NonCasePreservingHash": 48127,
434 | "CasePreservingHash": 30603
435 | },
436 | {
437 | "Name": "SimpleConstructionScript",
438 | "NonCasePreservingHash": 11028,
439 | "CasePreservingHash": 8274
440 | },
441 | {
442 | "Name": "SoftObjectPath",
443 | "NonCasePreservingHash": 41343,
444 | "CasePreservingHash": 41435
445 | },
446 | {
447 | "Name": "StrProperty",
448 | "NonCasePreservingHash": 49467,
449 | "CasePreservingHash": 9330
450 | },
451 | {
452 | "Name": "StructProperty",
453 | "NonCasePreservingHash": 48,
454 | "CasePreservingHash": 64668
455 | },
456 | {
457 | "Name": "TextProperty",
458 | "NonCasePreservingHash": 15044,
459 | "CasePreservingHash": 46964
460 | },
461 | {
462 | "Name": "then",
463 | "NonCasePreservingHash": 45441,
464 | "CasePreservingHash": 32978
465 | },
466 | {
467 | "Name": "ThumbnailInfo",
468 | "NonCasePreservingHash": 19634,
469 | "CasePreservingHash": 45875
470 | },
471 | {
472 | "Name": "ToolTip",
473 | "NonCasePreservingHash": 60085,
474 | "CasePreservingHash": 48647
475 | },
476 | {
477 | "Name": "UbergraphPages",
478 | "NonCasePreservingHash": 8986,
479 | "CasePreservingHash": 13218
480 | },
481 | {
482 | "Name": "UserConstructionScript",
483 | "NonCasePreservingHash": 45901,
484 | "CasePreservingHash": 96
485 | },
486 | {
487 | "Name": "VariableGuid",
488 | "NonCasePreservingHash": 38571,
489 | "CasePreservingHash": 55934
490 | },
491 | {
492 | "Name": "Vector2D",
493 | "NonCasePreservingHash": 12373,
494 | "CasePreservingHash": 2412
495 | },
496 | {
497 | "Name": "/Game/BP_Actor_Simple",
498 | "NonCasePreservingHash": 45200,
499 | "CasePreservingHash": 1766
500 | },
501 | {
502 | "Name": "/Script/BlueprintGraph",
503 | "NonCasePreservingHash": 56297,
504 | "CasePreservingHash": 17532
505 | },
506 | {
507 | "Name": "/Script/CoreUObject",
508 | "NonCasePreservingHash": 18936,
509 | "CasePreservingHash": 15917
510 | },
511 | {
512 | "Name": "/Script/Engine",
513 | "NonCasePreservingHash": 16518,
514 | "CasePreservingHash": 18821
515 | },
516 | {
517 | "Name": "/Script/UnrealEd",
518 | "NonCasePreservingHash": 1068,
519 | "CasePreservingHash": 2199
520 | },
521 | {
522 | "Name": "Actor",
523 | "NonCasePreservingHash": 53037,
524 | "CasePreservingHash": 22819
525 | },
526 | {
527 | "Name": "Blueprint",
528 | "NonCasePreservingHash": 14612,
529 | "CasePreservingHash": 3379
530 | },
531 | {
532 | "Name": "BlueprintGeneratedClass",
533 | "NonCasePreservingHash": 39721,
534 | "CasePreservingHash": 11632
535 | },
536 | {
537 | "Name": "BP_Actor_Simple",
538 | "NonCasePreservingHash": 50246,
539 | "CasePreservingHash": 61200
540 | },
541 | {
542 | "Name": "BP_Actor_Simple_C",
543 | "NonCasePreservingHash": 49498,
544 | "CasePreservingHash": 25989
545 | },
546 | {
547 | "Name": "Class",
548 | "NonCasePreservingHash": 30580,
549 | "CasePreservingHash": 37240
550 | },
551 | {
552 | "Name": "Default__Actor",
553 | "NonCasePreservingHash": 52377,
554 | "CasePreservingHash": 37723
555 | },
556 | {
557 | "Name": "Default__BP_Actor_Simple_C",
558 | "NonCasePreservingHash": 55410,
559 | "CasePreservingHash": 35552
560 | },
561 | {
562 | "Name": "DefaultSceneRoot_GEN_VARIABLE",
563 | "NonCasePreservingHash": 32430,
564 | "CasePreservingHash": 18564
565 | },
566 | {
567 | "Name": "EdGraph",
568 | "NonCasePreservingHash": 28420,
569 | "CasePreservingHash": 23988
570 | },
571 | {
572 | "Name": "EdGraphSchema_K2",
573 | "NonCasePreservingHash": 49592,
574 | "CasePreservingHash": 3480
575 | },
576 | {
577 | "Name": "EventGraph",
578 | "NonCasePreservingHash": 42333,
579 | "CasePreservingHash": 23809
580 | },
581 | {
582 | "Name": "K2Node_Event",
583 | "NonCasePreservingHash": 34163,
584 | "CasePreservingHash": 7002
585 | },
586 | {
587 | "Name": "K2Node_FunctionEntry",
588 | "NonCasePreservingHash": 54171,
589 | "CasePreservingHash": 10757
590 | },
591 | {
592 | "Name": "MetaData",
593 | "NonCasePreservingHash": 32996,
594 | "CasePreservingHash": 37812
595 | },
596 | {
597 | "Name": "Object",
598 | "NonCasePreservingHash": 19301,
599 | "CasePreservingHash": 493
600 | },
601 | {
602 | "Name": "Package",
603 | "NonCasePreservingHash": 18291,
604 | "CasePreservingHash": 5512
605 | },
606 | {
607 | "Name": "PackageMetaData",
608 | "NonCasePreservingHash": 11421,
609 | "CasePreservingHash": 26020
610 | },
611 | {
612 | "Name": "SceneComponent",
613 | "NonCasePreservingHash": 6216,
614 | "CasePreservingHash": 24420
615 | },
616 | {
617 | "Name": "SceneThumbnailInfo",
618 | "NonCasePreservingHash": 59682,
619 | "CasePreservingHash": 46086
620 | },
621 | {
622 | "Name": "SCS_Node",
623 | "NonCasePreservingHash": 54065,
624 | "CasePreservingHash": 50642
625 | }
626 | ],
627 | "gatherableTextData":[
628 | {
629 | "NamespaceName": "SCS",
630 | "SourceData": {
631 | "SourceString": "Default",
632 | "SourceStringMetaData": {
633 | "ValueCount": 0,
634 | "Values": []
635 | }
636 | },
637 | "SourceSiteContexts": [
638 | {
639 | "KeyName": "Default",
640 | "SiteDescription": "/Game/BP_Actor_Simple.BP_Actor_Simple_C:SimpleConstructionScript_0.SCS_Node_0.CategoryName",
641 | "IsEditorOnly": 1,
642 | "IsOptional": 0,
643 | "InfoMetaData": {
644 | "ValueCount": 0,
645 | "Values": []
646 | },
647 | "KeyMetaData": {
648 | "ValueCount": 0,
649 | "Values": []
650 | }
651 | }
652 | ]
653 | }
654 | ]
655 | }
--------------------------------------------------------------------------------
/tests/uassets/ue50/BP_Actor_Simple.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blueprintue/uasset-reader-js/0e1dc14e10dcdf9b77cd0242e0f0298374406cec/tests/uassets/ue50/BP_Actor_Simple.uasset
--------------------------------------------------------------------------------
/tests/uassets/ue50/BP_Actor_Simple.utxt:
--------------------------------------------------------------------------------
1 | {
2 | "GatherableTextData": [
3 | {
4 | "NamespaceName": "SCS",
5 | "SourceData": {
6 | "SourceString": "Default",
7 | "SourceStringMetaData": {
8 | "ValueCount": 0,
9 | "Values": []
10 | }
11 | },
12 | "SourceSiteContexts": [
13 | {
14 | "KeyName": "Default",
15 | "SiteDescription": "/Game/BP_Actor_Simple.BP_Actor_Simple_C:SimpleConstructionScript_0.SCS_Node_0.CategoryName",
16 | "IsEditorOnly": true,
17 | "IsOptional": false,
18 | "InfoMetaData": {
19 | "ValueCount": 0,
20 | "Values": []
21 | },
22 | "KeyMetaData": {
23 | "ValueCount": 0,
24 | "Values": []
25 | }
26 | }
27 | ]
28 | }
29 | ],
30 | "Thumbnails": {
31 | "Thumbnails": [
32 | {
33 | "ImageWidth": 0,
34 | "ImageHeight": 0,
35 | "CompressedImageData": "Base64:"
36 | },
37 | {
38 | "ImageWidth": 0,
39 | "ImageHeight": 0,
40 | "CompressedImageData": "Base64:"
41 | }
42 | ],
43 | "Index": [
44 | {
45 | "ObjectClassName": "Blueprint",
46 | "ObjectPathWithoutPackageName": "BP_Actor_Simple",
47 | "FileOffset": 0
48 | },
49 | {
50 | "ObjectClassName": "BlueprintGeneratedClass",
51 | "ObjectPathWithoutPackageName": "BP_Actor_Simple_C",
52 | "FileOffset": 0
53 | }
54 | ]
55 | },
56 | "Exports": {
57 | "BP_Actor_Simple": {
58 | "__Class": "Class /Script/Engine.Blueprint",
59 | "__ObjectFlags": 11,
60 | "__bNotForClient": true,
61 | "__bNotForServer": true,
62 | "__bIsAsset": true,
63 | "__Value": {
64 | "BaseClassAutoGen": {
65 | "Data": {
66 | "Digest": "10372b3ba5db31ccfc7b581c21f43b10037f0083",
67 | "Base64": [
68 | "AAAAAAEAAAAEAAAAAAAAAAAAAAAAAgAAAAMAAAAEAAAAAAAAAAACAAAABAAAAAEAAAAEAAAAAAAAAAABAAAABQAAAAYAAAAIAAAAAAAAAAEAAAAAAQAAAAIA",
69 | "AAAHAAAABgAAAAgAAAAAAAAAAQAAAAABAAAAAwAAAAgAAAAGAAAAjgEAAAAAAAAJAAAAAAMAAAAIAAAACQAAAGUBAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAA",
70 | "AAAACwAAAAkAAAAEAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAACQAAABAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
71 | "AAAAAAAAAA8AAAAQAAAABAAAAAAAAAAAAACAvxEAAAALAAAACQAAAAQAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA0AAAAJAAAAEAAAAAAAAAAO",
72 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAAABAAAAAEAAAAAAAAAAAAAIC/EQAAAAsAAAAJAAAABAAAAAAAAAAMAAAAAAAAAAAAAAAA",
73 | "AAAAAAAAAAACAAAADQAAAAkAAAAQAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAEAAAAAQAAAAAAAAAAAAAgL8RAAAA",
74 | "EgAAAAEAAAAEAAAAAAAAAAAEAAAAEwAAAAEAAAAEAAAAAAAAAAAFAAAAFAAAABUAAAAAAAAAAAAAAAAAFgAAAAkAAAAQAAAAAAAAABcAAAAAAAAAAAAAAAAA",
75 | "AAAAAAAAAA/J7U/Ev9RHmOOY0CDtAukRAAAAAAAAAA=="
76 | ]
77 | },
78 | "Objects": [
79 | "Object:/Script/CoreUObject.Class /Script/Engine.Actor",
80 | "Object:/Script/Engine.SimpleConstructionScript /Game/BP_Actor_Simple.BP_Actor_Simple_C:SimpleConstructionScript_0",
81 | "Object:/Script/Engine.EdGraph /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph",
82 | "Object:/Script/Engine.EdGraph /Game/BP_Actor_Simple.BP_Actor_Simple:UserConstructionScript",
83 | "Object:/Script/UnrealEd.SceneThumbnailInfo /Game/BP_Actor_Simple.BP_Actor_Simple:SceneThumbnailInfo_0",
84 | "Object:/Script/Engine.BlueprintGeneratedClass /Game/BP_Actor_Simple.BP_Actor_Simple_C"
85 | ],
86 | "Names": [
87 | "ParentClass",
88 | "ObjectProperty",
89 | "BlueprintSystemVersion",
90 | "IntProperty",
91 | "SimpleConstructionScript",
92 | "UbergraphPages",
93 | "ArrayProperty",
94 | "FunctionGraphs",
95 | "LastEditedDocuments",
96 | "StructProperty",
97 | "EditedDocumentInfo",
98 | "EditedObjectPath",
99 | "SoftObjectPath",
100 | "SavedViewOffset",
101 | "Vector2D",
102 | "SavedZoomAmount",
103 | "FloatProperty",
104 | "None",
105 | "ThumbnailInfo",
106 | "GeneratedClass",
107 | "bLegacyNeedToPurgeSkelRefs",
108 | "BoolProperty",
109 | "BlueprintGuid",
110 | "Guid"
111 | ],
112 | "SoftObjectPaths": [
113 | "Object:/Game/BP_Actor_Simple.BP_Actor_Simple_C:SimpleConstructionScript_0",
114 | "Object:/Game/BP_Actor_Simple.BP_Actor_Simple:UserConstructionScript",
115 | "Object:/Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph"
116 | ]
117 | }
118 | }
119 | },
120 | "BP_Actor_Simple_C": {
121 | "__Class": "Class /Script/Engine.BlueprintGeneratedClass",
122 | "__SuperStruct": "Class /Script/Engine.Actor",
123 | "__ObjectFlags": 9,
124 | "__bIsAsset": true,
125 | "__Value": {
126 | "Data": {
127 | "Digest": "7c90b254dc8ce36d9252e841b03533c9882d3412",
128 | "Base64": [
129 | "AAAAAAEAAAAEAAAAAAAAAAAAAAAAAgAAAAAAAAABAAAAAAAAAAEAAAABAAAAAwAAAAEAIAABAAAAAQAAAAQAAAAIAAAARGVmYXVsdAABAAAACAAAAAQACAAE",
130 | "AAAAAAACAAAAAAIAAAAAAAAAAAAAAAAAAAAECIQAAwAAAAUAAAAEAAAAAAAAAAAAAAACAAAAAAAAAAUAAAA="
131 | ]
132 | },
133 | "Objects": [
134 | "Object:/Script/Engine.SimpleConstructionScript /Game/BP_Actor_Simple.BP_Actor_Simple_C:SimpleConstructionScript_0",
135 | "Object:/Script/CoreUObject.Class /Script/Engine.Actor",
136 | "Object:/Script/CoreUObject.Class /Script/Engine.SceneComponent",
137 | "Object:/Script/CoreUObject.Class /Script/CoreUObject.Object",
138 | "Object:/Script/Engine.Blueprint /Game/BP_Actor_Simple.BP_Actor_Simple",
139 | "Object:/Game/BP_Actor_Simple.BP_Actor_Simple_C /Game/BP_Actor_Simple.Default__BP_Actor_Simple_C"
140 | ],
141 | "Names": [
142 | "SimpleConstructionScript",
143 | "ObjectProperty",
144 | "None",
145 | "DefaultSceneRoot",
146 | "Category",
147 | "Engine"
148 | ]
149 | }
150 | },
151 | "Default__BP_Actor_Simple_C": {
152 | "__Class": "BlueprintGeneratedClass /Game/BP_Actor_Simple.BP_Actor_Simple_C",
153 | "__ObjectFlags": 49,
154 | "__Value": {
155 | "Data": "Base64:AAAAAAAAAAA=",
156 | "Objects": [
157 | null
158 | ],
159 | "Names": [
160 | "None"
161 | ]
162 | }
163 | },
164 | "BP_Actor_Simple:EventGraph": {
165 | "__Class": "Class /Script/Engine.EdGraph",
166 | "__Outer": "Blueprint /Game/BP_Actor_Simple.BP_Actor_Simple",
167 | "__ObjectFlags": 8,
168 | "__Value": {
169 | "Properties": {
170 | "Schema": {
171 | "__Type": "ObjectProperty",
172 | "__Value": "Object:/Script/CoreUObject.Class /Script/BlueprintGraph.EdGraphSchema_K2"
173 | },
174 | "Nodes": {
175 | "__Type": "ArrayProperty",
176 | "__InnerType": "ObjectProperty",
177 | "__Value": [
178 | "Object:/Script/BlueprintGraph.K2Node_Event /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph.K2Node_Event_0",
179 | "Object:/Script/BlueprintGraph.K2Node_Event /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph.K2Node_Event_1",
180 | "Object:/Script/BlueprintGraph.K2Node_Event /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph.K2Node_Event_2"
181 | ]
182 | },
183 | "bAllowDeletion": {
184 | "__Type": "BoolProperty",
185 | "__Value": 0
186 | },
187 | "GraphGuid": {
188 | "__Type": "StructProperty",
189 | "__StructName": "Guid",
190 | "__Value": "80D7644A4C053D71DC2DD3957E802C71"
191 | }
192 | }
193 | }
194 | },
195 | "BP_Actor_Simple:UserConstructionScript": {
196 | "__Class": "Class /Script/Engine.EdGraph",
197 | "__Outer": "Blueprint /Game/BP_Actor_Simple.BP_Actor_Simple",
198 | "__ObjectFlags": 8,
199 | "__Value": {
200 | "Properties": {
201 | "Schema": {
202 | "__Type": "ObjectProperty",
203 | "__Value": "Object:/Script/CoreUObject.Class /Script/BlueprintGraph.EdGraphSchema_K2"
204 | },
205 | "Nodes": {
206 | "__Type": "ArrayProperty",
207 | "__InnerType": "ObjectProperty",
208 | "__Value": [
209 | "Object:/Script/BlueprintGraph.K2Node_FunctionEntry /Game/BP_Actor_Simple.BP_Actor_Simple:UserConstructionScript.K2Node_FunctionEntry_0"
210 | ]
211 | },
212 | "bAllowDeletion": {
213 | "__Type": "BoolProperty",
214 | "__Value": 0
215 | },
216 | "GraphGuid": {
217 | "__Type": "StructProperty",
218 | "__StructName": "Guid",
219 | "__Value": "62BB7F164F284D40007185972DF6D63F"
220 | }
221 | }
222 | }
223 | },
224 | "BP_Actor_Simple:EventGraph.K2Node_Event_0": {
225 | "__Class": "Class /Script/BlueprintGraph.K2Node_Event",
226 | "__Outer": "EdGraph /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph",
227 | "__ObjectFlags": 8,
228 | "__Value": {
229 | "BaseClassAutoGen": {
230 | "Data": {
231 | "Digest": "3010a4471c0269a54720aaae696bc4e0f0ae324a",
232 | "Base64": [
233 | "AAAAAAEAAAAuAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAEAAAABAAAAAAAAAAAAAAAAAUAAAAGAAAABAAAAAAAAAAABwAAAAgAAAAJAAAACgAA",
234 | "AAAAAAAAAAAAAQALAAAADAAAAAQAAAAAAAAADQAAAAAOAAAADwAAAAoAAAAAAAAAAAAAAAEAEAAAAAoAAAAAAAAAAAAAAAEAEQAAABIAAABYAAAAAAAAAABU",
235 | "AAAAVGhpcyBub2RlIGlzIGRpc2FibGVkIGFuZCB3aWxsIG5vdCBiZSBjYWxsZWQuCkRyYWcgb2ZmIHBpbnMgdG8gYnVpbGQgZnVuY3Rpb25hbGl0eS4AEwAA",
236 | "AAEAAAAQAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAErEMMhye4dDkwlWjvBkyBsIAAAAAAAAAAIAAAAAAAAAAQAAAOt2CaTCkRFIk6vV5P/B4rQBAAAA",
237 | "63YJpMKREUiTq9Xk/8HitBUAAAAAAAAA/wAAAAD/////AAAAAAEWAAAACAAAAAIAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
238 | "AAAAAAAAAAAAAAAAAAIAAAAAAAAA/wAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAB5FgZWkOSFDtXa0O68Lx/gBAAAA",
239 | "HkWBlaQ5IUO1drQ7rwvH+BcAAAAAAAAA/wAAAAD/////AAAAAAEYAAAACAAAAAIAAAAAAAAAAAAAAAACAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
240 | "AAAAAAAAAAAAAAAAAAIAAAAAAAAA/wAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
241 | ]
242 | },
243 | "Objects": [
244 | "Object:/Script/CoreUObject.Class /Script/Engine.Actor",
245 | "Object:/Script/BlueprintGraph.K2Node_Event /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph.K2Node_Event_0",
246 | null
247 | ],
248 | "Names": [
249 | "EventReference",
250 | "StructProperty",
251 | "MemberReference",
252 | "MemberParent",
253 | "ObjectProperty",
254 | "MemberName",
255 | "NameProperty",
256 | "ReceiveBeginPlay",
257 | "None",
258 | "bOverrideFunction",
259 | "BoolProperty",
260 | "EnabledState",
261 | "EnumProperty",
262 | "ENodeEnabledState",
263 | "ENodeEnabledState::Disabled",
264 | "bCommentBubblePinned",
265 | "bCommentBubbleVisible",
266 | "NodeComment",
267 | "StrProperty",
268 | "NodeGuid",
269 | "Guid",
270 | "OutputDelegate",
271 | "delegate",
272 | "then",
273 | "exec"
274 | ]
275 | }
276 | }
277 | },
278 | "BP_Actor_Simple:EventGraph.K2Node_Event_1": {
279 | "__Class": "Class /Script/BlueprintGraph.K2Node_Event",
280 | "__Outer": "EdGraph /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph",
281 | "__ObjectFlags": 8,
282 | "__Value": {
283 | "BaseClassAutoGen": {
284 | "Data": {
285 | "Digest": "e3b3b9cc96a99308ee01d552146996c4337522bf",
286 | "Base64": [
287 | "AAAAAAEAAAAuAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAEAAAABAAAAAAAAAAAAAAAAAUAAAAGAAAABAAAAAAAAAAABwAAAAgAAAAJAAAACgAA",
288 | "AAAAAAAAAAAAAQALAAAADAAAAAQAAAAAAAAAANAAAAANAAAADgAAAAQAAAAAAAAADwAAAAAQAAAAEQAAAAoAAAAAAAAAAAAAAAEAEgAAAAoAAAAAAAAAAAAA",
289 | "AAEAEwAAABQAAABYAAAAAAAAAABUAAAAVGhpcyBub2RlIGlzIGRpc2FibGVkIGFuZCB3aWxsIG5vdCBiZSBjYWxsZWQuCkRyYWcgb2ZmIHBpbnMgdG8gYnVp",
290 | "bGQgZnVuY3Rpb25hbGl0eS4AFQAAAAEAAAAQAAAAAAAAABYAAAAAAAAAAAAAAAAAAAAAAAAAAFrQJUwFeA5Ou5uMIryPUq0IAAAAAAAAAAMAAAAAAAAAAQAA",
291 | "ABCQu7JBkuxGu4hOZYadL6MBAAAAEJC7skGS7Ea7iE5lhp0voxcAAAAAAAAA/wAAAAD/////AAAAAAEYAAAACAAAAAIAAAAAAAAAAAAAAAAAAAAABwAAAAAA",
292 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAA/wAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA",
293 | "ACQpWe2xfPRDmqFkTo897woBAAAAJClZ7bF89EOaoWROjz3vChkAAAAAAAAA/wAAAAD/////AAAAAAEaAAAACAAAAAIAAAAAAAAAAAAAAAACAAAACAAAAAAA",
294 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAA/wAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA",
295 | "AFDKR5O36itDhQXpXBnWB3MBAAAAUMpHk7fqK0OFBelcGdYHcxsAAAAAAAAA/wAAAAD/////IwAAAE90aGVyIEFjdG9yCkFjdG9yIE9iamVjdCBSZWZlcmVu",
296 | "Y2UAARwAAAAIAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAD/AAAAAAAAAAAAAAAA",
297 | "AQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
298 | ]
299 | },
300 | "Objects": [
301 | "Object:/Script/CoreUObject.Class /Script/Engine.Actor",
302 | "Object:/Script/BlueprintGraph.K2Node_Event /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph.K2Node_Event_1",
303 | null
304 | ],
305 | "Names": [
306 | "EventReference",
307 | "StructProperty",
308 | "MemberReference",
309 | "MemberParent",
310 | "ObjectProperty",
311 | "MemberName",
312 | "NameProperty",
313 | "ReceiveActorBeginOverlap",
314 | "None",
315 | "bOverrideFunction",
316 | "BoolProperty",
317 | "NodePosY",
318 | "IntProperty",
319 | "EnabledState",
320 | "EnumProperty",
321 | "ENodeEnabledState",
322 | "ENodeEnabledState::Disabled",
323 | "bCommentBubblePinned",
324 | "bCommentBubbleVisible",
325 | "NodeComment",
326 | "StrProperty",
327 | "NodeGuid",
328 | "Guid",
329 | "OutputDelegate",
330 | "delegate",
331 | "then",
332 | "exec",
333 | "OtherActor",
334 | "object"
335 | ]
336 | }
337 | }
338 | },
339 | "BP_Actor_Simple:EventGraph.K2Node_Event_2": {
340 | "__Class": "Class /Script/BlueprintGraph.K2Node_Event",
341 | "__Outer": "EdGraph /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph",
342 | "__ObjectFlags": 8,
343 | "__Value": {
344 | "BaseClassAutoGen": {
345 | "Data": {
346 | "Digest": "98daf35e4938c7a8412e6067ffab274146e7924e",
347 | "Base64": [
348 | "AAAAAAEAAAAuAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAEAAAABAAAAAAAAAAAAAAAAAUAAAAGAAAABAAAAAAAAAAABwAAAAgAAAAJAAAACgAA",
349 | "AAAAAAAAAAAAAQALAAAADAAAAAQAAAAAAAAAAKABAAANAAAADgAAAAQAAAAAAAAADwAAAAAQAAAAEQAAAAoAAAAAAAAAAAAAAAEAEgAAAAoAAAAAAAAAAAAA",
350 | "AAEAEwAAABQAAABYAAAAAAAAAABUAAAAVGhpcyBub2RlIGlzIGRpc2FibGVkIGFuZCB3aWxsIG5vdCBiZSBjYWxsZWQuCkRyYWcgb2ZmIHBpbnMgdG8gYnVp",
351 | "bGQgZnVuY3Rpb25hbGl0eS4AFQAAAAEAAAAQAAAAAAAAABYAAAAAAAAAAAAAAAAAAAAAAAAAAE5UY/6qyqNMrmjiWuqwZQYIAAAAAAAAAAMAAAAAAAAAAQAA",
352 | "AJqvoqoJhsRDm8XX4xLF6IcBAAAAmq+iqgmGxEObxdfjEsXohxcAAAAAAAAA/wAAAAD/////AAAAAAEYAAAACAAAAAIAAAAAAAAAAAAAAAAAAAAABwAAAAAA",
353 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAA/wAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA",
354 | "AMxc37R4qyFEn2iBanIz59ABAAAAzFzftHirIUSfaIFqcjPn0BkAAAAAAAAA/wAAAAD/////AAAAAAEaAAAACAAAAAIAAAAAAAAAAAAAAAACAAAACAAAAAAA",
355 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAA/wAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA",
356 | "AGY5Q/lkzOBChxv07QHqyxUBAAAAZjlD+WTM4EKHG/TtAerLFRsAAAAAAAAA/wAAAAD/////JwAAAERlbHRhIFNlY29uZHMKRmxvYXQgKHNpbmdsZS1wcmVj",
357 | "aXNpb24pAAEcAAAAHQAAAAIAAAAAAAAAAAAAAAACAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAMC4wAAQAAAAwLjAAAgAAAAAAAAD/",
358 | "AAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
359 | ]
360 | },
361 | "Objects": [
362 | "Object:/Script/CoreUObject.Class /Script/Engine.Actor",
363 | "Object:/Script/BlueprintGraph.K2Node_Event /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph.K2Node_Event_2",
364 | null
365 | ],
366 | "Names": [
367 | "EventReference",
368 | "StructProperty",
369 | "MemberReference",
370 | "MemberParent",
371 | "ObjectProperty",
372 | "MemberName",
373 | "NameProperty",
374 | "ReceiveTick",
375 | "None",
376 | "bOverrideFunction",
377 | "BoolProperty",
378 | "NodePosY",
379 | "IntProperty",
380 | "EnabledState",
381 | "EnumProperty",
382 | "ENodeEnabledState",
383 | "ENodeEnabledState::Disabled",
384 | "bCommentBubblePinned",
385 | "bCommentBubbleVisible",
386 | "NodeComment",
387 | "StrProperty",
388 | "NodeGuid",
389 | "Guid",
390 | "OutputDelegate",
391 | "delegate",
392 | "then",
393 | "exec",
394 | "DeltaSeconds",
395 | "real",
396 | "float"
397 | ]
398 | }
399 | }
400 | },
401 | "BP_Actor_Simple:UserConstructionScript.K2Node_FunctionEntry_0": {
402 | "__Class": "Class /Script/BlueprintGraph.K2Node_FunctionEntry",
403 | "__Outer": "EdGraph /Game/BP_Actor_Simple.BP_Actor_Simple:UserConstructionScript",
404 | "__ObjectFlags": 8,
405 | "__Value": {
406 | "BaseClassAutoGen": {
407 | "Data": {
408 | "Digest": "da857612cee7916519bd235beb4b8d02da47ae57",
409 | "Base64": [
410 | "AAAAAAEAAAAuAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAEAAAABAAAAAAAAAAAAAAAAAUAAAAGAAAABAAAAAAAAAAABwAAAAgAAAAJAAAAAQAA",
411 | "ABAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAcDt3wFpStUekfzhJGpRyHAgAAAAAAAAAAQAAAAAAAAABAAAA81AWZG2BT0Wh6ad7uJPjaQEAAADzUBZk",
412 | "bYFPRaHpp3u4k+NpCwAAAAAAAAD/AAAAAP////8AAAAAAQwAAAAIAAAAAgAAAAAAAAAAAAAAAAIAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
413 | "AAAAAAAAAAAAAgAAAAAAAAD/AAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
414 | ]
415 | },
416 | "Objects": [
417 | "Object:/Script/CoreUObject.Class /Script/Engine.Actor",
418 | "Object:/Script/BlueprintGraph.K2Node_FunctionEntry /Game/BP_Actor_Simple.BP_Actor_Simple:UserConstructionScript.K2Node_FunctionEntry_0",
419 | null
420 | ],
421 | "Names": [
422 | "FunctionReference",
423 | "StructProperty",
424 | "MemberReference",
425 | "MemberParent",
426 | "ObjectProperty",
427 | "MemberName",
428 | "NameProperty",
429 | "UserConstructionScript",
430 | "None",
431 | "NodeGuid",
432 | "Guid",
433 | "then",
434 | "exec"
435 | ]
436 | }
437 | }
438 | },
439 | "PackageMetaData": {
440 | "__Class": "Class /Script/CoreUObject.MetaData",
441 | "__ObjectFlags": 2,
442 | "__bNotForClient": true,
443 | "__bNotForServer": true,
444 | "__Value": {
445 | "Properties": {},
446 | "ObjectMetaDataMap": [
447 | [
448 | "Object:/Script/BlueprintGraph.K2Node_FunctionEntry /Game/BP_Actor_Simple.BP_Actor_Simple:UserConstructionScript.K2Node_FunctionEntry_0",
449 | [
450 | [
451 | "DefaultGraphNode",
452 | "true"
453 | ]
454 | ]
455 | ],
456 | [
457 | null,
458 | [
459 | [
460 | "BlueprintInternalUseOnly",
461 | "true"
462 | ],
463 | [
464 | "Comment",
465 | "/**\n\t * Construction script, the place to spawn components and do other setup.\n\t * @note Name used in CreateBlueprint function\n\t */"
466 | ],
467 | [
468 | "DisplayName",
469 | "Construction Script"
470 | ],
471 | [
472 | "ModuleRelativePath",
473 | "Classes/GameFramework/Actor.h"
474 | ],
475 | [
476 | "ToolTip",
477 | "Construction script, the place to spawn components and do other setup.\n@note Name used in CreateBlueprint function"
478 | ]
479 | ]
480 | ],
481 | [
482 | null,
483 | [
484 | [
485 | "BlueprintType",
486 | "true"
487 | ]
488 | ]
489 | ],
490 | [
491 | "Object:/Script/Engine.BlueprintGeneratedClass /Game/BP_Actor_Simple.BP_Actor_Simple_C",
492 | [
493 | [
494 | "BlueprintType",
495 | "true"
496 | ]
497 | ]
498 | ],
499 | [
500 | "Object:/Script/BlueprintGraph.K2Node_Event /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph.K2Node_Event_0",
501 | [
502 | [
503 | "DefaultGraphNode",
504 | "true"
505 | ]
506 | ]
507 | ],
508 | [
509 | "Object:/Script/BlueprintGraph.K2Node_Event /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph.K2Node_Event_1",
510 | [
511 | [
512 | "DefaultGraphNode",
513 | "true"
514 | ]
515 | ]
516 | ],
517 | [
518 | "Object:/Script/BlueprintGraph.K2Node_Event /Game/BP_Actor_Simple.BP_Actor_Simple:EventGraph.K2Node_Event_2",
519 | [
520 | [
521 | "DefaultGraphNode",
522 | "true"
523 | ]
524 | ]
525 | ]
526 | ],
527 | "RootMetaDataMap": [
528 | [
529 | "PackageLocalizationNamespace",
530 | "50B4947A4816F182AF72CC889D9D0EB8"
531 | ]
532 | ]
533 | }
534 | },
535 | "BP_Actor_Simple_C:DefaultSceneRoot_GEN_VARIABLE": {
536 | "__Class": "Class /Script/Engine.SceneComponent",
537 | "__Outer": "BlueprintGeneratedClass /Game/BP_Actor_Simple.BP_Actor_Simple_C",
538 | "__ObjectFlags": 41,
539 | "__Value": {
540 | "BaseClassAutoGen": {
541 | "Data": "Base64:AAAAAAEAAAAAAAAAAAAAAAEAAgAAAAAAAAA=",
542 | "Names": [
543 | "bVisualizeComponent",
544 | "BoolProperty",
545 | "None"
546 | ]
547 | }
548 | }
549 | },
550 | "BP_Actor_Simple:SceneThumbnailInfo_0": {
551 | "__Class": "Class /Script/UnrealEd.SceneThumbnailInfo",
552 | "__Outer": "Blueprint /Game/BP_Actor_Simple.BP_Actor_Simple",
553 | "__ObjectFlags": 8,
554 | "__Value": {
555 | "BaseClassAutoGen": {
556 | "Data": "Base64:AAAAAAAAAAA=",
557 | "Names": [
558 | "None"
559 | ]
560 | }
561 | }
562 | },
563 | "BP_Actor_Simple_C:SimpleConstructionScript_0.SCS_Node_0": {
564 | "__Class": "Class /Script/Engine.SCS_Node",
565 | "__Outer": "SimpleConstructionScript /Game/BP_Actor_Simple.BP_Actor_Simple_C:SimpleConstructionScript_0",
566 | "__ObjectFlags": 8,
567 | "__Value": {
568 | "BaseClassAutoGen": {
569 | "Data": {
570 | "Digest": "09e3221fe1e01809393718552a21d9282757908c",
571 | "Base64": [
572 | "AAAAAAEAAAAEAAAAAAAAAAAAAAAAAgAAAAEAAAAEAAAAAAAAAAABAAAAAwAAAAQAAAAlAAAAAAAAAAAIAAAAAAQAAABTQ1MACAAAAERlZmF1bHQACAAAAERl",
573 | "ZmF1bHQABQAAAAYAAAAQAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAOFU8+m//pdCrS+eS124x/wIAAAACQAAAAQAAAAAAAAAAAoAAAALAAAAAAAAAA=="
574 | ]
575 | },
576 | "Objects": [
577 | "Object:/Script/CoreUObject.Class /Script/Engine.SceneComponent",
578 | "Object:/Script/Engine.SceneComponent /Game/BP_Actor_Simple.BP_Actor_Simple_C:DefaultSceneRoot_GEN_VARIABLE"
579 | ],
580 | "Names": [
581 | "ComponentClass",
582 | "ObjectProperty",
583 | "ComponentTemplate",
584 | "CategoryName",
585 | "TextProperty",
586 | "VariableGuid",
587 | "StructProperty",
588 | "Guid",
589 | "InternalVariableName",
590 | "NameProperty",
591 | "DefaultSceneRoot",
592 | "None"
593 | ]
594 | }
595 | }
596 | },
597 | "BP_Actor_Simple_C:SimpleConstructionScript_0": {
598 | "__Class": "Class /Script/Engine.SimpleConstructionScript",
599 | "__Outer": "BlueprintGeneratedClass /Game/BP_Actor_Simple.BP_Actor_Simple_C",
600 | "__ObjectFlags": 8,
601 | "__Value": {
602 | "BaseClassAutoGen": {
603 | "Data": "Base64:AAAAAAEAAAAIAAAAAAAAAAIAAAAAAQAAAAAAAAADAAAAAQAAAAgAAAAAAAAAAgAAAAABAAAAAAAAAAQAAAACAAAABAAAAAAAAAAAAAAAAAUAAAAAAAAA",
604 | "Objects": [
605 | "Object:/Script/Engine.SCS_Node /Game/BP_Actor_Simple.BP_Actor_Simple_C:SimpleConstructionScript_0.SCS_Node_0"
606 | ],
607 | "Names": [
608 | "RootNodes",
609 | "ArrayProperty",
610 | "ObjectProperty",
611 | "AllNodes",
612 | "DefaultSceneRootNode",
613 | "None"
614 | ]
615 | }
616 | }
617 | }
618 | },
619 | "Summary": {
620 | "Tag": -1641380927,
621 | "LegacyFileVersion": -8,
622 | "LegacyUE3Version": 864,
623 | "FileVersionUE4": 522,
624 | "FileVersionUE5": 1004,
625 | "FileVersionLicenseeUE4": 0,
626 | "CustomVersions": [
627 | {
628 | "Key": "29E575DDE0A346279D10D276232CDCEA",
629 | "Version": 17
630 | },
631 | {
632 | "Key": "375EC13C06E448FBB50084F0262A717E",
633 | "Version": 4
634 | },
635 | {
636 | "Key": "59DA5D5212324948B878597870B8E98B",
637 | "Version": 8
638 | },
639 | {
640 | "Key": "601D1886AC644F84AA16D3DE0DEAC7D6",
641 | "Version": 59
642 | },
643 | {
644 | "Key": "697DD581E64F41ABAA4A51ECBEB7B628",
645 | "Version": 59
646 | },
647 | {
648 | "Key": "9C54D522A8264FBE9421074661B482D0",
649 | "Version": 44
650 | },
651 | {
652 | "Key": "B0D832E41F894F0DACCF7EB736FD4AA2",
653 | "Version": 10
654 | },
655 | {
656 | "Key": "CFFC743F43B04480939114DF171D2073",
657 | "Version": 37
658 | },
659 | {
660 | "Key": "D89B5E4224BD4D468412ACA8DF641779",
661 | "Version": 36
662 | },
663 | {
664 | "Key": "E4B068EDF49442E9A231DA0B2E46BB41",
665 | "Version": 40
666 | }
667 | ],
668 | "TotalHeaderSize": 0,
669 | "FolderName": "None",
670 | "PackageFlags": 1024,
671 | "NameCount": 107,
672 | "NameOffset": 0,
673 | "LocalizationId": "50B4947A4816F182AF72CC889D9D0EB8",
674 | "GatherableTextDataCount": 1,
675 | "GatherableTextDataOffset": 0,
676 | "ExportCount": 14,
677 | "ExportOffset": 0,
678 | "ImportCount": 18,
679 | "ImportOffset": 0,
680 | "DependsOffset": 0,
681 | "SoftPackageReferencesCount": 0,
682 | "SoftPackageReferencesOffset": 0,
683 | "SearchableNamesOffset": 0,
684 | "ThumbnailTableOffset": 0,
685 | "Guid": "A4C929A946BF2ED15058CBB53ECABC7B",
686 | "PersistentGuid": "46AA6F4949616DB6D6933C9DC1622787",
687 | "GenerationCount": 1,
688 | "Generations": [
689 | {
690 | "ExportCount": 14,
691 | "NameCount": 107
692 | }
693 | ],
694 | "SavedByEngineVersion": "5.0.3-20979098+++UE5+Release-5.0",
695 | "CompatibleWithEngineVersion": "5.0.0-19505902+++UE5+Release-5.0",
696 | "CompressionFlags": 0,
697 | "CompressedChunks": [],
698 | "PackageSource": 81731590,
699 | "AdditionalPackagesToCook": [],
700 | "AssetRegistryDataOffset": 0,
701 | "BulkDataStartOffset": 0,
702 | "WorldTileInfoDataOffset": 0,
703 | "ChunkIDs": [],
704 | "PreloadDependencyCount": 0,
705 | "PreloadDependencyOffset": 0,
706 | "NamesReferencedFromExportDataCount": 81,
707 | "PayloadTocOffset": -1
708 | }
709 | }
--------------------------------------------------------------------------------