Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d9fd79e
Add Blueprints catalog tab backed by weblink repo
tastybento Apr 24, 2026
f4fcdde
docs: document Blueprints tab + weblink sync in CLAUDE.md
tastybento Apr 25, 2026
8f2ec28
Add Discord-authenticated blueprint submissions + image serving
tastybento Apr 25, 2026
d85d5f9
Refresh site visuals: paper aesthetic, Landing + Blueprints, Custom +…
tastybento Apr 26, 2026
a0884a2
chore: ignore macOS metadata, runtime data dir, and design bundles
tastybento Apr 26, 2026
9d9f951
Wire the Blueprints upload tile to /submit with file hand-off
tastybento Apr 26, 2026
651db92
Redesign /submit in the navy-paper sub-brand
tastybento Apr 26, 2026
761f57b
Add `yarn prime-cache` script to seed JarCache.sqlite in one shot
tastybento Apr 26, 2026
949f737
Render the actual blueprint in the /submit live preview
tastybento Apr 26, 2026
1bbe8fc
Clear file-derived fields when Replace is clicked on /submit
tastybento Apr 26, 2026
585b2d0
Add admin interface foundation
tastybento Apr 26, 2026
3c2bafb
Build the Admins tab — promote/demote admins by Discord ID
tastybento Apr 26, 2026
aeab34f
Build the Presets tab — reorder and edit homepage presets
tastybento Apr 26, 2026
0866b01
Build the Addons tab — full CRUD plus per-addon version mappings
tastybento Apr 26, 2026
9d30bb9
Add Recent tab — audit log, reset-to-baseline, and Export-PR
tastybento Apr 26, 2026
d6599f8
Refresh landing copy for Minecraft year-based versions
tastybento Apr 26, 2026
df46cc2
Update CLAUDE.md
tastybento Apr 26, 2026
e61fe5a
Update src/web/components/Privacy.tsx
tastybento Apr 26, 2026
f38f5aa
Update src/index.ts
tastybento Apr 26, 2026
db19ffa
Address Copilot PR review
tastybento Apr 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@ yarn-error.log
.idea
.env
env.json
jarcache.sqlite
downloads.sqlite
*.sqlite
*.old*
/.project

# macOS Finder metadata
.DS_Store

# Runtime data (Auth DB, the auto-cloned weblink mirror, etc.)
/data/

# Design hand-off bundles dropped at the repo root
/design_handoff_*/
/BentoBox Download Site*.zip
110 changes: 107 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,30 @@ yarn site # Frontend-only dev rebuild + start server

**Frontend** (`src/web/`):
- React 17 SPA with React Router, styled with Tailwind CSS + twin.macro/styled-components
- Three pages: Presets (`/`), Custom builder (`/custom`), Third-party catalog (`/thirdparty`)
- Pages: Presets (`/`), Custom builder (`/custom`), Third-party catalog (`/thirdparty`), Blueprints (`/blueprints`), Submit (`/submit`), Account (`/account`), Terms (`/terms`), Privacy (`/privacy`)
- Components in `src/web/components/`, API calls via `src/web/ApiRequestManager.ts` using SWR

**Configuration files** (project root, read at runtime from `../` relative to `dist/`):
- `config.json` — addon and preset definitions (the primary data source for all addons)
- `thirdparty.json` — third-party addon registry
- `env.json` (optional, from `env.example.json`) — GitHub token, Discord webhook, port settings
- `env.json` (optional, from `env.example.json`) — GitHub token, Discord webhook, port settings, optional `weblink` block (url/path/branch) for the blueprint sync
- `Installation-Guide.txt` — bundled in generated ZIP files

