feat: add multiplayer capture vertical slice
This commit is contained in:
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
# shellcheck source=lib.sh
|
||||
source "${SCRIPT_DIR}/lib.sh"
|
||||
|
||||
require_command git
|
||||
require_command pnpm
|
||||
|
||||
stage_parent="$(make_stage_parent)"
|
||||
trap 'safe_remove_stage "${stage_parent}"' EXIT
|
||||
source_dir="${stage_parent}/source"
|
||||
|
||||
prepare_source "${source_dir}"
|
||||
run_bun install --cwd "${source_dir}" --frozen-lockfile
|
||||
run_bun test --cwd "${source_dir}"
|
||||
run_bun run --cwd "${source_dir}" build
|
||||
|
||||
output_dir="${TOOL_ROOT}/dist"
|
||||
mkdir -p -- "${output_dir}"
|
||||
cp -- "${source_dir}/dist/mcp.js" "${output_dir}/mcp-projectcapture-1.6.1.js"
|
||||
cp -- "${source_dir}/dist/icon.svg" "${output_dir}/mcp-icon.svg"
|
||||
cp -- "${source_dir}/dist/about.md" "${output_dir}/mcp-about.md"
|
||||
|
||||
bundle_hash="$(sha256_file "${output_dir}/mcp-projectcapture-1.6.1.js")"
|
||||
write_dist_checksums "${output_dir}"
|
||||
printf 'Gehärtetes Build erstellt: %s\nSHA-256: %s\n' \
|
||||
"${output_dir}/mcp-projectcapture-1.6.1.js" "${bundle_hash}"
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
umask 077
|
||||
|
||||
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
# shellcheck source=lib.sh
|
||||
source "${SCRIPT_DIR}/lib.sh"
|
||||
|
||||
require_command git
|
||||
|
||||
if [[ "$#" -ne 2 ]]; then
|
||||
printf 'Verwendung: %s AUSGABEDATEI ABSOLUTER_ASSET_ROOT\n' "$0" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
output="$1"
|
||||
asset_root="$2"
|
||||
|
||||
output_parent="$(CDPATH= cd -- "$(dirname -- "${output}")" && pwd -P)" || {
|
||||
printf 'Das Ausgabeverzeichnis muss bereits existieren.\n' >&2
|
||||
exit 1
|
||||
}
|
||||
output="${output_parent}/$(basename -- "${output}")"
|
||||
project_root="$(git -C "${TOOL_ROOT}" rev-parse --show-toplevel)"
|
||||
project_root="$(CDPATH= cd -- "${project_root}" && pwd -P)"
|
||||
case "${output}" in
|
||||
"${project_root}"|"${project_root}"/*)
|
||||
printf 'Die Secret-Datei darf nicht im Repository liegen.\n' >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
[[ "${asset_root}" == /* ]] || {
|
||||
printf 'Asset-Root muss absolut sein.\n' >&2
|
||||
exit 1
|
||||
}
|
||||
[[ ! -e "${output}" ]] || {
|
||||
printf 'Ausgabedatei existiert bereits; sie wird nicht überschrieben.\n' >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
token="$(openssl rand -base64 48 | tr -d '\n')"
|
||||
else
|
||||
printf 'openssl wird zur sicheren Token-Erzeugung benötigt.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf 'PROJECTCAPTURE_BLOCKBENCH_TOKEN=%q\nPROJECTCAPTURE_ASSET_ROOT=%q\n' \
|
||||
"${token}" "${asset_root}" > "${output}"
|
||||
chmod 0600 "${output}"
|
||||
printf 'Lokale Environment-Datei erstellt (Token wird nicht ausgegeben): %s\n' "${output}"
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
# shellcheck source=lib.sh
|
||||
source "${SCRIPT_DIR}/lib.sh"
|
||||
|
||||
if [[ "$#" -ne 2 || "$1" != "--i-reviewed-gpl" ]]; then
|
||||
printf 'Verwendung: %s --i-reviewed-gpl EXPLIZITES_PLUGIN_ZIELVERZEICHNIS\n' "$0" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
destination="$2"
|
||||
[[ -d "${destination}" && ! -L "${destination}" ]] || {
|
||||
printf 'Ziel muss ein vorhandenes echtes Verzeichnis sein: %s\n' "${destination}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
mcp_source="${TOOL_ROOT}/dist/mcp-projectcapture-1.6.1.js"
|
||||
hytale_source="${TOOL_ROOT}/dist/hytale_plugin-0.9.1.js"
|
||||
[[ -f "${mcp_source}" && ! -L "${mcp_source}" ]] || {
|
||||
printf 'MCP-Build fehlt; zuerst scripts/build.sh ausführen.\n' >&2
|
||||
exit 1
|
||||
}
|
||||
[[ -f "${hytale_source}" && ! -L "${hytale_source}" ]] || {
|
||||
printf 'Hytale-Plugin fehlt; zuerst scripts/stage-hytale-plugin.sh ausführen.\n' >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Bestehende Dateien werden absichtlich nicht überschrieben. Review/Backup ist
|
||||
# Sache des aufrufenden Installationsschritts.
|
||||
for target in "${destination}/mcp.js" "${destination}/hytale_plugin.js"; do
|
||||
[[ ! -e "${target}" ]] || {
|
||||
printf 'Zieldatei existiert bereits; Installation abgebrochen: %s\n' "${target}" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
cp -- "${mcp_source}" "${destination}/mcp.js"
|
||||
cp -- "${hytale_source}" "${destination}/hytale_plugin.js"
|
||||
printf 'Geprüfte Plugins installiert. Codex-Konfiguration wurde nicht verändert.\n'
|
||||
Executable
+96
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
TOOL_ROOT="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
||||
MCP_REPOSITORY="https://github.com/jasonjgardner/blockbench-mcp-plugin.git"
|
||||
MCP_COMMIT="6b069e308fdfc9b0a1c15bc924ca78150815f143"
|
||||
MCP_PATCH="${TOOL_ROOT}/patches/0001-projectcapture-hardening.patch"
|
||||
MCP_PATCH_SHA256="9de0b3767e96db7a68ef4c7082d7c76bf140b4932fc9550ad6e99d9a24a048c3"
|
||||
BUN_VERSION="1.3.14"
|
||||
|
||||
require_command() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
printf 'Fehlendes Werkzeug: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
sha256_file() {
|
||||
if command -v shasum >/dev/null 2>&1; then
|
||||
shasum -a 256 "$1" | awk '{print $1}'
|
||||
elif command -v sha256sum >/dev/null 2>&1; then
|
||||
sha256sum "$1" | awk '{print $1}'
|
||||
else
|
||||
printf 'Weder shasum noch sha256sum ist verfügbar.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_patch() {
|
||||
local actual
|
||||
actual="$(sha256_file "${MCP_PATCH}")"
|
||||
if [[ "${actual}" != "${MCP_PATCH_SHA256}" ]]; then
|
||||
printf 'Patch-Hash stimmt nicht: erwartet %s, erhalten %s\n' \
|
||||
"${MCP_PATCH_SHA256}" "${actual}" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_source() {
|
||||
local destination="$1"
|
||||
if [[ -z "${destination}" || -e "${destination}" ]]; then
|
||||
printf 'Temporäres Ziel muss neu und nicht vorhanden sein: %s\n' "${destination}" >&2
|
||||
exit 1
|
||||
fi
|
||||
verify_patch
|
||||
git clone --quiet --filter=blob:none --no-checkout "${MCP_REPOSITORY}" "${destination}"
|
||||
git -C "${destination}" checkout --quiet --detach "${MCP_COMMIT}"
|
||||
local resolved
|
||||
resolved="$(git -C "${destination}" rev-parse HEAD)"
|
||||
if [[ "${resolved}" != "${MCP_COMMIT}" ]]; then
|
||||
printf 'Upstream-Commit stimmt nicht: %s\n' "${resolved}" >&2
|
||||
exit 1
|
||||
fi
|
||||
git -C "${destination}" apply --check "${MCP_PATCH}"
|
||||
git -C "${destination}" apply "${MCP_PATCH}"
|
||||
git -C "${destination}" diff --check
|
||||
}
|
||||
|
||||
make_stage_parent() {
|
||||
mktemp -d "${TMPDIR:-/tmp}/projectcapture-blockbench-mcp.XXXXXX"
|
||||
}
|
||||
|
||||
safe_remove_stage() {
|
||||
local stage="$1"
|
||||
local leaf
|
||||
leaf="$(basename -- "${stage}")"
|
||||
if [[ -d "${stage}" && ! -L "${stage}" && "${leaf}" == projectcapture-blockbench-mcp.* ]]; then
|
||||
rm -rf -- "${stage}"
|
||||
else
|
||||
printf 'Unsicheres temporäres Löschziel wurde nicht entfernt: %s\n' "${stage}" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
run_bun() {
|
||||
pnpm dlx "bun@${BUN_VERSION}" "$@"
|
||||
}
|
||||
|
||||
write_dist_checksums() {
|
||||
local output_dir="$1"
|
||||
local checksum_file="${output_dir}/SHA256SUMS"
|
||||
local temporary_file="${checksum_file}.tmp.$$"
|
||||
local artifact
|
||||
|
||||
: > "${temporary_file}"
|
||||
for artifact in \
|
||||
hytale_plugin-0.9.1.js \
|
||||
mcp-about.md \
|
||||
mcp-icon.svg \
|
||||
mcp-projectcapture-1.6.1.js; do
|
||||
if [[ -f "${output_dir}/${artifact}" && ! -L "${output_dir}/${artifact}" ]]; then
|
||||
printf '%s %s\n' "$(sha256_file "${output_dir}/${artifact}")" "${artifact}" \
|
||||
>> "${temporary_file}"
|
||||
fi
|
||||
done
|
||||
mv -- "${temporary_file}" "${checksum_file}"
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
# shellcheck source=lib.sh
|
||||
source "${SCRIPT_DIR}/lib.sh"
|
||||
|
||||
require_command git
|
||||
|
||||
repository="https://github.com/JannisX11/hytale-blockbench-plugin.git"
|
||||
commit="82dc58d19949c802f60f31c24fcb063a6b12fb07"
|
||||
expected_sha="ce1b0a6a3ad2f36b073b96a71a416261e43f089f4c02799b180b71c9e3f849f3"
|
||||
|
||||
stage_parent="$(make_stage_parent)"
|
||||
trap 'safe_remove_stage "${stage_parent}"' EXIT
|
||||
source_dir="${stage_parent}/hytale-plugin"
|
||||
git clone --quiet --filter=blob:none --no-checkout "${repository}" "${source_dir}"
|
||||
git -C "${source_dir}" checkout --quiet --detach "${commit}"
|
||||
[[ "$(git -C "${source_dir}" rev-parse HEAD)" == "${commit}" ]] || exit 1
|
||||
|
||||
artifact="${source_dir}/dist/hytale_plugin.js"
|
||||
actual_sha="$(sha256_file "${artifact}")"
|
||||
if [[ "${actual_sha}" != "${expected_sha}" ]]; then
|
||||
printf 'Hytale-Plugin-Hash stimmt nicht.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
output_dir="${TOOL_ROOT}/dist"
|
||||
mkdir -p -- "${output_dir}"
|
||||
cp -- "${artifact}" "${output_dir}/hytale_plugin-0.9.1.js"
|
||||
write_dist_checksums "${output_dir}"
|
||||
printf 'Offizielles Hytale-Plugin geprüft und bereitgestellt: %s\n' \
|
||||
"${output_dir}/hytale_plugin-0.9.1.js"
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
# shellcheck source=lib.sh
|
||||
source "${SCRIPT_DIR}/lib.sh"
|
||||
|
||||
require_command git
|
||||
require_command pnpm
|
||||
|
||||
stage_parent="$(make_stage_parent)"
|
||||
trap 'safe_remove_stage "${stage_parent}"' EXIT
|
||||
source_dir="${stage_parent}/source"
|
||||
|
||||
prepare_source "${source_dir}"
|
||||
run_bun install --cwd "${source_dir}" --frozen-lockfile
|
||||
run_bun test --cwd "${source_dir}"
|
||||
run_bun run --cwd "${source_dir}" build
|
||||
|
||||
bundle="${source_dir}/dist/mcp.js"
|
||||
[[ -f "${bundle}" ]] || {
|
||||
printf 'Build-Artefakt fehlt: %s\n' "${bundle}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
for forbidden_network_marker in 'https://cdn.jsdelivr.net' 'fetch('; do
|
||||
if grep -Fq "${forbidden_network_marker}" "${bundle}"; then
|
||||
printf 'Unerwarteter Netzwerkmarker im Build: %s\n' "${forbidden_network_marker}" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
printf 'Blockbench-MCP: Tests und Build erfolgreich.\n'
|
||||
Reference in New Issue
Block a user