botw-ist

安装python3.12及以上

rust

bash 复制代码
sudo pacman -S curl base-devel git go-task nodejs npm pnpm unzip openssh wget jq
cargo install magoo
bash 复制代码
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
rustup target add wasm32-unknown-unknown --toolchain nightly
bash 复制代码
curl -fsSL https://bun.sh/install | bash
source /home/Nightmare/.bash_profile
bash 复制代码
git clone https://github.com/Pistonite/botw-ist.git --depth 1
bash 复制代码
sudo pacman -Syu --needed base-devel cmake zlib
git clone https://github.com/Pistonight/symbotw.git
cd symbotw/
bash 复制代码
nano packages/uking-relocate/Cargo.toml

替换

yoml 复制代码
[dependencies.cu]
git = "https://github.com/Pistonight/cu"
package = "pistonite-cu"
features = ["cli", "fs"]
bash 复制代码
cargo build --release -p uking-relocate
bash 复制代码
sudo pacman -Syu ninja cmake ccache xdelta3 clang openssl pkgconf

修改taskfile.yml

yml 复制代码
      - task: itemsys-build:bsource

packages/blueflame-deps/scripts/gen-actors.ts

typescript 复制代码
import { ActorDataMap } from "../../itemsys/src/generated/actor_data_map.ts"
import { getActorParam, getItemTypeAndUse, PouchItemType, PouchItemUse } from "../../itemsys/src/data"

packages/app/vite.config.ts

typescript 复制代码
/// <reference types="vitest" />

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { spawnSync } from "child_process";

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import path from "path";

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import fs from "fs";

import { type Plugin, defineConfig, type UserConfig } from "vite";
import serveStatic from "vite-plugin-serve-static";
import intwc from "@pistonite/vite-plugin-intwc";
import monodev from "mono-dev/vite";
import { createWriteStream } from "fs";
import { pipeline } from "stream";
import { promisify } from "util";
import { request } from "https";

const pipelineAsync = promisify(pipeline);

const downloadMissingAssets = (): Plugin => {
    return {
        name: "download-missing-assets",
        apply: "serve",
        configureServer(server) {
            server.middlewares.use(async (req, _, next) => {
                if (req.url?.startsWith("/static/itemsys/")) {
                    const filePath = req.url.replace("/static/itemsys/", "");
                    const localPath = path.join("..", "itemsys-build", "public", filePath);

                    // 检查本地文件是否存在
                    if (!fs.existsSync(localPath)) {
                        console.log(`File ${localPath} not found, downloading from remote...`);

                        try {
                            // 确保目录存在
                            const dir = path.dirname(localPath);
                            if (!fs.existsSync(dir)) {
                                fs.mkdirSync(dir, { recursive: true });
                            }

                            // 从远程下载文件
                            const remoteUrl = `https://ist.pistonite.app/static/itemsys/${filePath}`;
                            console.log(`Downloading from: ${remoteUrl}`);

                            await new Promise((resolve, reject) => {
                                const req = request(remoteUrl, (res) => {
                                    if (res.statusCode === 200) {
                                        const writeStream = createWriteStream(localPath);
                                        pipelineAsync(res, writeStream)
                                            .then(() => {
                                                console.log(`Successfully downloaded: ${filePath}`);
                                                resolve({ success: true });
                                            })
                                            .catch(reject);
                                    } else {
                                        reject(
                                            new Error(
                                                `HTTP ${res.statusCode}: ${res.statusMessage}`,
                                            ),
                                        );
                                    }
                                });
                                req.on("error", reject);
                                req.end();
                            });
                        } catch (error) {
                            console.error(`Failed to download ${filePath}:`, error);
                        }
                    }
                }
                next();
            });
        },
    };
};

const staticAssetHeader = (): Plugin => {
    return {
        name: "static-asset-header",
        apply: "serve",
        configureServer(server) {
            server.middlewares.use((req, res, next) => {
                if (req.url?.startsWith("/runtime/")) {
                    res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
                    res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
                }
                next();
            });
        },
    };
};

// https://vitejs.dev/config/
export default defineConfig(({ command }) => {
    const commit = spawnSync("git", ["rev-parse", "HEAD"], {
        encoding: "utf-8",
    }).stdout.trim();
    console.log(`commit: ${commit}`);

    const packageJson = JSON.parse(fs.readFileSync("../../package.json", "utf-8"));
    const version = packageJson.version;
    console.log(`version: ${version}`);

    const monodevConfig = monodev({
        https: command === "serve",
    });
    return monodevConfig<UserConfig>({
        define: {
            "import.meta.env.COMMIT": JSON.stringify(commit),
            "import.meta.env.VERSION": JSON.stringify(version),
            "import.meta.vitest": "undefined",
        },
        plugins: [
            intwc({ basicLanguages: [] }),
            staticAssetHeader(),
            downloadMissingAssets(),
            serveStatic([
                {
                    pattern: /^\/runtime\/(.*)/,
                    resolve: ([_, capture]) => path.join("..", "runtime-wasm", "dist", capture),
                },
                {
                    pattern: /^\/static\/itemsys\/(.*)/,
                    resolve: ([_, capture]) => path.join("..", "itemsys-build", "public", capture),
                },
            ]),
        ],
        resolve: {
            dedupe: ["botw-item-assets"],
        },
        server: {
            port: 23172,
            headers: {
                "Cross-Origin-Embedder-Policy": "require-corp",
                "Cross-Origin-Opener-Policy": "same-origin",
            },
        },
        build: {
            rollupOptions: {
                input: {
                    index: "index.html",
                    popout: "popout.html",
                },
            },
        },
        test: {
            includeSource: ["src/**/*.{js,ts}"],
            environment: "jsdom",
        },
    });
});

