Bootstrap Warium NeoForge port scaffold
Some checks failed
Build / build (push) Failing after 13m38s
Release Dry Run / release-dry-run (push) Successful in 5s
Codex Template Compliance / template-compliance (push) Successful in 5s

This commit is contained in:
Codex
2026-05-09 20:59:05 +02:00
commit 6ef5fdd378
36 changed files with 3073 additions and 0 deletions

76
.codex/project.md Normal file
View 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
View 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}"

View 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

View 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

View 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

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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"
}
}
}

View File

@@ -0,0 +1 @@

43
docs/agent-handoff.md Normal file
View 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.

View 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
View 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
View 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
View 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
View 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

Binary file not shown.

View 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
View 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
View 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
View 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'

View 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);
}
}

View 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"

View File

@@ -0,0 +1,3 @@
{
"itemGroup.crusty_chunks.warium": "Warium"
}

View File

@@ -0,0 +1,6 @@
{
"pack": {
"pack_format": 34,
"description": "Private internal Warium NeoForge 1.21.1 port pending rights clearance"
}
}

View 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()

View 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()

View 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()

View 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
View 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
View 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",
}