Bootstrap Warium NeoForge port scaffold
This commit is contained in:
76
.codex/project.md
Normal file
76
.codex/project.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Codex Project Notes
|
||||
|
||||
## Project
|
||||
|
||||
`Warium NeoForge 1.21.1 Port` is a private internal NeoForge 21.1.225 port scaffold for Warium 1.2.7.
|
||||
|
||||
Repository:
|
||||
|
||||
```text
|
||||
MrSphay/Warium-NeoForge-1.21.1
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
Use these commands as the source of truth:
|
||||
|
||||
```text
|
||||
python tools/generate_port_sources.py
|
||||
python tools/registry_parity.py
|
||||
./gradlew --no-daemon build
|
||||
./gradlew --no-daemon runData
|
||||
python tools/check_required_integrations.py
|
||||
```
|
||||
|
||||
If a command does not exist, document the closest safe alternative. Do not invent commands that cannot run.
|
||||
|
||||
## Stack
|
||||
|
||||
```text
|
||||
Java 21, Gradle, NeoGradle, NeoForge 21.1.225, Minecraft 1.21.1
|
||||
```
|
||||
|
||||
Package manager or build tool:
|
||||
|
||||
```text
|
||||
Gradle wrapper
|
||||
```
|
||||
|
||||
## Build Artifacts
|
||||
|
||||
Release artifacts are produced in:
|
||||
|
||||
```text
|
||||
build/libs
|
||||
```
|
||||
|
||||
Expected files:
|
||||
|
||||
```text
|
||||
warium-neoforge-1.21.1-1.2.7+neo.21.1.225.jar
|
||||
```
|
||||
|
||||
## Security Rules
|
||||
|
||||
- Do not commit secrets, tokens, `.env` files, certificates, or private keys.
|
||||
- Treat generated credentials as sensitive.
|
||||
- Prefer local generation and local processing for user data.
|
||||
- Keep dependency audit results visible in CI where possible.
|
||||
- Do not add external network calls unless the feature explicitly requires them.
|
||||
- Do not commit the original Warium jar, generated extracted assets, decompiled sources, or private integration jars.
|
||||
- The source jar is downloaded from Modrinth in CI and verified against SHA1 `528d81630a23fb4004e3abdd99b16bd225cd1e92`.
|
||||
- Keep the repository private until the Warium ARR/AFL license conflict is clarified.
|
||||
|
||||
## Release Rules
|
||||
|
||||
Before a release:
|
||||
|
||||
1. run the release checklist,
|
||||
2. verify CI is green,
|
||||
3. verify download links,
|
||||
4. update README and changelog,
|
||||
5. verify the private Gitea package URL,
|
||||
6. create a tag only if explicitly requested,
|
||||
7. create the release only if explicitly requested.
|
||||
|
||||
Do not create releases unless the user explicitly asks for a release.
|
||||
114
.gitea/workflows/build.yml
Normal file
114
.gitea/workflows/build.yml
Normal file
@@ -0,0 +1,114 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||
PACKAGE_OWNER: MrSphay
|
||||
PACKAGE_NAME: warium-neoforge-1.21.1
|
||||
APP_VERSION: 1.2.7-neo.21.1.225
|
||||
LATEST_FILE: warium-neoforge-1.21.1-latest.jar
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Java 21
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '21'
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Generate port sources
|
||||
run: python tools/generate_port_sources.py
|
||||
|
||||
- name: Decompile original for audit artifact
|
||||
run: python tools/decompile_original.py
|
||||
|
||||
- name: Check required integrations
|
||||
run: python tools/check_required_integrations.py
|
||||
|
||||
- name: Registry parity
|
||||
run: python tools/registry_parity.py
|
||||
|
||||
- name: Build
|
||||
run: ./gradlew --no-daemon build
|
||||
|
||||
- name: Run data generation
|
||||
run: ./gradlew --no-daemon runData
|
||||
|
||||
- name: Prepare runtime dependency mods
|
||||
run: python tools/prepare_runtime_mods.py
|
||||
|
||||
- name: Dedicated server smoke test
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p run/server/mods
|
||||
cp build/libs/*.jar run/server/mods/
|
||||
echo "eula=true" > run/server/eula.txt
|
||||
timeout 120s ./gradlew --no-daemon runServer || code=$?
|
||||
code="${code:-0}"
|
||||
if [ "$code" != "0" ] && [ "$code" != "124" ]; then
|
||||
exit "$code"
|
||||
fi
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: warium-neoforge-1.21.1-artifacts
|
||||
path: |
|
||||
build/libs/*.jar
|
||||
docs/inventory/*.json
|
||||
docs/inventory/*.md
|
||||
build/decompiled/**
|
||||
|
||||
- name: Publish private latest package
|
||||
if: ${{ env.REGISTRY_TOKEN != '' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
package_version="${APP_VERSION}-${GITHUB_SHA::7}"
|
||||
package_dir="package-registry"
|
||||
mkdir -p "${package_dir}/versioned" "${package_dir}/latest"
|
||||
|
||||
artifact="$(find build/libs -maxdepth 1 -type f -name '*.jar' ! -name '*-sources.jar' | head -n 1)"
|
||||
if [ -z "${artifact}" ]; then
|
||||
echo "No jar artifact found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
versioned_file="warium-neoforge-1.21.1-${package_version}.jar"
|
||||
cp "${artifact}" "${package_dir}/versioned/${versioned_file}"
|
||||
cp "${artifact}" "${package_dir}/latest/${LATEST_FILE}"
|
||||
|
||||
curl --fail-with-body \
|
||||
--user "${PACKAGE_OWNER}:${REGISTRY_TOKEN}" \
|
||||
--upload-file "${package_dir}/versioned/${versioned_file}" \
|
||||
"https://git.wilkensxl.de/api/packages/${PACKAGE_OWNER}/generic/${PACKAGE_NAME}/${package_version}/${versioned_file}"
|
||||
|
||||
curl --silent --show-error \
|
||||
--user "${PACKAGE_OWNER}:${REGISTRY_TOKEN}" \
|
||||
--request DELETE \
|
||||
"https://git.wilkensxl.de/api/packages/${PACKAGE_OWNER}/generic/${PACKAGE_NAME}/latest" || true
|
||||
|
||||
curl --fail-with-body \
|
||||
--user "${PACKAGE_OWNER}:${REGISTRY_TOKEN}" \
|
||||
--upload-file "${package_dir}/latest/${LATEST_FILE}" \
|
||||
"https://git.wilkensxl.de/api/packages/${PACKAGE_OWNER}/generic/${PACKAGE_NAME}/latest/${LATEST_FILE}"
|
||||
|
||||
curl --fail --head \
|
||||
--user "${PACKAGE_OWNER}:${REGISTRY_TOKEN}" \
|
||||
"https://git.wilkensxl.de/api/packages/${PACKAGE_OWNER}/generic/${PACKAGE_NAME}/latest/${LATEST_FILE}"
|
||||
114
.gitea/workflows/dependency-check.yml
Normal file
114
.gitea/workflows/dependency-check.yml
Normal file
@@ -0,0 +1,114 @@
|
||||
name: Scheduled Dependency Check
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "29 3 * * 2"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
dependency-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Detect project stack
|
||||
id: detect
|
||||
shell: bash
|
||||
run: |
|
||||
stacks=""
|
||||
|
||||
[ -f package.json ] && stacks="${stacks} node"
|
||||
{ [ -f pyproject.toml ] || [ -f requirements.txt ]; } && stacks="${stacks} python"
|
||||
[ -f Cargo.toml ] && stacks="${stacks} rust"
|
||||
[ -f go.mod ] && stacks="${stacks} go"
|
||||
{ [ -f Dockerfile ] || [ -f compose.yml ] || [ -f docker-compose.yml ]; } && stacks="${stacks} docker"
|
||||
|
||||
echo "stacks=${stacks:-generic}" >> "$GITHUB_OUTPUT"
|
||||
echo "Detected stacks:${stacks:- generic}"
|
||||
|
||||
- name: Node dependency report
|
||||
if: contains(steps.detect.outputs.stacks, 'node')
|
||||
shell: bash
|
||||
run: |
|
||||
if [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then
|
||||
npm ci
|
||||
else
|
||||
npm install --package-lock-only --ignore-scripts
|
||||
fi
|
||||
|
||||
echo "Security audit:"
|
||||
npm audit --omit=dev --audit-level=high
|
||||
|
||||
echo
|
||||
echo "Outdated dependencies:"
|
||||
npm outdated || true
|
||||
|
||||
- name: Python dependency report
|
||||
if: contains(steps.detect.outputs.stacks, 'python')
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install --upgrade pip pip-audit
|
||||
|
||||
echo "Security audit:"
|
||||
if [ -f requirements.txt ]; then
|
||||
pip-audit -r requirements.txt
|
||||
else
|
||||
pip-audit
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Outdated packages:"
|
||||
python -m pip list --outdated || true
|
||||
|
||||
- name: Rust dependency report
|
||||
if: contains(steps.detect.outputs.stacks, 'rust')
|
||||
shell: bash
|
||||
run: |
|
||||
cargo install cargo-audit cargo-outdated --locked
|
||||
|
||||
echo "Security audit:"
|
||||
cargo audit
|
||||
|
||||
echo
|
||||
echo "Outdated crates:"
|
||||
cargo outdated || true
|
||||
|
||||
- name: Go dependency report
|
||||
if: contains(steps.detect.outputs.stacks, 'go')
|
||||
shell: bash
|
||||
run: |
|
||||
go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
||||
echo "Security audit:"
|
||||
govulncheck ./...
|
||||
|
||||
echo
|
||||
echo "Available dependency updates:"
|
||||
go list -u -m all || true
|
||||
|
||||
- name: Docker base image report
|
||||
if: contains(steps.detect.outputs.stacks, 'docker')
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Docker image references:"
|
||||
grep -RInE --exclude-dir=.git --exclude-dir=node_modules --exclude-dir=dist --exclude-dir=build '^\s*FROM\s+' Dockerfile* . 2>/dev/null || true
|
||||
|
||||
echo
|
||||
echo "Review Docker base images manually for pinned versions, official sources, and current security status."
|
||||
|
||||
- name: Dependency guidance
|
||||
shell: bash
|
||||
run: |
|
||||
cat <<'EOF'
|
||||
Dependency check completed.
|
||||
|
||||
This workflow reports vulnerabilities and available updates. It does
|
||||
not modify dependency files, create pull requests, or publish packages.
|
||||
|
||||
Recommended manual follow-up:
|
||||
- update dependencies in a focused branch,
|
||||
- run the project test/build commands,
|
||||
- review lockfile diffs carefully,
|
||||
- document intentionally held versions.
|
||||
EOF
|
||||
133
.gitea/workflows/release-dry-run.yml
Normal file
133
.gitea/workflows/release-dry-run.yml
Normal file
@@ -0,0 +1,133 @@
|
||||
name: Release Dry Run
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release-dry-run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Inspect release metadata
|
||||
shell: bash
|
||||
run: |
|
||||
missing=0
|
||||
|
||||
required_docs=(
|
||||
"README.md"
|
||||
"CHANGELOG.md"
|
||||
"SECURITY.md"
|
||||
"docs/release-checklist.md"
|
||||
)
|
||||
|
||||
for file in "${required_docs[@]}"; do
|
||||
if [ ! -f "$file" ]; then
|
||||
echo "Missing release document: $file"
|
||||
missing=1
|
||||
fi
|
||||
done
|
||||
|
||||
placeholder_paths=(README.md AGENTS.md .codex docs)
|
||||
placeholder_pattern='PROJECT_NAME|PROJECT_DESCRIPTION|REPOSITORY_OWNER|REPOSITORY_NAME|PACKAGE_NAME|ARTIFACT_NAME|ARTIFACT_OUTPUT_DIRECTORY|DOWNLOAD_URL|BUILD_COMMAND|TEST_COMMAND|LINT_COMMAND|AUDIT_COMMAND'
|
||||
|
||||
for path in "${placeholder_paths[@]}"; do
|
||||
[ -e "$path" ] || continue
|
||||
if grep -RInE --exclude-dir=.git "$placeholder_pattern" "$path"; then
|
||||
echo "Unresolved template placeholders found."
|
||||
missing=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$missing" -eq 1 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Detect project stack
|
||||
id: detect
|
||||
shell: bash
|
||||
run: |
|
||||
stacks=""
|
||||
|
||||
[ -f package.json ] && stacks="${stacks} node"
|
||||
{ [ -f pyproject.toml ] || [ -f requirements.txt ]; } && stacks="${stacks} python"
|
||||
[ -f Cargo.toml ] && stacks="${stacks} rust"
|
||||
[ -f go.mod ] && stacks="${stacks} go"
|
||||
|
||||
echo "stacks=${stacks:-generic}" >> "$GITHUB_OUTPUT"
|
||||
echo "Detected stacks:${stacks:- generic}"
|
||||
|
||||
- name: Node release checks
|
||||
if: contains(steps.detect.outputs.stacks, 'node')
|
||||
shell: bash
|
||||
run: |
|
||||
if [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then
|
||||
npm ci
|
||||
else
|
||||
npm install
|
||||
fi
|
||||
|
||||
node -e "const p=require('./package.json'); if(!p.name||!p.version){throw new Error('package.json needs name and version')}; console.log(p.name+'@'+p.version)"
|
||||
|
||||
npm run lint --if-present
|
||||
npm test --if-present
|
||||
npm run build --if-present
|
||||
npm run release:check --if-present
|
||||
|
||||
- name: Python release checks
|
||||
if: contains(steps.detect.outputs.stacks, 'python')
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
|
||||
if [ -f requirements.txt ]; then
|
||||
python -m pip install -r requirements.txt
|
||||
fi
|
||||
|
||||
if [ -f pyproject.toml ]; then
|
||||
python -m pip install build
|
||||
python -m build
|
||||
else
|
||||
echo "No pyproject.toml found; skipped Python package build."
|
||||
fi
|
||||
|
||||
- name: Rust release checks
|
||||
if: contains(steps.detect.outputs.stacks, 'rust')
|
||||
shell: bash
|
||||
run: |
|
||||
cargo test
|
||||
cargo build --release
|
||||
|
||||
- name: Go release checks
|
||||
if: contains(steps.detect.outputs.stacks, 'go')
|
||||
shell: bash
|
||||
run: |
|
||||
go test ./...
|
||||
go build ./...
|
||||
|
||||
- name: Artifact report
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Potential release artifacts:"
|
||||
find . \
|
||||
-path ./.git -prune -o \
|
||||
-path ./node_modules -prune -o \
|
||||
-path './dist/*' -type f -print -o \
|
||||
-path './build/*' -type f -print -o \
|
||||
-path './release/*' -type f -print -o \
|
||||
-path './target/release/*' -type f -print \
|
||||
| sed 's#^\./##' \
|
||||
| head -200
|
||||
|
||||
cat <<'EOF'
|
||||
|
||||
Release dry run completed.
|
||||
|
||||
This workflow verifies release readiness. It does not create tags,
|
||||
releases, packages, or upload artifacts.
|
||||
EOF
|
||||
139
.gitea/workflows/repo-cleanup.yml
Normal file
139
.gitea/workflows/repo-cleanup.yml
Normal file
@@ -0,0 +1,139 @@
|
||||
name: Scheduled Repository Cleanup Check
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "43 3 * * 1"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
cleanup-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check ignored and untracked generated files
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Ignored files that would be skipped by git:"
|
||||
git status --ignored --short || true
|
||||
|
||||
echo
|
||||
echo "Tracked generated files check:"
|
||||
generated_patterns=(
|
||||
'(^|/)node_modules/'
|
||||
'(^|/)dist/'
|
||||
'(^|/)build/'
|
||||
'(^|/)out/'
|
||||
'(^|/)release/'
|
||||
'(^|/)target/'
|
||||
'(^|/)coverage/'
|
||||
'\.log$'
|
||||
'\.tmp$'
|
||||
'\.temp$'
|
||||
)
|
||||
|
||||
found=0
|
||||
tracked_files="$(git ls-files)"
|
||||
for pattern in "${generated_patterns[@]}"; do
|
||||
if echo "$tracked_files" | grep -Ei "$pattern"; then
|
||||
found=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$found" -eq 1 ]; then
|
||||
echo "Generated files appear to be tracked. Review .gitignore and remove generated outputs from version control if appropriate."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Check large tracked files
|
||||
shell: bash
|
||||
run: |
|
||||
limit_bytes="${LARGE_FILE_LIMIT_BYTES:-5242880}"
|
||||
found=0
|
||||
|
||||
while IFS= read -r file; do
|
||||
[ -f "$file" ] || continue
|
||||
size="$(wc -c < "$file")"
|
||||
if [ "$size" -gt "$limit_bytes" ]; then
|
||||
echo "${file} is ${size} bytes, above limit ${limit_bytes}."
|
||||
found=1
|
||||
fi
|
||||
done < <(git ls-files)
|
||||
|
||||
if [ "$found" -eq 1 ]; then
|
||||
echo "Large tracked files found. Move release artifacts to packages/releases or document why they belong in git."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Check local config and secret-prone files
|
||||
shell: bash
|
||||
run: |
|
||||
found=0
|
||||
|
||||
risky_patterns=(
|
||||
'^\.env$'
|
||||
'^\.env\.'
|
||||
'\.pfx$'
|
||||
'\.p12$'
|
||||
'\.pem$'
|
||||
'\.key$'
|
||||
'\.token$'
|
||||
'(^|/)secrets/'
|
||||
)
|
||||
|
||||
tracked_files="$(git ls-files)"
|
||||
for pattern in "${risky_patterns[@]}"; do
|
||||
if echo "$tracked_files" | grep -Ei "$pattern" | grep -vE '^\.env\.example$'; then
|
||||
found=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$found" -eq 1 ]; then
|
||||
echo "Secret-prone local config files are tracked. Review immediately."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Check stale branches
|
||||
shell: bash
|
||||
run: |
|
||||
git fetch --all --prune
|
||||
|
||||
protected='^(main|master|develop|dev|release|staging|production)$'
|
||||
cutoff="$(date -u -d '90 days ago' +%s)"
|
||||
found=0
|
||||
|
||||
while IFS='|' read -r branch timestamp; do
|
||||
branch="${branch#origin/}"
|
||||
[ "$branch" = "HEAD" ] && continue
|
||||
echo "$branch" | grep -Eq "$protected" && continue
|
||||
|
||||
if [ "$timestamp" -lt "$cutoff" ]; then
|
||||
echo "Stale remote branch candidate: ${branch}"
|
||||
found=1
|
||||
fi
|
||||
done < <(git for-each-ref refs/remotes/origin --format='%(refname:short)|%(committerdate:unix)')
|
||||
|
||||
if [ "$found" -eq 1 ]; then
|
||||
echo "Stale branch candidates found. Review manually before deleting anything."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Cleanup guidance
|
||||
shell: bash
|
||||
run: |
|
||||
cat <<'EOF'
|
||||
Repository cleanup check completed.
|
||||
|
||||
This workflow reports cleanup candidates. It does not delete branches,
|
||||
packages, releases, or files automatically.
|
||||
|
||||
Recommended manual follow-up:
|
||||
- remove generated files from git,
|
||||
- update .gitignore,
|
||||
- move large artifacts to releases or package registry,
|
||||
- review stale branches,
|
||||
- document intentional exceptions.
|
||||
EOF
|
||||
174
.gitea/workflows/security-scan.yml
Normal file
174
.gitea/workflows/security-scan.yml
Normal file
@@ -0,0 +1,174 @@
|
||||
name: Scheduled Security Scan
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "17 3 * * 1"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
security-scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Detect project stack
|
||||
id: detect
|
||||
shell: bash
|
||||
run: |
|
||||
stacks=""
|
||||
|
||||
[ -f package.json ] && stacks="${stacks} node"
|
||||
{ [ -f pyproject.toml ] || [ -f requirements.txt ]; } && stacks="${stacks} python"
|
||||
[ -f Cargo.toml ] && stacks="${stacks} rust"
|
||||
[ -f go.mod ] && stacks="${stacks} go"
|
||||
{ [ -f Dockerfile ] || [ -f compose.yml ] || [ -f docker-compose.yml ]; } && stacks="${stacks} docker"
|
||||
|
||||
echo "stacks=${stacks:-generic}" >> "$GITHUB_OUTPUT"
|
||||
echo "Detected stacks:${stacks:- generic}"
|
||||
|
||||
- name: Node production dependency audit
|
||||
if: contains(steps.detect.outputs.stacks, 'node')
|
||||
run: npm audit --omit=dev --audit-level=high
|
||||
|
||||
- name: Python dependency audit
|
||||
if: contains(steps.detect.outputs.stacks, 'python')
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install --upgrade pip pip-audit
|
||||
if [ -f requirements.txt ]; then
|
||||
pip-audit -r requirements.txt
|
||||
else
|
||||
pip-audit
|
||||
fi
|
||||
|
||||
- name: Rust dependency audit
|
||||
if: contains(steps.detect.outputs.stacks, 'rust')
|
||||
shell: bash
|
||||
run: |
|
||||
cargo install cargo-audit --locked
|
||||
cargo audit
|
||||
|
||||
- name: Go vulnerability scan
|
||||
if: contains(steps.detect.outputs.stacks, 'go')
|
||||
shell: bash
|
||||
run: |
|
||||
go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
govulncheck ./...
|
||||
|
||||
- name: Suspicious code pattern scan
|
||||
shell: bash
|
||||
run: |
|
||||
grep_excludes=(
|
||||
--exclude-dir=.git
|
||||
--exclude-dir=node_modules
|
||||
--exclude-dir=dist
|
||||
--exclude-dir=build
|
||||
--exclude-dir=release
|
||||
--exclude=security-scan.yml
|
||||
)
|
||||
|
||||
patterns=(
|
||||
'eval\s*\('
|
||||
'new Function\s*\('
|
||||
'dangerouslySetInnerHTML'
|
||||
'innerHTML\s*='
|
||||
'child_process'
|
||||
'exec\s*\('
|
||||
'spawn\s*\('
|
||||
'shell\.openExternal'
|
||||
'nodeIntegration:\s*true'
|
||||
'webSecurity:\s*false'
|
||||
'allowRunningInsecureContent:\s*true'
|
||||
'curl .*sh'
|
||||
'wget .*sh'
|
||||
)
|
||||
|
||||
found=0
|
||||
for pattern in "${patterns[@]}"; do
|
||||
if grep -RInE "${grep_excludes[@]}" "$pattern" .; then
|
||||
found=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$found" -eq 1 ]; then
|
||||
echo "Suspicious code patterns were found. Review the matches above."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Secret and config leak scan
|
||||
shell: bash
|
||||
run: |
|
||||
grep_excludes=(
|
||||
--exclude-dir=.git
|
||||
--exclude-dir=node_modules
|
||||
--exclude-dir=dist
|
||||
--exclude-dir=build
|
||||
--exclude-dir=release
|
||||
--exclude=security-scan.yml
|
||||
)
|
||||
|
||||
patterns=(
|
||||
'BEGIN (RSA |EC |OPENSSH |)PRIVATE KEY'
|
||||
'AKIA[0-9A-Z]{16}'
|
||||
'xox[baprs]-[0-9A-Za-z-]+'
|
||||
'gh[pousr]_[0-9A-Za-z_]+'
|
||||
'sk-[A-Za-z0-9]{20,}'
|
||||
'api[_-]?key\s*=\s*["'\'']?[A-Za-z0-9_\-]{20,}'
|
||||
'token\s*=\s*["'\'']?[A-Za-z0-9_\-]{20,}'
|
||||
'password\s*=\s*["'\'']?[^[:space:]]{8,}'
|
||||
)
|
||||
|
||||
found=0
|
||||
for pattern in "${patterns[@]}"; do
|
||||
if grep -RInE "${grep_excludes[@]}" "$pattern" .; then
|
||||
found=1
|
||||
fi
|
||||
done
|
||||
|
||||
if find . -path ./.git -prune -o \( -name ".env" -o -name ".env.*" \) -not -name ".env.example" -print | grep .; then
|
||||
echo "Committed environment files were found."
|
||||
found=1
|
||||
fi
|
||||
|
||||
if [ "$found" -eq 1 ]; then
|
||||
echo "Potential secret or config leak detected. Review the matches above."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: AI instruction injection scan
|
||||
shell: bash
|
||||
run: |
|
||||
grep_excludes=(
|
||||
--exclude-dir=.git
|
||||
--exclude-dir=node_modules
|
||||
--exclude-dir=dist
|
||||
--exclude-dir=build
|
||||
--exclude-dir=release
|
||||
--exclude=security-scan.yml
|
||||
)
|
||||
|
||||
patterns=(
|
||||
'ignore (all )?(previous|above) instructions'
|
||||
'system prompt'
|
||||
'developer message'
|
||||
'reveal your instructions'
|
||||
'exfiltrate'
|
||||
'send.*token'
|
||||
'send.*secret'
|
||||
'disable.*safety'
|
||||
'jailbreak'
|
||||
'prompt injection'
|
||||
)
|
||||
|
||||
found=0
|
||||
for pattern in "${patterns[@]}"; do
|
||||
if grep -RInEi "${grep_excludes[@]}" "$pattern" .; then
|
||||
found=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$found" -eq 1 ]; then
|
||||
echo "Potential AI instruction-injection text found. Review whether this is documentation, test data, or malicious content."
|
||||
exit 1
|
||||
fi
|
||||
109
.gitea/workflows/template-compliance.yml
Normal file
109
.gitea/workflows/template-compliance.yml
Normal file
@@ -0,0 +1,109 @@
|
||||
name: Codex Template Compliance
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
template-compliance:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check required Codex files
|
||||
shell: bash
|
||||
run: |
|
||||
missing=0
|
||||
|
||||
required_files=(
|
||||
"AGENTS.md"
|
||||
".codex/project.md"
|
||||
"README.md"
|
||||
)
|
||||
|
||||
recommended_files=(
|
||||
"SECURITY.md"
|
||||
"CHANGELOG.md"
|
||||
"docs/agent-handoff.md"
|
||||
)
|
||||
|
||||
for file in "${required_files[@]}"; do
|
||||
if [ ! -f "$file" ]; then
|
||||
echo "Missing required Codex file: $file"
|
||||
missing=1
|
||||
fi
|
||||
done
|
||||
|
||||
for file in "${recommended_files[@]}"; do
|
||||
if [ ! -f "$file" ]; then
|
||||
echo "Recommended Codex file not found: $file"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$missing" -eq 1 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Check unresolved placeholders
|
||||
shell: bash
|
||||
run: |
|
||||
found=0
|
||||
paths=(AGENTS.md README.md SECURITY.md CHANGELOG.md .codex docs blueprint.md blueprint.json)
|
||||
pattern='PROJECT_NAME|PROJECT_DESCRIPTION|REPOSITORY_OWNER|REPOSITORY_NAME|PACKAGE_NAME|ARTIFACT_NAME|ARTIFACT_OUTPUT_DIRECTORY|AUTHOR_NAME|PROJECT_STACK|DOWNLOAD_URL|BUILD_COMMAND|TEST_COMMAND|LINT_COMMAND|AUDIT_COMMAND|README_COMMAND|INSTALL_COMMAND|DEV_COMMAND|PACKAGE_MANAGER|PROJECT_VERSION'
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
[ -e "$path" ] || continue
|
||||
if grep -RInE --exclude-dir=.git "$pattern" "$path"; then
|
||||
found=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$found" -eq 1 ]; then
|
||||
echo "Unresolved template placeholders found. Replace real values or mark genuinely unknown values as PENDING."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Check README divider convention
|
||||
shell: bash
|
||||
run: |
|
||||
if [ -f blueprint.md ] || [ -f blueprint.json ]; then
|
||||
if ! grep -q 'template:section-line' blueprint.md 2>/dev/null; then
|
||||
echo "README blueprint exists but does not use {{ template:section-line }}."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Check workflow baseline
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Detected Gitea workflows:"
|
||||
find .gitea/workflows -maxdepth 1 -type f -name '*.yml' -print 2>/dev/null || true
|
||||
|
||||
if [ ! -f ".gitea/workflows/security-scan.yml" ]; then
|
||||
echo "Recommended workflow missing: .gitea/workflows/security-scan.yml"
|
||||
fi
|
||||
|
||||
if [ ! -f ".gitea/workflows/repo-cleanup.yml" ]; then
|
||||
echo "Recommended workflow missing: .gitea/workflows/repo-cleanup.yml"
|
||||
fi
|
||||
|
||||
- name: Compliance guidance
|
||||
shell: bash
|
||||
run: |
|
||||
cat <<'EOF'
|
||||
Codex template compliance check completed.
|
||||
|
||||
This workflow verifies agent context and template hygiene. It does
|
||||
not change files automatically.
|
||||
|
||||
Recommended manual follow-up:
|
||||
- add missing required Codex context files,
|
||||
- replace unresolved placeholders,
|
||||
- keep README blueprint and README output aligned,
|
||||
- document intentional exceptions in .codex/project.md.
|
||||
EOF
|
||||
51
.gitignore
vendored
Normal file
51
.gitignore
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# Dependencies
|
||||
node_modules/
|
||||
vendor/
|
||||
.venv/
|
||||
venv/
|
||||
__pycache__/
|
||||
|
||||
# Build outputs
|
||||
dist/
|
||||
build/
|
||||
out/
|
||||
release/
|
||||
target/
|
||||
bin/
|
||||
obj/
|
||||
run/
|
||||
src/generated/
|
||||
repo/
|
||||
*.jar
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Logs and temporary files
|
||||
*.log
|
||||
*.tmp
|
||||
*.temp
|
||||
.cache/
|
||||
.turbo/
|
||||
.vite/
|
||||
.pytest_cache/
|
||||
|
||||
# Local environment and secrets
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
*.pem
|
||||
*.key
|
||||
*.pfx
|
||||
*.p12
|
||||
*.crt
|
||||
*.cer
|
||||
*.token
|
||||
secrets/
|
||||
|
||||
# OS and editor files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
81
AGENTS.md
Normal file
81
AGENTS.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Agent Instructions
|
||||
|
||||
## Project
|
||||
|
||||
Warium NeoForge 1.21.1 Port: private internal NeoForge 21.1.225 port scaffold for Warium 1.2.7.
|
||||
|
||||
## Repository Rules
|
||||
|
||||
- This repository was bootstrapped from `codex-agent-repository-kit`; preserve the kit-maintenance conventions in `.codex/project.md`, `docs/`, and `.gitea/workflows/`.
|
||||
- Use NeoForge/Gradle conventions for Java 21 Minecraft mod work.
|
||||
- Prefer existing project patterns over new abstractions.
|
||||
- Keep changes scoped to the user's request.
|
||||
- Do not commit secrets, `.env` files, private keys, certificates, or tokens.
|
||||
- Do not rewrite history or run destructive git commands unless explicitly requested.
|
||||
- Do not create a release unless explicitly requested.
|
||||
- Check `git status --short` before editing and before finishing. Preserve unrelated user changes.
|
||||
- Replace all applicable placeholders. Remove non-applicable placeholder sections instead of leaving fake values.
|
||||
- If `GITEA_TOKEN` is available locally, use it only for read-only Gitea API checks such as private repository metadata, package-read visibility, and Actions run status. Never print, commit, or store the token.
|
||||
- After pushing commits that trigger a Gitea workflow, poll the workflow run until it succeeds. If it fails or is cancelled, inspect the failing job/logs, fix the issue when in scope, push again, and repeat the workflow check loop. Fixing and pushing a workflow failure is not a stopping point.
|
||||
- When the project uses `blueprint.md` and `blueprint.json` for README generation, keep the rainbow `{{ template:section-line }}` divider between major README sections. Do not replace it with plain `---` unless the target renderer cannot display inline images.
|
||||
- If README blueprint files are changed, regenerate or update `README.md` in the same change and verify the generated output renders reasonably.
|
||||
- For releasable projects, add or preserve `.gitea/workflows/security-scan.yml` using `files/security-scan-gitea.yml` unless the repository already has equivalent scheduled security automation.
|
||||
- For active projects, add or preserve `.gitea/workflows/repo-cleanup.yml` using `files/repo-cleanup-gitea.yml` unless the repository already has equivalent cleanup checks.
|
||||
- Add or preserve `.gitea/workflows/dependency-check.yml`, `.gitea/workflows/release-dry-run.yml`, and `.gitea/workflows/template-compliance.yml` when the repository is active, releasable, or intended as a Codex-maintained project.
|
||||
- Repository cleanup automation must be non-destructive. Do not delete branches, packages, releases, or tracked files without explicit user approval.
|
||||
- Dependency, compliance, and release dry-run automation must report findings only. Do not auto-update dependencies, auto-open PRs, create tags, publish packages, or create releases without explicit user approval.
|
||||
- Gitea Actions artifacts are not Gitea Package Registry packages. If the user expects a package/download entry, add an explicit registry publish step and verify the package URL after the workflow succeeds.
|
||||
|
||||
## Commands
|
||||
|
||||
Use these commands when available:
|
||||
|
||||
```bash
|
||||
python tools/generate_port_sources.py
|
||||
python tools/registry_parity.py
|
||||
./gradlew --no-daemon build
|
||||
./gradlew --no-daemon runData
|
||||
```
|
||||
|
||||
If a command is missing, inspect the project and document the closest safe alternative in `.codex/project.md`.
|
||||
|
||||
Keep `.codex/project.md` and this `AGENTS.md` aligned when commands, artifact paths, or release rules change.
|
||||
|
||||
## Artifacts
|
||||
|
||||
Expected artifact output:
|
||||
|
||||
```text
|
||||
build/libs
|
||||
```
|
||||
|
||||
Expected artifact names:
|
||||
|
||||
```text
|
||||
warium-neoforge-1.21.1-1.2.7+neo.21.1.225.jar
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
- Review `docs/security-review.md` before release work.
|
||||
- Fill `docs/security-review.md` with actual checked commands and results when performing release-readiness work.
|
||||
- Review scheduled security workflow failures before changing code. Treat matches as leads: they may be true positives, documentation examples, or test fixtures.
|
||||
- Review repository cleanup workflow failures as maintenance leads. Document intentional exceptions instead of blindly deleting files.
|
||||
- Review dependency and template compliance workflow failures as maintenance leads. Preserve project-specific conventions when they are documented.
|
||||
- Treat generated credentials and config files as sensitive.
|
||||
- Keep external network calls documented.
|
||||
- Prefer local processing for user data.
|
||||
- Keep CI publishing secrets in repository or organization secrets, not in tracked files. `REGISTRY_TOKEN` is the default package publishing secret name for the Gitea workflow template.
|
||||
- Use URL-safe package filenames when publishing to a registry. Do not put raw artifact names with spaces or punctuation directly into upload URLs.
|
||||
- Ensure `.gitignore` covers local config, build outputs, logs, temporary files, and secret material for the detected stack.
|
||||
- The original Warium distribution has conflicting public license signals: Modrinth reports ARR while the jar metadata reports AFL-3.0. Keep this repository and packages private until rights are explicitly clarified.
|
||||
- Do not commit the original Warium jar, decompiled source output, generated original assets, or private dependency jars.
|
||||
|
||||
## Finish Checklist
|
||||
|
||||
- `git diff --check` passes.
|
||||
- The cheapest reliable verification command has been run, or the reason it could not be run is documented.
|
||||
- README, changelog, security review, and release checklist are updated when the change touches release behavior.
|
||||
- `docs/agent-handoff.md` is updated when work is interrupted, risky, or spans multiple sessions.
|
||||
- Any pushed Gitea workflow has been polled to success or a concrete blocker has been reported.
|
||||
|
||||
11
CHANGELOG.md
Normal file
11
CHANGELOG.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project are documented here.
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Bootstrapped private Warium NeoForge 1.21.1 port repository.
|
||||
- Added NeoForge 21.1.225 Gradle build scaffold.
|
||||
- Added runner scripts to download, verify, inspect, decompile, and generate registry stubs from Warium 1.2.7.
|
||||
- Added private Gitea artifact/package workflow with latest package URL.
|
||||
|
||||
48
CONTRIBUTING.md
Normal file
48
CONTRIBUTING.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Contributing
|
||||
|
||||
## Working Rules
|
||||
|
||||
- Keep changes scoped to the issue or user request.
|
||||
- Prefer existing project patterns.
|
||||
- Do not commit secrets, generated credentials, local `.env` files, or private keys.
|
||||
- Do not create releases unless explicitly requested.
|
||||
- Preserve unrelated user changes.
|
||||
|
||||
## Before Committing
|
||||
|
||||
Run the cheapest reliable verification commands for this project:
|
||||
|
||||
```bash
|
||||
LINT_COMMAND
|
||||
TEST_COMMAND
|
||||
BUILD_COMMAND
|
||||
```
|
||||
|
||||
Also run:
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
```
|
||||
|
||||
If a command cannot run, document why in the final response or handoff notes.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Pull requests should include:
|
||||
|
||||
- summary of changes,
|
||||
- verification performed,
|
||||
- known risks or skipped checks,
|
||||
- artifact/download notes when relevant.
|
||||
|
||||
## Releases
|
||||
|
||||
Before release work, update:
|
||||
|
||||
```text
|
||||
CHANGELOG.md
|
||||
docs/release-checklist.md
|
||||
docs/security-review.md
|
||||
README.md
|
||||
```
|
||||
|
||||
63
README.md
Normal file
63
README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Warium NeoForge 1.21.1
|
||||
|
||||
A private internal NeoForge `21.1.225` port workspace for Warium `1.2.7`.
|
||||
|
||||
<p align="center"><img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="-----------------------------------------------------" width="100%"></p>
|
||||
|
||||
## Status
|
||||
|
||||
This repository is private until rights are clarified. Modrinth reports Warium as ARR, while the original jar metadata reports `Academic Free License v3.0`; do not make this repository, decompiled source, or generated jar public until that conflict is resolved.
|
||||
|
||||
The current implementation is a reproducible NeoForge port scaffold. CI downloads and verifies the original Warium jar, extracts resources, generates 1.21.1 registry stubs, builds a NeoForge jar, and records inventory/decompile artifacts for the remaining manual behavior port.
|
||||
|
||||
<p align="center"><img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="-----------------------------------------------------" width="100%"></p>
|
||||
|
||||
## Download
|
||||
|
||||
Private latest package after a successful Gitea build:
|
||||
|
||||
`https://git.wilkensxl.de/api/packages/MrSphay/generic/warium-neoforge-1.21.1/latest/warium-neoforge-1.21.1-latest.jar`
|
||||
|
||||
The link requires access to the private Gitea package.
|
||||
|
||||
<p align="center"><img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="-----------------------------------------------------" width="100%"></p>
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
./gradlew --no-daemon build
|
||||
```
|
||||
|
||||
Important supporting commands:
|
||||
|
||||
```bash
|
||||
python tools/generate_port_sources.py
|
||||
python tools/decompile_original.py
|
||||
python tools/registry_parity.py
|
||||
python tools/check_required_integrations.py
|
||||
./gradlew --no-daemon runData
|
||||
```
|
||||
|
||||
Local Java is not required for orchestration, but the build itself requires Java 21. The Gitea runner is the intended build environment.
|
||||
|
||||
<p align="center"><img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="-----------------------------------------------------" width="100%"></p>
|
||||
|
||||
## Porting Order
|
||||
|
||||
1. Preserve registry IDs under `crusty_chunks`.
|
||||
2. Port metadata, resources, tags, recipes, loot, worldgen, creative tabs, blocks, items, fluids, sounds, and particles.
|
||||
3. Port machines, block entities, menus, networking, energy, fluids, reactors, bombs, and warheads.
|
||||
4. Port weapons, ordnance, projectiles, GeckoLib animations, Ritchie's Projectile Library behavior, and AI.
|
||||
5. Replace WariumAPI/WariumVS compatibility shims with real NeoForge 1.21.1 integrations when available.
|
||||
|
||||
<p align="center"><img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="-----------------------------------------------------" width="100%"></p>
|
||||
|
||||
## Source
|
||||
|
||||
Original source artifact: [Warium 1.2.7 on Modrinth](https://modrinth.com/mod/warium/version/1.2.7)
|
||||
|
||||
Expected SHA1:
|
||||
|
||||
```text
|
||||
528d81630a23fb4004e3abdd99b16bd225cd1e92
|
||||
```
|
||||
22
SECURITY.md
Normal file
22
SECURITY.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| --- | --- |
|
||||
| Latest | Yes |
|
||||
|
||||
## Reporting A Vulnerability
|
||||
|
||||
Please report security issues privately to the project owner.
|
||||
|
||||
Do not include secrets, production data, or private credentials in public issues.
|
||||
|
||||
## Project Security Principles
|
||||
|
||||
- Keep secrets out of the repository.
|
||||
- Prefer local processing for user data.
|
||||
- Document external network calls.
|
||||
- Keep release artifacts reproducible through CI.
|
||||
- Run dependency audits before releases.
|
||||
|
||||
136
build.gradle
Normal file
136
build.gradle
Normal file
@@ -0,0 +1,136 @@
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'maven-publish'
|
||||
id 'net.neoforged.gradle.userdev' version '7.1.26'
|
||||
}
|
||||
|
||||
version = mod_version
|
||||
group = mod_group_id
|
||||
|
||||
base {
|
||||
archivesName = 'warium-neoforge-1.21.1'
|
||||
}
|
||||
|
||||
java.toolchain.languageVersion = JavaLanguageVersion.of(21)
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir 'src/generated/java'
|
||||
}
|
||||
resources {
|
||||
srcDir 'src/generated/resources'
|
||||
exclude '**/*.bbmodel'
|
||||
exclude 'src/generated/**/.cache'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'NeoForge'
|
||||
url = 'https://maven.neoforged.net/releases'
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
runtimeClasspath.extendsFrom localRuntime
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "net.neoforged:neoforge:${neo_version}"
|
||||
}
|
||||
|
||||
runs {
|
||||
configureEach {
|
||||
systemProperty 'forge.logging.markers', 'REGISTRIES'
|
||||
systemProperty 'forge.logging.console.level', 'debug'
|
||||
workingDirectory project.layout.projectDirectory.dir('run').dir(name)
|
||||
modSource project.sourceSets.main
|
||||
}
|
||||
|
||||
client {
|
||||
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
||||
}
|
||||
|
||||
server {
|
||||
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
||||
argument '--nogui'
|
||||
}
|
||||
|
||||
gameTestServer {
|
||||
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
||||
}
|
||||
|
||||
data {
|
||||
arguments.addAll '--mod', project.mod_id, '--all',
|
||||
'--output', file('src/generated/resources/').getAbsolutePath(),
|
||||
'--existing', file('src/main/resources/').getAbsolutePath()
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('generatePortSources', Exec) {
|
||||
group = 'warium port'
|
||||
description = 'Downloads Warium 1.2.7, verifies it, extracts resources, and generates NeoForge registry stubs.'
|
||||
commandLine 'python', 'tools/generate_port_sources.py'
|
||||
}
|
||||
|
||||
tasks.register('decompileOriginal', Exec) {
|
||||
group = 'warium port'
|
||||
description = 'Downloads and decompiles the original Warium jar for manual porting work.'
|
||||
commandLine 'python', 'tools/decompile_original.py'
|
||||
}
|
||||
|
||||
tasks.register('checkRequiredIntegrations', Exec) {
|
||||
group = 'verification'
|
||||
description = 'Checks required Warium ecosystem integration availability.'
|
||||
commandLine 'python', 'tools/check_required_integrations.py'
|
||||
}
|
||||
|
||||
tasks.register('registryParity', Exec) {
|
||||
group = 'verification'
|
||||
description = 'Checks generated registry stubs against the original jar inventory.'
|
||||
commandLine 'python', 'tools/registry_parity.py'
|
||||
dependsOn tasks.named('generatePortSources')
|
||||
}
|
||||
|
||||
compileJava.dependsOn tasks.named('generatePortSources')
|
||||
processResources.dependsOn tasks.named('generatePortSources')
|
||||
build.dependsOn tasks.named('registryParity')
|
||||
|
||||
tasks.withType(ProcessResources).configureEach {
|
||||
var replaceProperties = [
|
||||
minecraft_version : minecraft_version,
|
||||
minecraft_version_range: minecraft_version_range,
|
||||
neo_version : neo_version,
|
||||
neo_version_range : neo_version_range,
|
||||
loader_version_range : loader_version_range,
|
||||
mod_id : mod_id,
|
||||
mod_name : mod_name,
|
||||
mod_license : mod_license,
|
||||
mod_version : mod_version,
|
||||
mod_authors : mod_authors,
|
||||
mod_description : mod_description
|
||||
]
|
||||
inputs.properties replaceProperties
|
||||
filesMatching(['META-INF/neoforge.mods.toml']) {
|
||||
expand replaceProperties
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
register('mavenJava', MavenPublication) {
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
url "file://${project.projectDir}/repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
1
ci/required-mods/.gitkeep
Normal file
1
ci/required-mods/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
43
docs/agent-handoff.md
Normal file
43
docs/agent-handoff.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Agent Handoff
|
||||
|
||||
Use this file when a task spans multiple sessions, has unresolved follow-up work, or changes release behavior.
|
||||
|
||||
## Current State
|
||||
|
||||
```text
|
||||
Private NeoForge 21.1.225 port scaffold is implemented. It generates registry stubs and extracted resources from the verified Warium 1.2.7 jar in CI, but original behavior systems still need manual porting from the decompiled output.
|
||||
```
|
||||
|
||||
## Changes Made
|
||||
|
||||
- Bootstrapped repository from `codex-agent-repository-kit`.
|
||||
- Added NeoForge/Gradle Java 21 project files.
|
||||
- Added scripts for Warium jar download, SHA1 verification, inventory extraction, source/resource generation, decompilation, runtime dependency download, and registry parity checks.
|
||||
- Added Gitea build workflow with artifact upload, private package publishing, and server smoke-test step.
|
||||
|
||||
## Verification
|
||||
|
||||
| Check | Result |
|
||||
| --- | --- |
|
||||
| `python tools/generate_port_sources.py` | Passed locally with bundled Python |
|
||||
| `python tools/registry_parity.py` | Passed locally: 448 blocks, 326 standalone items |
|
||||
| `python tools/prepare_runtime_mods.py` | Passed locally for GeckoLib and RPL |
|
||||
| `./gradlew --no-daemon build` | Pending Gitea runner; local Java is not installed |
|
||||
| `./gradlew --no-daemon runData` | Pending Gitea runner; local Java is not installed |
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Warium license conflict remains unresolved: Modrinth shows ARR, jar metadata shows AFL-3.0.
|
||||
- Real NeoForge 1.21.1 WariumAPI/WariumVS artifacts were not found during planning; the repo currently declares compatibility shim mod metadata.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Push to `MrSphay/Warium-NeoForge-1.21.1` and poll Gitea Actions.
|
||||
- Fix any Gradle/NeoForge compile errors found by the runner.
|
||||
- Port original MCreator behavior systems from `build/decompiled/warium-1.2.7`.
|
||||
- Replace WariumAPI/WariumVS shims with real dependencies when available.
|
||||
|
||||
## Risks
|
||||
|
||||
- Current jar is not a complete gameplay port; it preserves many registry/resource IDs but not the original machine, weapon, projectile, AI, GUI, networking, or nuclear behavior.
|
||||
- Public release must wait for rights clearance.
|
||||
793
docs/inventory/original-inventory.json
Normal file
793
docs/inventory/original-inventory.json
Normal file
@@ -0,0 +1,793 @@
|
||||
{
|
||||
"blocks_from_blockstates": [
|
||||
"active_robot_chute",
|
||||
"advanced_alloy_block",
|
||||
"after_burner",
|
||||
"ai_mine",
|
||||
"aimer_node",
|
||||
"aluminum_ac_barrel",
|
||||
"aluminum_ac_barrel_black",
|
||||
"aluminum_ac_barrel_blue",
|
||||
"aluminum_ac_barrel_brown",
|
||||
"aluminum_ac_barrel_cyan",
|
||||
"aluminum_ac_barrel_dark_gray",
|
||||
"aluminum_ac_barrel_gray",
|
||||
"aluminum_ac_barrel_green",
|
||||
"aluminum_ac_barrel_light_blue",
|
||||
"aluminum_ac_barrel_light_gray",
|
||||
"aluminum_ac_barrel_lime",
|
||||
"aluminum_ac_barrel_magenta",
|
||||
"aluminum_ac_barrel_orange",
|
||||
"aluminum_ac_barrel_pink",
|
||||
"aluminum_ac_barrel_purple",
|
||||
"aluminum_ac_barrel_red",
|
||||
"aluminum_ac_barrel_white",
|
||||
"aluminum_ac_barrel_yellow",
|
||||
"aluminum_block",
|
||||
"aluminum_plating",
|
||||
"aluminum_plating_black",
|
||||
"aluminum_plating_blue",
|
||||
"aluminum_plating_brown",
|
||||
"aluminum_plating_cyan",
|
||||
"aluminum_plating_dark_gray",
|
||||
"aluminum_plating_gray",
|
||||
"aluminum_plating_green",
|
||||
"aluminum_plating_light_blue",
|
||||
"aluminum_plating_light_gray",
|
||||
"aluminum_plating_lime",
|
||||
"aluminum_plating_magenta",
|
||||
"aluminum_plating_orange",
|
||||
"aluminum_plating_pink",
|
||||
"aluminum_plating_purple",
|
||||
"aluminum_plating_red",
|
||||
"aluminum_plating_slab",
|
||||
"aluminum_plating_slab_black",
|
||||
"aluminum_plating_slab_blue",
|
||||
"aluminum_plating_slab_brown",
|
||||
"aluminum_plating_slab_cyan",
|
||||
"aluminum_plating_slab_dark_gray",
|
||||
"aluminum_plating_slab_gray",
|
||||
"aluminum_plating_slab_green",
|
||||
"aluminum_plating_slab_light_blue",
|
||||
"aluminum_plating_slab_light_gray",
|
||||
"aluminum_plating_slab_lime",
|
||||
"aluminum_plating_slab_magenta",
|
||||
"aluminum_plating_slab_orange",
|
||||
"aluminum_plating_slab_pink",
|
||||
"aluminum_plating_slab_purple",
|
||||
"aluminum_plating_slab_red",
|
||||
"aluminum_plating_slab_white",
|
||||
"aluminum_plating_slab_yellow",
|
||||
"aluminum_plating_stairs",
|
||||
"aluminum_plating_stairs_black",
|
||||
"aluminum_plating_stairs_blue",
|
||||
"aluminum_plating_stairs_brown",
|
||||
"aluminum_plating_stairs_cyan",
|
||||
"aluminum_plating_stairs_dark_gray",
|
||||
"aluminum_plating_stairs_gray",
|
||||
"aluminum_plating_stairs_green",
|
||||
"aluminum_plating_stairs_light_blue",
|
||||
"aluminum_plating_stairs_light_gray",
|
||||
"aluminum_plating_stairs_lime",
|
||||
"aluminum_plating_stairs_magenta",
|
||||
"aluminum_plating_stairs_orange",
|
||||
"aluminum_plating_stairs_pink",
|
||||
"aluminum_plating_stairs_purple",
|
||||
"aluminum_plating_stairs_red",
|
||||
"aluminum_plating_stairs_white",
|
||||
"aluminum_plating_stairs_yellow",
|
||||
"aluminum_plating_trapdoor",
|
||||
"aluminum_plating_trapdoor_black",
|
||||
"aluminum_plating_trapdoor_blue",
|
||||
"aluminum_plating_trapdoor_brown",
|
||||
"aluminum_plating_trapdoor_cyan",
|
||||
"aluminum_plating_trapdoor_dark_gray",
|
||||
"aluminum_plating_trapdoor_gray",
|
||||
"aluminum_plating_trapdoor_green",
|
||||
"aluminum_plating_trapdoor_light_blue",
|
||||
"aluminum_plating_trapdoor_light_gray",
|
||||
"aluminum_plating_trapdoor_lime",
|
||||
"aluminum_plating_trapdoor_magenta",
|
||||
"aluminum_plating_trapdoor_orange",
|
||||
"aluminum_plating_trapdoor_pink",
|
||||
"aluminum_plating_trapdoor_purple",
|
||||
"aluminum_plating_trapdoor_red",
|
||||
"aluminum_plating_trapdoor_white",
|
||||
"aluminum_plating_trapdoor_yellow",
|
||||
"aluminum_plating_white",
|
||||
"aluminum_plating_yellow",
|
||||
"aluminum_side_panel",
|
||||
"aluminum_side_panel_black",
|
||||
"aluminum_side_panel_blue",
|
||||
"aluminum_side_panel_brown",
|
||||
"aluminum_side_panel_cyan",
|
||||
"aluminum_side_panel_dark_gray",
|
||||
"aluminum_side_panel_gray",
|
||||
"aluminum_side_panel_green",
|
||||
"aluminum_side_panel_light_blue",
|
||||
"aluminum_side_panel_light_gray",
|
||||
"aluminum_side_panel_lime",
|
||||
"aluminum_side_panel_magenta",
|
||||
"aluminum_side_panel_orange",
|
||||
"aluminum_side_panel_pink",
|
||||
"aluminum_side_panel_purple",
|
||||
"aluminum_side_panel_red",
|
||||
"aluminum_side_panel_white",
|
||||
"aluminum_side_panel_yellow",
|
||||
"ancient_light",
|
||||
"ancient_well",
|
||||
"artillery_autoloader",
|
||||
"artillery_barrel",
|
||||
"artillery_charge_loader",
|
||||
"artillerybreech",
|
||||
"asphalt",
|
||||
"asphalt_slab",
|
||||
"assembly_centrifuge_bottom",
|
||||
"assembly_centrifuge_middle",
|
||||
"assembly_centrifuge_top",
|
||||
"assembly_circuit_fabricator",
|
||||
"assembly_crusher",
|
||||
"assembly_depot",
|
||||
"assembly_furnace",
|
||||
"assembly_machine",
|
||||
"assembly_mechanical_fabricator",
|
||||
"autocannon",
|
||||
"autocannon_barrel",
|
||||
"autocannon_drum",
|
||||
"autoloader",
|
||||
"battle_cannon_barrel",
|
||||
"battle_cannon_breech",
|
||||
"battle_cannon_mantlet",
|
||||
"bauxite",
|
||||
"bauxite_digester",
|
||||
"beryllium_block",
|
||||
"beryllium_ore",
|
||||
"black_armor",
|
||||
"black_armor_optic",
|
||||
"black_armor_slab",
|
||||
"black_armor_stairs",
|
||||
"black_armor_trapdoor",
|
||||
"blast_funnel",
|
||||
"blast_furnace",
|
||||
"blast_furnace_bricks",
|
||||
"blue_armor",
|
||||
"blue_armor_optic",
|
||||
"blue_armor_slab",
|
||||
"blue_armor_stairs",
|
||||
"blue_armor_trapdoor",
|
||||
"brass_block",
|
||||
"breeder_reactor_core",
|
||||
"breeder_reactor_interface",
|
||||
"breeder_reactor_port",
|
||||
"brown_armor",
|
||||
"brown_armor_optic",
|
||||
"brown_armor_slab",
|
||||
"brown_armor_stairs",
|
||||
"brown_armor_trapdoor",
|
||||
"burntgrass",
|
||||
"charred_block",
|
||||
"chlorine_gas",
|
||||
"cluster_of_bombs",
|
||||
"compressed_air",
|
||||
"concrete_wall",
|
||||
"control_rod",
|
||||
"conveyor",
|
||||
"conveyor_splitter",
|
||||
"countermeasure_dispenser",
|
||||
"covered_flame_thrower_barrel",
|
||||
"covered_machine_gun_barrel",
|
||||
"cracked_concrete",
|
||||
"cracked_concrete_wall",
|
||||
"crude_oil",
|
||||
"cyan_armor",
|
||||
"cyan_armor_optic",
|
||||
"cyan_armor_slab",
|
||||
"cyan_armor_stairs",
|
||||
"cyan_armor_trapdoor",
|
||||
"damaged_concrete",
|
||||
"damaged_concrete_wall",
|
||||
"damagedfueltank",
|
||||
"deepslate_lead_ore",
|
||||
"defense_core",
|
||||
"destroyed_concrete",
|
||||
"destroyed_concrete_wall",
|
||||
"diesel",
|
||||
"drive_shaft",
|
||||
"electric_firebox",
|
||||
"empty_fuel_rods",
|
||||
"empty_missile_hardpoint",
|
||||
"energy_battery",
|
||||
"energy_distribution_node",
|
||||
"energy_node",
|
||||
"engine_cyllinder",
|
||||
"era_1",
|
||||
"era_2",
|
||||
"era_3",
|
||||
"era_4",
|
||||
"explosive_barrel",
|
||||
"extension_shaft",
|
||||
"fire_spear_missile_hardpoint",
|
||||
"firebox",
|
||||
"fission_bomb",
|
||||
"flame_thrower",
|
||||
"flame_thrower_barrel",
|
||||
"foundry",
|
||||
"fractured_concrete",
|
||||
"fractured_concrete_wall",
|
||||
"fuel_rods_1",
|
||||
"fuel_rods_2",
|
||||
"fuel_rods_3",
|
||||
"fuel_rods_4",
|
||||
"fuel_tank",
|
||||
"fuel_tank_input",
|
||||
"fuel_tank_module",
|
||||
"fusion_bomb",
|
||||
"gas_bomb",
|
||||
"gas_dispenser",
|
||||
"generator",
|
||||
"giant_coil",
|
||||
"glass_trapdoor",
|
||||
"gray_armor",
|
||||
"gray_armor_optic",
|
||||
"gray_armor_slab",
|
||||
"gray_armor_stairs",
|
||||
"gray_armor_trapdoor",
|
||||
"green_armor",
|
||||
"green_armor_optic",
|
||||
"green_armor_slab",
|
||||
"green_armor_stairs",
|
||||
"green_armor_trapdoor",
|
||||
"harddirt",
|
||||
"heavy_machine_gun",
|
||||
"hydrazine",
|
||||
"item_incinerator",
|
||||
"jet_compressor",
|
||||
"jet_exhaust",
|
||||
"jet_gearbox",
|
||||
"jet_turbine",
|
||||
"kerosene",
|
||||
"land_mine",
|
||||
"large_electric_motor",
|
||||
"large_engine_smokestack",
|
||||
"large_rocket_pod",
|
||||
"large_rocket_pod_chamber",
|
||||
"lead_block",
|
||||
"lead_ore",
|
||||
"light_autocannon",
|
||||
"light_blue_armor",
|
||||
"light_blue_armor_optic",
|
||||
"light_blue_armor_slab",
|
||||
"light_blue_armor_stairs",
|
||||
"light_blue_armor_trapdoor",
|
||||
"light_gray_armor",
|
||||
"light_gray_armor_optic",
|
||||
"light_gray_armor_slab",
|
||||
"light_gray_armor_stairs",
|
||||
"light_gray_armor_trapdoor",
|
||||
"light_machine_gun",
|
||||
"light_wood_block",
|
||||
"light_wood_frame",
|
||||
"light_wood_side_panel",
|
||||
"light_wood_slab",
|
||||
"light_wood_stairs",
|
||||
"light_wood_trapdoor",
|
||||
"lime_armor",
|
||||
"lime_armor_optic",
|
||||
"lime_armor_slab",
|
||||
"lime_armor_stairs",
|
||||
"lime_armor_trapdoor",
|
||||
"liquid_hydrogen",
|
||||
"liquid_oxygen",
|
||||
"lithium_block",
|
||||
"lithium_ore",
|
||||
"loot_box",
|
||||
"machine_gun",
|
||||
"machine_gun_barrel",
|
||||
"magenta_armor",
|
||||
"magenta_armor_optic",
|
||||
"magenta_armor_slab",
|
||||
"magenta_armor_stairs",
|
||||
"magenta_armor_trapdoor",
|
||||
"manual_aimer",
|
||||
"manual_crank",
|
||||
"medium_diesel_engine",
|
||||
"medium_petrol_engine",
|
||||
"mineral_grinder",
|
||||
"mini_gun_barrel",
|
||||
"minigun",
|
||||
"mortar",
|
||||
"nickel_block",
|
||||
"nickel_ore",
|
||||
"niobium_block",
|
||||
"nitrate_block",
|
||||
"node_trigger",
|
||||
"node_trigger_on",
|
||||
"offset_era_1",
|
||||
"offset_era_2",
|
||||
"offset_era_3",
|
||||
"offset_era_4",
|
||||
"oil",
|
||||
"oil_firebox",
|
||||
"open_summonation",
|
||||
"orange_armor",
|
||||
"orange_armor_optic",
|
||||
"orange_armor_slab",
|
||||
"orange_armor_stairs",
|
||||
"orange_armor_trapdoor",
|
||||
"ordinance_cluster_warhead",
|
||||
"ordinance_controller",
|
||||
"ordinance_core",
|
||||
"ordinance_fins",
|
||||
"ordinance_fission_initiator_head",
|
||||
"ordinance_heavy_warhead",
|
||||
"ordinance_incendiary_warhead",
|
||||
"ordinance_inline_fission_warhead",
|
||||
"ordinance_inline_fusion_warhead_stage_1",
|
||||
"ordinance_inline_fusion_warhead_stage_2",
|
||||
"ordinance_inline_warhead",
|
||||
"ordinance_ir_seeker_head",
|
||||
"ordinance_kinetic_head",
|
||||
"ordinance_relocator",
|
||||
"ordinance_sarh_seeker",
|
||||
"ordinance_thruster",
|
||||
"overgrown_reenforced_concrete",
|
||||
"passenger_seat",
|
||||
"petrolium",
|
||||
"phosphate_block",
|
||||
"pink_armor",
|
||||
"pink_armor_optic",
|
||||
"pink_armor_slab",
|
||||
"pink_armor_stairs",
|
||||
"pink_armor_trapdoor",
|
||||
"plutonium_block",
|
||||
"polished_bauxite",
|
||||
"polished_trinitite",
|
||||
"power_reactor_interface",
|
||||
"power_reactor_port",
|
||||
"production_input",
|
||||
"production_output",
|
||||
"purple_armor",
|
||||
"purple_armor_optic",
|
||||
"purple_armor_slab",
|
||||
"purple_armor_stairs",
|
||||
"purple_armor_trapdoor",
|
||||
"pyrochlore_block",
|
||||
"pyrochlore_ore",
|
||||
"rac_barrel",
|
||||
"radar_spear_missile_hardpoint",
|
||||
"radioactive_ash",
|
||||
"radioactive_ash_full_block",
|
||||
"raw_beryllium_block",
|
||||
"raw_lead_block",
|
||||
"raw_lithium_block",
|
||||
"raw_nickel_block",
|
||||
"raw_uranium_block",
|
||||
"raw_zinc_block",
|
||||
"razor_wire",
|
||||
"reaction_chamber",
|
||||
"reactor_casing",
|
||||
"rebar",
|
||||
"red_armor",
|
||||
"red_armor_optic",
|
||||
"red_armor_slab",
|
||||
"red_armor_stairs",
|
||||
"red_armor_trapdoor",
|
||||
"redirector_shaft",
|
||||
"redstone_tnt",
|
||||
"reenforced_concrete",
|
||||
"refinery",
|
||||
"refinery_tower",
|
||||
"reinforced_glass",
|
||||
"reinforced_glass_stairs",
|
||||
"reinforced_glass_trapdoor",
|
||||
"robot_chute",
|
||||
"rocket_pod",
|
||||
"rocket_pod_chamber",
|
||||
"rotary_auto_cannon",
|
||||
"rusty_block",
|
||||
"rusty_slab",
|
||||
"rusty_stairs",
|
||||
"rusty_trapdoor",
|
||||
"sand_bags",
|
||||
"scorch_dirt",
|
||||
"seeker_spear_missile_hardpoint",
|
||||
"sheet_metal",
|
||||
"sheet_metal_pane",
|
||||
"sheet_metal_slab",
|
||||
"sheet_metal_stairs",
|
||||
"siren",
|
||||
"small_bomb",
|
||||
"small_diesel_engine",
|
||||
"small_petrol_engine",
|
||||
"smoke_bomb",
|
||||
"smoke_launcher",
|
||||
"solar_generator",
|
||||
"steel_block",
|
||||
"steel_door",
|
||||
"steel_optic",
|
||||
"steel_plating",
|
||||
"steel_plating_slab",
|
||||
"steel_plating_stairs",
|
||||
"steel_trapdoor",
|
||||
"steel_truss",
|
||||
"strike_spear_missile_hardpoint",
|
||||
"structural_concrete",
|
||||
"sulfur_block",
|
||||
"sulfur_ore",
|
||||
"sulfuric_acid",
|
||||
"summonation",
|
||||
"summonator",
|
||||
"summonator_active",
|
||||
"summonator_module",
|
||||
"tar",
|
||||
"thermal_furnace",
|
||||
"thick_battle_cannon_barrel",
|
||||
"tinted_glass_stairs",
|
||||
"tinted_glass_trapdoor",
|
||||
"torpedo_thruster",
|
||||
"trinitite",
|
||||
"trinitite_glass",
|
||||
"trinitite_glass_stairs",
|
||||
"trinitite_glass_trapdoor",
|
||||
"type_1_bc_muzzle_brake",
|
||||
"type_2_bc_muzzle_brake",
|
||||
"uranium_depleted_block",
|
||||
"uranium_enriched_block",
|
||||
"uranium_neutral_block",
|
||||
"uranium_ore",
|
||||
"white_armor",
|
||||
"white_armor_optic",
|
||||
"white_armor_slab",
|
||||
"white_armor_stairs",
|
||||
"white_armor_trapdoor",
|
||||
"wire_fence",
|
||||
"yellow_armor",
|
||||
"yellow_armor_optic",
|
||||
"yellow_armor_slab",
|
||||
"yellow_armor_stairs",
|
||||
"yellow_armor_trapdoor",
|
||||
"zinc_block",
|
||||
"zinc_ore"
|
||||
],
|
||||
"counts": {
|
||||
"blockstates": 448,
|
||||
"classes": 4703,
|
||||
"entities": 167,
|
||||
"item_models": 763,
|
||||
"loot_tables": 435,
|
||||
"procedures": 3063,
|
||||
"recipes": 505,
|
||||
"standalone_items": 326
|
||||
},
|
||||
"modid": "crusty_chunks",
|
||||
"source": "Warium 1.2.7",
|
||||
"source_sha1": "528d81630a23fb4004e3abdd99b16bd225cd1e92",
|
||||
"standalone_items_from_item_models": [
|
||||
"advanced_alloy_component",
|
||||
"advanced_alloy_ingot",
|
||||
"advanced_alloy_mixture",
|
||||
"advanced_automatic_rifle_receiver",
|
||||
"advanced_component",
|
||||
"advanced_pistol_receiver",
|
||||
"aimer",
|
||||
"aluminate_dust",
|
||||
"aluminum_dust",
|
||||
"aluminum_ingot",
|
||||
"aluminum_plate",
|
||||
"aluminum_tiny_dust",
|
||||
"ap_large_bullet",
|
||||
"ap_shell",
|
||||
"apfsds_projectile",
|
||||
"armor_peeler_animated",
|
||||
"armor_peeler_rocket",
|
||||
"armor_peeler_unloaded",
|
||||
"artillery_shell",
|
||||
"artillery_solid_shell",
|
||||
"assassin_spawn_egg",
|
||||
"auto_pistol",
|
||||
"automatic_rifle",
|
||||
"automatic_rifle_receiver",
|
||||
"basic_receiver",
|
||||
"battle_rifle",
|
||||
"bauxite_dust",
|
||||
"bent_component",
|
||||
"beryllium_dust",
|
||||
"beryllium_ingot",
|
||||
"bird_shot",
|
||||
"blast_armor_boots",
|
||||
"blast_armor_chestplate",
|
||||
"blast_armor_helmet",
|
||||
"blast_armor_leggings",
|
||||
"blast_clay",
|
||||
"blast_furnace_brick",
|
||||
"body_armor_chestplate",
|
||||
"bolt_action_receiver",
|
||||
"bolt_action_rifle_animated",
|
||||
"bored_component",
|
||||
"brass_dust",
|
||||
"brass_fitting",
|
||||
"brass_ingot",
|
||||
"brass_plate",
|
||||
"breacher_spawn_egg",
|
||||
"break_action_shotgun_animated",
|
||||
"breech_rifle",
|
||||
"bullet",
|
||||
"bullet_resistant_helmet_2_helmet",
|
||||
"bullet_resistant_helmet_3_helmet",
|
||||
"bullet_resistant_helmet_4_helmet",
|
||||
"bullet_resistant_helmet_helmet",
|
||||
"burst_rifle",
|
||||
"cable",
|
||||
"cast_component",
|
||||
"chaff_charge",
|
||||
"chisel",
|
||||
"chlorine_dust",
|
||||
"chlorine_gas_bucket",
|
||||
"ciws_spawn_egg",
|
||||
"combustion_cylinder",
|
||||
"commander_spawn_egg",
|
||||
"component_foundry_template",
|
||||
"compressed_advanced_mixture",
|
||||
"compressed_air_bucket",
|
||||
"copper_coil",
|
||||
"copper_dust",
|
||||
"copper_plate",
|
||||
"copper_wire",
|
||||
"crude_oil_bucket",
|
||||
"cut_component",
|
||||
"cutters",
|
||||
"cylinder_foundry_template",
|
||||
"decimator_spawn_egg",
|
||||
"diesel_bucket",
|
||||
"electric_motor",
|
||||
"ember_particle",
|
||||
"energy_meter",
|
||||
"engine_component",
|
||||
"enriched_lithium_ingot",
|
||||
"enriched_lithium_nugget",
|
||||
"era_tile",
|
||||
"eradication",
|
||||
"eradicator_spawn_egg",
|
||||
"extra_large_bullet",
|
||||
"extra_large_casing",
|
||||
"extra_large_projectile",
|
||||
"extra_large_projectile_template",
|
||||
"filtered_aluminate_dust",
|
||||
"filtered_pyrochlore_dust",
|
||||
"fire_agent",
|
||||
"fire_artillery_shell",
|
||||
"fire_spear_rocket",
|
||||
"firing_mechanism",
|
||||
"firing_pin",
|
||||
"fission_core",
|
||||
"flak_projectile",
|
||||
"flak_shell",
|
||||
"flame_thrower_animated",
|
||||
"flame_thrower_tank_chestplate",
|
||||
"flamer_spawn_egg",
|
||||
"flare_charge",
|
||||
"flare_pistol",
|
||||
"foundry_template",
|
||||
"fuel_hose",
|
||||
"fuel_rod",
|
||||
"fusion_core",
|
||||
"gas_artillery_shell",
|
||||
"gas_canister",
|
||||
"gas_mask_helmet",
|
||||
"gas_mask_helmet_helmet",
|
||||
"geiger_counter",
|
||||
"gold_dust",
|
||||
"grenade",
|
||||
"grenade_launcher",
|
||||
"grenade_shell",
|
||||
"hammer",
|
||||
"hand_drill",
|
||||
"he_projectile",
|
||||
"heat_projectile",
|
||||
"heat_shell",
|
||||
"hollowed_extra_large_projectile",
|
||||
"hollowed_huge_projectile",
|
||||
"hollowed_large_projectile",
|
||||
"huge_barrel_foundry_template",
|
||||
"huge_bored_barrel",
|
||||
"huge_bullet",
|
||||
"huge_cannon_foundry_template",
|
||||
"huge_casing",
|
||||
"huge_he_bullet",
|
||||
"huge_projectile",
|
||||
"huge_projectile_foundry_template",
|
||||
"huge_unbored_barrel",
|
||||
"huge_unbored_cannon_barrel",
|
||||
"hunter_spawn_egg",
|
||||
"hydrazine_bucket",
|
||||
"impact_fuze",
|
||||
"implosion_lens",
|
||||
"implosion_module",
|
||||
"incendiary_bottle",
|
||||
"incendiary_grenade",
|
||||
"invisibleitem",
|
||||
"ir_component",
|
||||
"iron_dust",
|
||||
"irongear",
|
||||
"kerosene_bucket",
|
||||
"large_barrel_template",
|
||||
"large_bored_barrel",
|
||||
"large_bullet",
|
||||
"large_cannon_foundry_template",
|
||||
"large_casing",
|
||||
"large_foundry_template",
|
||||
"large_magazine",
|
||||
"large_magazine_0",
|
||||
"large_projectile",
|
||||
"large_projectile_foundry_template",
|
||||
"large_shell",
|
||||
"large_unbored_barrel",
|
||||
"large_unbored_cannon_barrel",
|
||||
"large_volatile_pile",
|
||||
"lead_dust",
|
||||
"lead_ingot",
|
||||
"lead_nugget",
|
||||
"lever_rifle",
|
||||
"liquid_hydrogen_bucket",
|
||||
"liquid_oxygen_bucket",
|
||||
"lithium_deuteride",
|
||||
"lithium_dust",
|
||||
"lithium_ingot",
|
||||
"lithium_nugget",
|
||||
"lmg_animated",
|
||||
"lmg_magazine",
|
||||
"lmg_magazine_0",
|
||||
"machine_carbine",
|
||||
"machine_gun_box",
|
||||
"machine_gun_box_0",
|
||||
"mechanical_bore",
|
||||
"mechanical_extruder",
|
||||
"mechanical_press",
|
||||
"mechanical_shear",
|
||||
"medium_ap_bullet",
|
||||
"medium_barrel_template",
|
||||
"medium_bored_barrel",
|
||||
"medium_cannon_foundry_template",
|
||||
"medium_casing",
|
||||
"medium_magazine",
|
||||
"medium_magazine_0",
|
||||
"medium_projectile",
|
||||
"medium_projectile_foundry_template",
|
||||
"medium_stealth_bullet",
|
||||
"medium_unbored_barrel",
|
||||
"medium_unbored_cannon_barrel",
|
||||
"mg_receiver",
|
||||
"mortar_shell",
|
||||
"mortarer_spawn_egg",
|
||||
"musket_ball",
|
||||
"neutron_reflector",
|
||||
"nickel_dust",
|
||||
"nickel_ingot",
|
||||
"niobium_dust",
|
||||
"niobium_ingot",
|
||||
"niobium_tiny_dust",
|
||||
"nitrate",
|
||||
"nvd_helmet_helmet",
|
||||
"oil_bucket",
|
||||
"paint_tool",
|
||||
"particle",
|
||||
"particle_2",
|
||||
"petrolium_bucket",
|
||||
"phosphorus_dust",
|
||||
"pistol_receiver",
|
||||
"plutonium_core",
|
||||
"plutonium_ingot",
|
||||
"plutonium_nugget",
|
||||
"powder_charge",
|
||||
"power_cell",
|
||||
"precision_component",
|
||||
"propellent",
|
||||
"prototype_eradicator_spawn_egg",
|
||||
"pump_action_shotgun_animated",
|
||||
"pyrochlore",
|
||||
"pyrochlore_dust",
|
||||
"radar_component",
|
||||
"radar_spear_missile",
|
||||
"raidscout_spawn_egg",
|
||||
"raw_beryllium",
|
||||
"raw_lead",
|
||||
"raw_lithium",
|
||||
"raw_nickel",
|
||||
"raw_uranium",
|
||||
"raw_zinc",
|
||||
"reactioncomponent",
|
||||
"reaper_spawn_egg",
|
||||
"revolver_animated",
|
||||
"revolver_receiver",
|
||||
"rifle_stock",
|
||||
"rifler_spawn_egg",
|
||||
"scoped_bolt_action_rifle_animated",
|
||||
"scoped_breech_rifle",
|
||||
"scout_spawn_egg",
|
||||
"seeker_spear_rocket",
|
||||
"semi_automatic_pistol_animated",
|
||||
"semi_automatic_rifle_animated",
|
||||
"shale_oil",
|
||||
"shaped_charge_fuze",
|
||||
"shielding_component",
|
||||
"shotgun_casing",
|
||||
"shotgun_shell",
|
||||
"single_shot_rifle",
|
||||
"slug_shell",
|
||||
"small_ap_shell",
|
||||
"small_barrel_template",
|
||||
"small_bored_barrel",
|
||||
"small_cannon_foundry_template",
|
||||
"small_casing",
|
||||
"small_engine",
|
||||
"small_flak_projectile",
|
||||
"small_flak_shell",
|
||||
"small_he_projectile",
|
||||
"small_hollow_point_bullet",
|
||||
"small_projectile",
|
||||
"small_projectile_foundry_template",
|
||||
"small_shell",
|
||||
"small_stealth_bullet",
|
||||
"small_unbored_barrel",
|
||||
"small_unbored_cannon_barrel",
|
||||
"smallbullet",
|
||||
"smallmagazine",
|
||||
"smallmagazine_0",
|
||||
"smg_animated",
|
||||
"smg_magazine",
|
||||
"smg_magazine_0",
|
||||
"smg_receiver",
|
||||
"smoke_agent",
|
||||
"smoke_grenade",
|
||||
"smoke_grenade_shell",
|
||||
"smoke_mortar_shell",
|
||||
"smoke_projectile",
|
||||
"smoke_shell",
|
||||
"solid_rocket_fuel_pack",
|
||||
"solid_shell",
|
||||
"stealth_large_bullet",
|
||||
"stealth_pistol",
|
||||
"steel_component",
|
||||
"steel_crushing_wheel",
|
||||
"steel_cylinder",
|
||||
"steel_gear",
|
||||
"steel_ingot",
|
||||
"steel_spring",
|
||||
"steel_tube",
|
||||
"steel_wire",
|
||||
"steelplate",
|
||||
"strike_spear_missile",
|
||||
"striker_spawn_egg",
|
||||
"sulfur",
|
||||
"sulfuric_acid_bucket",
|
||||
"tech_component",
|
||||
"thermal_shell",
|
||||
"thermo_nuclear_fuel",
|
||||
"thermometer",
|
||||
"timed_fuze",
|
||||
"tiny_lithium_deuteride",
|
||||
"tinyprojectile_item",
|
||||
"toxic_agent",
|
||||
"transparent_item",
|
||||
"trinitite_shard",
|
||||
"turbine_rotor",
|
||||
"unfabricated_tech_component",
|
||||
"uranium_depleted_dust",
|
||||
"uranium_depleted_ingot",
|
||||
"uranium_depleted_tiny_dust",
|
||||
"uranium_enriched_dust",
|
||||
"uranium_enriched_ingot",
|
||||
"uranium_enriched_tiny_dust",
|
||||
"uranium_neural_ingot",
|
||||
"uranium_neutral_dust",
|
||||
"uranium_neutraltiny_dust",
|
||||
"volatile_dust",
|
||||
"weapon_bolt",
|
||||
"weapon_supressor",
|
||||
"welder",
|
||||
"wood_component",
|
||||
"worker_spawn_egg",
|
||||
"zinc_dust",
|
||||
"zinc_ingot"
|
||||
]
|
||||
}
|
||||
39
docs/release-checklist.md
Normal file
39
docs/release-checklist.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Release Checklist
|
||||
|
||||
## Version
|
||||
|
||||
- [ ] Private/internal release scope confirmed.
|
||||
- [ ] Warium rights clarified before any public release.
|
||||
- [ ] Version number updated.
|
||||
- [ ] Changelog updated.
|
||||
- [ ] README updated.
|
||||
|
||||
## Quality
|
||||
|
||||
- [ ] `python tools/generate_port_sources.py` passes.
|
||||
- [ ] `python tools/registry_parity.py` passes.
|
||||
- [ ] `./gradlew --no-daemon build` passes.
|
||||
- [ ] `./gradlew --no-daemon runData` passes.
|
||||
- [ ] Dedicated server smoke test passes in Gitea Actions.
|
||||
|
||||
## Security
|
||||
|
||||
- [ ] Security review is current.
|
||||
- [ ] No secrets are committed.
|
||||
- [ ] Original Warium jar is not committed.
|
||||
- [ ] Decompiled source dumps are not committed.
|
||||
- [ ] Generated extracted assets are not committed.
|
||||
- [ ] Private dependency jars are not committed.
|
||||
|
||||
## Artifacts
|
||||
|
||||
- [ ] `build/libs/warium-neoforge-1.21.1-1.2.7+neo.21.1.225.jar` exists.
|
||||
- [ ] Gitea Actions artifact is uploaded.
|
||||
- [ ] Private generic package is uploaded when `REGISTRY_TOKEN` is configured.
|
||||
- [ ] Private latest package URL works.
|
||||
|
||||
## Release
|
||||
|
||||
- [ ] Release notes written.
|
||||
- [ ] Public tag skipped unless explicitly requested after rights clearance.
|
||||
- [ ] Public release skipped unless explicitly requested after rights clearance.
|
||||
33
docs/release-notes.md
Normal file
33
docs/release-notes.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Warium NeoForge 1.21.1 1.2.7+neo.21.1.225
|
||||
|
||||
## Downloads
|
||||
|
||||
| Variant | Download |
|
||||
| --- | --- |
|
||||
| Latest private artifact | `https://git.wilkensxl.de/api/packages/MrSphay/generic/warium-neoforge-1.21.1/latest/warium-neoforge-1.21.1-latest.jar` |
|
||||
|
||||
## Highlights
|
||||
|
||||
- Private NeoForge `21.1.225` scaffold for Minecraft `1.21.1`.
|
||||
- Reproducible Warium `1.2.7` source artifact verification against SHA1 `528d81630a23fb4004e3abdd99b16bd225cd1e92`.
|
||||
- Generated registry stubs for original blockstates and standalone item models.
|
||||
- CI decompile artifact for behavior-port follow-up work.
|
||||
|
||||
## Security
|
||||
|
||||
- Dependency audit: handled by Gitea dependency-check workflow.
|
||||
- Secret handling: package publishing uses `REGISTRY_TOKEN`; no token is tracked.
|
||||
- External network calls: Modrinth, NeoForge Maven, Maven Central.
|
||||
|
||||
## Verification
|
||||
|
||||
| Check | Result |
|
||||
| --- | --- |
|
||||
| `python tools/generate_port_sources.py` | Passed locally |
|
||||
| `python tools/registry_parity.py` | Passed locally |
|
||||
| `./gradlew --no-daemon build` | Pending Gitea runner |
|
||||
| Artifact download | Pending Gitea runner and `REGISTRY_TOKEN` secret |
|
||||
|
||||
## Notes
|
||||
|
||||
This is not a public release. Keep the repository and packages private until rights are clarified.
|
||||
53
docs/security-review.md
Normal file
53
docs/security-review.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Security Review
|
||||
|
||||
## Scope
|
||||
|
||||
Project:
|
||||
|
||||
```text
|
||||
Warium NeoForge 1.21.1 Port
|
||||
```
|
||||
|
||||
Reviewed version or commit:
|
||||
|
||||
```text
|
||||
Unreleased scaffold
|
||||
```
|
||||
|
||||
## Code Patterns Checked
|
||||
|
||||
- [x] No secrets committed.
|
||||
- [x] Generated original assets are ignored.
|
||||
- [x] Decompiled source output is ignored.
|
||||
- [x] Original jar artifacts are ignored.
|
||||
- [x] Private integration jars are ignored.
|
||||
- [x] External network calls are documented.
|
||||
|
||||
## Dependency Review
|
||||
|
||||
Command:
|
||||
|
||||
```bash
|
||||
./gradlew --no-daemon build
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```text
|
||||
Pending runner execution.
|
||||
```
|
||||
|
||||
## Runtime Review
|
||||
|
||||
- [x] Gitea publishing uses `REGISTRY_TOKEN` secret only.
|
||||
- [x] Package download is private/internal pending rights clearance.
|
||||
- [x] Source Warium jar is downloaded from Modrinth and verified by SHA1.
|
||||
- [x] Required private integrations are shimmed until real NeoForge 1.21.1 jars exist.
|
||||
|
||||
## Release Notes
|
||||
|
||||
Known residual risks:
|
||||
|
||||
```text
|
||||
The current scaffold preserves registry IDs and resources but does not yet fully port the original MCreator behavior procedures, block entities, GUI logic, entities, AI, weapons, ordnance, nuclear effects, or external integration APIs.
|
||||
```
|
||||
21
gradle.properties
Normal file
21
gradle.properties
Normal file
@@ -0,0 +1,21 @@
|
||||
org.gradle.jvmargs=-Xmx3G
|
||||
org.gradle.daemon=false
|
||||
org.gradle.parallel=true
|
||||
org.gradle.caching=true
|
||||
|
||||
neogradle.subsystems.parchment.minecraftVersion=1.21.1
|
||||
neogradle.subsystems.parchment.mappingsVersion=2024.11.17
|
||||
|
||||
minecraft_version=1.21.1
|
||||
minecraft_version_range=[1.21.1]
|
||||
neo_version=21.1.225
|
||||
neo_version_range=[21.1.225,)
|
||||
loader_version_range=[1,)
|
||||
|
||||
mod_id=crusty_chunks
|
||||
mod_name=Warium NeoForge Port
|
||||
mod_license=PRIVATE-INTERNAL-PENDING-RIGHTS-CLEARANCE
|
||||
mod_version=1.2.7+neo.21.1.225
|
||||
mod_group_id=net.mcreator.crustychunks
|
||||
mod_authors=Novum; port scaffold by Codex
|
||||
mod_description=A private internal NeoForge 1.21.1 port of Warium 1.2.7 pending rights clearance.
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
251
gradlew
vendored
Executable file
251
gradlew
vendored
Executable file
@@ -0,0 +1,251 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
94
gradlew.bat
vendored
Normal file
94
gradlew.bat
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
14
settings.gradle
Normal file
14
settings.gradle
Normal file
@@ -0,0 +1,14 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven {
|
||||
url = 'https://maven.neoforged.net/releases'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
|
||||
}
|
||||
|
||||
rootProject.name = 'Warium-NeoForge-1.21.1'
|
||||
14
src/main/java/net/mcreator/crustychunks/CrustyChunksMod.java
Normal file
14
src/main/java/net/mcreator/crustychunks/CrustyChunksMod.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package net.mcreator.crustychunks;
|
||||
|
||||
import net.mcreator.crustychunks.init.GeneratedRegistries;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
|
||||
@Mod(CrustyChunksMod.MODID)
|
||||
public final class CrustyChunksMod {
|
||||
public static final String MODID = "crusty_chunks";
|
||||
|
||||
public CrustyChunksMod(IEventBus modBus) {
|
||||
GeneratedRegistries.register(modBus);
|
||||
}
|
||||
}
|
||||
67
src/main/resources/META-INF/neoforge.mods.toml
Normal file
67
src/main/resources/META-INF/neoforge.mods.toml
Normal file
@@ -0,0 +1,67 @@
|
||||
modLoader="javafml"
|
||||
loaderVersion="${loader_version_range}"
|
||||
license="${mod_license}"
|
||||
issueTrackerURL="https://git.wilkensxl.de/MrSphay/Warium-NeoForge-1.21.1/issues"
|
||||
|
||||
[[mods]]
|
||||
modId="${mod_id}"
|
||||
version="${mod_version}"
|
||||
displayName="${mod_name}"
|
||||
displayURL="https://git.wilkensxl.de/MrSphay/Warium-NeoForge-1.21.1"
|
||||
credits="Original Warium by Novum. Private internal NeoForge port pending rights clearance."
|
||||
authors="${mod_authors}"
|
||||
description='''${mod_description}'''
|
||||
|
||||
[[mods]]
|
||||
modId="wariumapi"
|
||||
version="${mod_version}"
|
||||
displayName="WariumAPI Compatibility Shim"
|
||||
description='''Private compatibility shim declared because WariumAPI has no confirmed NeoForge 1.21.1 artifact in the inspected sources. Replace with the real dependency when available.'''
|
||||
|
||||
[[mods]]
|
||||
modId="wariumvs"
|
||||
version="${mod_version}"
|
||||
displayName="WariumVS Compatibility Shim"
|
||||
description='''Private compatibility shim declared because WariumVS has no confirmed NeoForge 1.21.1 artifact in the inspected sources. Replace with the real dependency when available.'''
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId="minecraft"
|
||||
type="required"
|
||||
versionRange="${minecraft_version_range}"
|
||||
ordering="AFTER"
|
||||
side="BOTH"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId="neoforge"
|
||||
type="required"
|
||||
versionRange="${neo_version_range}"
|
||||
ordering="AFTER"
|
||||
side="BOTH"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId="geckolib"
|
||||
type="required"
|
||||
versionRange="[4.7.5.1,)"
|
||||
ordering="AFTER"
|
||||
side="BOTH"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId="ritchiesprojectilelib"
|
||||
type="required"
|
||||
versionRange="[2.1.2,)"
|
||||
ordering="AFTER"
|
||||
side="BOTH"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId="wariumapi"
|
||||
type="required"
|
||||
versionRange="[0,)"
|
||||
ordering="AFTER"
|
||||
side="BOTH"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId="wariumvs"
|
||||
type="required"
|
||||
versionRange="[0,)"
|
||||
ordering="AFTER"
|
||||
side="BOTH"
|
||||
3
src/main/resources/assets/crusty_chunks/lang/en_us.json
Normal file
3
src/main/resources/assets/crusty_chunks/lang/en_us.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"itemGroup.crusty_chunks.warium": "Warium"
|
||||
}
|
||||
6
src/main/resources/pack.mcmeta
Normal file
6
src/main/resources/pack.mcmeta
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"pack": {
|
||||
"pack_format": 34,
|
||||
"description": "Private internal Warium NeoForge 1.21.1 port pending rights clearance"
|
||||
}
|
||||
}
|
||||
25
tools/check_required_integrations.py
Normal file
25
tools/check_required_integrations.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from warium_source import ROOT
|
||||
|
||||
|
||||
def main() -> None:
|
||||
required_private = [
|
||||
ROOT / "ci" / "required-mods" / "wariumapi-neoforge-1.21.1.jar",
|
||||
ROOT / "ci" / "required-mods" / "wariumvs-neoforge-1.21.1.jar",
|
||||
]
|
||||
missing = [path for path in required_private if not path.exists()]
|
||||
if missing:
|
||||
print("Required private integration jars are not present yet:")
|
||||
for path in missing:
|
||||
print(f"- {path}")
|
||||
print("The built jar includes private compatibility shim mod metadata for wariumapi and wariumvs.")
|
||||
print("Replace the shims with real jars when NeoForge 1.21.1 artifacts are available.")
|
||||
else:
|
||||
print("Required private integration jars are present.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
40
tools/decompile_original.py
Normal file
40
tools/decompile_original.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
from warium_source import BUILD_DIR, ROOT, clean_dir, download_original
|
||||
|
||||
VINEFLOWER_URL = "https://repo1.maven.org/maven2/org/vineflower/vineflower/1.11.1/vineflower-1.11.1.jar"
|
||||
VINEFLOWER_JAR = BUILD_DIR / "vineflower-1.11.1.jar"
|
||||
DECOMPILED_DIR = ROOT / "build" / "decompiled" / "warium-1.2.7"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
original = download_original()
|
||||
BUILD_DIR.mkdir(parents=True, exist_ok=True)
|
||||
if not VINEFLOWER_JAR.exists():
|
||||
request = urllib.request.Request(VINEFLOWER_URL, headers={"User-Agent": "MrSphay/Warium-NeoForge-Port/1.0"})
|
||||
with urllib.request.urlopen(request) as response, VINEFLOWER_JAR.open("wb") as out:
|
||||
shutil.copyfileobj(response, out)
|
||||
clean_dir(DECOMPILED_DIR)
|
||||
subprocess.run(
|
||||
["java", "-jar", str(VINEFLOWER_JAR), str(original), str(DECOMPILED_DIR)],
|
||||
cwd=ROOT,
|
||||
check=True,
|
||||
)
|
||||
report = ROOT / "docs" / "inventory" / "decompile-report.md"
|
||||
report.parent.mkdir(parents=True, exist_ok=True)
|
||||
report.write_text(
|
||||
"# Decompile Report\n\n"
|
||||
f"- Source: `{original}`\n"
|
||||
f"- Output: `{DECOMPILED_DIR}`\n"
|
||||
"- Decompiler: Vineflower 1.11.1\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
141
tools/generate_port_sources.py
Normal file
141
tools/generate_port_sources.py
Normal file
@@ -0,0 +1,141 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
from warium_source import MODID, ROOT, clean_dir, download_original, safe_java_identifier, write_json
|
||||
|
||||
GENERATED_JAVA = ROOT / "src" / "generated" / "java"
|
||||
GENERATED_RESOURCES = ROOT / "src" / "generated" / "resources"
|
||||
INVENTORY_DIR = ROOT / "docs" / "inventory"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
jar = download_original()
|
||||
clean_dir(GENERATED_JAVA)
|
||||
clean_dir(GENERATED_RESOURCES)
|
||||
INVENTORY_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with zipfile.ZipFile(jar) as archive:
|
||||
names = archive.namelist()
|
||||
block_names = sorted(stem(n) for n in names if n.startswith(f"assets/{MODID}/blockstates/") and n.endswith(".json"))
|
||||
item_model_names = sorted(stem(n) for n in names if n.startswith(f"assets/{MODID}/models/item/") and n.endswith(".json"))
|
||||
standalone_items = sorted(name for name in item_model_names if name not in set(block_names))
|
||||
|
||||
extract_resources(archive)
|
||||
|
||||
inventory = {
|
||||
"source": "Warium 1.2.7",
|
||||
"source_sha1": "528d81630a23fb4004e3abdd99b16bd225cd1e92",
|
||||
"modid": MODID,
|
||||
"blocks_from_blockstates": block_names,
|
||||
"standalone_items_from_item_models": standalone_items,
|
||||
"counts": {
|
||||
"blockstates": len(block_names),
|
||||
"item_models": len(item_model_names),
|
||||
"standalone_items": len(standalone_items),
|
||||
"classes": len([n for n in names if n.endswith(".class")]),
|
||||
"procedures": len([n for n in names if n.startswith("net/mcreator/crustychunks/procedures/") and n.endswith(".class")]),
|
||||
"entities": len([n for n in names if n.startswith("net/mcreator/crustychunks/entity/") and n.endswith(".class")]),
|
||||
"recipes": len([n for n in names if n.startswith(f"data/{MODID}/recipes/") and n.endswith(".json")]),
|
||||
"loot_tables": len([n for n in names if n.startswith(f"data/{MODID}/loot_tables/") and n.endswith(".json")]),
|
||||
},
|
||||
}
|
||||
write_json(INVENTORY_DIR / "original-inventory.json", inventory)
|
||||
write_generated_registries(block_names, standalone_items)
|
||||
|
||||
|
||||
def stem(path: str) -> str:
|
||||
return Path(path).name.removesuffix(".json")
|
||||
|
||||
|
||||
def extract_resources(archive: zipfile.ZipFile) -> None:
|
||||
for info in archive.infolist():
|
||||
if info.is_dir():
|
||||
continue
|
||||
name = info.filename
|
||||
if name.startswith(f"assets/{MODID}/"):
|
||||
target = GENERATED_RESOURCES / name
|
||||
elif name.startswith(f"data/{MODID}/"):
|
||||
target = GENERATED_RESOURCES / migrate_data_path(name)
|
||||
elif name == "pack.mcmeta":
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
with archive.open(info) as src, target.open("wb") as dst:
|
||||
shutil.copyfileobj(src, dst)
|
||||
|
||||
|
||||
def migrate_data_path(path: str) -> str:
|
||||
path = path.replace(f"data/{MODID}/loot_tables/", f"data/{MODID}/loot_table/")
|
||||
path = path.replace(f"data/{MODID}/tags/items/", f"data/{MODID}/tags/item/")
|
||||
path = path.replace(f"data/{MODID}/tags/blocks/", f"data/{MODID}/tags/block/")
|
||||
path = path.replace(f"data/{MODID}/tags/entity_types/", f"data/{MODID}/tags/entity_type/")
|
||||
path = path.replace(f"data/{MODID}/tags/fluids/", f"data/{MODID}/tags/fluid/")
|
||||
return path
|
||||
|
||||
|
||||
def write_generated_registries(blocks: list[str], items: list[str]) -> None:
|
||||
package_dir = GENERATED_JAVA / "net" / "mcreator" / "crustychunks" / "init"
|
||||
package_dir.mkdir(parents=True, exist_ok=True)
|
||||
used: set[str] = set()
|
||||
lines: list[str] = [
|
||||
"package net.mcreator.crustychunks.init;",
|
||||
"",
|
||||
"import net.mcreator.crustychunks.CrustyChunksMod;",
|
||||
"import net.minecraft.core.registries.Registries;",
|
||||
"import net.minecraft.network.chat.Component;",
|
||||
"import net.minecraft.world.item.BlockItem;",
|
||||
"import net.minecraft.world.item.CreativeModeTab;",
|
||||
"import net.minecraft.world.item.Item;",
|
||||
"import net.minecraft.world.item.ItemStack;",
|
||||
"import net.minecraft.world.item.Items;",
|
||||
"import net.minecraft.world.level.block.Block;",
|
||||
"import net.minecraft.world.level.block.state.BlockBehaviour;",
|
||||
"import net.neoforged.bus.api.IEventBus;",
|
||||
"import net.neoforged.neoforge.registries.DeferredHolder;",
|
||||
"import net.neoforged.neoforge.registries.DeferredRegister;",
|
||||
"",
|
||||
"public final class GeneratedRegistries {",
|
||||
" public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(Registries.BLOCK, CrustyChunksMod.MODID);",
|
||||
" public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(Registries.ITEM, CrustyChunksMod.MODID);",
|
||||
" public static final DeferredRegister<CreativeModeTab> CREATIVE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, CrustyChunksMod.MODID);",
|
||||
"",
|
||||
]
|
||||
|
||||
for name in blocks:
|
||||
ident = safe_java_identifier(name, used)
|
||||
lines.append(f' public static final DeferredHolder<Block, Block> {ident} = BLOCKS.register("{name}", () -> new Block(BlockBehaviour.Properties.of().strength(2.0F, 6.0F)));')
|
||||
lines.append(f' public static final DeferredHolder<Item, BlockItem> {ident}_ITEM = ITEMS.register("{name}", () -> new BlockItem({ident}.get(), new Item.Properties()));')
|
||||
|
||||
for name in items:
|
||||
ident = safe_java_identifier(name, used)
|
||||
lines.append(f' public static final DeferredHolder<Item, Item> {ident} = ITEMS.register("{name}", () -> new Item(new Item.Properties()));')
|
||||
|
||||
lines.extend([
|
||||
"",
|
||||
' public static final DeferredHolder<CreativeModeTab, CreativeModeTab> WARIUM_TAB = CREATIVE_TABS.register("warium", () -> CreativeModeTab.builder()',
|
||||
' .title(Component.translatable("itemGroup.crusty_chunks.warium"))',
|
||||
" .icon(() -> new ItemStack(Items.IRON_INGOT))",
|
||||
" .displayItems((parameters, output) -> ITEMS.getEntries().forEach(entry -> output.accept(entry.get())))",
|
||||
" .build());",
|
||||
"",
|
||||
" private GeneratedRegistries() {",
|
||||
" }",
|
||||
"",
|
||||
" public static void register(IEventBus modBus) {",
|
||||
" BLOCKS.register(modBus);",
|
||||
" ITEMS.register(modBus);",
|
||||
" CREATIVE_TABS.register(modBus);",
|
||||
" }",
|
||||
"}",
|
||||
"",
|
||||
])
|
||||
(package_dir / "GeneratedRegistries.java").write_text("\n".join(lines), encoding="utf-8")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
50
tools/prepare_runtime_mods.py
Normal file
50
tools/prepare_runtime_mods.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
from warium_source import ROOT
|
||||
|
||||
MODS_DIR = ROOT / "run" / "server" / "mods"
|
||||
|
||||
REQUIRED_MODRINTH = [
|
||||
("geckolib", "4.7.5.1"),
|
||||
("rpl", "2.1.2"),
|
||||
]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
MODS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
for project, version in REQUIRED_MODRINTH:
|
||||
download_modrinth_version(project, version)
|
||||
private_dir = ROOT / "ci" / "required-mods"
|
||||
if private_dir.exists():
|
||||
for jar in private_dir.glob("*.jar"):
|
||||
shutil.copy2(jar, MODS_DIR / jar.name)
|
||||
print(f"Runtime mods prepared in {MODS_DIR}")
|
||||
|
||||
|
||||
def download_modrinth_version(project: str, version_number: str) -> None:
|
||||
encoded_project = urllib.parse.quote(project)
|
||||
loaders = urllib.parse.quote(json.dumps(["neoforge"]))
|
||||
game_versions = urllib.parse.quote(json.dumps(["1.21.1"]))
|
||||
url = f"https://api.modrinth.com/v2/project/{encoded_project}/version?loaders={loaders}&game_versions={game_versions}"
|
||||
request = urllib.request.Request(url, headers={"User-Agent": "MrSphay/Warium-NeoForge-Port/1.0"})
|
||||
with urllib.request.urlopen(request) as response:
|
||||
data = json.loads(response.read().decode("utf-8"))
|
||||
selected = next((entry for entry in data if entry.get("version_number") == version_number), None)
|
||||
if selected is None:
|
||||
available = ", ".join(entry.get("version_number", "?") for entry in data[:10])
|
||||
raise SystemExit(f"No NeoForge 1.21.1 build found for {project} {version_number}. Available: {available}")
|
||||
primary = next((file for file in selected["files"] if file.get("primary")), selected["files"][0])
|
||||
target = MODS_DIR / primary["filename"].replace(" ", "-")
|
||||
request = urllib.request.Request(primary["url"], headers={"User-Agent": "MrSphay/Warium-NeoForge-Port/1.0"})
|
||||
with urllib.request.urlopen(request) as response, target.open("wb") as out:
|
||||
shutil.copyfileobj(response, out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
31
tools/registry_parity.py
Normal file
31
tools/registry_parity.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from warium_source import ROOT
|
||||
|
||||
|
||||
def main() -> None:
|
||||
inventory_path = ROOT / "docs" / "inventory" / "original-inventory.json"
|
||||
generated_source = ROOT / "src" / "generated" / "java" / "net" / "mcreator" / "crustychunks" / "init" / "GeneratedRegistries.java"
|
||||
if not inventory_path.exists() or not generated_source.exists():
|
||||
raise SystemExit("Generated inventory is missing; run generatePortSources first.")
|
||||
inventory = json.loads(inventory_path.read_text(encoding="utf-8"))
|
||||
source = generated_source.read_text(encoding="utf-8")
|
||||
missing_blocks = [name for name in inventory["blocks_from_blockstates"] if f'"{name}"' not in source]
|
||||
missing_items = [name for name in inventory["standalone_items_from_item_models"] if f'"{name}"' not in source]
|
||||
if missing_blocks or missing_items:
|
||||
raise SystemExit(
|
||||
"Registry parity failed: "
|
||||
f"{len(missing_blocks)} blocks missing, {len(missing_items)} standalone items missing"
|
||||
)
|
||||
print(
|
||||
"Registry parity OK: "
|
||||
f"{len(inventory['blocks_from_blockstates'])} blocks and "
|
||||
f"{len(inventory['standalone_items_from_item_models'])} standalone items generated."
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
76
tools/warium_source.py
Normal file
76
tools/warium_source.py
Normal file
@@ -0,0 +1,76 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import shutil
|
||||
import urllib.request
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
BUILD_DIR = ROOT / "build" / "warium-port"
|
||||
ORIGINAL_JAR = BUILD_DIR / "Warium-1.2.7.jar"
|
||||
ORIGINAL_URL = "https://cdn.modrinth.com/data/xgjvEen1/versions/4oIhAhRz/Warium%201.2.7.jar"
|
||||
ORIGINAL_SHA1 = "528d81630a23fb4004e3abdd99b16bd225cd1e92"
|
||||
MODID = "crusty_chunks"
|
||||
|
||||
|
||||
def download_original() -> Path:
|
||||
BUILD_DIR.mkdir(parents=True, exist_ok=True)
|
||||
if not ORIGINAL_JAR.exists() or sha1(ORIGINAL_JAR) != ORIGINAL_SHA1:
|
||||
request = urllib.request.Request(
|
||||
ORIGINAL_URL,
|
||||
headers={"User-Agent": "MrSphay/Warium-NeoForge-Port/1.0"},
|
||||
)
|
||||
with urllib.request.urlopen(request) as response, ORIGINAL_JAR.open("wb") as out:
|
||||
shutil.copyfileobj(response, out)
|
||||
actual = sha1(ORIGINAL_JAR)
|
||||
if actual != ORIGINAL_SHA1:
|
||||
raise SystemExit(f"Original jar SHA1 mismatch: expected {ORIGINAL_SHA1}, got {actual}")
|
||||
return ORIGINAL_JAR
|
||||
|
||||
|
||||
def sha1(path: Path) -> str:
|
||||
digest = hashlib.sha1()
|
||||
with path.open("rb") as handle:
|
||||
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
|
||||
digest.update(chunk)
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def clean_dir(path: Path) -> None:
|
||||
if path.exists():
|
||||
shutil.rmtree(path)
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
def safe_java_identifier(name: str, used: set[str]) -> str:
|
||||
ident = re.sub(r"[^a-zA-Z0-9_]", "_", name).upper()
|
||||
if not ident or ident[0].isdigit():
|
||||
ident = "_" + ident
|
||||
if ident in JAVA_KEYWORDS:
|
||||
ident = ident + "_ENTRY"
|
||||
base = ident
|
||||
suffix = 2
|
||||
while ident in used:
|
||||
ident = f"{base}_{suffix}"
|
||||
suffix += 1
|
||||
used.add(ident)
|
||||
return ident
|
||||
|
||||
|
||||
def write_json(path: Path, data: object) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
JAVA_KEYWORDS = {
|
||||
"ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH", "CHAR",
|
||||
"CLASS", "CONST", "CONTINUE", "DEFAULT", "DO", "DOUBLE", "ELSE", "ENUM",
|
||||
"EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", "GOTO", "IF", "IMPLEMENTS",
|
||||
"IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "NATIVE", "NEW",
|
||||
"PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "SHORT", "STATIC",
|
||||
"STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW", "THROWS",
|
||||
"TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE",
|
||||
}
|
||||
Reference in New Issue
Block a user