**Blueprint catalog** (`src/api/weblink.ts`, `src/api/blueprintCatalog.ts`):
- `WeblinkSync` shallow-clones `BentoBoxWorld/weblink` into `data/weblink/` on startup and `git pull --ff-only`s it on the same 6-minute cron used for addon refresh. Default branch is `master`.
- `buildCatalog()` scans `weblink/blueprints/<gameMode>/`, parses `.blueprint` files and bundle `.json` files (per BentoBox's `blueprint.schema.json` / `blueprint-bundle.schema.json`), and derives stats: dimensions, block-type counts, entity-type counts, air count, biome list, sinking flag.
- The optional `blueprints/catalog.json` overlay in weblink supplies curation fields (`displayName`, `description`, `author`, `authorLink`, `tags`, `license`, `image`) plus tag colours and game-mode display names; overlay fields take precedence over what is in the `.blueprint` file.
- Images live at `weblink/blueprints/images/<gameMode>/<name>.png` (recommended 800×450, with optional `<name>.thumb.png` at 400×225). The catalog auto-detects them at sync time when the overlay does not specify `image`. The Express handler at `src/index.ts` serves them under `/blueprints/images/...` with a path-traversal guard and PNG-only whitelist.
- Endpoints: `GET /api/blueprints` (full catalog), `GET /api/blueprints/download?id=<gameMode>/<name>&type=blueprint|bundle` (single file), `GET /api/blueprints/zip?ids=[...]|gameMode=<gm>` (multi-select or whole-game-mode zip). IDs are validated against a strict regex and resolved paths are checked against the blueprints root before any read.

**Auth + submissions** (`src/api/auth.ts`, `src/api/submissions.ts`, `src/api/models/auth.ts`):
- Discord OAuth (server-side authorization-code flow, `identify` scope only). Sessions stored in `data/Auth.sqlite` via Sequelize (`User`, `Session`, `Submission` tables). Session cookie is HttpOnly, `SameSite=Lax`, `Secure` in production, and carries an opaque server-generated session id. 30-day TTL, max 5 concurrent sessions per user, daily prune cron.
- CSRF: per-session token returned by `GET /api/me`, required as `X-Csrf-Token` on every POST.
- Rate limits: 30 OAuth callbacks/min/IP; 3 submissions/hour, 10/day per Discord user.
- `POST /api/blueprints/submit` accepts a multipart upload (max 5 MB), JSON-parses, ajv-validates against `src/api/schemas/blueprint.schema.json` (vendored from `bentobox/`), runs `validateBlueprintSubmission` (rejects command-block materials and opaque `inventory` payloads), checks slug collision against the local clone, then opens a PR on `BentoBoxWorld/weblink` via Octokit using `env.weblink_github_token` — branch `submit/<discordId>/<slug>-<ts>` with two file commits (the `.blueprint` and the patched `catalog.json`).
- Helmet config in `src/index.ts` is the canonical CSP — Discord OAuth navigation works without an explicit allowlist because helmet's CSP does not constrain top-level navigation.
- `env.json` keys: `discord_client_id`, `discord_client_secret`, `discord_redirect_uri`, `weblink_github_token` (fine-grained PAT scoped to `BentoBoxWorld/weblink` with `contents: write` + `pull-requests: write`).

## Key Patterns

- All addon metadata is configuration-driven via `config.json`; adding an addon means editing that file
Expand All @@ -49,4 +64,93 @@ yarn site # Frontend-only dev rebuild + start server

## CI

GitHub Actions (`.github/workflows/build.yml`) runs on push/PR to `develop`: tests Node.js 12.x/14.x/16.x with `yarn && yarn add sqlite3 && yarn build`.
GitHub Actions (`.github/workflows/build.yml`) runs on push/PR to `develop`: tests Node.js 20.x/22.x with `yarn && yarn add sqlite3 && yarn build`.

## Dependency Source Lookup

When you need to inspect source code for a dependency (e.g., BentoBox, addons):

1. **Check local Maven repo first**: `~/.m2/repository/` — sources jars are named `*-sources.jar`
2. **Check the workspace**: Look for sibling directories or Git submodules that may contain the dependency as a local project (e.g., `../bentoBox`, `../addon-*`)
3. **Check Maven local cache for already-extracted sources** before downloading anything
4. Only download a jar or fetch from the internet if the above steps yield nothing useful

Prefer reading `.java` source files directly from a local Git clone over decompiling or extracting a jar.

In general, the latest version of BentoBox should be targeted.

## Project Layout

Related projects are checked out as siblings under `~/git/`:

**Core:**
- `bentobox/` — core BentoBox framework

**Game modes:**
- `addon-acidisland/` — AcidIsland game mode
- `addon-bskyblock/` — BSkyBlock game mode
- `Boxed/` — Boxed game mode (expandable box area)
- `CaveBlock/` — CaveBlock game mode
- `OneBlock/` — AOneBlock game mode
- `SkyGrid/` — SkyGrid game mode
- `RaftMode/` — Raft survival game mode
- `StrangerRealms/` — StrangerRealms game mode
- `Brix/` — plot game mode
- `parkour/` — Parkour game mode
- `poseidon/` — Poseidon game mode
- `gg/` — gg game mode

**Addons:**
- `addon-level/` — island level calculation
- `addon-challenges/` — challenges system
- `addon-welcomewarpsigns/` — warp signs
- `addon-limits/` — block/entity limits
- `addon-invSwitcher/` / `invSwitcher/` — inventory switcher
- `addon-biomes/` / `Biomes/` — biomes management
- `Bank/` — island bank
- `Border/` — world border for islands
- `Chat/` — island chat
- `CheckMeOut/` — island submission/voting
- `ControlPanel/` — game mode control panel
- `Converter/` — ASkyBlock to BSkyBlock converter
- `DimensionalTrees/` — dimension-specific trees
- `discordwebhook/` — Discord integration
- `Downloads/` — BentoBox downloads site
- `DragonFights/` — per-island ender dragon fights
- `ExtraMobs/` — additional mob spawning rules
- `FarmersDance/` — twerking crop growth
- `GravityFlux/` — gravity addon
- `Greenhouses-addon/` — greenhouse biomes
- `IslandFly/` — island flight permission
- `IslandRankup/` — island rankup system
- `Likes/` — island likes/dislikes
- `Limits/` — block/entity limits
- `lost-sheep/` — lost sheep adventure
- `MagicCobblestoneGenerator/` — custom cobblestone generator
- `PortalStart/` — portal-based island start
- `pp/` — pp addon
- `Regionerator/` — region management
- `Residence/` — residence addon
- `TopBlock/` — top ten for OneBlock
- `TwerkingForTrees/` — twerking tree growth
- `Upgrades/` — island upgrades (Vault)
- `Visit/` — island visiting
- `weblink/` — data repo (blueprints, challenges, MCG configs, addon downloads matrix); the Downloads server clones a copy of this for the Blueprints tab
- `CrowdBound/` — CrowdBound addon

**Data packs:**
- `BoxedDataPack/` — advancement datapack for Boxed

**Documentation & tools:**
- `docs/` — main documentation site
- `docs-chinese/` — Chinese documentation
- `docs-french/` — French documentation
- `BentoBoxWorld.github.io/` — GitHub Pages site
- `website/` — website
- `translation-tool/` — translation tool

Check these for source before any network fetch.

## Key Dependencies (source locations)

- `world.bentobox:bentobox` → `~/git/bentobox/src/`
18 changes: 17 additions & 1 deletion env.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,21 @@
"github_token": "ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"github_downloads": 2,
"discord_error_webhook_url": "/api/webhooks/xxxxxxxxxxxxxxxxxxxxxxxxxxx",
"port": 8080
"port": 8080,
"weblink": {
"url": "https://github.com/BentoBoxWorld/weblink.git",
"path": "./../data/weblink",
"branch": "master"
},
"discord_client_id": "0000000000000000000",
"discord_client_secret": "REPLACE_ME",
"discord_redirect_uri": "https://download.bentobox.world/api/auth/discord/callback",
"weblink_github_token": "github_pat_REPLACE_ME",
"admin_discord_ids": ["REPLACE_WITH_DISCORD_USER_ID"],
"admin_github": {
"owner": "BentoBoxWorld",
"repo": "Downloads",
"branch": "develop",
"token": "github_pat_REPLACE_ME"
}
}
13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"build": "tsc --project tsconfig.compile.json && webpack --config webpack.config.cjs --env env=production",
"start": "cd dist && node index.js",
"dev": "yarn clean && tsc --project tsconfig.compile.json && webpack --config webpack.config.cjs --env env=development && yarn start",
"site": "webpack --config webpack.config.cjs --env env=development && yarn start"
"site": "webpack --config webpack.config.cjs --env env=development && yarn start",
"prime-cache": "cd dist && node scripts/prime-cache.js"
},
"keywords": [],
"author": "Fredthedoggy",
Expand All @@ -25,20 +26,25 @@
"@octokit/plugin-throttling": "^3.5.1",
"@tailwindcss/custom-forms": "^0.2.1",
"@types/archiver": "^5.1.1",
"@types/express": "^4.17.13",
"@types/cookie-parser": "^1.4.10",
"@types/express": "^4.17.21",
"@types/jenkins": "^0.23.2",
"@types/mime-types": "^2.1.0",
"@types/node-cron": "^2.0.4",
"@types/react-router-dom": "^5.1.8",
"@types/styled-components": "^5.1.11",
"ajv": "^8.20.0",
"ajv-formats": "^3.0.1",
"archiver": "^5.3.0",
"axios": "^0.21.1",
"clean-webpack-plugin": "^4.0.0-alpha.0",
"cookie-parser": "^1.4.7",
"copy-webpack-plugin": "^9.0.1",
"express": "^4.17.1",
"helmet": "^4.6.0",
"jenkins": "^0.28.1",
"mime-types": "^2.1.31",
"multer": "^2.1.1",
"node-cron": "^3.0.0",
"octokit": "^1.1.0",
"react": "^17.0.2",
Expand All @@ -50,7 +56,7 @@
"remark-breaks": "^2.0.2",
"sequelize": "^6.6.5",
"source-map-loader": "^3.0.0",
"sqlite3": "^5.0.2",
"sqlite3": "^6.0.1",
"styled-components": "^5.3.0",
"swr": "^0.5.6",
"tailwind": "^4.0.0",
Expand All @@ -64,6 +70,7 @@
"@babel/preset-react": "^7.13.13",
"@babel/preset-typescript": "^7.13.0",
"@babel/runtime": "^7.13.16",
"@types/multer": "^2.1.0",
"@types/react": "^17.0.15",
"@types/react-dom": "^17.0.3",
"@typescript-eslint/eslint-plugin": "^4.28.5",
Expand Down
Loading
Loading