├── .editorconfig
├── .erb
├── configs
│ ├── .eslintrc
│ ├── webpack.config.base.ts
│ ├── webpack.config.eslint.ts
│ ├── webpack.config.main.prod.ts
│ ├── webpack.config.renderer.dev.dll.ts
│ ├── webpack.config.renderer.dev.ts
│ ├── webpack.config.renderer.prod.ts
│ └── webpack.paths.ts
├── img
│ ├── erb-banner.svg
│ └── erb-logo.png
├── mocks
│ └── fileMock.js
└── scripts
│ ├── .eslintrc
│ ├── check-build-exists.ts
│ ├── check-native-dep.js
│ ├── check-node-env.js
│ ├── check-port-in-use.js
│ ├── clean.js
│ ├── delete-source-maps.js
│ ├── electron-rebuild.js
│ ├── link-modules.ts
│ └── notarize.js
├── .eslintignore
├── .eslintrc.js
├── .gitattributes
├── .github
└── workflows
│ └── release.yml
├── .gitignore
├── .vscode
├── extensions.json
├── launch.json
├── settings.json
└── tasks.json
├── COMMAND.md
├── FAQ.md
├── LICENSE
├── README.md
├── assets
├── NanumSquareB.woff
├── NanumSquareEB.woff
├── NanumSquareL.woff
├── NanumSquareR.woff
├── adb
│ ├── AdbWinApi.dll
│ ├── AdbWinUsbApi.dll
│ └── adb.exe
├── arrowLeft.svg
├── asFilePaths.lock
├── assets.d.ts
├── boot_ffc6.as
├── delta.png
├── discord.svg
├── entitlements.mac.plist
├── extract.svg
├── ffdec
│ ├── CHANGELOG.md
│ ├── ffdec.jar
│ ├── lib
│ │ ├── JavactiveX.jar
│ │ ├── LZMA.jar
│ │ ├── avi.jar
│ │ ├── avi.montemedia.license.txt
│ │ ├── cmykjpeg.jar
│ │ ├── ddsreader.jar
│ │ ├── ffdec_lib.jar
│ │ ├── ffdec_lib.license.txt
│ │ ├── flamingo-6.2.jar
│ │ ├── flamingo.license.txt
│ │ ├── flashdebugger.jar
│ │ ├── gif.jar
│ │ ├── gif.license.txt
│ │ ├── gnujpdf.jar
│ │ ├── graphs.jar
│ │ ├── jargs.jar
│ │ ├── jl.license.txt
│ │ ├── jl1.0.1.jar
│ │ ├── jna-3.5.1.jar
│ │ ├── jna.license.txt
│ │ ├── jpacker.jar
│ │ ├── jpacker.license.txt
│ │ ├── jpproxy.jar
│ │ ├── jpproxy.muffin.license.txt
│ │ ├── jsyntaxpane-0.9.5.jar
│ │ ├── jsyntaxpane.license.txt
│ │ ├── minimal-json-0.9.5.jar
│ │ ├── minimal-json.license.txt
│ │ ├── nellymoser.jar
│ │ ├── nellymoser.license.txt
│ │ ├── sfntly.jar
│ │ ├── sfntly.license.txt
│ │ ├── substance-6.2.jar
│ │ ├── substance-flamingo-6.2.jar
│ │ ├── substance-flamingo.license.txt
│ │ ├── substance.license.txt
│ │ ├── tablelayout.jar
│ │ ├── treetable.jar
│ │ ├── trident-6.2.jar
│ │ ├── trident.license.txt
│ │ ├── ttf.doubletype.license.txt
│ │ ├── ttf.fontastic.license.txt
│ │ └── ttf.jar
│ └── license.txt
├── filePaths.lock
├── folder.svg
├── github.png
├── icon.icns
├── icon.ico
├── icons
│ ├── 1024x1024.png
│ ├── 128x128.png
│ ├── 16x16.png
│ ├── 24x24.png
│ ├── 256x256.png
│ ├── 32x32.png
│ ├── 48x48.png
│ ├── 512x512.png
│ ├── 64x64.png
│ └── 96x96.png
├── images
│ ├── ch10.jpg
│ ├── ch10_banner.png
│ ├── ch10_special.gif
│ ├── ch10_spin.png
│ ├── ch10_walk.gif
│ ├── couette.jpg
│ ├── couette_banner.png
│ ├── couette_special.gif
│ ├── couette_spin.png
│ ├── couette_walk.gif
│ ├── theo.jpg
│ ├── theo_banner.png
│ ├── theo_special.gif
│ ├── theo_spin.png
│ └── theo_walk.gif
├── info.svg
├── item_bronze.png
├── item_gold.png
├── item_rainbow.png
├── item_silver.png
├── item_white.png
├── settings.svg
├── trash.svg
└── viewer.svg
├── package.json
├── release
└── app
│ ├── package.json
│ └── yarn.lock
├── src
├── main
│ ├── flatomo
│ │ ├── customTweenRecord.ts
│ │ ├── customTweenTools.ts
│ │ ├── graphicsLoopKindTools.ts
│ │ ├── graphicsSource.ts
│ │ ├── intMatrix.ts
│ │ ├── matrixHashTable.ts
│ │ ├── partState.ts
│ │ ├── partStateParameter.ts
│ │ ├── partStateParameterHashTable.ts
│ │ └── partsAnimationSource.ts
│ ├── main.ts
│ ├── menu.ts
│ ├── preload.js
│ ├── util.ts
│ └── wf
│ │ ├── constants.js
│ │ ├── digest.js
│ │ ├── helpers.ts
│ │ ├── index.ts
│ │ ├── logger.ts
│ │ ├── readOrderedMap.js
│ │ ├── restoreMp3.js
│ │ ├── typedefs.ts
│ │ └── wfFileReader.js
└── renderer
│ ├── App.css
│ ├── App.tsx
│ ├── components
│ ├── Modal.tsx
│ ├── Switch.tsx
│ ├── TextField.tsx
│ ├── Typography.tsx
│ ├── WfButton.tsx
│ └── WfCard.tsx
│ ├── helpers
│ ├── hooks.tsx
│ └── index.tsx
│ ├── index.ejs
│ ├── index.tsx
│ └── worker.ejs
├── tsconfig.json
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = crlf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/.erb/configs/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-console": "off",
4 | "global-require": "off",
5 | "import/no-dynamic-require": "off"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.base.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Base webpack config used across other specific configs
3 | */
4 |
5 | import webpack from 'webpack';
6 | import webpackPaths from './webpack.paths';
7 | import { dependencies as externals } from '../../release/app/package.json';
8 |
9 | const configuration: webpack.Configuration = {
10 | externals: [...Object.keys(externals || {})],
11 |
12 | stats: 'errors-only',
13 |
14 | module: {
15 | rules: [
16 | {
17 | test: /\.[jt]sx?$/,
18 | exclude: /node_modules/,
19 | use: {
20 | loader: 'ts-loader',
21 | options: {
22 | // Remove this line to enable type checking in webpack builds
23 | transpileOnly: true,
24 | },
25 | },
26 | },
27 | ],
28 | },
29 |
30 | output: {
31 | path: webpackPaths.srcPath,
32 | // https://github.com/webpack/webpack/issues/1114
33 | library: {
34 | type: 'commonjs2',
35 | },
36 | },
37 |
38 | /**
39 | * Determine the array of extensions that should be used to resolve modules.
40 | */
41 | resolve: {
42 | extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
43 | modules: [webpackPaths.srcPath, 'node_modules'],
44 | },
45 |
46 | plugins: [
47 | new webpack.EnvironmentPlugin({
48 | NODE_ENV: 'production',
49 | }),
50 | ],
51 | };
52 |
53 | export default configuration;
54 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.eslint.ts:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved: off, import/no-self-import: off */
2 |
3 | module.exports = require('./webpack.config.renderer.dev').default;
4 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.main.prod.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Webpack config for production electron main process
3 | */
4 |
5 | import path from 'path';
6 | import webpack from 'webpack';
7 | import { merge } from 'webpack-merge';
8 | import TerserPlugin from 'terser-webpack-plugin';
9 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
10 | import baseConfig from './webpack.config.base';
11 | import webpackPaths from './webpack.paths';
12 | import checkNodeEnv from '../scripts/check-node-env';
13 | import deleteSourceMaps from '../scripts/delete-source-maps';
14 |
15 | checkNodeEnv('production');
16 | deleteSourceMaps();
17 |
18 | const devtoolsConfig =
19 | process.env.DEBUG_PROD === 'true'
20 | ? {
21 | devtool: 'source-map',
22 | }
23 | : {};
24 |
25 | const configuration: webpack.Configuration = {
26 | ...devtoolsConfig,
27 |
28 | mode: 'production',
29 |
30 | target: 'electron-main',
31 |
32 | entry: {
33 | main: path.join(webpackPaths.srcMainPath, 'main.ts'),
34 | preload: path.join(webpackPaths.srcMainPath, 'preload.js'),
35 | },
36 |
37 | output: {
38 | path: webpackPaths.distMainPath,
39 | filename: '[name].js',
40 | },
41 |
42 | optimization: {
43 | minimizer: [
44 | new TerserPlugin({
45 | parallel: true,
46 | }),
47 | ],
48 | },
49 |
50 | plugins: [
51 | new BundleAnalyzerPlugin({
52 | analyzerMode: process.env.ANALYZE === 'true' ? 'server' : 'disabled',
53 | }),
54 |
55 | /**
56 | * Create global constants which can be configured at compile time.
57 | *
58 | * Useful for allowing different behaviour between development builds and
59 | * release builds
60 | *
61 | * NODE_ENV should be production so that modules do not perform certain
62 | * development checks
63 | */
64 | new webpack.EnvironmentPlugin({
65 | NODE_ENV: 'production',
66 | DEBUG_PROD: false,
67 | START_MINIMIZED: false,
68 | }),
69 | ],
70 |
71 | /**
72 | * Disables webpack processing of __dirname and __filename.
73 | * If you run the bundle in node.js it falls back to these values of node.js.
74 | * https://github.com/webpack/webpack/issues/2010
75 | */
76 | node: {
77 | __dirname: false,
78 | __filename: false,
79 | },
80 | };
81 |
82 | export default merge(baseConfig, configuration);
83 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.renderer.dev.dll.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Builds the DLL for development electron renderer process
3 | */
4 |
5 | import webpack from 'webpack';
6 | import path from 'path';
7 | import { merge } from 'webpack-merge';
8 | import baseConfig from './webpack.config.base';
9 | import webpackPaths from './webpack.paths';
10 | import { dependencies } from '../../package.json';
11 | import checkNodeEnv from '../scripts/check-node-env';
12 |
13 | checkNodeEnv('development');
14 |
15 | const dist = webpackPaths.dllPath;
16 |
17 | const configuration: webpack.Configuration = {
18 | context: webpackPaths.rootPath,
19 |
20 | devtool: 'eval',
21 |
22 | mode: 'development',
23 |
24 | target: 'electron-renderer',
25 |
26 | externals: ['fsevents', 'crypto-browserify'],
27 |
28 | /**
29 | * Use `module` from `webpack.config.renderer.dev.js`
30 | */
31 | module: require('./webpack.config.renderer.dev').default.module,
32 |
33 | entry: {
34 | renderer: Object.keys(dependencies || {}),
35 | },
36 |
37 | output: {
38 | path: dist,
39 | filename: '[name].dev.dll.js',
40 | library: {
41 | name: 'renderer',
42 | type: 'var',
43 | },
44 | },
45 |
46 | plugins: [
47 | new webpack.DllPlugin({
48 | path: path.join(dist, '[name].json'),
49 | name: '[name]',
50 | }),
51 |
52 | /**
53 | * Create global constants which can be configured at compile time.
54 | *
55 | * Useful for allowing different behaviour between development builds and
56 | * release builds
57 | *
58 | * NODE_ENV should be production so that modules do not perform certain
59 | * development checks
60 | */
61 | new webpack.EnvironmentPlugin({
62 | NODE_ENV: 'development',
63 | }),
64 |
65 | new webpack.LoaderOptionsPlugin({
66 | debug: true,
67 | options: {
68 | context: webpackPaths.srcPath,
69 | output: {
70 | path: webpackPaths.dllPath,
71 | },
72 | },
73 | }),
74 | ],
75 | };
76 |
77 | export default merge(baseConfig, configuration);
78 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.renderer.dev.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fs from 'fs';
3 | import webpack from 'webpack';
4 | import HtmlWebpackPlugin from 'html-webpack-plugin';
5 | import chalk from 'chalk';
6 | import { merge } from 'webpack-merge';
7 | import { spawn, execSync } from 'child_process';
8 | import baseConfig from './webpack.config.base';
9 | import webpackPaths from './webpack.paths';
10 | import checkNodeEnv from '../scripts/check-node-env';
11 | import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
12 |
13 | // When an ESLint server is running, we can't set the NODE_ENV so we'll check if it's
14 | // at the dev webpack config is not accidentally run in a production environment
15 | if (process.env.NODE_ENV === 'production') {
16 | checkNodeEnv('development');
17 | }
18 |
19 | const port = process.env.PORT || 1212;
20 | const manifest = path.resolve(webpackPaths.dllPath, 'renderer.json');
21 | const requiredByDLLConfig = module.parent!.filename.includes(
22 | 'webpack.config.renderer.dev.dll'
23 | );
24 |
25 | /**
26 | * Warn if the DLL is not built
27 | */
28 | if (
29 | !requiredByDLLConfig &&
30 | !(fs.existsSync(webpackPaths.dllPath) && fs.existsSync(manifest))
31 | ) {
32 | console.log(
33 | chalk.black.bgYellow.bold(
34 | 'The DLL files are missing. Sit back while we build them for you with "npm run build-dll"'
35 | )
36 | );
37 | execSync('npm run postinstall');
38 | }
39 |
40 | const configuration: webpack.Configuration = {
41 | devtool: 'inline-source-map',
42 |
43 | mode: 'development',
44 |
45 | target: ['web', 'electron-renderer'],
46 |
47 | entry: [
48 | `webpack-dev-server/client?http://localhost:${port}/dist`,
49 | 'webpack/hot/only-dev-server',
50 | 'core-js',
51 | 'regenerator-runtime/runtime',
52 | path.join(webpackPaths.srcRendererPath, 'index.tsx'),
53 | ],
54 |
55 | output: {
56 | path: webpackPaths.distRendererPath,
57 | publicPath: '/',
58 | filename: 'renderer.dev.js',
59 | library: {
60 | type: 'umd',
61 | },
62 | },
63 |
64 | module: {
65 | rules: [
66 | {
67 | test: /\.s?css$/,
68 | use: [
69 | 'style-loader',
70 | {
71 | loader: 'css-loader',
72 | options: {
73 | modules: true,
74 | sourceMap: true,
75 | importLoaders: 1,
76 | },
77 | },
78 | 'sass-loader',
79 | ],
80 | include: /\.module\.s?(c|a)ss$/,
81 | },
82 | {
83 | test: /\.s?css$/,
84 | use: ['style-loader', 'css-loader', 'sass-loader'],
85 | exclude: /\.module\.s?(c|a)ss$/,
86 | },
87 | // Fonts
88 | {
89 | test: /\.(woff|woff2|eot|ttf|otf)$/i,
90 | type: 'asset/resource',
91 | },
92 | // Images
93 | {
94 | test: /\.(png|svg|jpg|jpeg|gif)$/i,
95 | type: 'asset/resource',
96 | },
97 | ],
98 | },
99 | plugins: [
100 | ...(requiredByDLLConfig
101 | ? []
102 | : [
103 | new webpack.DllReferencePlugin({
104 | context: webpackPaths.dllPath,
105 | manifest: require(manifest),
106 | sourceType: 'var',
107 | }),
108 | ]),
109 |
110 | new webpack.NoEmitOnErrorsPlugin(),
111 |
112 | /**
113 | * Create global constants which can be configured at compile time.
114 | *
115 | * Useful for allowing different behaviour between development builds and
116 | * release builds
117 | *
118 | * NODE_ENV should be production so that modules do not perform certain
119 | * development checks
120 | *
121 | * By default, use 'development' as NODE_ENV. This can be overriden with
122 | * 'staging', for example, by changing the ENV variables in the npm scripts
123 | */
124 | new webpack.EnvironmentPlugin({
125 | NODE_ENV: 'development',
126 | }),
127 |
128 | new webpack.LoaderOptionsPlugin({
129 | debug: true,
130 | }),
131 |
132 | new ReactRefreshWebpackPlugin(),
133 |
134 | new HtmlWebpackPlugin({
135 | filename: path.join('index.html'),
136 | template: path.join(webpackPaths.srcRendererPath, 'index.ejs'),
137 | minify: {
138 | collapseWhitespace: true,
139 | removeAttributeQuotes: true,
140 | removeComments: true,
141 | },
142 | isBrowser: false,
143 | env: process.env.NODE_ENV,
144 | isDevelopment: process.env.NODE_ENV !== 'production',
145 | nodeModules: webpackPaths.appNodeModulesPath,
146 | }),
147 | ],
148 |
149 | node: {
150 | __dirname: false,
151 | __filename: false,
152 | },
153 |
154 | // @ts-ignore
155 | devServer: {
156 | port,
157 | compress: true,
158 | hot: true,
159 | headers: { 'Access-Control-Allow-Origin': '*' },
160 | static: {
161 | publicPath: '/',
162 | },
163 | historyApiFallback: {
164 | verbose: true,
165 | },
166 | onBeforeSetupMiddleware() {
167 | console.log('Starting Main Process...');
168 | spawn('npm', ['run', 'start:main'], {
169 | shell: true,
170 | env: process.env,
171 | stdio: 'inherit',
172 | })
173 | .on('close', (code: number) => process.exit(code!))
174 | .on('error', (spawnError) => console.error(spawnError));
175 | },
176 | },
177 | };
178 |
179 | export default merge(baseConfig, configuration);
180 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.renderer.prod.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Build config for electron renderer process
3 | */
4 |
5 | import path from 'path';
6 | import webpack from 'webpack';
7 | import HtmlWebpackPlugin from 'html-webpack-plugin';
8 | import MiniCssExtractPlugin from 'mini-css-extract-plugin';
9 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
10 | import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
11 | import { merge } from 'webpack-merge';
12 | import TerserPlugin from 'terser-webpack-plugin';
13 | import baseConfig from './webpack.config.base';
14 | import webpackPaths from './webpack.paths';
15 | import checkNodeEnv from '../scripts/check-node-env';
16 | import deleteSourceMaps from '../scripts/delete-source-maps';
17 |
18 | checkNodeEnv('production');
19 | deleteSourceMaps();
20 |
21 | const devtoolsConfig =
22 | process.env.DEBUG_PROD === 'true'
23 | ? {
24 | devtool: 'source-map',
25 | }
26 | : {};
27 |
28 | const configuration: webpack.Configuration = {
29 | ...devtoolsConfig,
30 |
31 | mode: 'production',
32 |
33 | target: ['web', 'electron-renderer'],
34 |
35 | entry: [
36 | 'core-js',
37 | 'regenerator-runtime/runtime',
38 | path.join(webpackPaths.srcRendererPath, 'index.tsx'),
39 | ],
40 |
41 | output: {
42 | path: webpackPaths.distRendererPath,
43 | publicPath: './',
44 | filename: 'renderer.js',
45 | library: {
46 | type: 'umd',
47 | },
48 | },
49 |
50 | module: {
51 | rules: [
52 | {
53 | test: /\.s?(a|c)ss$/,
54 | use: [
55 | MiniCssExtractPlugin.loader,
56 | {
57 | loader: 'css-loader',
58 | options: {
59 | modules: true,
60 | sourceMap: true,
61 | importLoaders: 1,
62 | },
63 | },
64 | 'sass-loader',
65 | ],
66 | include: /\.module\.s?(c|a)ss$/,
67 | },
68 | {
69 | test: /\.s?(a|c)ss$/,
70 | use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
71 | exclude: /\.module\.s?(c|a)ss$/,
72 | },
73 | // Fonts
74 | {
75 | test: /\.(woff|woff2|eot|ttf|otf)$/i,
76 | type: 'asset/resource',
77 | },
78 | // Images
79 | {
80 | test: /\.(png|svg|jpg|jpeg|gif)$/i,
81 | type: 'asset/resource',
82 | },
83 | ],
84 | },
85 |
86 | optimization: {
87 | minimize: true,
88 | minimizer: [
89 | new TerserPlugin({
90 | parallel: true,
91 | }),
92 | new CssMinimizerPlugin(),
93 | ],
94 | },
95 |
96 | plugins: [
97 | /**
98 | * Create global constants which can be configured at compile time.
99 | *
100 | * Useful for allowing different behaviour between development builds and
101 | * release builds
102 | *
103 | * NODE_ENV should be production so that modules do not perform certain
104 | * development checks
105 | */
106 | new webpack.EnvironmentPlugin({
107 | NODE_ENV: 'production',
108 | DEBUG_PROD: false,
109 | }),
110 |
111 | new MiniCssExtractPlugin({
112 | filename: 'style.css',
113 | }),
114 |
115 | new BundleAnalyzerPlugin({
116 | analyzerMode: process.env.ANALYZE === 'true' ? 'server' : 'disabled',
117 | }),
118 |
119 | new HtmlWebpackPlugin({
120 | filename: 'index.html',
121 | template: path.join(webpackPaths.srcRendererPath, 'index.ejs'),
122 | minify: {
123 | collapseWhitespace: true,
124 | removeAttributeQuotes: true,
125 | removeComments: true,
126 | },
127 | isBrowser: false,
128 | isDevelopment: process.env.NODE_ENV !== 'production',
129 | }),
130 | ],
131 | };
132 |
133 | export default merge(baseConfig, configuration);
134 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.paths.ts:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const rootPath = path.join(__dirname, '../..');
4 |
5 | const dllPath = path.join(__dirname, '../dll');
6 |
7 | const srcPath = path.join(rootPath, 'src');
8 | const srcMainPath = path.join(srcPath, 'main');
9 | const srcRendererPath = path.join(srcPath, 'renderer');
10 |
11 | const releasePath = path.join(rootPath, 'release');
12 | const appPath = path.join(releasePath, 'app');
13 | const appPackagePath = path.join(appPath, 'package.json');
14 | const appNodeModulesPath = path.join(appPath, 'node_modules');
15 | const srcNodeModulesPath = path.join(srcPath, 'node_modules');
16 |
17 | const distPath = path.join(appPath, 'dist');
18 | const distMainPath = path.join(distPath, 'main');
19 | const distRendererPath = path.join(distPath, 'renderer');
20 |
21 | const buildPath = path.join(releasePath, 'build');
22 |
23 | export default {
24 | rootPath,
25 | dllPath,
26 | srcPath,
27 | srcMainPath,
28 | srcRendererPath,
29 | releasePath,
30 | appPath,
31 | appPackagePath,
32 | appNodeModulesPath,
33 | srcNodeModulesPath,
34 | distPath,
35 | distMainPath,
36 | distRendererPath,
37 | buildPath,
38 | };
39 |
--------------------------------------------------------------------------------
/.erb/img/erb-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/.erb/img/erb-logo.png
--------------------------------------------------------------------------------
/.erb/mocks/fileMock.js:
--------------------------------------------------------------------------------
1 | export default 'test-file-stub';
2 |
--------------------------------------------------------------------------------
/.erb/scripts/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-console": "off",
4 | "global-require": "off",
5 | "import/no-dynamic-require": "off",
6 | "import/no-extraneous-dependencies": "off"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/.erb/scripts/check-build-exists.ts:
--------------------------------------------------------------------------------
1 | // Check if the renderer and main bundles are built
2 | import path from 'path';
3 | import chalk from 'chalk';
4 | import fs from 'fs';
5 | import webpackPaths from '../configs/webpack.paths';
6 |
7 | const mainPath = path.join(webpackPaths.distMainPath, 'main.js');
8 | const rendererPath = path.join(webpackPaths.distRendererPath, 'renderer.js');
9 |
10 | if (!fs.existsSync(mainPath)) {
11 | throw new Error(
12 | chalk.whiteBright.bgRed.bold(
13 | 'The main process is not built yet. Build it by running "npm run build:main"'
14 | )
15 | );
16 | }
17 |
18 | if (!fs.existsSync(rendererPath)) {
19 | throw new Error(
20 | chalk.whiteBright.bgRed.bold(
21 | 'The renderer process is not built yet. Build it by running "npm run build:renderer"'
22 | )
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/.erb/scripts/check-native-dep.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import chalk from 'chalk';
3 | import { execSync } from 'child_process';
4 | import { dependencies } from '../../package.json';
5 |
6 | if (dependencies) {
7 | const dependenciesKeys = Object.keys(dependencies);
8 | const nativeDeps = fs
9 | .readdirSync('node_modules')
10 | .filter((folder) => fs.existsSync(`node_modules/${folder}/binding.gyp`));
11 | if (nativeDeps.length === 0) {
12 | process.exit(0);
13 | }
14 | try {
15 | // Find the reason for why the dependency is installed. If it is installed
16 | // because of a devDependency then that is okay. Warn when it is installed
17 | // because of a dependency
18 | const { dependencies: dependenciesObject } = JSON.parse(
19 | execSync(`npm ls ${nativeDeps.join(' ')} --json`).toString()
20 | );
21 | const rootDependencies = Object.keys(dependenciesObject);
22 | const filteredRootDependencies = rootDependencies.filter((rootDependency) =>
23 | dependenciesKeys.includes(rootDependency)
24 | );
25 | if (filteredRootDependencies.length > 0) {
26 | const plural = filteredRootDependencies.length > 1;
27 | console.log(`
28 | ${chalk.whiteBright.bgYellow.bold(
29 | 'Webpack does not work with native dependencies.'
30 | )}
31 | ${chalk.bold(filteredRootDependencies.join(', '))} ${
32 | plural ? 'are native dependencies' : 'is a native dependency'
33 | } and should be installed inside of the "./release/app" folder.
34 | First, uninstall the packages from "./package.json":
35 | ${chalk.whiteBright.bgGreen.bold('npm uninstall your-package')}
36 | ${chalk.bold(
37 | 'Then, instead of installing the package to the root "./package.json":'
38 | )}
39 | ${chalk.whiteBright.bgRed.bold('npm install your-package')}
40 | ${chalk.bold('Install the package to "./release/app/package.json"')}
41 | ${chalk.whiteBright.bgGreen.bold('cd ./release/app && npm install your-package')}
42 | Read more about native dependencies at:
43 | ${chalk.bold(
44 | 'https://electron-react-boilerplate.js.org/docs/adding-dependencies/#module-structure'
45 | )}
46 | `);
47 | process.exit(1);
48 | }
49 | } catch (e) {
50 | console.log('Native dependencies could not be checked');
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/.erb/scripts/check-node-env.js:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk';
2 |
3 | export default function checkNodeEnv(expectedEnv) {
4 | if (!expectedEnv) {
5 | throw new Error('"expectedEnv" not set');
6 | }
7 |
8 | if (process.env.NODE_ENV !== expectedEnv) {
9 | console.log(
10 | chalk.whiteBright.bgRed.bold(
11 | `"process.env.NODE_ENV" must be "${expectedEnv}" to use this webpack config`
12 | )
13 | );
14 | process.exit(2);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.erb/scripts/check-port-in-use.js:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk';
2 | import detectPort from 'detect-port';
3 |
4 | const port = process.env.PORT || '1212';
5 |
6 | detectPort(port, (err, availablePort) => {
7 | if (port !== String(availablePort)) {
8 | throw new Error(
9 | chalk.whiteBright.bgRed.bold(
10 | `Port "${port}" on "localhost" is already in use. Please use another port. ex: PORT=4343 npm start`
11 | )
12 | );
13 | } else {
14 | process.exit(0);
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/.erb/scripts/clean.js:
--------------------------------------------------------------------------------
1 | import rimraf from 'rimraf';
2 | import webpackPaths from '../configs/webpack.paths.ts';
3 | import process from 'process';
4 |
5 | const args = process.argv.slice(2);
6 | const commandMap = {
7 | dist: webpackPaths.distPath,
8 | release: webpackPaths.releasePath,
9 | dll: webpackPaths.dllPath,
10 | };
11 |
12 | args.forEach((x) => {
13 | const pathToRemove = commandMap[x];
14 | if (pathToRemove !== undefined) {
15 | rimraf.sync(pathToRemove);
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/.erb/scripts/delete-source-maps.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import rimraf from 'rimraf';
3 | import webpackPaths from '../configs/webpack.paths';
4 |
5 | export default function deleteSourceMaps() {
6 | rimraf.sync(path.join(webpackPaths.distMainPath, '*.js.map'));
7 | rimraf.sync(path.join(webpackPaths.distRendererPath, '*.js.map'));
8 | }
9 |
--------------------------------------------------------------------------------
/.erb/scripts/electron-rebuild.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import { execSync } from 'child_process';
3 | import fs from 'fs';
4 | import { dependencies } from '../../release/app/package.json';
5 | import webpackPaths from '../configs/webpack.paths';
6 |
7 | if (
8 | Object.keys(dependencies || {}).length > 0 &&
9 | fs.existsSync(webpackPaths.appNodeModulesPath)
10 | ) {
11 | const electronRebuildCmd =
12 | '../../node_modules/.bin/electron-rebuild --parallel --force --types prod,dev,optional --module-dir .';
13 | const cmd =
14 | process.platform === 'win32'
15 | ? electronRebuildCmd.replace(/\//g, '\\')
16 | : electronRebuildCmd;
17 | execSync(cmd, {
18 | cwd: webpackPaths.appPath,
19 | stdio: 'inherit',
20 | });
21 | }
22 |
--------------------------------------------------------------------------------
/.erb/scripts/link-modules.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import webpackPaths from '../configs/webpack.paths';
3 |
4 | const srcNodeModulesPath = webpackPaths.srcNodeModulesPath;
5 | const appNodeModulesPath = webpackPaths.appNodeModulesPath
6 |
7 | if (!fs.existsSync(srcNodeModulesPath) && fs.existsSync(appNodeModulesPath)) {
8 | fs.symlinkSync(appNodeModulesPath, srcNodeModulesPath, 'junction');
9 | }
10 |
--------------------------------------------------------------------------------
/.erb/scripts/notarize.js:
--------------------------------------------------------------------------------
1 | const { notarize } = require('electron-notarize');
2 | const { build } = require('../../package.json');
3 |
4 | exports.default = async function notarizeMacos(context) {
5 | const { electronPlatformName, appOutDir } = context;
6 | if (electronPlatformName !== 'darwin') {
7 | return;
8 | }
9 |
10 | if (process.env.CI !== "true") {
11 | console.warn('Skipping notarizing step. Packaging is not running in CI');
12 | return;
13 | }
14 |
15 | if (!('APPLE_ID' in process.env && 'APPLE_ID_PASS' in process.env)) {
16 | console.warn('Skipping notarizing step. APPLE_ID and APPLE_ID_PASS env variables must be set');
17 | return;
18 | }
19 |
20 | const appName = context.packager.appInfo.productFilename;
21 |
22 | await notarize({
23 | appBundleId: build.appId,
24 | appPath: `${appOutDir}/${appName}.app`,
25 | appleId: process.env.APPLE_ID,
26 | appleIdPassword: process.env.APPLE_ID_PASS,
27 | });
28 | };
29 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Coverage directory used by tools like istanbul
11 | coverage
12 | .eslintcache
13 |
14 | # Dependency directory
15 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
16 | node_modules
17 |
18 | # OSX
19 | .DS_Store
20 |
21 | release/app/dist
22 | release/build
23 | .erb/dll
24 |
25 | .idea
26 | npm-debug.log.*
27 | *.css.d.ts
28 | *.sass.d.ts
29 | *.scss.d.ts
30 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: 'erb',
3 | rules: {
4 | // A temporary hack related to IDE not resolving correct package.json
5 | 'import/no-extraneous-dependencies': 'off',
6 | 'import/no-unresolved': 'error',
7 | // Since React 17 and typescript 4.1 you can safely disable the rule
8 | 'react/react-in-jsx-scope': 'off',
9 | 'jsx-a11y/click-events-have-key-events': 'off',
10 | 'jsx-a11y/no-static-element-interactions': 'off',
11 | 'no-restricted-syntax': 'off',
12 | 'no-underscore-dangle': 'off',
13 | 'no-await-in-loop': 'off',
14 | 'max-classes-per-file': 'off',
15 | 'no-continue': 'off',
16 | 'jsx-a11y/anchor-is-valid': 'off',
17 | 'react/jsx-props-no-spreading': 'off',
18 | 'no-bitwise': 'off',
19 | 'no-plusplus': 'off',
20 | 'jsx-a11y/no-noninteractive-element-interactions': 'off',
21 | '@typescript-eslint/no-loop-func': 'off',
22 | 'prettier/prettier': [
23 | 'error',
24 | {
25 | endOfLine: 'auto',
26 | },
27 | ],
28 | },
29 | parserOptions: {
30 | ecmaVersion: 2020,
31 | sourceType: 'module',
32 | project: './tsconfig.json',
33 | tsconfigRootDir: __dirname,
34 | createDefaultProgram: true,
35 | },
36 | settings: {
37 | 'import/resolver': {
38 | // See https://github.com/benmosher/eslint-plugin-import/issues/1396#issuecomment-575727774 for line below
39 | node: {},
40 | webpack: {
41 | config: require.resolve('./.erb/configs/webpack.config.eslint.ts'),
42 | },
43 | typescript: {},
44 | },
45 | 'import/parsers': {
46 | '@typescript-eslint/parser': ['.ts', '.tsx'],
47 | },
48 | },
49 | };
50 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 | *.exe binary
3 | *.png binary
4 | *.jpg binary
5 | *.gif binary
6 | *.jpeg binary
7 | *.ico binary
8 | *.icns binary
9 | *.eot binary
10 | *.otf binary
11 | *.ttf binary
12 | *.woff binary
13 | *.woff2 binary
14 | *.jar binary
15 | *.dll binary
16 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches: [ "master" ]
4 | pull_request:
5 | branches: [ "master" ]
6 |
7 | jobs:
8 | build-windows:
9 | runs-on: windows-latest
10 | steps:
11 | - uses: actions/checkout@v3
12 | - name: Use Node.js 16
13 | uses: actions/setup-node@v3
14 | with:
15 | node-version: 16
16 | - name: Install dependencies
17 | run: yarn install --network-timeout 600000
18 | - name: Build and publish to github release.
19 | run: npx cross-env GH_TOKEN=${{ secrets.GH_TOKEN }} yarn deploy
20 | build-linux:
21 | runs-on: ubuntu-latest
22 | steps:
23 | - uses: actions/checkout@v3
24 | - name: Use Node.js 16
25 | uses: actions/setup-node@v3
26 | with:
27 | node-version: 16
28 | - name: Install dependencies
29 | run: yarn install --network-timeout 600000
30 | - name: Build and publish to github release.
31 | run: npx cross-env GH_TOKEN=${{ secrets.GH_TOKEN }} yarn deploy
32 | build-macos:
33 | runs-on: macos-latest
34 | steps:
35 | - uses: actions/checkout@v3
36 | - name: Use Node.js 16
37 | uses: actions/setup-node@v3
38 | with:
39 | node-version: 16
40 | - name: Setup Python
41 | uses: actions/setup-python@v4.5.0
42 | with:
43 | python-version: 3
44 | - name: Install dependencies
45 | run: yarn install --network-timeout 600000
46 | - name: Build and publish to github release.
47 | run: npx cross-env GH_TOKEN=${{ secrets.GH_TOKEN }} yarn deploy
48 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # build config
6 | electron-builder.yml
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 | .eslintcache
16 | *package-lock.json
17 |
18 | # Dependency directory
19 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
20 | node_modules
21 |
22 | # OSX
23 | .DS_Store
24 |
25 | release/app/dist
26 | release/build
27 | .erb/dll
28 |
29 | tests*
30 |
31 | .idea
32 | npm-debug.log.*
33 | *.css.d.ts
34 | *.sass.d.ts
35 | *.scss.d.ts
36 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["dbaeumer.vscode-eslint", "EditorConfig.EditorConfig"]
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.1",
3 | "configurations": [
4 | {
5 | "name": "Electron: Main",
6 | "type": "node",
7 | "request": "launch",
8 | "protocol": "inspector",
9 | "runtimeExecutable": "npm",
10 | "runtimeArgs": [
11 | "run start:main --inspect=5858 --remote-debugging-port=9223"
12 | ],
13 | "preLaunchTask": "Start Webpack Dev"
14 | },
15 | {
16 | "name": "Electron: Renderer",
17 | "type": "chrome",
18 | "request": "attach",
19 | "port": 9223,
20 | "webRoot": "${workspaceFolder}",
21 | "timeout": 15000
22 | }
23 | ],
24 | "compounds": [
25 | {
26 | "name": "Electron: All",
27 | "configurations": ["Electron: Main", "Electron: Renderer"]
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | ".eslintrc": "jsonc",
4 | ".prettierrc": "jsonc",
5 | ".eslintignore": "ignore"
6 | },
7 |
8 | "javascript.validate.enable": false,
9 | "javascript.format.enable": false,
10 | "typescript.format.enable": false,
11 |
12 | "search.exclude": {
13 | ".git": true,
14 | ".eslintcache": true,
15 | ".erb/dll": true,
16 | "release/{build,app/dist}": true,
17 | "node_modules": true,
18 | "npm-debug.log.*": true,
19 | "test/**/__snapshots__": true,
20 | "package-lock.json": true,
21 | "*.{css,sass,scss}.d.ts": true
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "type": "npm",
6 | "label": "Start Webpack Dev",
7 | "script": "start:renderer",
8 | "options": {
9 | "cwd": "${workspaceFolder}"
10 | },
11 | "isBackground": true,
12 | "problemMatcher": {
13 | "owner": "custom",
14 | "pattern": {
15 | "regexp": "____________"
16 | },
17 | "background": {
18 | "activeOnStart": true,
19 | "beginsPattern": "Compiling\\.\\.\\.$",
20 | "endsPattern": "(Compiled successfully|Failed to compile)\\.$"
21 | }
22 | }
23 | }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/COMMAND.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Supported commands are like below:
5 |
6 | ## animate [option]
7 |
8 | Crop normal/special sprite sheet of specific character and create animated gif of it. characterId is dev id of specific character, for example characterId of fluffy is combat_animal.
9 |
10 | If you want to generate animated GIF of boss monsters (as in battle/boss/*), use the animateBoss command instead
11 |
12 | #### Options:
13 | **-character \** Specify characterId you want to create animation for. Either this or general argument is required.
14 |
15 | **-general \** Specify path to the sprite_sheet you want to generate animated GIFs based on timeline/atlas file located along with the sprite. Either this or character argument is required.
16 |
17 | **-scale \** Specify scale of generated GIF. default to 1.
18 |
19 | **-sheetName \** Specify name of the sprite sheet png file in the target directory. Default to "sprite_sheet".
20 |
21 | **-atlasName \** Specify name of the *.atlas.json file in the target directory. Default to "sprite_sheet".
22 |
23 | **-timelineName \** Specify name of the *.timeline.json file in the target directory. Default to "pixelart".
24 |
25 | **-metaName \** Specify name of the sprite_sheet, atlas, timeline name at the same time, if they're all same.
26 |
27 |
28 | #### Example:
29 | animate -character combat_animal
30 |
31 | animate -general character/big_bear_monster_light/pixelart -scale 2
32 |
33 |
34 |
35 | ## animateBoss [option]
36 |
37 | Create animated gif based on specific sprite_sheet with .parts / .timeline / .atlas file. .parts file is required to execute this command.
38 |
39 | If you want to generate animated GIF of common characters (as in character/*), use the animate command instead
40 |
41 | #### Options:
42 | **-sprite \** Specify path to the sprite_sheet you want to generate animated GIFs based on parts file located along with the sprite. Required.
43 |
44 | **-scale \** Specify scale of generated GIF. default to 1.
45 |
46 | **-meta \** Specify name root of the parts/timeline/atlas file, if you'd like to pick just one. if this is not specified, command will target all the parts file that is found within target directory.
47 |
48 | **-merge** If this flag is set, while generating GIFs, tool will try to merge same group of GIFs into a single GIF, such as `skill_start1, skill_charge1, skill_attack1, skill_attack_loop1, skill_attack_end1`
49 |
50 | **-frameMs \** Specify the time span of a single frame, in milliseconds. Default to 16 (60 frames in one second)
51 |
52 | **-mergeLoopAmount \** While merging, loop animations will loop number of times as specified. Default to 8.
53 |
54 | **-mergeChargeAmount \** While merging, charge animations will loop number of times as specified. Default to 3.
55 |
56 | **-all** Recursively search target directory specified by -searchTarget and find all boos-like sprites / parts metadata and generate animation if possible.
57 |
58 | **-searchTarget** Target directory to search when -all flag is set. Default to `battle/boss`
59 |
60 |
61 | #### Example:
62 | animateBoss -sprite battle/boss/maou_2nd/maou_2nd -scale 2 -merge
63 |
64 | animateBoss -meta high_epuration_boss_3anv -sprite battle/boss/high_epuration_boss_3anv/high_epuration_boss_3anv -scale 4 -merge
65 |
66 | animateBoss -all -searchTarget battle/boss -scale 2 -merge -mergeLoopAmount 5 -mergeChargeAmount 2
67 |
68 |
69 | ## sprite [option] [assetpath]
70 |
71 | Crop sprites and scale cropped images to the specified ratio.
72 |
73 | #### Options:
74 | **-scale \** Specify scale ratio of cropped sprite images. default to 1.
75 |
76 | **-delta \** Specify target delta version to change work directory to that delta directory.
77 |
78 | **-eliyabot** Set this flag if you want to extract equipment sprites from item/sprite_sheet specially formatted for eliyabot asset format.
79 |
80 | #### Example:
81 | sprite -delta 1.570.21 -scale 4 -eliyabot item/sprite_sheet
82 |
83 | sprite -scale 16 character/battle_maid_xm19/pixelart/sprite_sheet
84 |
85 |
86 | ## search [assetpath]
87 | **-format \<.fileformat1|.fileformat2|...\>**
88 | **-ff \<.fileformat1|.fileformat2|...\>** Specify file formats to be used within format search.
89 |
90 | **-extract**
91 | **-e** If found, proceed to extract the asset found by path query.
92 |
93 | Search the asset hash and file formats if anything matches your path query. Useful if you want to find hidden master table files or assets.
94 |
95 | #### Example:
96 | search master/ex_boost/odds/ability/alterite_r3_a
97 |
98 |
99 | ## master [assetpath]
100 |
101 | Rename, decompile and export master table (orderedmap) asset from assetpath to output/orderedmap directory
102 |
103 | #### Example:
104 | master master/ex_boost/odds/ability/alterite_r3_a.orderedmap
105 |
106 |
107 | ## image [assetpath]
108 |
109 | Rename, decompile and export image asset from assetpath to output/asset directory.
110 |
111 | #### Example:
112 | image item/sprite_sheet.png
113 |
114 |
115 | ## audio [assetpath]
116 |
117 | Rename, decompile and export image asset from assetpath to output/asset directory.
118 |
119 | #### Example:
120 | audio bgm/common/encyclopedia.mp3
121 |
122 |
123 | ## general [assetpath]
124 |
125 | Rename, decompile and export general asset from assetpath to output/asset directory. (Automatically converts amf3 into json file format.)
126 |
127 | #### Example:
128 | general battle/action/skill/action/rare5/hero_girl_vt22$hero_girl_vt22_2.action.dsl.amf3.deflate
129 |
130 |
131 | ## enemyDsl [assetpath]
132 |
133 | search for the path if .esdl file exist. if exist, export all related assets with found .esdl file.
134 |
135 | #### Example:
136 | master master/ex_boost/odds/ability/alterite_r3_a.orderedmap
137 |
138 |
139 | ## exboost
140 |
141 | Extract and create odds summary json for exboost odds table [JP Only]
142 |
143 | ## fetchAssets [baseVersion]
144 |
145 | Fetch assets from JP asset api server, using baseVersion as client asset version header.
146 |
147 | #### Example:
148 | fetchAssets 1.531.10
149 |
150 | ## character [characterId]
151 |
152 | Force search for specific [characterId] assets and export them if exists. This command is useful if there's any character assets whose characterId isn't documented in character master table files yet.
153 |
154 | #### Example:
155 | character kyaru
156 |
157 | ## checkUnknowns [option]
158 |
159 | Search and export images files u failed to recover hashes. (WARNING: do not run this command if u have unexported set of images, such as when u only exported character images but general image assets. these unexported set of images will be recognized as unknown images.)
160 |
161 | Exported images are saved under [delta-assetVersion if exists, or workspace root]/output/assets/unknown/images
162 |
163 | #### Options:
164 | **-delta \** Specify target delta asset version if u need to search for specific delta directory. (Available for only those versions u exported with delta-extraction mode)
165 |
166 | #### Example:
167 | checkUnknowns
168 |
169 | checkUnknowns -delta 1.532.20
170 |
171 |
172 |
--------------------------------------------------------------------------------
/FAQ.md:
--------------------------------------------------------------------------------
1 | # World Filpper Asset Extractor FAQs
2 |
3 | These Frequantly asked quetions have been taken from Guthub Issues and other comments made from the commmunity.
4 |
5 | 📝 Controbutions to this documentation are encouraged.
6 |
7 | ## Q: What operating Systems are currently supported for this tool?
8 |
9 | Currently, only Windows is supported. (recommended 10 or higher)
10 |
11 | ## Q: Why is extracting assets from my real device not working?
12 |
13 | Althought there may be other reasons, the most common issue is becuase your device is not rooted.
14 |
15 | ## Q: Where do I find the 5 Element Icons?
16 |
17 | These assets can be found in the sprite sheet `output\assets\scene\general\sprite_sheet_minimal.png` and in the folder `output\assets\scene\general\sprite_sheet\vector_icon_color-assets`.
18 |
19 | ## Q: Why don't I have the `output\assets\scene\general` folder after extracting?
20 |
21 | Some assets, especially those with prefix `scene/general`, are not downloadable through asset API and they're shipped with APK itself (/assets/bundle.zip). The tool's already built to search for those assets (more likely to, if you have full swf scripts decompiled), and if its not found on your end, you need to either pull assets directly from your device using the tool or manually extract them from APK and put it to `dump/` directory along with other asset dumps.
22 |
23 | So if you want to extract those assets manually, follow the next steps.
24 |
25 | 1. Unpack application APK file.
26 |
27 | 2. Locate the bundled assets saved in `PATH_TO_UNPACKED_APK/assets/bundle.zip.`
28 |
29 | 3. Unzip it.
30 |
31 | 4. Copy all the contents inside `bundle.zip/production/bundle` `bundle.zip/production/medium_bundle` into `WORK_DIRECTORY/dump/upload`. WORK_DIR is the Extraction Directory you selected from the tool. (Make sure copied raw asset file paths are look like `WORK_DIR/dump/upload/73/4130924e07d945ae79acac1599758c4e50c432`)
32 |
33 | 5. Open `WORK_DIR/metadata.json` file and modify the key `lockedHashMap` value to `false`.
34 |
35 | 5.1. If you want to confirm everything was done correctly, try executing the command `image scene/general/sprite_sheet.png`. If that command successfully exports the designated asset then you're good to go.
36 |
37 | 6. Try extracting assets again.
38 |
39 | If you can't still find assets after 6 but command in 5.1 works, make sure you turned on the `Search ActionScripts for assets` option and put all the decompiled SWF scripts in the right location. or you can try manually extract them one by one using commands. note that the paths you mentioned above are generated paths and they're actually included in one same sprite file named `scene/general/sprite_sheet` so you'd want to run sprite `scene/general/sprite_sheet` command to crop the image and save cropped sprite to designated path.
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-present Electron React Boilerplate
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 | # World Filpper Asset Extractor
2 |
3 | #### DISCLAIMER: All the rights of extracted assets belong to cygames/citail and/or its affiliates. Do not share the files extracted by the tool. I do not encourage you to use any of extracted assets in inappropriate purpose. If you use any assets extracted by this tool, you do so at your sole risk.
4 |
5 | Asset Extraction tool for World Flipper.
6 |
7 | This tool extracts the assets from world flipper application installed on your device / emulator using ADB and FFDEC, rename digested file paths with original file path, restore corrupted png and mp3 data, export irregular (amf, orderedmap, etc) files in regular data format such as json.
8 |
9 | Supports JP/EN/KR/CN/TW Variants
10 |
11 | ## Installation
12 |
13 | Check out the [release page of this repo](https://github.com/ScripterSugar/wdfp-extractor/releases).
14 |
15 | ## Requirements
16 |
17 | Runs on Windows, Mac or Linux machines.
18 |
19 | #### Pulling from API
20 |
21 | Some regions may not be able to call asset download api (For example, KR/CN Ips are banned from JP api server.) If you have trouble pulling assets from API, consider using VPN to call those APIs
22 |
23 | #### Pulling from devices/emulator
24 |
25 | Requires [Java 8 or later](https://www.java.com/en/download/) to run FFDEC.
26 |
27 | if you're willing to extract assets from real device, your device must be rooted.
28 |
29 | ## Recommended environments
30 |
31 | #### General environmental concerns
32 |
33 | The tool isnt greatly optimized performance-wise, so your machine's cpu/ram usage may reach very high load while extraction.
34 |
35 | #### Emulator/Device extraction
36 |
37 | The tool only tested for limited use cases, thus should have various bugs or even crahses among other enviornments. Basically this tool works best with modified, non-production adbd, which supports adb running as root permission and grants full access to data directory.
38 |
39 | To use this tool, your device should at least have file-listing access to the /data directory.
40 |
41 | #### Using Emulator
42 |
43 | - Nox player (version 7.0.x) - **Recommended (Global)**
44 | - Bluestacks 5 (Not recommended - bad performance due to unabled adbd root access.)
45 |
46 | #### Using Real device
47 |
48 | - Pixel 2 (Android 11)
49 | - Pixel 4 XL (Android 12)
50 | - Pixel 6 Pro (Android 13)
51 |
52 | ## Usage
53 |
54 | #### Select workspace directory
55 |
56 | Select the directory you want to use as workspace directory. Note that your directory must only includes english alphabets or numbers. I recommend you to use the directory under the root directory in the disk such as `C:/wafuriextract`
57 |
58 | #### Pull Assets from API / Device / Emulator
59 |
60 | 
61 |
62 | You need to pull raw asset files from your device/emulator or directly from wdfp api server.
63 |
64 | Click on the `Pull/Downlaod Assets` and select the asset source, region variant and start pulling the assets. Wait until the pulling process is done.
65 |
66 | When using your device or emulator, The device must downloaded all the assets from world flipper client before you use this tool.
67 |
68 | #### Extract assets
69 |
70 | 
71 |
72 | Once you pulled raw assets successfully, click on the `Extract Data` button and select options you want and proceed.
73 |
74 | Once the extraction is done, you can find inflated asset files located in the output directory under your extraction directory.
75 |
76 | **Do not close the app even if it hangs. The process might hangs a lot and several tasks require more than dozens of minutes. Be patient while extraction is in progress**
77 |
78 | #### Delta extraction
79 |
80 | 
81 |
82 | You can turn on the delta extraction mode by clicking the delta icon button located at right side of extract data button.
83 |
84 | In the delta extraction mode,
85 |
86 | - You can pull new assets from API mode only.
87 | - newly pulled assets will placed inside `delta-latest` directory under your workspace directory.
88 | - once you pulled delta assets, `Extract Data` feature will only targets assets inside delta directory created above.
89 | - after your delta extraction is done, `delta-latest` directory will be renamed to `delta-{assetVersion}` directory for better labeling.
90 |
91 | #### Supported commands
92 |
93 | U can use in-built commands for debugging or advanced usage. refer to the [Command documentation](COMMAND.md) for more details.
94 |
95 | ## Frequently asked questions
96 |
97 | Refer to the [FAQ for more details](FAQ.md).
98 |
99 | Thanks to @michaelcurry for the documentation.
100 |
101 | ## Supported Assets
102 |
103 | - APK
104 | - Decompiled SWF
105 | - Master table
106 | - Character image assets
107 | - Character image atlases/frame/parts/timeline (exported as json format)
108 | - Miscellaneous image assets.
109 | - Audio files including BGM, Character voice lines, S/E and more.
110 | - Cropped sprites based on atlases and sprite sheet
111 | - Animated images generated from sprites (Character images only)
112 | - Skill/Action descriptors for characters / bosses / items, including all the details about the skills.
113 | - Summarized Gacha, EX Boost rates table.
114 |
115 | ## Planned feature
116 |
117 | - Support extraction of ability texts
118 | - Data viewer
119 |
120 | ## Known issues
121 |
122 | The repository is open to your contribution! if you're having problem with the issues that listed here, feel free to open PRs to resolve it and make other pepople can benefit from your contribution.
123 |
124 | - Whitespaces in Windows user name / extraction directory path causing crashes on extraction process. (Due date: TBD)
125 |
126 | ## Contributing
127 |
128 | I won't actively troubleshoot the bugs as far as it works for me, so if you're having trouble using the tool on your side, in most cases you'll have to fix the problem yourself, or at least provide me all the details about your environments, runtime context, ETC. Please include all the details when you open issue here. Also feel free to open any PR.
129 |
130 | If you want more asset coverage added to tool, please provide the details about assets you want to export, including file formats, asset path, format of data, etc.
131 |
132 | The application is built from the [electron-react-boilerplate](https://github.com/electron-react-boilerplate/electron-react-boilerplate). Refer to the repository to check how to install dependencies and start development on your local machine.
133 |
134 |
--------------------------------------------------------------------------------
/assets/NanumSquareB.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/NanumSquareB.woff
--------------------------------------------------------------------------------
/assets/NanumSquareEB.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/NanumSquareEB.woff
--------------------------------------------------------------------------------
/assets/NanumSquareL.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/NanumSquareL.woff
--------------------------------------------------------------------------------
/assets/NanumSquareR.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/NanumSquareR.woff
--------------------------------------------------------------------------------
/assets/adb/AdbWinApi.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/adb/AdbWinApi.dll
--------------------------------------------------------------------------------
/assets/adb/AdbWinUsbApi.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/adb/AdbWinUsbApi.dll
--------------------------------------------------------------------------------
/assets/adb/adb.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/adb/adb.exe
--------------------------------------------------------------------------------
/assets/arrowLeft.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/assets.d.ts:
--------------------------------------------------------------------------------
1 | type Styles = Record;
2 |
3 | declare module '*.svg' {
4 | const content: string;
5 | export default content;
6 | }
7 |
8 | declare module '*.png' {
9 | const content: string;
10 | export default content;
11 | }
12 |
13 | declare module '*.jpg' {
14 | const content: string;
15 | export default content;
16 | }
17 |
18 | declare module '*.scss' {
19 | const content: Styles;
20 | export default content;
21 | }
22 |
23 | declare module '*.sass' {
24 | const content: Styles;
25 | export default content;
26 | }
27 |
28 | declare module '*.css' {
29 | const content: Styles;
30 | export default content;
31 | }
32 |
--------------------------------------------------------------------------------
/assets/delta.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/delta.png
--------------------------------------------------------------------------------
/assets/discord.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/assets/entitlements.mac.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.cs.allow-unsigned-executable-memory
6 |
7 | com.apple.security.cs.allow-jit
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/assets/extract.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/ffdec/ffdec.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/ffdec.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/JavactiveX.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/JavactiveX.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/LZMA.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/LZMA.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/avi.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/avi.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/avi.montemedia.license.txt:
--------------------------------------------------------------------------------
1 | Monte Media Library � 2012
2 | Werner Randelshofer, Hausmatt 10, CH-6405 Goldau Switzerland
3 | werner.randelshofer@bluewin.ch
4 | All Rights Reserved.
5 |
6 | The Monte Media Library can be licensed under the terms of the Creative Commons BY 3.0 license, and/or under the terms of the Lesser General Public License LGPL Version 3.
7 |
8 | The license is free for commercial and non-commercial use.
9 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/cmykjpeg.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/cmykjpeg.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/ddsreader.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/ddsreader.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/ffdec_lib.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/ffdec_lib.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/ffdec_lib.license.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/flamingo-6.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/flamingo-6.2.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/flamingo.license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2005-2010 Flamingo Kirill Grouchnikov. All Rights Reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are met:
5 |
6 | o Redistributions of source code must retain the above copyright notice,
7 | this list of conditions and the following disclaimer.
8 |
9 | o Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | o Neither the name of Flamingo Kirill Grouchnikov nor the names of
14 | its contributors may be used to endorse or promote products derived
15 | from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/flashdebugger.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/flashdebugger.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/gif.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/gif.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/gif.license.txt:
--------------------------------------------------------------------------------
1 | Created by Elliot Kroo on 2009-04-25.
2 |
3 | This work is licensed under the Creative Commons Attribution 3.0 Unported
4 | License. To view a copy of this license, visit
5 | http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative
6 | Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
7 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/gnujpdf.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/gnujpdf.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/graphs.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/graphs.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/jargs.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/jargs.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/jl.license.txt:
--------------------------------------------------------------------------------
1 | Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
2 | Berlin University of Technology
3 | -----------------------------------------------------------------------
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU Library General Public License as published
6 | by the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Library General Public License for more details.
13 |
14 | You should have received a copy of the GNU Library General Public
15 | License along with this program; if not, write to the Free Software
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 | ----------------------------------------------------------------------
18 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/jl1.0.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/jl1.0.1.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/jna-3.5.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/jna-3.5.1.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/jna.license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2007 Timothy Wall, All Rights Reserved
2 |
3 | This library is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU Lesser General Public
5 | License as published by the Free Software Foundation; either
6 | version 2.1 of the License, or (at your option) any later version.
7 |
8 | This library is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | Lesser General Public License for more details.
12 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/jpacker.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/jpacker.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/jpacker.license.txt:
--------------------------------------------------------------------------------
1 | Packer version 3.0 (final)
2 | Copyright 2004-2007, Dean Edwards
3 | Web: http://dean.edwards.name/
4 |
5 | This software is licensed under the MIT license
6 | Web: http://www.opensource.org/licenses/mit-license
7 |
8 | Ported to Java by Pablo Santiago based on C# version by Jesse Hansen,
9 | Web: http://jpacker.googlecode.com/
10 | Email: pablo.santiago@gmail.com
11 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/jpproxy.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/jpproxy.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/jpproxy.muffin.license.txt:
--------------------------------------------------------------------------------
1 | Copyright (C) 1996-2003 Mark R. Boyns
2 |
3 | Muffin is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | Muffin is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with Muffin; see the file COPYING. If not, write to the
15 | Free Software Foundation, Inc.,
16 | 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/jsyntaxpane-0.9.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/jsyntaxpane-0.9.5.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/jsyntaxpane.license.txt:
--------------------------------------------------------------------------------
1 | Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License
6 | at http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/minimal-json-0.9.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/minimal-json-0.9.5.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/minimal-json.license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, 2014 EclipseSource
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/nellymoser.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/nellymoser.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/nellymoser.license.txt:
--------------------------------------------------------------------------------
1 | NellyMoser ASAO codec
2 | Copyright (C) 2007-2008 UAB "DKD"
3 | Copyright (C) 2007-2008 Joseph Artsimovich
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | This library is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | Lesser General Public License for more details.
14 |
15 | You should have received a copy of the GNU Lesser General Public
16 | License along with FFmpeg; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/sfntly.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/sfntly.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/sfntly.license.txt:
--------------------------------------------------------------------------------
1 | Copyright 2010 Google Inc. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/substance-6.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/substance-6.2.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/substance-flamingo-6.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/substance-flamingo-6.2.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/substance-flamingo.license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2005-2010 Flamingo / Substance Kirill Grouchnikov. All Rights Reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are met:
5 |
6 | o Redistributions of source code must retain the above copyright notice,
7 | this list of conditions and the following disclaimer.
8 |
9 | o Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | o Neither the name of Flamingo Kirill Grouchnikov nor the names of
14 | its contributors may be used to endorse or promote products derived
15 | from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/substance.license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2005-2010, Kirill Grouchnikov and contributors
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright
10 | notice, this list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 | * Neither the name of the Kirill Grouchnikov and contributors nor
13 | the names of its contributors may be used to endorse or promote products
14 | derived from this software without specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 | THE POSSIBILITY OF SUCH DAMAGE.
27 |
28 | >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
29 |
30 | The original artwork used in the Quaqua color chooser implementation
31 | has been replaced by images from Famfam Silk collection available
32 | under Creative Commons Attribution-ShareAlike 2.5 license and
33 | images created dynamically by the Substance core code.
34 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/tablelayout.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/tablelayout.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/treetable.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/treetable.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/trident-6.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/trident-6.2.jar
--------------------------------------------------------------------------------
/assets/ffdec/lib/trident.license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2005-2010 Trident Kirill Grouchnikov. All Rights Reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are met:
5 |
6 | o Redistributions of source code must retain the above copyright notice,
7 | this list of conditions and the following disclaimer.
8 |
9 | o Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | o Neither the name of Trident Kirill Grouchnikov nor the names of
14 | its contributors may be used to endorse or promote products derived
15 | from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/ttf.doubletype.license.txt:
--------------------------------------------------------------------------------
1 | This program is free software; you can redistribute it and/or modify
2 | it under the terms of the GNU General Public License as published by
3 | the Free Software Foundation; either version 2 of the License, or
4 | (at your option) any later version.
5 |
6 | This Program is distributed in the hope that it will be useful,
7 | but WITHOUT ANY WARRANTY; without even the implied warranty of
8 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 | GNU General Public License for more details.
10 |
11 | You should have received a copy of the GNU General Public License
12 | along with this program; if not, write to the Free Software
13 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 |
15 | In addition, as a special exception, e.e d3si9n gives permission to
16 | link the code of this program with any Java Platform that is available
17 | to public with free of charge, including but not limited to
18 | Sun Microsystem's JAVA(TM) 2 RUNTIME ENVIRONMENT (J2RE),
19 | and distribute linked combinations including the two.
20 | You must obey the GNU General Public License in all respects for all
21 | of the code used other than Java Platform. If you modify this file,
22 | you may extend this exception to your version of the file, but you are not
23 | obligated to do so. If you do not wish to do so, delete this exception
24 | statement from your version.
25 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/ttf.fontastic.license.txt:
--------------------------------------------------------------------------------
1 | Fontastic
2 | A font file writer to create TTF and WOFF (Webfonts).
3 | http://code.andreaskoller.com/libraries/fontastic
4 |
5 | Copyright (C) 2013 Andreas Koller http://andreaskoller.com
6 |
7 | This library is free software; you can redistribute it and/or
8 | modify it under the terms of the GNU Lesser General Public
9 | License as published by the Free Software Foundation; either
10 | version 2.1 of the License, or (at your option) any later version.
11 |
12 | This library is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | Lesser General Public License for more details.
16 |
17 | You should have received a copy of the GNU Lesser General
18 | Public License along with this library; if not, write to the
19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 | Boston, MA 02111-1307 USA
21 |
--------------------------------------------------------------------------------
/assets/ffdec/lib/ttf.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/ffdec/lib/ttf.jar
--------------------------------------------------------------------------------
/assets/folder.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/github.png
--------------------------------------------------------------------------------
/assets/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icon.icns
--------------------------------------------------------------------------------
/assets/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icon.ico
--------------------------------------------------------------------------------
/assets/icons/1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icons/1024x1024.png
--------------------------------------------------------------------------------
/assets/icons/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icons/128x128.png
--------------------------------------------------------------------------------
/assets/icons/16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icons/16x16.png
--------------------------------------------------------------------------------
/assets/icons/24x24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icons/24x24.png
--------------------------------------------------------------------------------
/assets/icons/256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icons/256x256.png
--------------------------------------------------------------------------------
/assets/icons/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icons/32x32.png
--------------------------------------------------------------------------------
/assets/icons/48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icons/48x48.png
--------------------------------------------------------------------------------
/assets/icons/512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icons/512x512.png
--------------------------------------------------------------------------------
/assets/icons/64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icons/64x64.png
--------------------------------------------------------------------------------
/assets/icons/96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/icons/96x96.png
--------------------------------------------------------------------------------
/assets/images/ch10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/ch10.jpg
--------------------------------------------------------------------------------
/assets/images/ch10_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/ch10_banner.png
--------------------------------------------------------------------------------
/assets/images/ch10_special.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/ch10_special.gif
--------------------------------------------------------------------------------
/assets/images/ch10_spin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/ch10_spin.png
--------------------------------------------------------------------------------
/assets/images/ch10_walk.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/ch10_walk.gif
--------------------------------------------------------------------------------
/assets/images/couette.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/couette.jpg
--------------------------------------------------------------------------------
/assets/images/couette_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/couette_banner.png
--------------------------------------------------------------------------------
/assets/images/couette_special.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/couette_special.gif
--------------------------------------------------------------------------------
/assets/images/couette_spin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/couette_spin.png
--------------------------------------------------------------------------------
/assets/images/couette_walk.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/couette_walk.gif
--------------------------------------------------------------------------------
/assets/images/theo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/theo.jpg
--------------------------------------------------------------------------------
/assets/images/theo_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/theo_banner.png
--------------------------------------------------------------------------------
/assets/images/theo_special.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/theo_special.gif
--------------------------------------------------------------------------------
/assets/images/theo_spin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/theo_spin.png
--------------------------------------------------------------------------------
/assets/images/theo_walk.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/images/theo_walk.gif
--------------------------------------------------------------------------------
/assets/info.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/item_bronze.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/item_bronze.png
--------------------------------------------------------------------------------
/assets/item_gold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/item_gold.png
--------------------------------------------------------------------------------
/assets/item_rainbow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/item_rainbow.png
--------------------------------------------------------------------------------
/assets/item_silver.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/item_silver.png
--------------------------------------------------------------------------------
/assets/item_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScripterSugar/wdfp-extractor/28dc2e06d79de65894b95f04ead880633f149708/assets/item_white.png
--------------------------------------------------------------------------------
/assets/settings.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/trash.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/viewer.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wdfp-extractor",
3 | "version": "0.6.10",
4 | "description": "World Flipper asset extractor.",
5 | "scripts": {
6 | "build": "concurrently \"npm run build:main\" \"npm run build:renderer\"",
7 | "build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts",
8 | "build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts",
9 | "rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app",
10 | "lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx",
11 | "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never",
12 | "deploy": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish always",
13 | "postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts && opencollective-postinstall",
14 | "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer",
15 | "start:main": "cross-env NODE_ENV=development electron -r ts-node/register/transpile-only ./src/main/main.ts",
16 | "start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts",
17 | "test": "jest"
18 | },
19 | "lint-staged": {
20 | "*.{js,jsx,ts,tsx}": [
21 | "cross-env NODE_ENV=development eslint --cache"
22 | ],
23 | "*.json,.{eslintrc,prettierrc}": [
24 | "prettier --ignore-path .eslintignore --parser json --write"
25 | ],
26 | "*.{css,scss}": [
27 | "prettier --ignore-path .eslintignore --single-quote --write"
28 | ],
29 | "*.{html,md,yml}": [
30 | "prettier --ignore-path .eslintignore --single-quote --write"
31 | ]
32 | },
33 | "build": {
34 | "productName": "WDFP Extractor",
35 | "appId": "org.inasom.wdfpextractor",
36 | "asar": true,
37 | "asarUnpack": "**\\*.{node,dll}",
38 | "files": [
39 | "dist",
40 | "node_modules",
41 | "package.json"
42 | ],
43 | "afterSign": ".erb/scripts/notarize.js",
44 | "mac": {
45 | "target": {
46 | "target": "default",
47 | "arch": [
48 | "arm64",
49 | "x64"
50 | ]
51 | },
52 | "type": "distribution",
53 | "hardenedRuntime": true,
54 | "entitlements": "assets/entitlements.mac.plist",
55 | "entitlementsInherit": "assets/entitlements.mac.plist",
56 | "gatekeeperAssess": false
57 | },
58 | "dmg": {
59 | "contents": [
60 | {
61 | "x": 130,
62 | "y": 220
63 | },
64 | {
65 | "x": 410,
66 | "y": 220,
67 | "type": "link",
68 | "path": "/Applications"
69 | }
70 | ]
71 | },
72 | "win": {
73 | "target": [
74 | "nsis"
75 | ]
76 | },
77 | "linux": {
78 | "target": [
79 | "AppImage"
80 | ],
81 | "category": "Development"
82 | },
83 | "directories": {
84 | "app": "release/app",
85 | "buildResources": "assets",
86 | "output": "release/build"
87 | },
88 | "extraResources": [
89 | "./assets/**"
90 | ]
91 | },
92 | "repository": {
93 | "type": "git",
94 | "url": "https://github.com/ScripterSugar/wdfp-extractor.git"
95 | },
96 | "author": {
97 | "name": "NASOM",
98 | "email": "scriptersugar@gmail.com"
99 | },
100 | "license": "MIT",
101 | "keywords": [
102 | "electron",
103 | "boilerplate",
104 | "react",
105 | "typescript",
106 | "ts",
107 | "sass",
108 | "webpack",
109 | "hot",
110 | "reload"
111 | ],
112 | "devDependencies": {
113 | "@pmmmwh/react-refresh-webpack-plugin": "0.5.4",
114 | "@teamsupercell/typings-for-css-modules-loader": "^2.5.1",
115 | "@testing-library/jest-dom": "^5.16.1",
116 | "@testing-library/react": "^12.1.2",
117 | "@types/jest": "^27.0.3",
118 | "@types/node": "17.0.5",
119 | "@types/react": "^17.0.38",
120 | "@types/react-dom": "^17.0.11",
121 | "@types/react-test-renderer": "^17.0.1",
122 | "@types/terser-webpack-plugin": "^5.0.4",
123 | "@types/webpack-env": "^1.16.3",
124 | "@typescript-eslint/eslint-plugin": "^5.8.1",
125 | "@typescript-eslint/parser": "^5.8.1",
126 | "browserslist-config-erb": "^0.0.3",
127 | "chalk": "^4.1.2",
128 | "concurrently": "^6.5.1",
129 | "core-js": "^3.20.1",
130 | "cross-env": "^7.0.3",
131 | "css-loader": "^6.5.1",
132 | "css-minimizer-webpack-plugin": "^3.3.1",
133 | "detect-port": "^1.3.0",
134 | "electron": "^16.0.5",
135 | "electron-builder": "^23.6.0",
136 | "electron-devtools-installer": "^3.2.0",
137 | "electron-notarize": "^1.1.1",
138 | "electron-rebuild": "^3.2.5",
139 | "eslint": "^8.5.0",
140 | "eslint-config-airbnb-base": "^15.0.0",
141 | "eslint-config-erb": "^4.0.3",
142 | "eslint-import-resolver-typescript": "^2.5.0",
143 | "eslint-import-resolver-webpack": "^0.13.2",
144 | "eslint-plugin-compat": "^4.0.0",
145 | "eslint-plugin-import": "^2.25.3",
146 | "eslint-plugin-jest": "^25.3.2",
147 | "eslint-plugin-jsx-a11y": "^6.5.1",
148 | "eslint-plugin-promise": "^6.0.0",
149 | "eslint-plugin-react": "^7.28.0",
150 | "eslint-plugin-react-hooks": "^4.3.0",
151 | "file-loader": "^6.2.0",
152 | "html-webpack-plugin": "^5.5.0",
153 | "identity-obj-proxy": "^3.0.0",
154 | "jest": "^27.4.5",
155 | "lint-staged": "^12.1.4",
156 | "mini-css-extract-plugin": "^2.4.5",
157 | "opencollective-postinstall": "^2.0.3",
158 | "prettier": "^2.5.1",
159 | "react-refresh": "^0.11.0",
160 | "react-refresh-typescript": "^2.0.3",
161 | "react-test-renderer": "^17.0.2",
162 | "rimraf": "^3.0.2",
163 | "sass": "^1.45.1",
164 | "sass-loader": "^12.4.0",
165 | "style-loader": "^3.3.1",
166 | "terser-webpack-plugin": "^5.3.0",
167 | "ts-jest": "^27.1.2",
168 | "ts-loader": "^9.2.6",
169 | "ts-node": "^10.4.0",
170 | "typescript": "^4.5.4",
171 | "url-loader": "^4.1.1",
172 | "webpack": "^5.65.0",
173 | "webpack-bundle-analyzer": "^4.5.0",
174 | "webpack-cli": "^4.9.1",
175 | "webpack-dev-server": "^4.7.1",
176 | "webpack-merge": "^5.8.0"
177 | },
178 | "dependencies": {
179 | "adm-zip": "^0.5.9",
180 | "amfjs": "^1.3.1",
181 | "bytearray-nodejs": "^1.0.1",
182 | "csv-parse": "^5.3.0",
183 | "electron-debug": "^3.2.0",
184 | "electron-log": "^4.4.4",
185 | "electron-updater": "^4.6.4",
186 | "get-pixels": "^3.3.3",
187 | "gif-encoder": "^0.7.2",
188 | "history": "^5.2.0",
189 | "moment": "^2.29.2",
190 | "msgpack-lite": "^0.1.26",
191 | "node-fetch": "2.x",
192 | "react": "^17.0.2",
193 | "react-dom": "^17.0.2",
194 | "react-router-dom": "^6.2.1",
195 | "regenerator-runtime": "^0.13.9",
196 | "simple-get": "4.0.1",
197 | "styled-components": "^5.3.3"
198 | },
199 | "devEngines": {
200 | "node": ">=14.x",
201 | "npm": ">=7.x"
202 | },
203 | "browserslist": [],
204 | "prettier": {
205 | "overrides": [
206 | {
207 | "files": [
208 | ".prettierrc",
209 | ".eslintrc"
210 | ],
211 | "options": {
212 | "parser": "json"
213 | }
214 | }
215 | ],
216 | "singleQuote": true
217 | }
218 | }
219 |
220 |
--------------------------------------------------------------------------------
/release/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wdfp-extractor",
3 | "version": "0.6.10",
4 | "description": "World Flipper asset extractor.",
5 | "main": "./dist/main/main.js",
6 | "author": {
7 | "name": "NASOM",
8 | "email": "scriptersugar@gmail.com"
9 | },
10 | "scripts": {
11 | "electron-rebuild": "node -r ts-node/register ../../.erb/scripts/electron-rebuild.js",
12 | "link-modules": "node -r ts-node/register ../../.erb/scripts/link-modules.ts",
13 | "postinstall": "npm run electron-rebuild && npm run link-modules"
14 | },
15 | "dependencies": {
16 | "fkill": "7.2.1",
17 | "iconv-lite": "^0.6.3",
18 | "sharp": "^0.29.3"
19 | },
20 | "license": "MIT"
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/src/main/flatomo/customTweenRecord.ts:
--------------------------------------------------------------------------------
1 | import CustomTweenTools from './customTweenTools';
2 |
3 | export default class CustomTweenRecord {
4 | segments: SegmentRecord[];
5 |
6 | segmentNumber: number;
7 |
8 | resource: number[];
9 |
10 | constructor(param1: number[] = undefined) {
11 | this.resource = param1;
12 | const segmentNumberCalc = Math.floor((param1.length + 2) / 6);
13 | this.segmentNumber =
14 | segmentNumberCalc < 0
15 | ? Math.floor(segmentNumberCalc - 1e-10)
16 | : Math.floor(segmentNumberCalc + 1e-10);
17 | this.segments = Array(this.segmentNumber).fill(null);
18 | }
19 |
20 | getTweenRatio(param1: number): number {
21 | let index = 0;
22 | let high = this.segmentNumber - 1;
23 | while (high !== index) {
24 | const mid = index + Math.ceil((high - index) / 2);
25 | const midValue =
26 | this.resource[mid * 6 - 2] / CustomTweenTools.CUSTOM_TWEEN_MAX;
27 | if (param1 < midValue) {
28 | high = mid - 1;
29 | } else {
30 | index = mid;
31 | }
32 | }
33 |
34 | let segment = this.segments[index];
35 | if (segment === null) {
36 | const startX =
37 | index === 0
38 | ? 0
39 | : this.resource[index * 6 - 2] / CustomTweenTools.CUSTOM_TWEEN_MAX;
40 | const startY =
41 | index === 0
42 | ? 0
43 | : this.resource[index * 6 - 1] / CustomTweenTools.CUSTOM_TWEEN_MAX;
44 | const endX =
45 | index === this.segmentNumber - 1
46 | ? 1
47 | : this.resource[index * 6 + 4] / CustomTweenTools.CUSTOM_TWEEN_MAX;
48 | const endY =
49 | index === this.segmentNumber - 1
50 | ? 1
51 | : this.resource[index * 6 + 5] / CustomTweenTools.CUSTOM_TWEEN_MAX;
52 |
53 | segment = this.segments[index] = new SegmentRecord(
54 | startX,
55 | startY,
56 | this.resource[index * 6] / CustomTweenTools.CUSTOM_TWEEN_MAX,
57 | this.resource[index * 6 + 1] / CustomTweenTools.CUSTOM_TWEEN_MAX,
58 | this.resource[index * 6 + 2] / CustomTweenTools.CUSTOM_TWEEN_MAX,
59 | this.resource[index * 6 + 3] / CustomTweenTools.CUSTOM_TWEEN_MAX,
60 | endX,
61 | endY
62 | );
63 | }
64 |
65 | return segment.getYForX(param1);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/flatomo/customTweenTools.ts:
--------------------------------------------------------------------------------
1 | export default class CustomTweenTools {
2 | static CUSTOM_TWEEN_MAX: number = 1000000;
3 |
4 | static toResource(param1: { x: number; y: number }[]): number[] {
5 | const result: number[] = [];
6 | for (let i = 1; i < param1.length - 1; i++) {
7 | const item = param1[i];
8 | result.push(Math.round(item.x * CustomTweenTools.CUSTOM_TWEEN_MAX));
9 | result.push(Math.round(item.y * CustomTweenTools.CUSTOM_TWEEN_MAX));
10 | }
11 | return result;
12 | }
13 |
14 | static toString(param1: any[]): string {
15 | return param1.join(',');
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/flatomo/graphicsLoopKindTools.ts:
--------------------------------------------------------------------------------
1 | export default class GraphicsLoopKindTools {
2 | static getFutureFrame(
3 | param1: number,
4 | param2: number,
5 | param3: number,
6 | param4: number
7 | ): number {
8 | switch (param1) {
9 | case 0:
10 | return param2;
11 | case 1:
12 | return Math.ceil(Math.min(param2 + param3, param4 - 1));
13 | case 2:
14 | return (param2 + param3) % param4;
15 | default:
16 | return 0;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/flatomo/intMatrix.ts:
--------------------------------------------------------------------------------
1 | export default class IntMatrix {
2 | static RESOLUTION: number = 4096;
3 |
4 | intTy: number;
5 |
6 | intTx: number;
7 |
8 | intD: number;
9 |
10 | intC: number;
11 |
12 | intB: number;
13 |
14 | intA: number;
15 |
16 | constructor(
17 | param1 = 0,
18 | param2 = 0,
19 | param3 = 0,
20 | param4 = 0,
21 | param5 = 0,
22 | param6 = 0
23 | ) {
24 | this.intA = param1;
25 | this.intB = param2;
26 | this.intC = param3;
27 | this.intD = param4;
28 | this.intTx = param5;
29 | this.intTy = param6;
30 | }
31 |
32 | static getIdentity(): IntMatrix {
33 | return new IntMatrix(
34 | IntMatrix.RESOLUTION,
35 | 0,
36 | 0,
37 | IntMatrix.RESOLUTION,
38 | 0,
39 | 0
40 | );
41 | }
42 |
43 | static floatToInt(param1: number): number {
44 | let modifiableParam = param1;
45 |
46 | modifiableParam *= IntMatrix.RESOLUTION;
47 | if (modifiableParam >= 2147483647) {
48 | return 2147483647;
49 | }
50 | if (modifiableParam <= -2147483648) {
51 | return -2147483648;
52 | }
53 | if (modifiableParam < 0) {
54 | return Math.floor(modifiableParam - 1e-10);
55 | }
56 | return Math.floor(modifiableParam + 1e-10);
57 | }
58 |
59 | get ty(): number {
60 | return this.intTy / IntMatrix.RESOLUTION;
61 | }
62 |
63 | get tx(): number {
64 | return this.intTx / IntMatrix.RESOLUTION;
65 | }
66 |
67 | get d(): number {
68 | return this.intD / IntMatrix.RESOLUTION;
69 | }
70 |
71 | get c(): number {
72 | return this.intC / IntMatrix.RESOLUTION;
73 | }
74 |
75 | get b(): number {
76 | return this.intB / IntMatrix.RESOLUTION;
77 | }
78 |
79 | get a(): number {
80 | return this.intA / IntMatrix.RESOLUTION;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/flatomo/matrixHashTable.ts:
--------------------------------------------------------------------------------
1 | import IntMatrix from './intMatrix';
2 |
3 | export default class MatrixHashTable {
4 | static init__: boolean;
5 |
6 | static SIZE: number = 100000;
7 |
8 | static table: IntMatrix[] = [];
9 |
10 | constructor() {}
11 |
12 | static getByFloat(
13 | param1: number,
14 | param2: number,
15 | param3: number,
16 | param4: number,
17 | param5: number,
18 | param6: number
19 | ): IntMatrix {
20 | const _loc7_: number = param1 * IntMatrix.RESOLUTION;
21 | const _loc8_: number = this.floatToInt(_loc7_);
22 | const _loc9_: number = param2 * IntMatrix.RESOLUTION;
23 | const _loc10_: number = this.floatToInt(_loc9_);
24 | const _loc11_: number = param3 * IntMatrix.RESOLUTION;
25 | const _loc12_: number = this.floatToInt(_loc11_);
26 | const _loc13_: number = param4 * IntMatrix.RESOLUTION;
27 | const _loc14_: number = this.floatToInt(_loc13_);
28 | const _loc15_: number = param5 * IntMatrix.RESOLUTION;
29 | const _loc16_: number = this.floatToInt(_loc15_);
30 | const _loc17_: number = param6 * IntMatrix.RESOLUTION;
31 | const _loc18_: number = this.floatToInt(_loc17_);
32 | const _loc19_: number =
33 | 1759 +
34 | _loc8_ * 5360233 +
35 | _loc10_ * 8417077 +
36 | _loc12_ * 4323961 +
37 | _loc14_ * 1764881 +
38 | _loc16_ * 2337539 +
39 | _loc18_ * 3257117;
40 | const _loc20_: number =
41 | _loc19_ < 0 ? Math.floor(_loc19_ - 1e-10) : Math.floor(_loc19_ + 1e-10);
42 | const _loc21_: number = Math.abs(_loc20_) % MatrixHashTable.SIZE;
43 | const _loc22_: IntMatrix = MatrixHashTable.table[_loc21_];
44 |
45 | if (
46 | _loc22_ &&
47 | _loc22_.intA === _loc8_ &&
48 | _loc22_.intB === _loc10_ &&
49 | _loc22_.intC === _loc12_ &&
50 | _loc22_.intD === _loc14_ &&
51 | _loc22_.intTx === _loc16_ &&
52 | _loc22_.intTy === _loc18_
53 | ) {
54 | return _loc22_;
55 | }
56 |
57 | return (MatrixHashTable.table[_loc21_] = new IntMatrix(
58 | _loc8_,
59 | _loc10_,
60 | _loc12_,
61 | _loc14_,
62 | _loc16_,
63 | _loc18_
64 | ));
65 | }
66 |
67 | static get(
68 | param1: number,
69 | param2: number,
70 | param3: number,
71 | param4: number,
72 | param5: number,
73 | param6: number
74 | ): IntMatrix {
75 | const _loc7_: number =
76 | 1759 +
77 | param1 * 5360233 +
78 | param2 * 8417077 +
79 | param3 * 4323961 +
80 | param4 * 1764881 +
81 | param5 * 2337539 +
82 | param6 * 3257117;
83 | const _loc8_: number =
84 | _loc7_ < 0 ? Math.floor(_loc7_ - 1e-10) : Math.floor(_loc7_ + 1e-10);
85 | const _loc9_: number = Math.abs(_loc8_) % MatrixHashTable.SIZE;
86 | const _loc10_: IntMatrix = MatrixHashTable.table[_loc9_];
87 |
88 | if (
89 | _loc10_ &&
90 | _loc10_.intA === param1 &&
91 | _loc10_.intB === param2 &&
92 | _loc10_.intC === param3 &&
93 | _loc10_.intD === param4 &&
94 | _loc10_.intTx === param5 &&
95 | _loc10_.intTy === param6
96 | ) {
97 | return _loc10_;
98 | }
99 |
100 | return (MatrixHashTable.table[_loc9_] = new IntMatrix(
101 | param1,
102 | param2,
103 | param3,
104 | param4,
105 | param5,
106 | param6
107 | ));
108 | }
109 |
110 | static calculateHash(
111 | param1: number,
112 | param2: number,
113 | param3: number,
114 | param4: number,
115 | param5: number,
116 | param6: number
117 | ): number {
118 | const _loc7_: number =
119 | 1759 +
120 | param1 * 5360233 +
121 | param2 * 8417077 +
122 | param3 * 4323961 +
123 | param4 * 1764881 +
124 | param5 * 2337539 +
125 | param6 * 3257117;
126 | const _loc8_: number =
127 | _loc7_ < 0 ? Math.floor(_loc7_ - 1e-10) : Math.floor(_loc7_ + 1e-10);
128 | return Math.abs(_loc8_);
129 | }
130 |
131 | private static floatToInt(param1: number): number {
132 | if (param1 >= 2147483647) {
133 | return 2147483647;
134 | }
135 | if (param1 <= -2147483648) {
136 | return -2147483648;
137 | }
138 | if (param1 < 0) {
139 | return Math.floor(param1 - 1e-10);
140 | }
141 | return Math.floor(param1 + 1e-10);
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/main/flatomo/partState.ts:
--------------------------------------------------------------------------------
1 | import PartStateParameters from './partStateParameter';
2 |
3 | export default class PartState {
4 | parameters: PartStateParameters;
5 |
6 | next: PartState;
7 |
8 | kind: number;
9 |
10 | referencingFrame: number;
11 |
12 | id: number;
13 |
14 | indexForPath: number;
15 |
16 | constructor(
17 | param1 = 0,
18 | param2 = 0,
19 | param3 = 0,
20 | param4 = 0,
21 | param5: PartStateParameters,
22 | param6: PartState
23 | ) {
24 | this.parameters = param5;
25 | this.next = param6;
26 | this.kind = param1;
27 | this.referencingFrame = param3;
28 | this.id = param2;
29 | this.indexForPath = param4;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/flatomo/partStateParameter.ts:
--------------------------------------------------------------------------------
1 | import IntMatrix from './intMatrix';
2 |
3 | export default class PartStateParameters {
4 | matrix: IntMatrix;
5 |
6 | colorTransform: number;
7 |
8 | alphaAndBlendMode: number;
9 |
10 | constructor(param1: IntMatrix, param2 = 0, param3 = 0) {
11 | this.alphaAndBlendMode = param2;
12 | this.matrix = param1;
13 | this.colorTransform = param3;
14 | }
15 |
16 | get intAlpha(): number {
17 | return this.alphaAndBlendMode & 255;
18 | }
19 |
20 | get blendMode(): number {
21 | return this.alphaAndBlendMode >> 8;
22 | }
23 |
24 | get alpha(): number {
25 | return (this.alphaAndBlendMode & 255) / 255;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/flatomo/partStateParameterHashTable.ts:
--------------------------------------------------------------------------------
1 | import IntMatrix from './intMatrix';
2 | import PartStateParameters from './partStateParameter';
3 |
4 | export default class PartStateParametersHashTable {
5 | static init__: boolean;
6 |
7 | static SIZE: number = 100000;
8 |
9 | static table: PartStateParameters[] = [];
10 |
11 | constructor() {}
12 |
13 | static get(
14 | param1: IntMatrix,
15 | param2: number,
16 | param3: number
17 | ): PartStateParameters {
18 | const _loc4_: number =
19 | 1759 +
20 | param1.intA * 5360233 +
21 | param1.intB * 8417077 +
22 | param1.intC * 4323961 +
23 | param1.intD * 1764881 +
24 | param1.intTx * 2337539 +
25 | param1.intTy * 3257117 +
26 | param2 * 28979 +
27 | param3 * 178627 +
28 | 99809;
29 | const _loc5_: number =
30 | _loc4_ < 0 ? Math.floor(_loc4_ - 1e-10) : Math.floor(_loc4_ + 1e-10);
31 | const _loc6_: number = Math.abs(_loc5_) % PartStateParametersHashTable.SIZE;
32 | const _loc7_: PartStateParameters =
33 | PartStateParametersHashTable.table[_loc6_];
34 | if (
35 | _loc7_ &&
36 | _loc7_.matrix === param1 &&
37 | _loc7_.alphaAndBlendMode === param2 &&
38 | _loc7_.colorTransform === param3
39 | ) {
40 | return _loc7_;
41 | }
42 | return (PartStateParametersHashTable.table[_loc6_] =
43 | new PartStateParameters(param1, param2, param3));
44 | }
45 |
46 | static calculateHash(
47 | param1: IntMatrix,
48 | param2: number,
49 | param3: number
50 | ): number {
51 | const _loc4_: number =
52 | 1759 +
53 | param1.intA * 5360233 +
54 | param1.intB * 8417077 +
55 | param1.intC * 4323961 +
56 | param1.intD * 1764881 +
57 | param1.intTx * 2337539 +
58 | param1.intTy * 3257117 +
59 | param2 * 28979 +
60 | param3 * 178627 +
61 | 99809;
62 | const _loc5_: number =
63 | _loc4_ < 0 ? Math.floor(_loc4_ - 1e-10) : Math.floor(_loc4_ + 1e-10);
64 | return Math.abs(_loc5_);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/flatomo/partsAnimationSource.ts:
--------------------------------------------------------------------------------
1 | import GraphicsSource from './graphicsSource';
2 | import IntMatrix from './intMatrix';
3 | import MatrixHashTable from './matrixHashTable';
4 |
5 | export default class PartsAnimationSource {
6 | defaultScale: number;
7 |
8 | imageMaxNumbers: number;
9 |
10 | movieMaxNumbers: number;
11 |
12 | metaData: Record;
13 |
14 | images: any[];
15 |
16 | graphics: GraphicsSource[] = [];
17 |
18 | constructor(parts: Record) {
19 | this.defaultScale = parts.s;
20 | this.imageMaxNumbers = parts.a;
21 | this.movieMaxNumbers = parts.o;
22 | this.metaData = parts.f;
23 | const parsedMatrices = PartsAnimationSource.parseMatrix(parts);
24 | this.images = parts.i;
25 |
26 | this.parseGraphics(parts, parsedMatrices);
27 | }
28 |
29 | static parseMatrix(param1: any): IntMatrix[] {
30 | const _loc2_: number = param1.t.length;
31 | const _loc3_: IntMatrix[] = new Array(_loc2_);
32 | for (let _loc4_ = 0; _loc4_ < _loc2_; _loc4_++) {
33 | const _loc6_ = param1.t[_loc4_];
34 | const _loc7_: number = _loc6_.a;
35 | const _loc8_: number = _loc6_.b;
36 | const _loc9_: number = _loc6_.c;
37 | const _loc10_: number = _loc6_.d;
38 | const _loc11_: number = _loc6_.x;
39 | const _loc12_: number = _loc6_.y;
40 | const _loc13_: number =
41 | 1759 +
42 | _loc7_ * 5360233 +
43 | _loc8_ * 8417077 +
44 | _loc9_ * 4323961 +
45 | _loc10_ * 1764881 +
46 | _loc11_ * 2337539 +
47 | _loc12_ * 3257117;
48 | const _loc14_: number =
49 | _loc13_ < 0 ? Math.floor(_loc13_ - 1e-10) : Math.floor(_loc13_ + 1e-10);
50 | const _loc15_: number = Math.abs(_loc14_) % MatrixHashTable.SIZE;
51 | const _loc16_: IntMatrix = MatrixHashTable.table[_loc15_];
52 | _loc3_[_loc4_] =
53 | _loc16_ &&
54 | _loc16_.intA === _loc7_ &&
55 | _loc16_.intB === _loc8_ &&
56 | _loc16_.intC === _loc9_ &&
57 | _loc16_.intD === _loc10_ &&
58 | _loc16_.intTx === _loc11_ &&
59 | _loc16_.intTy === _loc12_
60 | ? _loc16_
61 | : (MatrixHashTable.table[_loc15_] = new IntMatrix(
62 | _loc7_,
63 | _loc8_,
64 | _loc9_,
65 | _loc10_,
66 | _loc11_,
67 | _loc12_
68 | ));
69 | }
70 | return _loc3_;
71 | }
72 |
73 | parseGraphics(parts: Record, matrices: IntMatrix[]): void {
74 | for (const graphicDescriber of parts.g) {
75 | const graphic = new GraphicsSource(
76 | graphicDescriber.s,
77 | graphicDescriber.t,
78 | matrices,
79 | parts.g
80 | );
81 | this.graphics.push(graphic);
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/main/main.ts:
--------------------------------------------------------------------------------
1 | /* eslint global-require: off, no-console: off, promise/always-return: off */
2 |
3 | /**
4 | * This module executes inside of electron's main process. You can start
5 | * electron renderer process from here and communicate with the other processes
6 | * through IPC.
7 | *
8 | * When running `npm run build` or `npm run build:main`, this file is compiled to
9 | * `./src/main.js` using webpack. This gives us some performance wins.
10 | */
11 | import 'core-js/stable';
12 | import 'regenerator-runtime/runtime';
13 | import path from 'path';
14 | import { app, BrowserWindow, shell, ipcMain, dialog } from 'electron';
15 | import { autoUpdater } from 'electron-updater';
16 | import log from 'electron-log';
17 | import { createWriteStream } from 'fs';
18 | import MenuBuilder from './menu';
19 | import { resolveHtmlPath } from './util';
20 | import logger from './wf/logger';
21 | import WfExtractor from './wf';
22 | import { asyncReadFile } from './wf/helpers';
23 |
24 | let mainWindow: BrowserWindow | null = null;
25 |
26 | ipcMain.on('showOpenDialog', async (event, arg) => {
27 | const returnedPath = dialog.showOpenDialogSync({
28 | properties: ['openDirectory'],
29 | });
30 |
31 | event.reply('showOpenDialog', returnedPath);
32 | });
33 |
34 | ipcMain.on('openDevTools', async (event, arg) => {
35 | mainWindow.webContents.openDevTools();
36 | });
37 |
38 | ipcMain.on('getAppVersion', async (event) => {
39 | event.reply('appVersion', app.getVersion());
40 | });
41 |
42 | ipcMain.on('openDirectory', async (event, openPath) => {
43 | shell.openPath(openPath);
44 | });
45 | ipcMain.on('updateApp', async (event, openPath) => {
46 | autoUpdater.quitAndInstall();
47 | });
48 |
49 | ipcMain.on('clearMeta', async (event, rootDir, targetData) => {
50 | const wfExtractor = new WfExtractor({
51 | rootDir,
52 | });
53 |
54 | await wfExtractor.init();
55 |
56 | switch (targetData) {
57 | case 'characterSprites': {
58 | await wfExtractor.markMetaData({
59 | spriteProcessedLock: [],
60 | specialSpriteProcessedLock: [],
61 | });
62 |
63 | logger.log('Character sprites cache cleared.');
64 |
65 | return null;
66 | }
67 | default: {
68 | return null;
69 | }
70 | }
71 | });
72 |
73 | class ExtractionProcessor {
74 | packetResolver = (data: string) => {};
75 |
76 | awaitNextPacket = (): Promise => {
77 | return new Promise((resolve) => {
78 | this.packetResolver = resolve;
79 | });
80 | };
81 |
82 | resolveAwait = (data: string) => {
83 | if (this.packetResolver) {
84 | this.packetResolver(data);
85 | this.packetResolver = () => {};
86 | }
87 | };
88 | }
89 |
90 | const extractionProcessor = new ExtractionProcessor();
91 |
92 | ipcMain.on('extractionResponseRenderer', async (event, response) => {
93 | extractionProcessor.resolveAwait(response);
94 | });
95 |
96 | ipcMain.on('getMeta', async (event, rootDir) => {
97 | let meta = {};
98 |
99 | try {
100 | meta = JSON.parse(await asyncReadFile(`${rootDir}/metadata.json`));
101 | } catch (err) {
102 | console.log(err);
103 | }
104 | event.reply('getMetaResponse', meta);
105 | });
106 |
107 | ipcMain.on(
108 | 'startPull',
109 | async (
110 | event,
111 | rootDir,
112 | {
113 | region,
114 | regionVariant,
115 | variant,
116 | baseVersion,
117 | ignoreFull,
118 | skipSwfDecompile,
119 | parseActionScript,
120 | customPort,
121 | customCdn,
122 | deltaMode,
123 | }
124 | ) => {
125 | let replyPacket = '';
126 | let extractionPhase = 0;
127 |
128 | const wfExtractor = new WfExtractor({
129 | region,
130 | regionVariant,
131 | rootDir,
132 | swfMode: (parseActionScript && 'full') || 'simple',
133 | customPort,
134 | extractAllFrames: false,
135 | deltaMode,
136 | });
137 |
138 | while (replyPacket !== 'done') {
139 | if (/phase/.test(replyPacket)) {
140 | const targetPhase = parseFloat(replyPacket.split(':')[1]);
141 |
142 | extractionPhase = targetPhase;
143 | }
144 | try {
145 | if (extractionPhase <= 0) {
146 | await wfExtractor.init({ requireJava: variant === 'device' });
147 | extractionPhase = 1;
148 | }
149 |
150 | switch (variant) {
151 | case 'device': {
152 | if (extractionPhase <= 1) {
153 | if (/selectDevice/.test(replyPacket)) {
154 | const deviceId = replyPacket.replace(/selectDevice/, '');
155 | await wfExtractor.selectDevice(deviceId);
156 | } else {
157 | await wfExtractor.selectDevice();
158 | }
159 |
160 | extractionPhase = 2;
161 | }
162 |
163 | if (extractionPhase <= 2) {
164 | await wfExtractor.connectAdbShell();
165 | extractionPhase = 3;
166 | }
167 |
168 | if (skipSwfDecompile) {
169 | extractionPhase = 4;
170 | }
171 |
172 | if (extractionPhase <= 3) {
173 | await wfExtractor.dumpAndExtractApk();
174 | await wfExtractor.decompileAndExportSwf();
175 | extractionPhase = 4;
176 | }
177 |
178 | if (extractionPhase <= 4) {
179 | await wfExtractor.indexWfAssets();
180 | await wfExtractor.dumpWfAssets();
181 | await wfExtractor.mergeAssets();
182 | extractionPhase = 4.5;
183 | }
184 |
185 | break;
186 | }
187 | case 'api': {
188 | await wfExtractor.fetchAssetsFromApi(baseVersion, {
189 | ...(customCdn && { cdn: customCdn }),
190 | ignoreFull,
191 | });
192 |
193 | break;
194 | }
195 | default: {
196 | throw new Error(`Variant ${variant} not defined.`);
197 | }
198 | }
199 |
200 | break;
201 | } catch (err) {
202 | event.reply('extractionResponseMain', {
203 | error: err?.message || 'UNKNOWN',
204 | });
205 | replyPacket = await extractionProcessor.awaitNextPacket();
206 | }
207 | }
208 | event.reply('extractionResponseMain', { success: true });
209 | }
210 | );
211 |
212 | ipcMain.on(
213 | 'startExtraction',
214 | async (
215 | event,
216 | rootDir,
217 | {
218 | region,
219 | extractMaster,
220 | extractCharacterImage,
221 | extractMiscImage,
222 | extractAudio,
223 | extractAllFrames,
224 | extractGeneralAmf,
225 | extractEsdl,
226 | processAtlas,
227 | processAtlasMisc,
228 | parseActionScript,
229 | customPort,
230 | debug,
231 | deltaMode,
232 | }
233 | ) => {
234 | let replyPacket;
235 | let extractionPhase = 0;
236 |
237 | const wfExtractor = new WfExtractor({
238 | region,
239 | rootDir,
240 | swfMode: (parseActionScript && 'full') || 'simple',
241 | customPort,
242 | extractAllFrames,
243 | deltaMode,
244 | });
245 |
246 | if (debug) {
247 | const start = new Date().getTime();
248 | try {
249 | logger.log(`Executing command ${debug}`);
250 | await wfExtractor.executeCommand(debug);
251 | } catch (err) {
252 | console.log(err);
253 | logger.log(`Error executing command ${debug}`);
254 | logger.log(err?.message || `${err}`);
255 | }
256 | const end = new Date().getTime();
257 | logger.log(`Process done in ${((end - start) / 1000).toFixed(2)}s`);
258 |
259 | event.reply('extractionResponseMain', { success: true });
260 | return;
261 | }
262 |
263 | while (replyPacket !== 'done') {
264 | console.log(`TRYING EXTRACTION, Current Phase ${extractionPhase}`);
265 |
266 | if (replyPacket === 'purgeSwf') {
267 | await wfExtractor.markMetaData({
268 | lastSwfChecksum: null,
269 | lastSwfMode: null,
270 | });
271 | }
272 | if (/phase/.test(replyPacket)) {
273 | const targetPhase = parseFloat(replyPacket.split(':')[1]);
274 |
275 | extractionPhase = targetPhase;
276 | }
277 | try {
278 | if (extractionPhase <= 0) {
279 | await wfExtractor.init();
280 | extractionPhase = 1;
281 | }
282 |
283 | if (extractionPhase <= 4.5) {
284 | await wfExtractor.buildDigestFileMap();
285 |
286 | extractionPhase = 5;
287 | }
288 |
289 | if (extractionPhase <= 5) {
290 | if (extractMaster || /extractMaster/.test(replyPacket)) {
291 | await wfExtractor.extractMasterTable();
292 | if (parseActionScript) {
293 | await wfExtractor.buildAsFilePaths();
294 | } else {
295 | await wfExtractor.loadAsFilePaths();
296 | }
297 | } else {
298 | await wfExtractor.loadFilePaths();
299 | await wfExtractor.loadAsFilePaths();
300 | }
301 | extractionPhase = 5.5;
302 | }
303 |
304 | if (extractionPhase <= 5.5) {
305 | if (extractMaster) {
306 | await wfExtractor.extractGachaOdds();
307 | }
308 |
309 | extractionPhase = 6;
310 | }
311 |
312 | if (extractionPhase <= 6) {
313 | if (extractCharacterImage) {
314 | await wfExtractor.extractCharacterImageAssets();
315 |
316 | if (processAtlas) {
317 | await wfExtractor.extractCharacterSpriteMetaDatas();
318 | await wfExtractor.generateAnimatedSprites();
319 | }
320 | }
321 | extractionPhase = 7;
322 | }
323 |
324 | if (extractionPhase <= 7) {
325 | if (extractMiscImage) {
326 | await wfExtractor.extractPossibleImageAssets({
327 | cropSprites: processAtlasMisc,
328 | });
329 | }
330 |
331 | extractionPhase = 7.5;
332 | }
333 |
334 | if (extractionPhase <= 7.5) {
335 | if (extractGeneralAmf) {
336 | await wfExtractor.extractPossibleGeneralAmf3Assets();
337 | await wfExtractor.extractSkillEffects();
338 | }
339 |
340 | extractionPhase = 8;
341 | }
342 |
343 | if (extractionPhase <= 8) {
344 | if (extractAudio) {
345 | await wfExtractor.extractCharacterVoiceAssets();
346 | await wfExtractor.extractPossibleAudioAssets();
347 | }
348 |
349 | extractionPhase = 9;
350 | }
351 |
352 | if (extractionPhase <= 9) {
353 | if (extractEsdl) {
354 | await wfExtractor.extractPossibleEnemyDslAssets();
355 | }
356 |
357 | extractionPhase = 10;
358 | }
359 |
360 | await wfExtractor.saveConfirmedDigests();
361 |
362 | break;
363 | } catch (err) {
364 | console.log(err);
365 | logger.log(`Error ocurred while extraction: ${err?.message || err}`);
366 |
367 | event.reply('extractionResponseMain', {
368 | error: err?.message || 'UNKNOWN',
369 | });
370 | replyPacket = await extractionProcessor.awaitNextPacket();
371 | }
372 | }
373 |
374 | event.reply('extractionResponseMain', { success: true });
375 | }
376 | );
377 |
378 | if (process.env.NODE_ENV === 'production') {
379 | const sourceMapSupport = require('source-map-support');
380 | sourceMapSupport.install();
381 | }
382 |
383 | const isDevelopment =
384 | process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true';
385 | if (isDevelopment) {
386 | require('electron-debug')();
387 | }
388 |
389 | const installExtensions = async () => {
390 | const installer = require('electron-devtools-installer');
391 | const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
392 | const extensions = ['REACT_DEVELOPER_TOOLS'];
393 |
394 | return installer
395 | .default(
396 | extensions.map((name) => installer[name]),
397 | forceDownload
398 | )
399 | .catch(console.log);
400 | };
401 |
402 | const RESOURCE_PATH = app.isPackaged
403 | ? process.resourcesPath
404 | : path.join(__dirname, '../../');
405 |
406 | const ASSETS_PATH = path.join(RESOURCE_PATH, 'assets');
407 |
408 | const getAssetPath = (...paths: string[]): string => {
409 | return path.join(ASSETS_PATH, ...paths);
410 | };
411 |
412 | if (process.env.NODE_ENV !== 'development') {
413 | const logs = createWriteStream(path.join(RESOURCE_PATH, '/debug_out.log'));
414 | process.stdout.write = process.stderr.write = logs.write.bind(logs); // eslint-disable-line
415 | }
416 |
417 | const createWindow = async () => {
418 | if (isDevelopment) {
419 | await installExtensions();
420 | }
421 |
422 | mainWindow = new BrowserWindow({
423 | show: false,
424 | width: 1024,
425 | height: 728,
426 | resizable: false,
427 | icon: getAssetPath('icon.ico'),
428 | webPreferences: {
429 | preload: path.join(__dirname, 'preload.js'),
430 | },
431 | });
432 |
433 | logger.connectWindow(mainWindow);
434 |
435 | mainWindow.setMenu(null);
436 |
437 | mainWindow.loadURL(resolveHtmlPath('index.html'));
438 |
439 | mainWindow.on('ready-to-show', () => {
440 | if (!mainWindow) {
441 | throw new Error('"mainWindow" is not defined');
442 | }
443 | if (process.env.START_MINIMIZED) {
444 | mainWindow.minimize();
445 | } else {
446 | mainWindow.show();
447 | }
448 | autoUpdater.checkForUpdatesAndNotify();
449 | });
450 |
451 | mainWindow.on('closed', () => {
452 | mainWindow = null;
453 | });
454 | };
455 |
456 | /**
457 | * Add event listeners...
458 | */
459 |
460 | app.on('window-all-closed', () => {
461 | // Respect the OSX convention of having the application in memory even
462 | // after all windows have been closed
463 | if (process.platform !== 'darwin') {
464 | app.quit();
465 | }
466 | });
467 |
468 | app
469 | .whenReady()
470 | .then(() => {
471 | createWindow();
472 | app.on('activate', () => {
473 | // On macOS it's common to re-create a window in the app when the
474 | // dock icon is clicked and there are no other windows open.
475 | if (mainWindow === null) createWindow();
476 | });
477 | })
478 | .catch(console.log);
479 |
480 | autoUpdater.on('update-available', () => {
481 | mainWindow.webContents.send('update_available');
482 | });
483 | autoUpdater.on('update-downloaded', () => {
484 | mainWindow.webContents.send('update_downloaded');
485 | });
486 |
--------------------------------------------------------------------------------
/src/main/menu.ts:
--------------------------------------------------------------------------------
1 | import {
2 | app,
3 | Menu,
4 | shell,
5 | BrowserWindow,
6 | MenuItemConstructorOptions,
7 | } from 'electron';
8 |
9 | interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions {
10 | selector?: string;
11 | submenu?: DarwinMenuItemConstructorOptions[] | Menu;
12 | }
13 |
14 | export default class MenuBuilder {
15 | mainWindow: BrowserWindow;
16 |
17 | constructor(mainWindow: BrowserWindow) {
18 | this.mainWindow = mainWindow;
19 | }
20 |
21 | buildMenu(): Menu {
22 | if (
23 | process.env.NODE_ENV === 'development' ||
24 | process.env.DEBUG_PROD === 'true'
25 | ) {
26 | this.setupDevelopmentEnvironment();
27 | }
28 |
29 | const template = this.buildDefaultTemplate();
30 |
31 | const menu = Menu.buildFromTemplate(template);
32 | Menu.setApplicationMenu(menu);
33 |
34 | return menu;
35 | }
36 |
37 | setupDevelopmentEnvironment(): void {
38 | this.mainWindow.webContents.on('context-menu', (_, props) => {
39 | const { x, y } = props;
40 |
41 | Menu.buildFromTemplate([
42 | {
43 | label: 'Inspect element',
44 | click: () => {
45 | this.mainWindow.webContents.inspectElement(x, y);
46 | },
47 | },
48 | ]).popup({ window: this.mainWindow });
49 | });
50 | }
51 |
52 | buildDefaultTemplate() {
53 | const templateDefault = [
54 | {
55 | label: '&File',
56 | submenu: [
57 | {
58 | label: '&Open',
59 | accelerator: 'Ctrl+O',
60 | },
61 | {
62 | label: '&Close',
63 | accelerator: 'Ctrl+W',
64 | click: () => {
65 | this.mainWindow.close();
66 | },
67 | },
68 | ],
69 | },
70 | ];
71 |
72 | return templateDefault;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/preload.js:
--------------------------------------------------------------------------------
1 | const { contextBridge, ipcRenderer, shell } = require('electron');
2 |
3 | contextBridge.exposeInMainWorld('electron', {
4 | ipcRenderer: {
5 | showOpenDialog() {
6 | ipcRenderer.send('showOpenDialog', 'asd');
7 | },
8 | openDirectory(dir) {
9 | ipcRenderer.send('openDirectory', dir);
10 | },
11 | startExtraction(rootDir, options) {
12 | ipcRenderer.send('startExtraction', rootDir, options);
13 | },
14 | startPull(rootDir, options) {
15 | ipcRenderer.send('startPull', rootDir, options);
16 | },
17 | openExternal(external) {
18 | shell.openExternal(external);
19 | },
20 | openDevTools() {
21 | ipcRenderer.send('openDevTools');
22 | },
23 | clearMeta(rootDir, targetData) {
24 | ipcRenderer.send('clearMeta', rootDir, targetData);
25 | },
26 | getMeta(rootDir) {
27 | ipcRenderer.send('getMeta', rootDir);
28 | },
29 | getAppVersion() {
30 | ipcRenderer.send('getAppVersion');
31 | },
32 | updateApp() {
33 | ipcRenderer.send('updateApp');
34 | },
35 | responseExtraction(response) {
36 | ipcRenderer.send('extractionResponseRenderer', response);
37 | },
38 | on(channel, func) {
39 | ipcRenderer.on(channel, (event, ...args) => func(...args));
40 | },
41 | once(channel, func) {
42 | ipcRenderer.once(channel, (event, ...args) => func(...args));
43 | },
44 | removeAllListeners(channel) {
45 | ipcRenderer.removeAllListeners(channel);
46 | },
47 | },
48 | });
49 |
--------------------------------------------------------------------------------
/src/main/util.ts:
--------------------------------------------------------------------------------
1 | /* eslint import/prefer-default-export: off, import/no-mutable-exports: off */
2 | import { URL } from 'url';
3 | import path from 'path';
4 |
5 | export let resolveHtmlPath: (htmlFileName: string) => string;
6 |
7 | if (process.env.NODE_ENV === 'development') {
8 | const port = process.env.PORT || 1212;
9 | resolveHtmlPath = (htmlFileName: string) => {
10 | const url = new URL(`http://localhost:${port}`);
11 | url.pathname = htmlFileName;
12 | return url.href;
13 | };
14 | } else {
15 | resolveHtmlPath = (htmlFileName: string) => {
16 | return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`;
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/wf/constants.js:
--------------------------------------------------------------------------------
1 | export const ELIGIBLE_PATH_PREFIXES = [
2 | 'dump/upload/',
3 | 'dump/medium_upload/',
4 | 'dump/small_upload',
5 | ];
6 |
7 | export const MERGEABLE_PATH_PREFIXES = [
8 | 'dump/android_upload/',
9 | 'dump/android_small_upload/',
10 | 'dump/android_medium_upload/',
11 | 'dump/bundle/',
12 | 'dump/medium_bundle/',
13 | 'dump/small_bundle/',
14 | ];
15 |
16 | export const ANIMATION_COMMON_POSTFIXES = [
17 | 'start',
18 | 'charge',
19 | 'fire',
20 | 'attack',
21 | 'loop',
22 | 'set',
23 | 'end',
24 | 'start1',
25 | 'charge1',
26 | 'fire1',
27 | 'attack1',
28 | 'loop1',
29 | 'set1',
30 | 'end1',
31 | 'start2',
32 | 'charge2',
33 | 'fire2',
34 | 'attack2',
35 | 'loop2',
36 | 'set2',
37 | 'end2',
38 | 'start3',
39 | 'charge3',
40 | 'fire3',
41 | 'attack3',
42 | 'loop3',
43 | 'set3',
44 | 'end3',
45 | 'start4',
46 | 'charge4',
47 | 'fire4',
48 | 'attack4',
49 | 'loop4',
50 | 'set4',
51 | 'end4',
52 | 'start5',
53 | 'charge5',
54 | 'fire5',
55 | 'attack5',
56 | 'loop5',
57 | 'set5',
58 | 'end5',
59 | ];
60 |
61 | export const ACTION_DSL_FORMAT_DEFLATE = '.action.dsl.amf3.deflate';
62 | export const ENEMY_DSL_FORMAT_DEFLATE = '.esdl.amf3.deflate';
63 |
64 | export const CHARACTER_SPRITE_PRESETS = [
65 | (character, index) => `character/${character}/pixelart/sprite_sheet`,
66 | (character, index) => `character/${character}/pixelart/special_sprite_sheet`,
67 | (character, index) => `character/${character}/pixelart/special`,
68 | (character, index) => `character/${character}/ui/skill_cutin_${index}`,
69 | (character, index) => `character/${character}/ui/cutin_skill_chain_${index}`,
70 | (character, index) => `character/${character}/pixelart/pixelart`,
71 | (character, index) => `character/${character}/ui/thumb_party_unison_${index}`,
72 | (character, index) => `character/${character}/ui/thumb_party_main_${index}`,
73 | (character, index) =>
74 | `character/${character}/ui/battle_member_status_${index}`,
75 | (character, index) => `character/${character}/ui/thumb_level_up_${index}`,
76 | (character, index) => `character/${character}/ui/square_${index}`,
77 | (character, index) => `character/${character}/ui/square_132_132_${index}`,
78 | (character, index) =>
79 | `character/${character}/ui/square_round_136_136_${index}`,
80 | (character, index) => `character/${character}/ui/square_round_95_95_${index}`,
81 | (character, index) =>
82 | `character/${character}/ui/battle_member_status_${index}`,
83 | (character, index) => `character/${character}/ui/episode_banner_0`,
84 | (character, index) =>
85 | `character/${character}/ui/battle_control_board_${index}`,
86 | (character, index) =>
87 | `character/${character}/battle/character_detail_skill_preview`,
88 | (character, index) =>
89 | `character/${character}/ui/illustration_setting_sprite_sheet`,
90 | (character, index) =>
91 | `character/${character}/battle/character_info_skill_preview`,
92 | (character, index) =>
93 | `character/${character}/ui/full_shot_1440_1920_${index}`,
94 | (character, index) =>
95 | `character/${character}/ui/full_shot_illustration_setting_${index}`,
96 | (character) => `character/${character}/ui/story/anger`,
97 | (character) => `character/${character}/ui/story/anger_b`,
98 | (character) => `character/${character}/ui/story/anger_c`,
99 | (character) => `character/${character}/ui/story/anger_d`,
100 | (character) => `character/${character}/ui/story/anger_e`,
101 | (character) => `character/${character}/ui/story/anger_f`,
102 | (character) => `character/${character}/ui/story/base_0`,
103 | (character) => `character/${character}/ui/story/base_0_b`,
104 | (character) => `character/${character}/ui/story/base_0_c`,
105 | (character) => `character/${character}/ui/story/base_0_d`,
106 | (character) => `character/${character}/ui/story/base_0_e`,
107 | (character) => `character/${character}/ui/story/base_0_f`,
108 | (character) => `character/${character}/ui/story/base_1`,
109 | (character) => `character/${character}/ui/story/base_1_b`,
110 | (character) => `character/${character}/ui/story/base_1_c`,
111 | (character) => `character/${character}/ui/story/base_1_d`,
112 | (character) => `character/${character}/ui/story/base_1_e`,
113 | (character) => `character/${character}/ui/story/base_1_f`,
114 | (character) => `character/${character}/ui/story/normal`,
115 | (character) => `character/${character}/ui/story/normal_b`,
116 | (character) => `character/${character}/ui/story/normal_c`,
117 | (character) => `character/${character}/ui/story/normal_d`,
118 | (character) => `character/${character}/ui/story/normal_e`,
119 | (character) => `character/${character}/ui/story/normal_f`,
120 | (character) => `character/${character}/ui/story/sad`,
121 | (character) => `character/${character}/ui/story/sad_b`,
122 | (character) => `character/${character}/ui/story/sad_c`,
123 | (character) => `character/${character}/ui/story/sad_d`,
124 | (character) => `character/${character}/ui/story/sad_e`,
125 | (character) => `character/${character}/ui/story/sad_f`,
126 | (character) => `character/${character}/ui/story/serious`,
127 | (character) => `character/${character}/ui/story/serious_b`,
128 | (character) => `character/${character}/ui/story/serious_c`,
129 | (character) => `character/${character}/ui/story/serious_d`,
130 | (character) => `character/${character}/ui/story/serious_e`,
131 | (character) => `character/${character}/ui/story/serious_f`,
132 | (character) => `character/${character}/ui/story/shame`,
133 | (character) => `character/${character}/ui/story/shame_b`,
134 | (character) => `character/${character}/ui/story/shame_c`,
135 | (character) => `character/${character}/ui/story/shame_d`,
136 | (character) => `character/${character}/ui/story/shame_e`,
137 | (character) => `character/${character}/ui/story/shame_f`,
138 | (character) => `character/${character}/ui/story/shout`,
139 | (character) => `character/${character}/ui/story/shout_b`,
140 | (character) => `character/${character}/ui/story/shout_c`,
141 | (character) => `character/${character}/ui/story/shout_d`,
142 | (character) => `character/${character}/ui/story/shout_e`,
143 | (character) => `character/${character}/ui/story/shout_f`,
144 | (character) => `character/${character}/ui/story/smile`,
145 | (character) => `character/${character}/ui/story/smile_b`,
146 | (character) => `character/${character}/ui/story/smile_c`,
147 | (character) => `character/${character}/ui/story/smile_d`,
148 | (character) => `character/${character}/ui/story/smile_e`,
149 | (character) => `character/${character}/ui/story/smile_f`,
150 | (character) => `character/${character}/ui/story/surprise`,
151 | (character) => `character/${character}/ui/story/surprise_b`,
152 | (character) => `character/${character}/ui/story/surprise_c`,
153 | (character) => `character/${character}/ui/story/surprise_d`,
154 | (character) => `character/${character}/ui/story/surprise_e`,
155 | (character) => `character/${character}/ui/story/surprise_f`,
156 | (character) => `character/${character}/ui/story/sweat`,
157 | (character) => `character/${character}/ui/story/sweat_b`,
158 | (character) => `character/${character}/ui/story/sweat_c`,
159 | (character) => `character/${character}/ui/story/sweat_d`,
160 | (character) => `character/${character}/ui/story/sweat_e`,
161 | (character) => `character/${character}/ui/story/sweat_f`,
162 | (character) => `character/${character}/ui/story/think`,
163 | (character) => `character/${character}/ui/story/think_b`,
164 | (character) => `character/${character}/ui/story/think_c`,
165 | (character) => `character/${character}/ui/story/think_d`,
166 | (character) => `character/${character}/ui/story/think_e`,
167 | (character) => `character/${character}/ui/story/think_f`,
168 | (character) => `character/${character}/ui/story/vigilant`,
169 | (character) => `character/${character}/ui/story/vigilant_b`,
170 | (character) => `character/${character}/ui/story/vigilant_c`,
171 | (character) => `character/${character}/ui/story/vigilant_d`,
172 | (character) => `character/${character}/ui/story/vigilant_e`,
173 | (character) => `character/${character}/ui/story/vigilant_f`,
174 | ];
175 |
176 | export const CHARACTER_AMF_PRESERTS = [
177 | (character) => `character/${character}/pixelart/pixelart.frame.amf3.deflate`,
178 | (character) =>
179 | `character/${character}/pixelart/sprite_sheet.parts.amf3.deflate`,
180 | (character) =>
181 | `character/${character}/pixelart/pixelart.timeline.amf3.deflate`,
182 | (character) => `character/${character}/pixelart/special.frame.amf3.deflate`,
183 | (character) =>
184 | `character/${character}/pixelart/special_sprite_sheet.parts.amf3.deflate`,
185 | (character) =>
186 | `character/${character}/pixelart/special.timeline.amf3.deflate`,
187 | (character) =>
188 | `character/${character}/pixelart/special_sprite_sheet.atlas.amf3.deflate`,
189 | (character) =>
190 | `character/${character}/pixelart/sprite_sheet.atlas.amf3.deflate`,
191 | ];
192 |
193 | export const BASE_ODD_MAP = {
194 | 3: 0.7,
195 | 4: 0.25,
196 | 5: 0.05,
197 | };
198 |
199 | export const POSSIBLE_PATH_REGEX = /[.$a-zA-Z_0-9-]+?\/[.$a-zA-Z_0-9/-]+/g;
200 |
201 | export const IS_DEVELOPMENT = process.env.NODE_ENV === 'development';
202 |
203 | export const CHARACTER_VOICE_PRESETS = [
204 | (character) => `character/${character}/voice/ally/evolution.mp3`,
205 | (character) => `character/${character}/voice/ally/join.mp3`,
206 | (character) => `character/${character}/voice/battle/battle_start_0.mp3`,
207 | (character) => `character/${character}/voice/battle/battle_start_1.mp3`,
208 | (character) => `character/${character}/voice/battle/outhole_0.mp3`,
209 | (character) => `character/${character}/voice/battle/outhole_1.mp3`,
210 | (character) => `character/${character}/voice/battle/power_flip_0.mp3`,
211 | (character) => `character/${character}/voice/battle/power_flip_1.mp3`,
212 | (character) => `character/${character}/voice/battle/skill_0.mp3`,
213 | (character) => `character/${character}/voice/battle/skill_1.mp3`,
214 | (character) => `character/${character}/voice/battle/skill_ready.mp3`,
215 | (character) => `character/${character}/voice/battle/win_0.mp3`,
216 | (character) => `character/${character}/voice/battle/win_1.mp3`,
217 | ];
218 |
219 | export const NOX_PORT_LIST = [62001, 62025];
220 | export const DATEFORMAT_A = 'YYYY-MM-DD HH:mm';
221 |
222 | export const COMMON_FILE_FORMAT = [".php",".html",".txt",".htm",".aspx",".asp",".js",".css",".pgsql.txt",".mysql.txt",".pdf",".cgi",".inc",".gif",".jpg",".swf",".xml",".cfm",".xhtml",".wmv",".zip",".axd",".gz",".png",".doc",".shtml",".jsp",".ico",".exe",".csi",".inc.php",".config",".jpeg",".ashx",".log",".tar",".ini",".asa",".tgz",".PDF",".flv.bak",".rar",".asmx",".xlsx",".page",".phtml",".dll",".JPG",".asax.msg",".pl",".GIF",".ZIP",".csv",".nsf",".Pdf",".Gif",".bmp",".sql",".Jpeg",".Jpg",".xml.gz",".Zip",".new",".avi",".psd",".rss.wav",".action",".db",".dat",".do",".xsl",".class",".mdb",".include.cs",".class.php",".htc",".mov",".tpl.js.php",".mpg",".rdf",".rtf.ascx",".mvc.files",".master",".jar",".fla",".require",".de",".docx.wci",".readme.cfg",".aspx.cs",".cfc",".dwt",".ru",".LCK",".Config",".gif_var_DE",".net",".ttf",".HTM",".X-AOM",".jhtml",".mpeg",".ASP",".LOG",".vcf",".X-RMA",".X-OFFERS",".X-FCOMP",".X-GIFTREG",".X-PCONF",".X-SURVEY",".tif",".dir",".json.Zif",".wma.mid",".rm",".aspx.vb",".tar.gz",".woa",".main",".ram",".feed",".lasso.shtm",".sitemap",".scc",".tmp",".backup",".sln",".org",".conf",".uk",".TXT",".orig",".kml",".lck",".pps",".asx",".bok",".msi.c",".fcgi",".fopen",".html.",".bin",".htaccess",".info",".java",".jsf",".tmpl",".DOC",".bat",".com.html",".print",".resx",".ics",".php.php",".x",".PNG",".data",".dcr",".enfinity",".html.html",".licx",".mno",".plx",".vm",".dwg",".edu",".search",".static",".wws",".OLD.co.uk",".ece",".epc",".ice",".jspa",".lst",".php-dist",".svc",".vbs",".ai",".cur",".dmg",".img",".inf",".seam",".smtp.php",".ajax",".cfm.cfm",".chm",".csp",".edit",".file",".py",".sh",".test",".zdat.admin",".dev",".eps",".fr",".fsockopen",".new.html",".p",".store",".webinfo",".xml.php",".BAK",".htm.",".php.bak",".bk",".bsp",".cms",".d",".html,",".htmll",".idx",".images",".jad",".master.cs",".prev_next",".ssf",".stm",".txt.gz",".as",".asp.asp",".au",".cnf",".dhtml",".enu",".html.old",".lock",".m",".phps",".pm",".pptx",".sav",".ssi",".suo",".vbproj",".wml",".xsd",".ASPX",".JS",".PHP",".array-keys",".atom",".award",".bkp",".crt",".default",".eml",".epl",".fancybox",".fil",".geo",".h",".hmtl",".html.bak",".ida",".implode",".index.php",".iso",".kmz",".php.old",".php.txt",".rec",".storefront",".taf",".war",".xslt.CSS",".NSF",".Sponsors",".a",".aquery",".ascx.cs",".cat",".contrib",".ds",".dwf",".film",".g",".go",".googlebook",".gpx",".hotelName",".htm.htm",".ihtml",".in-array",".index",".ini.php",".layer",".maninfo",".odt",".price",".read",".sit",".src",".tpl.php",".trck",".uguide",".vorteil",".wbp",".AVI",".Asp",".EXE",".WMV",".asax.vb",".aspx.aspx",".btr",".cer",".common.php",".de.html",".jbf",".lbi",".lib.php",".lnk",".login",".login.php",".mhtml",".mpl",".mso",".original",".pgp",".ph",".php.",".preview",".search.htm",".site",".text",".view.ICO",".Web",".XLS.asc",".asp.bak",".aspx.resx",".browse",".code",".csproj",".dtd",".en.html",".ep",".eu",".index.html",".it",".nl",".ogg",".out",".pgt",".php",".po",".prt",".query",".rb",".rhtml",".ru.html",".save",".search.php",".t",".wsdl",".CFM",".MOV",".MPEG",".Master",".PPT",".TTF",".Templates",".XML",".adp",".ajax.php",".apsx",".asf",".bck",".bu",".calendar",".captcha",".cart",".com.crt",".core",".dict.php",".dot",".egov",".en.php",".eot",".git",".ht",".hta",".html.LCK",".ini.sample",".lib",".lic",".map",".master.vb",".mi",".mkdir",".o.pac",".pd",".phtm",".png.php",".portal",".printable",".psql",".pub",".q",".ra",".reg",".rpm",".strpos",".tcl",".template",".tiff",".tv",".us",".WAV",".acgi",".alt",".back",".cfml",".cmd",".detail",".disabled",".dist.php",".djvu",".dta",".e",".extract",".fpl",".framework",".fread",".htm.LCK",".inc.js",".includes",".jp",".jpg.html",".l",".letter",".local",".num",".pem",".php.sample",".php",".php~",".pot",".preg-match",".process",".ps",".r",".raw",".rc",".s",".search.",".server",".sis",".sql.gz",".squery",".subscribe",".svg",".svn",".thtml",".tpl.html",".ua",".vcs",".xhtm",".xml.asp",".xpi.A",".PAGE",".SWF",".add",".array-rand",".asax.cs",".asax.resx",".ascx.vb",".aspx,",".aspx.",".awm",".b",".bhtml",".bml",".ca",".cache",".cfg.php",".cn",".cz",".de.txt",".diff",".email",".en",".error",".faces",".filesize",".hml",".htmls",".htx",".i",".idq",".jpe",".js.aspx",".js.gz",".jspf",".load",".media.mspx",".mv",".mysql",".new.php",".ocx",".oui",".outcontrol",".pad",".pages",".pdb",".pdf.",".pnp",".popup.php",".pvk",".results",".run",".scripts",".sdb",".ser",".shop",".smi",".start",".ste",".swf.swf",".templates",".textsearch",".torrent",".v",".web",".wmf",".wpd",".ws",".xpml",".y",".AdCode",".Aspx",".C.",".COM",".Html",".Run.AdCode",".Skins",".Z",".ajax.asp",".app",".asd",".asm",".assets",".at",".bad.blog",".casino",".cc",".cdr",".children",".com,",".content",".copy",".count",".cp",".custom",".dbf",".deb",".delete",".dic",".divx",".download",".epub",".err",".es",".exclude",".home",".htlm",".htm,",".html-",".image",".inc.html",".it.html",".j",".jnlp",".link",".mc_id",".menu.php",".mgi",".mod",".net.html",".news",".none",".prg",".print.html",".print.php",".pwd",".pyc",".red",".se",".sea",".sema",".session",".setup",".sitx",".smil",".srv",".swi",".swp",".sxw.tem",".temp",".top",".txt.php",".types",".unlink",".url",".vspscc",".vssscc",".w",".work",".wvx",".xspf",".-",".Admin",".E.",".Engineer",".INC",".LOG.new",".MAXIMIZE",".MPG",".NDM",".Php",".R",".SIM",".SQL",".Services",".file",".accdb",".act",".admin.php",".ads",".alhtm",".all",".ani",".apf",".apj",".ar",".arc",".bfhtm",".br",".browser",".build",".buscar",".categorias",".categories",".ccs",".ch",".cl",".click.php",".cls",".cls.php",".com.ar",".com.br",".com.htm",".com.old",".common",".conf.php",".control",".core.php",".create.php",".dbm",".dct",".dmb",".doc.doc",".dxf",".ed",".en.htm",".engine",".env",".error-log",".esp",".ex",".exc",".exe,",".ext",".external",".ficheros",".fichiers",".flush",".fmt",".fn",".footer",".form_jhtml",".friend",".g.",".geo.xml",".ghtml",".google.com",".gov",".gpg",".hl",".href",".htm.d",".htm.html",".html.sav",".html",".html",".htmlprint",".htm~",".hts",".hu",".hwp",".ibf",".il",".image.php",".imagejpeg",".iml",".imprimer",".imprimir",".info.html",".info.php",".ini.bak",".inl",".inv",".join",".jpg.jpg",".jps",".key",".kit",".lang",".lignee",".ltr",".lzh.mail",".metadesc",".metakeys",".mht",".min",".mld",".mobi",".mobile.n",".nfo",".nikon",".nodos",".nxg",".obyx",".old.html",".open",".ord",".org.zip",".ori",".partfinder",".pho",".php-",".phpl",".phpx",".pix",".pls",".prc",".pre",".prhtm",".print.",".printer",".properties",".propfinder",".pvx",".php",".recherche",".redirect",".req",".safe",".sbk",".se.php",".search.asp",".sec",".seo",".serv",".server.php",".servlet",".settings",".sf",".show",".sht",".skins",".so",".sph",".split",".sso",".stats.php",".story",".swd",".swf.html",".sys",".tex",".tga",".thm",".tlp",".tml",".tmp.php",".touch",".tsv",".txt.",".txt.html",".ug",".vsprintf",".vstemplate",".vtl",".wbmp",".webc",".webproj",".wihtm",".wp",".wps",".wri",".wsc",".www",".xsp",".xsql",".zip,",".zml",".ztml",". T.",". php",".A..AEFA",".ALT",".ASC.",".Appraisal",".BBC.BMP",".C.R.D.",".CAA",".Cfm",".Commerce",".Css",".D.",".D.R.",".DBF.DESC.",".DLL",".DOCX",".Direct",".EEA.Email",".Eus.FAE",".FRK",".H.I.",".INFO",".INI",".ISO",".Includes",".K.E.",".K.T.",".KB",".L.",".L.jpg",".LassoApp",".MLD",".Main",".NET",".Old",".Org.master",".Org.sln",".Org.vssscc",".P.",".PSD",".Publish",".RAW",".S",".SideMenu",".T.A",".T.A.",".TEST",".Tung.php",".WTC",".XMLHTTP",".Xml","._._order","._order",".a.html.aac",".access",".act.php",".action.php",".actions",".ad.php",".add.php",".adenaw.com",".adm",".advsearch",".ag.php",".aj_",".all.hawaii",".ap",".api",".apk",".archiv",".arj",".array-map",".art",".artdeco",".articlePk",".artnet.",".ascx.resx",".asia",".asp-",".asp.LCK",".asp",".asp_files",".aspl",".aspp",".asps",".aspx_files",".aspxx",".aspy",".asxp",".at.html",".avatar.php",".awstats",".backup.php",".bak.php",".banan.se",".banner.php",".barnes",".baut",".bc",".beta",".biz",".bmp.php",".board.asd",".boom",".buyadspace",".bycategory",".bylocation",".bz",".c.html",".cache.php",".car",".cat.php",".catalog",".cdf",".ce",".cfm.bak",".cfswf",".cfx",".cgis",".chat",".chdir",".cmp",".cnt",".co",".co.il",".com.au",".com.php",".com.ua",".com_files",".comments",".comments.",".conf.html",".console",".contact",".corp",".cqs",".cron",".crx",".csr",".css.LCK",".css.gz",".cssd",".csv.php",".ctp",".cx",".dal",".daniel",".data.php",".data_",".davis",".dbml",".dcf",".de.jsp",".del",".deleted",".dell",".demo",".dig",".dist",".dk",".dm",".dms",".dnn",".dogpl",".dontcopy",".du",".dump",".dws",".ebay",".ehtml",".en.jsp",".enn",".es.html",".es.jsp",".eur",".exec",".exp",".f.l.",".feeds.php",".ffa",".ficken.cx",".filereader",".flac",".flypage",".fon",".form.php",".forms",".forum",".frk",".ft",".ftl",".fucks.nl",".funzz.fr",".garcia",".gb",".get",".gif.count",".glasner.ru",".google",".gray",".gsp",".guiaweb.tk",".gutschein",".guy",".ha",".hasrett.de",".hawaii",".header.php",".henry",".him",".history",".hlr",".hm",".ho",".hokkaido",".hold",".home.php",".home.test",".homepage",".hp",".htm.bak",".htm.rc",".htm_",".html,,",".html-c",".html-old",".html-p",".html.htm",".html.inc",".html.none",".html.pdf",".html.start",".html_old",".htmla",".htmlc",".htmlfeed",".htmlq",".htmlu",".htn",".htpasswd",".html",".iac.",".iconv",".idf",".ignore.php",".ihmtl",".ihya",".imp",".in",".inactive",".incl",".indt",".insert",".ipl",".issues",".itml",".ixi",".jhtm",".job",".joseph",".jpf",".jpg.xml",".jpg",".js,",".js.LCK",".jsa",".jsd",".jso",".jsp.old",".jsps",".jtp",".keyword",".kk",".kokuken",".ks",".lang.php",".last",".latest",".lha",".links",".listing",".lng",".loc",".local.cfm",".lynkx",".mag",".mail.php",".mbizgroup",".mel",".members",".meus.php",".midi",".min_",".mkv",".mmap",".mp",".mreply.rc",".msp",".mvn",".mysqli",".net-en",".new.htm",".newsletter",".nl.html",".nonude.org",".nth",".nz",".od",".offer.php",".offline",".ogv",".ok.old.htm",".old.old",".older",".oliver",".online",".opensearch",".orig.html",".origin.php",".osg",".outbound",".owen",".pae",".pan",".parse-url",".part",".pass",".patch",".paul",".pdd",".pdf.html",".pdf.pdf",".pdf.php",".pdfx",".phdo",".photo",".php.LCK",".php.backup",".php.html",".php.inc",".php.mno",".php_",".php_OLD",".php_old",".phphp",".phppar",".php",".pht",".pl.html",".plugins",".png,bmp",".popup",".pornz.tv",".prev",".print.jsp",".prl",".prosdo.com",".psb",".qtgp",".qxd",".r.",".rabattlp",".rails",".readfile",".rec.html",".remove",".remove.php",".removed",".resultados",".resume",".rhtm",".rmvb",".ro",".roma",".rpt",".rsp",".rss.php",".rss_cars",".rss_homes",".rss_jobs",".rtfd",".rvt",".s.html",".safariextz",".sc",".scandir",".sec.cfm",".section",".secure",".send",".sent-",".service",".set",".sgf",".show.php",".shtml.html",".sidebar",".sisx",".sitemap.",".skin",".snuffx.com",".sort",".sp.srch",".srf",".srvl",".sta",".staged.php",".staging",".start.php",".stat",".stats",".step",".stml",".sts.php",".suarez",".submit",".support",".swf.LCK",".sym",".system",".tab-",".table.html",".tb",".tech",".temp.php",".test.cgi",".test.php",".tf",".tg",".thanks",".theme",".thompson",".thumb.jpg",".tim",".tk",".tls",".to",".trace",".trade",".ts",".tst",".tvpi",".txt.txt",".ufo",".update",".upgrade",".var.verify",".video",".vn",".vs",".vx",".vxlpub",".wax",".webalizer",".webarchive",".webm",".weedooz.eu",".wgx",".wimzi.php",".wireless",".wm",".working",".wpl",".wplus",".wps.rtf",".write.php",".xcam.at",".xconf",".xcwc.com",".xgi.xlt",".xm",".xml.old",".xpdf",".xqy",".xslx",".xst",".xsx",".xy.php",".yp",".ys",".z",".za",".zh.html",".zhtml",".zip.php"] // eslint-disable-line
223 |
--------------------------------------------------------------------------------
/src/main/wf/digest.js:
--------------------------------------------------------------------------------
1 | const crypto = require('crypto');
2 |
3 | const digestSha1 = (originText) => {
4 | const hash = crypto.createHash('sha1');
5 | hash.update(originText);
6 | return hash.digest('hex');
7 | };
8 |
9 | const digest = (originText) => {
10 | const shasum = crypto.createHash('sha1');
11 | shasum.update(`${originText}K6R9T9Hz22OpeIGEWB0ui6c6PYFQnJGy`);
12 | return shasum.digest('hex');
13 | };
14 |
15 | module.exports = {
16 | digestWfFileName: digest,
17 | digestSha1,
18 | };
19 |
--------------------------------------------------------------------------------
/src/main/wf/helpers.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import { exec, spawn } from 'child_process';
3 | import logger from './logger';
4 | import { NOX_PORT_LIST } from './constants';
5 |
6 | export const asyncMkdir = (...args) =>
7 | new Promise((resolve) => fs.mkdir(...args, resolve));
8 |
9 | export const asyncReadFile = (...args) =>
10 | new Promise((resolve) => fs.readFile(...args, (err, data) => resolve(data)));
11 |
12 | export const asyncReadDir = (...args) =>
13 | new Promise((resolve, reject) =>
14 | fs.readdir(...args, (err, data) => (err ? reject(err) : resolve(data)))
15 | );
16 |
17 | export const asyncRename = (...args) =>
18 | new Promise((resolve, reject) =>
19 | fs.rename(...args, (err, data) => (err ? reject(err) : resolve(data)))
20 | );
21 |
22 | export const asyncExec = async (command: string): Promise => {
23 | console.log(command);
24 | return new Promise((resolve, reject) =>
25 | exec(command, (err, stdout) => {
26 | console.log('EXEC', err, stdout);
27 | return err ? reject(err) : resolve(stdout);
28 | })
29 | );
30 | };
31 |
32 | export const sleep = (timeout) =>
33 | new Promise((resolve) => setTimeout(resolve, timeout));
34 |
35 | export const spawnCommand = (command, args, { wait, logFn }) => {
36 | const child = spawn(command, args, {});
37 | child.stderr.pipe(process.stderr);
38 | let awaitResolver;
39 |
40 | const awaiter = new Promise((resolve) => {
41 | awaitResolver = resolve;
42 | });
43 |
44 | if (logFn) {
45 | child.stdout.on('data', (chunk) => logFn(chunk, awaitResolver));
46 | }
47 |
48 | if (wait) {
49 | let lastChunkString;
50 |
51 | child.stdout.on('data', (chunk) => {
52 | console.log(chunk.toString());
53 | if (`${lastChunkString}${chunk.toString()}`.includes(wait)) {
54 | awaitResolver();
55 | }
56 |
57 | lastChunkString = chunk.toString();
58 | });
59 |
60 | return { process: child, awaiter };
61 | }
62 |
63 | child.on('exit', awaitResolver);
64 |
65 | return { process: child, awaiter };
66 | };
67 |
68 | export const refineLs = (lsResult): Array => {
69 | const splits = lsResult.split(/[\r]{0,}\n/);
70 |
71 | let root;
72 |
73 | return splits
74 | .map((split) => {
75 | if (!/^[-a-z]{10}/.test(split)) {
76 | if (/:$/.test(split)) {
77 | [root] = split.split(':');
78 | }
79 | return null;
80 | }
81 |
82 | const chunks = split.split(' ').filter((val) => val);
83 |
84 | const [permission, linkCount, owner, group, size, date, time, name] =
85 | chunks;
86 |
87 | return {
88 | isDirectory: permission[0] === 'd',
89 | permission,
90 | linkCount,
91 | owner,
92 | group,
93 | size,
94 | modifiedDate: `${date} ${time}`,
95 | name,
96 | path: `${root}/${name}`,
97 | };
98 | })
99 | .filter((val) => val);
100 | };
101 |
102 | export const deepSearchUniqueMeaningfulStringsFromObject = (obj, arr = []) => {
103 | for (const prop in obj) {
104 | if (obj.hasOwnProperty(prop)) {
105 | if (typeof obj[prop] === 'object') {
106 | deepSearchUniqueMeaningfulStringsFromObject(obj[prop], arr);
107 | } else if (typeof obj[prop] === 'string') {
108 | if (arr.indexOf(obj[prop]) === -1) {
109 | arr.push(obj[prop]);
110 | }
111 | }
112 | }
113 | }
114 | return arr;
115 | };
116 |
117 | export const withAsyncBandwidth = (
118 | array,
119 | asyncMapper,
120 | { bandwidth = 5 } = {}
121 | ) => {
122 | if (bandwidth < 2) throw new Error('Bandwidth must bigger than 1');
123 |
124 | const entries = [...array];
125 | const chainedResponses = new Array(bandwidth)
126 | .fill()
127 | .map(() => new Promise((resolve) => resolve()));
128 | let iterator = 0;
129 | let index = 0;
130 |
131 | while (entries.length) {
132 | const currentEntry = entries.shift();
133 | const currentIndex = index;
134 |
135 | const beforeResponse = chainedResponses[iterator];
136 |
137 | chainedResponses[iterator] = beforeResponse.then(() =>
138 | asyncMapper(currentEntry, currentIndex)
139 | );
140 |
141 | index += 1;
142 | if (iterator < bandwidth - 1) {
143 | iterator += 1;
144 | } else {
145 | iterator = 0;
146 | }
147 | }
148 |
149 | return chainedResponses;
150 | };
151 |
152 | export const compareVersion = (prev, next) => {
153 | const prevSplit = prev.split('.').map(parseFloat);
154 | const nextSplit = next.split('.').map(parseFloat);
155 |
156 | for (let majority = 0; majority < prevSplit.length; majority += 1) {
157 | const prevVersion = prevSplit[majority];
158 | const nextVersion = nextSplit[majority];
159 |
160 | if (prevVersion > nextVersion || !nextVersion) {
161 | return 1;
162 | }
163 | if (nextVersion > prevVersion) {
164 | return -1;
165 | }
166 | }
167 |
168 | return 0;
169 | };
170 |
--------------------------------------------------------------------------------
/src/main/wf/logger.ts:
--------------------------------------------------------------------------------
1 | import electron, { ipcMain } from 'electron';
2 |
3 | class Logger {
4 | window: electron.BrowserWindow;
5 |
6 | preventDoneLog = false;
7 |
8 | constructor({ window }: { window: electron.BrowserWindow }) {
9 | this.window = window;
10 | this.absCount = 0;
11 | }
12 |
13 | setThrottle = () => {
14 | if (this.throttleTimeout) {
15 | clearTimeout(this.throttleTimeout);
16 | }
17 | this.throttle = true;
18 |
19 | this.throttleTimeout = setTimeout(() => {
20 | this.throttle = false;
21 | }, 100);
22 | };
23 |
24 | isThrottled = (targetCount) => {
25 | this.absCount += 1;
26 |
27 | if (this.absCount >= (targetCount || 500)) {
28 | this.absCount = 0;
29 | this.setThrottle();
30 | return false;
31 | }
32 |
33 | if (this.throttle) return true;
34 |
35 | this.setThrottle();
36 |
37 | return false;
38 | };
39 |
40 | log = (...args) => {
41 | console.log(...args);
42 |
43 | if (this.window) {
44 | this.window.webContents.send('ipc-logger-log', ...args);
45 | }
46 | };
47 |
48 | data = (serializable, { maxThrottled } = { maxThrottled: 500 }) => {
49 | if (serializable.type === 'progress') {
50 | if (this.isThrottled(maxThrottled)) return;
51 | }
52 | if (this.window) {
53 | this.window.webContents.send(
54 | 'ipc-logger-log',
55 | JSON.stringify(serializable),
56 | 'data'
57 | );
58 | }
59 | };
60 |
61 | progressStart = ({ id, max }) => {
62 | this.data({
63 | type: 'progressStart',
64 | data: {
65 | id,
66 | max,
67 | },
68 | });
69 |
70 | let count = 0;
71 |
72 | return {
73 | progress: (add = 1) => {
74 | count += add;
75 | this.data({
76 | type: 'progress',
77 | data: {
78 | id,
79 | progress: count,
80 | },
81 | });
82 | },
83 | end: (preventLog = false) => {
84 | this.data({
85 | type: 'progressEnd',
86 | data: {
87 | id,
88 | },
89 | });
90 | if (preventLog || this.preventDoneLog) {
91 | return;
92 | }
93 | this.log(`${id} Done`);
94 | },
95 | };
96 | };
97 |
98 | progressAbort = (id) => {
99 | this.data({
100 | type: 'progressEnd',
101 | data: {
102 | id,
103 | },
104 | });
105 | this.log(`${id} Done`);
106 | };
107 |
108 | devLog = (...args) => {
109 | if (process.env.IS_DEBUG === 'true') {
110 | console.log(...args);
111 | }
112 | };
113 |
114 | connectWindow = (window: electron.BrowserWindow) => {
115 | this.window = window;
116 | };
117 | }
118 |
119 | export default new Logger({});
120 |
--------------------------------------------------------------------------------
/src/main/wf/readOrderedMap.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const { readFile } = require('fs/promises');
3 | const { parse } = require('csv-parse/sync');
4 | const zlib = require('zlib');
5 |
6 | const asyncUnzip = (...args) =>
7 | new Promise((resolve, reject) =>
8 | zlib.unzip(...args, (err, res) => (err ? reject(err) : resolve(res)))
9 | );
10 |
11 | const asyncDeflate = (data) =>
12 | new Promise((resolve, reject) =>
13 | zlib.deflate(data, (err, res) => (err ? reject(err) : resolve(res)))
14 | );
15 |
16 | const parseCsv = (data, options = {}) => {
17 | const records = parse(data, options);
18 |
19 | return records.reduce((acc, cur) => [...acc, ...cur], []);
20 | };
21 |
22 | const readOrderedMap = async (mapping) => {
23 | try {
24 | const rawUnzipped = await asyncUnzip(mapping);
25 |
26 | return parseCsv(rawUnzipped.toString('utf-8'));
27 | } catch (err) {
28 | // pass
29 | }
30 |
31 | try {
32 | const readHeaderSize = (buffer) => buffer.readInt32LE(0);
33 |
34 | const headerSize = readHeaderSize(mapping);
35 |
36 | const zlibCompressedHeader = mapping.slice(4, headerSize + 4);
37 | const uncompressedHeader = await asyncUnzip(zlibCompressedHeader);
38 |
39 | const readHeaderData = (headerDataBuffer) => {
40 | const entriesCount = headerDataBuffer.readInt32LE(0);
41 | const entryOffsetsBuffer = headerDataBuffer.slice(
42 | 4,
43 | entriesCount * 8 + 4
44 | );
45 |
46 | const entryOffsets = new Array(entriesCount)
47 | .fill()
48 | .map((_, entryIndex) => {
49 | const keyEndOffset = entryOffsetsBuffer.readInt32LE(entryIndex * 8);
50 | const dataEndOffset = entryOffsetsBuffer.readInt32LE(
51 | entryIndex * 8 + 4
52 | );
53 |
54 | return [keyEndOffset, dataEndOffset];
55 | });
56 |
57 | let currentKeyOffset = 0;
58 | const keysBuffer = headerDataBuffer.slice(entriesCount * 8 + 4);
59 |
60 | const keys = entryOffsets.map(([keyEndOffset]) => {
61 | const currentKey = keysBuffer.slice(currentKeyOffset, keyEndOffset);
62 | currentKeyOffset = keyEndOffset;
63 |
64 | return currentKey.toString('utf-8');
65 | });
66 |
67 | return {
68 | entryOffsets,
69 | keys,
70 | };
71 | };
72 |
73 | const { entryOffsets, keys } = readHeaderData(uncompressedHeader);
74 |
75 | const contentSection = mapping.slice(4 + headerSize);
76 |
77 | const readContentData = async (contentBuffer, offsets) => {
78 | let currentOffset = 0;
79 |
80 | const contents = offsets.map(([, dataOffset]) => {
81 | const content = contentBuffer.slice(currentOffset, dataOffset);
82 | currentOffset = dataOffset;
83 |
84 | return content;
85 | });
86 |
87 | return Promise.all(
88 | contents.map(async (content) => {
89 | try {
90 | const unzipped = await asyncUnzip(content);
91 |
92 | return unzipped.toString('utf-8');
93 | } catch (err) {
94 | return readOrderedMap(content);
95 | }
96 | })
97 | );
98 | };
99 |
100 | const values = await readContentData(contentSection, entryOffsets);
101 |
102 | return keys.reduce(
103 | (acc, key, index) => ({
104 | ...acc,
105 | [key]:
106 | typeof values[index] === 'string'
107 | ? parseCsv(values[index])
108 | : values[index],
109 | }),
110 | {}
111 | );
112 | } catch (err) {
113 | console.log('FAILED READING FILE DATA');
114 | console.log(err);
115 |
116 | return {};
117 | }
118 | };
119 |
120 | const createOrderedMap = async (targetObject) => {
121 | const keys = Object.keys(targetObject).map((key) => Buffer.from(key));
122 |
123 | const values = await Promise.all(
124 | Object.values(targetObject).map(async (value) =>
125 | Array.isArray(value)
126 | ? asyncDeflate(value.join(','))
127 | : createOrderedMap(value)
128 | )
129 | );
130 |
131 | let keyOffset = 0;
132 | let valueOffset = 0;
133 |
134 | const entryOffsets = keys
135 | .map((key, idx) => {
136 | const value = values[idx];
137 |
138 | keyOffset += key.length;
139 | valueOffset += value.length;
140 |
141 | const entryBuffer = Buffer.alloc(8);
142 |
143 | entryBuffer.writeInt32LE(keyOffset, 0);
144 | entryBuffer.writeInt32LE(valueOffset, 4);
145 |
146 | return entryBuffer;
147 | })
148 | .reduce((acc, buf) => Buffer.concat([acc, buf]), Buffer.alloc(0));
149 |
150 | const entriesCount = Buffer.alloc(4);
151 |
152 | entriesCount.writeInt32LE(keys.length);
153 |
154 | const headerBuffer = Buffer.concat([entriesCount, entryOffsets, ...keys]);
155 | const headerData = await asyncDeflate(headerBuffer);
156 |
157 | const headerLength = Buffer.alloc(4);
158 | headerLength.writeInt32LE(headerData.length);
159 |
160 | const data = Buffer.concat([headerLength, headerData, ...values]);
161 |
162 | return data;
163 | };
164 |
165 | const openAndReadOrderedMap = async (fileName) => {
166 | const openedFile = await readFile(fileName);
167 | return readOrderedMap(openedFile);
168 | };
169 |
170 | module.exports = {
171 | openAndReadOrderedMap,
172 | readOrderedMap,
173 | };
174 |
--------------------------------------------------------------------------------
/src/main/wf/restoreMp3.js:
--------------------------------------------------------------------------------
1 | const { readFile, writeFile } = require('fs/promises');
2 | const iconv = require('iconv-lite');
3 |
4 | const hexesToBin = (hexString) => {
5 | return hexString
6 | .match(/.{2}/g)
7 | .map((hex) => parseInt(hex, 16).toString(2).padStart(8, '0'))
8 | .reduce((acc, cur) => acc + cur, '');
9 | };
10 |
11 | const LAYER = {
12 | '00': 0,
13 | '01': 3,
14 | 10: 2,
15 | 11: 1,
16 | };
17 |
18 | const VERSION = {
19 | '00': 2.5,
20 | 10: 2,
21 | 11: 1,
22 | };
23 |
24 | const BITRATE_INDEX = {
25 | 1000: {
26 | v1l1: '256',
27 | v1l2: '128',
28 | v1l3: '112',
29 | v2l1: '128',
30 | v2l2: '64',
31 | v2l3: '64',
32 | },
33 | 1001: {
34 | v1l1: '288',
35 | v1l2: '160',
36 | v1l3: '128',
37 | v2l1: '144',
38 | v2l2: '80',
39 | v2l3: '80',
40 | },
41 | 1010: {
42 | v1l1: '320',
43 | v1l2: '192',
44 | v1l3: '160',
45 | v2l1: '160',
46 | v2l2: '96',
47 | v2l3: '96',
48 | },
49 | 1011: {
50 | v1l1: '352',
51 | v1l2: '224',
52 | v1l3: '192',
53 | v2l1: '176',
54 | v2l2: '112',
55 | v2l3: '112',
56 | },
57 | 1100: {
58 | v1l1: '384',
59 | v1l2: '256',
60 | v1l3: '224',
61 | v2l1: '192',
62 | v2l2: '128',
63 | v2l3: '128',
64 | },
65 | 1101: {
66 | v1l1: '416',
67 | v1l2: '320',
68 | v1l3: '256',
69 | v2l1: '224',
70 | v2l2: '144',
71 | v2l3: '144',
72 | },
73 | 1110: {
74 | v1l1: '448',
75 | v1l2: '384',
76 | v1l3: '320',
77 | v2l1: '256',
78 | v2l2: '160',
79 | v2l3: '160',
80 | },
81 | 1111: {
82 | v1l1: 'bad',
83 | v1l2: 'bad',
84 | v1l3: 'bad',
85 | v2l1: 'bad',
86 | v2l2: 'bad',
87 | v2l3: 'bad',
88 | },
89 | '0000': {
90 | v1l1: 'free',
91 | v1l2: 'free',
92 | v1l3: 'free',
93 | v2l1: 'free',
94 | v2l2: 'free',
95 | v2l3: 'free',
96 | },
97 | '0001': {
98 | v1l1: '32',
99 | v1l2: '32',
100 | v1l3: '32',
101 | v2l1: '32',
102 | v2l2: '8',
103 | v2l3: '8',
104 | },
105 | '0010': {
106 | v1l1: '64',
107 | v1l2: '48',
108 | v1l3: '40',
109 | v2l1: '48',
110 | v2l2: '16',
111 | v2l3: '16',
112 | },
113 | '0011': {
114 | v1l1: '96',
115 | v1l2: '56',
116 | v1l3: '48',
117 | v2l1: '56',
118 | v2l2: '24',
119 | v2l3: '24',
120 | },
121 | '0100': {
122 | v1l1: '128',
123 | v1l2: '64',
124 | v1l3: '56',
125 | v2l1: '64',
126 | v2l2: '32',
127 | v2l3: '32',
128 | },
129 | '0101': {
130 | v1l1: '160',
131 | v1l2: '80',
132 | v1l3: '64',
133 | v2l1: '80',
134 | v2l2: '40',
135 | v2l3: '40',
136 | },
137 | '0110': {
138 | v1l1: '192',
139 | v1l2: '96',
140 | v1l3: '80',
141 | v2l1: '96',
142 | v2l2: '48',
143 | v2l3: '48',
144 | },
145 | '0111': {
146 | v1l1: '224',
147 | v1l2: '112',
148 | v1l3: '96',
149 | v2l1: '112',
150 | v2l2: '56',
151 | v2l3: '56',
152 | },
153 | };
154 |
155 | const FREQUENCY = {
156 | 1: {
157 | '00': 44100,
158 | '01': 48000,
159 | 10: 32000,
160 | },
161 | 2: {
162 | '00': 22050,
163 | '01': 24000,
164 | 10: 16000,
165 | },
166 | 2.5: {
167 | '00': 11025,
168 | '01': 12000,
169 | 10: 8000,
170 | },
171 | };
172 |
173 | const calculateFrameSize = (binaryHeader) => {
174 | const mpegVersion = VERSION[binaryHeader.slice(11, 13)];
175 | const layer = LAYER[binaryHeader.slice(13, 15)];
176 | const bitrate =
177 | parseFloat(
178 | BITRATE_INDEX[binaryHeader.slice(16, 20)][
179 | `v${mpegVersion === 1 ? 1 : 2}l${layer}`
180 | ]
181 | ) * 1000;
182 | const frequency = FREQUENCY[mpegVersion][binaryHeader.slice(20, 22)];
183 | const padding = parseFloat(binaryHeader.slice(22, 23));
184 |
185 | return Math.floor((bitrate * 144) / frequency + padding);
186 | };
187 |
188 | const spliceBuffer = (buffer, targetIndex, deleteCount, ...items) => {
189 | const bufferArray = Array.from(buffer);
190 |
191 | bufferArray.splice(targetIndex, deleteCount, ...items);
192 |
193 | return Buffer.from(bufferArray);
194 | };
195 |
196 | const restoreCorruptedMp3 = async (filePath, debug) => {
197 | let file = await readFile(filePath);
198 |
199 | const hexString = file.toString('hex');
200 | if (hexString.slice(0, 6) === '494433') {
201 | // ID3V2
202 | const tit2Index = hexString.indexOf('54495432');
203 | if (tit2Index !== -1 && tit2Index < 1024) {
204 | const sizeByteIndex = (tit2Index + 8) / 2;
205 | const encodingByteIndex = (tit2Index + 20) / 2;
206 | const tit2Size = parseInt(
207 | hexString.slice(tit2Index + 8, tit2Index + 16),
208 | 16
209 | );
210 | const shiftJisTitle = file.slice(
211 | tit2Index / 2 + 11,
212 | tit2Index / 2 + 11 + tit2Size - 1
213 | );
214 | const decodedTitle = iconv.decode(shiftJisTitle, 'SHIFT_JIS');
215 | const utf8Title = iconv.encode(decodedTitle, 'utf-16');
216 | file[encodingByteIndex] = 1;
217 | utf8Title.length
218 | .toString(16)
219 | .padStart(8, '0')
220 | .match(/.{2}/g)
221 | .map((hex) => parseInt(hex, 16))
222 | .forEach((sizeByte, idx) => {
223 | file[sizeByteIndex + idx] = sizeByte;
224 | });
225 |
226 | try {
227 | if (tit2Size > 1024) throw Error('TOO LARGE TIT2');
228 | file = spliceBuffer(file, tit2Index / 2 + 11, tit2Size, ...utf8Title);
229 | } catch (err) {
230 | console.log(debug, tit2Index, tit2Size);
231 | }
232 | }
233 | }
234 |
235 | let byteIndex = file.toString('hex').indexOf('7ffb') / 2;
236 |
237 | while (byteIndex < file.byteLength) {
238 | const header = file.slice(byteIndex, byteIndex + 4).toString('hex');
239 | const binaryHeader = hexesToBin(header);
240 | if (!/^7f/.test(header)) {
241 | break;
242 | }
243 | file[byteIndex] = 255;
244 | const frameSize = calculateFrameSize(binaryHeader);
245 | byteIndex += frameSize;
246 | }
247 |
248 | return file;
249 | };
250 |
251 | module.exports = {
252 | restoreCorruptedMp3,
253 | };
254 |
--------------------------------------------------------------------------------
/src/main/wf/typedefs.ts:
--------------------------------------------------------------------------------
1 | export type LSResult = {
2 | permission: string;
3 | linkCount: string;
4 | owner: string;
5 | group: string;
6 | size: string;
7 | modifiedDate: string;
8 | name: string;
9 | path: string;
10 | };
11 |
12 | export type WFExtractorMetaData = {
13 | lastExtractionDate: string;
14 | lastPackageVersion: string;
15 | lastSwfChecksum: string;
16 | lastSwfMode: 'full' | 'simple';
17 | jpLatestApiAssetVersion: string;
18 | krLatestApiAssetVersion: string;
19 | enLatestApiAssetVersion: string;
20 | twLatestApiAssetVersion: string;
21 | cnLatestApiAssetVersion: string;
22 | spriteProcessedLock: string[];
23 | specialSpriteProcessedLock: string[];
24 | lockedHashMap: boolean;
25 | latestPullStamp: string;
26 | deltaAvailable: boolean;
27 | };
28 |
--------------------------------------------------------------------------------
/src/renderer/App.css:
--------------------------------------------------------------------------------
1 | /*
2 | * @NOTE: Prepend a `~` to css file paths that are in your node_modules
3 | * See https://github.com/webpack-contrib/sass-loader#imports
4 | */
5 |
6 | @font-face {
7 | font-family: 'NanumSquare';
8 | font-weight: 400;
9 | src: url(../../assets/NanumSquareR.woff) format('woff'),
10 | }
11 | @font-face {
12 | font-family: 'NanumSquare';
13 | font-weight: 600;
14 | src: url(../../assets/NanumSquareB.woff) format('woff'),
15 | }
16 | @font-face {
17 | font-family: 'NanumSquare';
18 | font-weight: 800;
19 | src: url(../../assets/NanumSquareEB.woff) format('woff'),
20 | }
21 | @font-face {
22 | font-family: 'NanumSquare';
23 | font-weight: 300;
24 | src: url(../../assets/NanumSquareL.woff) format('woff'),
25 | }
26 |
27 | * {
28 | box-sizing: border-box;
29 | font-family: NanumSquare, sans-serif;
30 | font-weight: 500;
31 | }
32 |
33 | body {
34 | position: relative;
35 | width: 100%;
36 | height: 100vh;
37 | padding: 0;
38 | margin: 0;
39 | }
40 |
41 | button {
42 | cursor: pointer;
43 | border: none;
44 | appearance: none;
45 | }
46 |
47 | li {
48 | list-style: none;
49 | }
50 |
51 | a {
52 | text-decoration: none;
53 | height: fit-content;
54 | width: fit-content;
55 | margin: 10px;
56 | }
57 |
58 | a:hover {
59 | opacity: 1;
60 | text-decoration: none;
61 | }
62 |
63 | .Hello {
64 | display: flex;
65 | justify-content: center;
66 | align-items: center;
67 | margin: 20px 0;
68 | }
69 |
70 | #root, #app-main {
71 | width: 100%;
72 | height: 100%;
73 | display: flex;
74 | flex-direction: column;
75 | align-items: center;
76 | justify-content: center;
77 | }
78 |
--------------------------------------------------------------------------------
/src/renderer/components/Modal.tsx:
--------------------------------------------------------------------------------
1 | import { createPortal } from 'react-dom';
2 | import styled from 'styled-components';
3 | import WfCard from './WfCard';
4 |
5 | const Backdrop = styled.div`
6 | position: absolute;
7 | width: 100%;
8 | height: 100%;
9 | top: 0;
10 | left: 0;
11 | z-index: 50;
12 | background: rgba(0, 0, 0, 0.15);
13 | `;
14 |
15 | const ModalLayout = styled.div`
16 | position: fixed;
17 | width: 100vw;
18 | height: 100vh;
19 | top: 0;
20 | left: 0;
21 | display: flex;
22 | z-index: 100;
23 | align-items: center;
24 | justify-content: center;
25 | `;
26 |
27 | const ModalContent = styled.div`
28 | position: relative;
29 | z-index: 100;
30 | `;
31 |
32 | const Modal = ({
33 | open,
34 | children,
35 | onClose,
36 | ...rest
37 | }: {
38 | open: boolean;
39 | children: React.ReactChildren;
40 | onClose: () => void;
41 | }) => {
42 | if (!open) return null;
43 |
44 | return createPortal(
45 | <>
46 |
47 |
48 |
49 | {children}
50 |
51 |
52 | >,
53 | document.getElementById('root')
54 | );
55 | };
56 |
57 | export default Modal;
58 |
--------------------------------------------------------------------------------
/src/renderer/components/Switch.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styled from 'styled-components';
3 |
4 | const SwitchWrapper = styled.div`
5 | flex-shrink: 0;
6 | width: 64px;
7 | height: 32px;
8 | display: flex;
9 | flex-direction: row;
10 | justify-content: space-around;
11 | border-radius: 32px;
12 | transition: all 0.2s ease-out;
13 | position: relative;
14 |
15 | border: #747474 2px solid;
16 | background: #686868;
17 |
18 | &[data-value='true'] {
19 | border: #f4b34a 2px solid;
20 | background: #f2a241;
21 | }
22 |
23 | cursor: pointer;
24 |
25 | &[data-disabled='true'] {
26 | border: #747474 2px solid;
27 | background: #343434;
28 |
29 | > * {
30 | background: #686868 !important;
31 | }
32 |
33 | cursor: initial;
34 | }
35 | `;
36 |
37 | const SwitchButton = styled.div`
38 | height: 24px;
39 | width: 24px;
40 | position: absolute;
41 | z-index: 1000;
42 | background: white;
43 | border-radius: 38px;
44 | transition: all 0.2s ease-out;
45 | left: 2px;
46 | top: 2px;
47 |
48 | &[data-value='true'] {
49 | left: 34px;
50 | }
51 | `;
52 |
53 | const Switch = ({
54 | value,
55 | onClick,
56 | ...rest
57 | }: {
58 | value: boolean;
59 | onClick: () => void;
60 | }) => {
61 | return (
62 |
63 |
64 |
65 | );
66 | };
67 |
68 | export default Switch;
69 |
--------------------------------------------------------------------------------
/src/renderer/components/TextField.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styled from 'styled-components';
3 |
4 | const TextFieldInput = styled.input`
5 | width: 100%;
6 | height: 24px;
7 | `;
8 |
9 | type TextFieldProps = {
10 | onChange: () => void;
11 | onEnter: () => void;
12 | onArrowUp: () => void;
13 | onArrowDown: () => void;
14 | value: string;
15 | };
16 |
17 | const TextField = ({
18 | onChange,
19 | onEnter,
20 | onArrowUp,
21 | onArrowDown,
22 | value,
23 | ...restinput
24 | }: TextFieldProps) => {
25 | return (
26 | {
29 | if (event.keyCode === 13 && onEnter) {
30 | onEnter();
31 | }
32 | if (event.keyCode === 38 && onArrowUp) {
33 | onArrowUp();
34 | }
35 | if (event.keyCode === 40 && onArrowDown) {
36 | onArrowDown();
37 | }
38 | }}
39 | onChange={onChange}
40 | value={value}
41 | />
42 | );
43 | };
44 |
45 | export default TextField;
46 |
--------------------------------------------------------------------------------
/src/renderer/components/Typography.tsx:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | export const IndicatorTypo = styled.p`
4 | display: inline-block;
5 | margin: 0;
6 | opacity: 0.7;
7 | font-size: 0.825rem;
8 | `;
9 |
10 | export default styled.p`
11 | display: inline-block;
12 | text-overflow: ellipsis;
13 | overflow: hidden;
14 | white-space: nowrap;
15 | margin: 0;
16 | `;
17 |
--------------------------------------------------------------------------------
/src/renderer/components/WfButton.tsx:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const WfButton = styled.button`
4 | padding: 8px;
5 | width: 100%;
6 | height: 64px;
7 | display: flex;
8 | align-items: center;
9 | justify-content: flex-start;
10 | font-size: 1.3rem;
11 | background: white;
12 | box-shadow: 0px 3px 13px -3px rgb(0 0 0 / 30%);
13 | border-radius: 16px;
14 | padding-left: 16px;
15 |
16 | > img,
17 | > svg {
18 | margin-right: 24px;
19 | }
20 |
21 | cursor: pointer;
22 |
23 | &:hover {
24 | background: #fafafa;
25 | transform: scale(1.01);
26 | }
27 | &:active {
28 | background: #efefef;
29 | }
30 |
31 | &:disabled {
32 | cursor: initial;
33 | background: #efefef;
34 | &:hover {
35 | background: #efefef;
36 | transform: scale(1);
37 | }
38 | &:active {
39 | background: #efefef;
40 | }
41 | }
42 | `;
43 |
44 | export const WfDangerButton = styled(WfButton)`
45 | background: #ea3450;
46 | color: white;
47 |
48 | &:hover {
49 | background: #d81634;
50 | }
51 | &:active {
52 | background: #be001d;
53 | }
54 |
55 | &:disabled {
56 | &:hover {
57 | background: #ea3450;
58 | }
59 | &:active {
60 | background: #ea3450;
61 | }
62 | }
63 | `;
64 |
65 | export const WfSelectButton = styled(WfButton)`
66 | &[data-selected='true'] {
67 | background: #f2a241;
68 | color: white;
69 |
70 | &:hover {
71 | background: #f2a241;
72 | }
73 | &:active {
74 | background: #f2a241;
75 | }
76 | }
77 | `;
78 |
79 | export default WfButton;
80 |
--------------------------------------------------------------------------------
/src/renderer/components/WfCard.tsx:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | export default styled.div`
4 | padding: 24px;
5 | background: white;
6 | box-shadow: 0px 3px 13px -3px rgb(0 0 0 / 30%);
7 | border-radius: 16px;
8 | background-color: #fafafa;
9 | display: flex;
10 | flex-direction: column;
11 | `;
12 |
--------------------------------------------------------------------------------
/src/renderer/helpers/hooks.tsx:
--------------------------------------------------------------------------------
1 | import { useRef, useState } from 'react';
2 |
3 | export const usePermanentState = (
4 | defaultState: T,
5 | permanentKey: string,
6 | getter: (string) => any = (val) => val,
7 | setter: (string) => any = (val) => val
8 | ): [T, React.Dispatch>] => {
9 | const [permanentValue, setPermanentValueOrigin] = useState(
10 | getter(localStorage.getItem(permanentKey)) || defaultState
11 | );
12 |
13 | const setPermanentValue = (newValue) => {
14 | setPermanentValueOrigin(newValue);
15 |
16 | if (newValue) {
17 | localStorage.setItem(permanentKey, setter(newValue));
18 | } else {
19 | localStorage.removeItem(permanentKey);
20 | }
21 | };
22 |
23 | return [permanentValue, setPermanentValue];
24 | };
25 |
26 | export const useStateRef = (initialValue) => {
27 | const [state, stateSetterOrigin] = useState(initialValue);
28 |
29 | const stateRef = useRef(state);
30 |
31 | const stateSetter = (nextState) => {
32 | if (typeof nextState === 'function') {
33 | let res = nextState(state);
34 |
35 | stateRef.current = res;
36 |
37 | if (typeof res === 'function') {
38 | res = () => res;
39 | }
40 | return stateSetterOrigin(res);
41 | }
42 | stateRef.current = nextState;
43 |
44 | return stateSetterOrigin(nextState);
45 | };
46 |
47 | return [state, stateSetter, stateRef];
48 | };
49 |
50 | export const asd = 1;
51 |
--------------------------------------------------------------------------------
/src/renderer/helpers/index.tsx:
--------------------------------------------------------------------------------
1 | export const getIpcReturn = (channel) => {
2 | return new Promise((resolve) => {
3 | window.electron.ipcRenderer.once(channel, resolve);
4 | });
5 | };
6 |
7 | export const asd = 1;
8 |
--------------------------------------------------------------------------------
/src/renderer/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | World Flipper Extractor
6 |
7 |
8 |
9 |
10 |
12 |
13 |
--------------------------------------------------------------------------------
/src/renderer/index.tsx:
--------------------------------------------------------------------------------
1 | import { render } from 'react-dom';
2 | import App from './App';
3 |
4 | render(, document.getElementById('root'));
5 |
--------------------------------------------------------------------------------
/src/renderer/worker.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | World Flipper Extractor
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2021",
4 | "module": "commonjs",
5 | "lib": ["dom", "esnext"],
6 | "declaration": true,
7 | "declarationMap": true,
8 | "jsx": "react-jsx",
9 | "strict": true,
10 | "pretty": true,
11 | "sourceMap": true,
12 | "baseUrl": "./src",
13 | "noUnusedLocals": true,
14 | "noUnusedParameters": true,
15 | "noImplicitReturns": true,
16 | "noFallthroughCasesInSwitch": true,
17 | "moduleResolution": "node",
18 | "esModuleInterop": true,
19 | "allowSyntheticDefaultImports": true,
20 | "resolveJsonModule": true,
21 | "allowJs": true,
22 | "outDir": "release/app/dist"
23 | },
24 | "exclude": ["test", "release/build", "release/app/dist", ".erb/dll"]
25 | }
26 |
--------------------------------------------------------------------------------