packages/runtime-wasm/Taskfile.yml

yml 复制代码
version: '3'

includes:
  ecma:
    taskfile: ../mono-dev/task/ecma.yaml
    internal: true
  cargo:
    taskfile: ../mono-dev/task/cargo.yaml
    internal: true

tasks:
  build:
    desc: Run wasm-bindgen and build the dev dist package
    cmds:
      - task: build-wasm
      - task: build-dist

  build-wasm-types:
    cmds:
      - $(which mkdir) -p node_modules/.wasm-out-type
      - wasm-pack build -t no-modules --no-pack --no-opt --out-dir node_modules/.wasm-out-type

  build-wasm:
    cmds:
      - task: cargo:wasm-pack-build
        vars:
          TARGET_DIR: ../../target
          PACKAGE: skybook_runtime_wasm
          WASM_PACK_ARGS: -t no-modules --no-pack
      - $(which mkdir) -p node_modules/.wasm-out-type
      - cp pkg/skybook_runtime_wasm.d.ts node_modules/.wasm-out-type

  clean-dist:
    cmds:
      - rm -rf dist

  build-dist:
    vars:
      BUILD_DIR: dist
      SKYBOOK_JS: "{{.BUILD_DIR}}/skybook.js"
      WORKER_JS: "{{.BUILD_DIR}}/worker.js"
      SKYBOOK_WASM: "{{.BUILD_DIR}}/skybook.wasm"
        
    cmds:
      - $(which mkdir) -p {{.BUILD_DIR}}
      - cp pkg/skybook_runtime_wasm_bg.wasm {{.SKYBOOK_WASM}}
      - cp pkg/skybook_runtime_wasm.js {{.SKYBOOK_JS}}
      - cmd: >
          echo 'bundling worker';
          cp pkg/skybook_runtime_wasm.js {{.WORKER_JS}};
          echo 'self["__skybook_path_base"]="/runtime/skybook";' >> {{.WORKER_JS}};
          echo 'self["__min"]=false;' >> {{.WORKER_JS}};
          bun build src/main.ts >> {{.WORKER_JS}};
        silent: true

  build-dist-min:
    desc: Clean and build the minified production package
    vars:
      BUILD_DIR: dist
      COMMIT_SHORT:
        sh: git rev-parse HEAD | cut -c1-8
      SKYBOOK_MIN_JS: "{{.BUILD_DIR}}/skybook-{{.COMMIT_SHORT}}.min.js"
      WORKER_MIN_JS: "{{.BUILD_DIR}}/worker-{{.COMMIT_SHORT}}.min.js"
      SKYBOOK_WASM: "{{.BUILD_DIR}}/skybook-{{.COMMIT_SHORT}}.wasm"
    cmds:
      - $(which mkdir) -p {{.BUILD_DIR}}
      - cp pkg/skybook_runtime_wasm_bg.wasm {{.SKYBOOK_WASM}}
      - cmd: >
          echo 'minifying wasm_bindgen module';
          echo 'let wasm_bindgen;(function(){function __export(x){wasm_bindgen=x;};' > {{.SKYBOOK_MIN_JS}};
          cp pkg/skybook_runtime_wasm.js {{.WORKER_MIN_JS}};
          echo '__export(wasm_bindgen)' >> {{.WORKER_MIN_JS}};
          bun build --minify {{.WORKER_MIN_JS}} >> {{.SKYBOOK_MIN_JS}};
          echo '})();' >> {{.SKYBOOK_MIN_JS}};
        silent: true
      - cmd: >
          echo 'bundling minified worker';
          cp {{.SKYBOOK_MIN_JS}} {{.WORKER_MIN_JS}};
          echo 'self["__skybook_path_base"]="/runtime/skybook-{{.COMMIT_SHORT}}";' >> {{.WORKER_MIN_JS}};
          echo 'self["__min"]=true;' >> {{.WORKER_MIN_JS}};
          bun build --minify src/main.ts >> {{.WORKER_MIN_JS}};
        silent: true
    

  check:
    cmds:
      - task: build-wasm-types
      - task: cargo:clippy-all
      - task: cargo:fmt-check
      - task: ecma:mono-check

  check-ts:
      - task: ecma:mono-check

  fix:
    cmds:
      - task: cargo:fmt-fix
      - task: ecma:mono-fix

  pull-dist:
    desc: Download Runtime WASM for local development
    vars:
      ORIGIN: https://ist.pistonite.app
      COMMIT:
        sh: curl {{.ORIGIN}}/commit | cut -c1-8
    cmds:
      - $(which mkdir) -p dist
      - wget -O dist/worker.js {{.ORIGIN}}/runtime/worker-{{.COMMIT}}.min.js
      - wget -O dist/skybook.js {{.ORIGIN}}/runtime/skybook-{{.COMMIT}}.min.js
      - wget -O dist/skybook.wasm {{.ORIGIN}}/runtime/skybook-{{.COMMIT}}.wasm
      - cp dist/worker.js dist/worker-{{.COMMIT}}.min.js
      - cp dist/skybook.js dist/skybook-{{.COMMIT}}.min.js
      - cp dist/skybook.wasm dist/skybook-{{.COMMIT}}.wasm 

  clean:
    desc: Clean the wasm artifacts that might help resolve build issues
    cmds:
      - rm -rf dist pkg