Skip to content

bkan0n/genji.pk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

83 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Genji Parkour — Community & Tools (Laravel 12)

Laravel Logo

Laravel PHP Node Build CSS License

Genji Parkour is a community website for Overwatch Genji parkour maps: leaderboards, powerful search, submissions & playtests, newsfeed, statistics/graphs, and a Convertor (OverPy → Workshop) with multilingual support. This repository hosts the Laravel 12 application that serves the UI (dark theme, Tailwind, Blade + per-page JS). The app is API-first by default and can optionally use a local database for specific modules.


✨ Features

  • Leaderboard — XP, tiers, skill ranks, world records, maps made, playtest votes.
  • Maps Search — rich filters (code, creator, name, difficulty, type, mechanics, restrictions, flags).
  • Submit & Playtest — submit maps/records, playtest queue, difficulty pills, custom dropdowns.
  • Newsfeed — announcements, new maps/records, guides, community picks, changelogs.
  • Statistics — charts & insights (difficulty distribution, popularity, time played, rank distribution).
  • Convertor (Beta) — OverPy → Workshop, translation helpers, map-data editor.
  • Multi-language — EN/FR (extensible), language detection & user selection.
  • Discord OAuth — login, navbar avatar, profile/notifications modals.
  • Strict CSPcsp_nonce() for scripts (including CDN), no inline styles.
  • API-first — UI reads from an external API secured. Local DB mode is optional.

🧱 Tech Stack

  • Backend: Laravel 12 (PHP ≥ 8.2), custom middlewares (language, user context, Sentry).
  • Frontend: Blade, modular page-scoped JS, Tailwind CSS, Vite.
  • i18n: resources/lang/{en,fr} + Convertor dictionaries.
  • Data: External API (default). Local DB is optional for persistence-heavy modules.

🚀 Getting Started

1) Requirements

  • PHP ≥ 8.2
  • Composer 2
  • Node ≥ 20 and npm
  • SQLite / MySQL / PostgreSQL (only if you enable local DB mode)

2) Installation

git clone <your-repo-url> genji
cd genji
cp .env.example .env
composer install
npm install
php artisan key:generate

3) Configure .env

Default: API-first (recommended)

APP_NAME="Genji Parkour"
APP_ENV=local
APP_URL=http://genji.test
APP_DEBUG=true

Sessions & cache

SESSION_DRIVER=file CACHE_STORE=file

External API (required)

API_ROOT="https://your.own.api/" # example base URL API_KEY="your-api-key"

Discord OAuth

DISCORD_CLIENT_ID="..." DISCORD_CLIENT_SECRET="..." DISCORD_REDIRECT="${APP_URL}/callback"

Sentry via proxy (optional)

SENTRY_DSN="" SENTRY_ENV="${APP_ENV}"

Localization

FALLBACK_LOCALE=en

In API-first mode, the UI fetches data from the external API (leaderboard, maps, newsfeed, etc.). It’s ideal for quick deployments and avoids heavy SQL on the web server.

Optional: Local Database (hybrid or DB-driven modules)

DB_CONNECTION=pgsql   # or mysql/sqlite
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=genji
DB_USERNAME=genji
DB_PASSWORD=secret
SESSION_DRIVER=database
CACHE_STORE=database

Then run migrations (if present):

php artisan migrate --seed

You can combine API usage and a local DB if some modules need persistence. API-first remains the default for public pages.

4) Run the App

# Dev (Vite + HMR)
npm run dev

Laravel server

php artisan serve

Open: http://127.0.0.1:8000 (or APP_URL).

5) Production Build

npm run build
php artisan optimize

🔐 Security & Content Security Policy (CSP)

  • The project enforces a strict CSP. Always use the nonce from csp_nonce() on scripts (including CDN imports):
@push('head')
  @php($nonce = csp_nonce())
  <script nonce="{{ $nonce }}" src="https://cdn.jsdelivr.net/gh/Zezombye/overpy@master/out/overpy_standalone.js" defer></script>
  <script nonce="{{ $nonce }}" src="https://cdn.jsdelivr.net/npm/diff@5.1.0/dist/diff.min.js" defer></script>
@endpush
  • Avoid inline styles; prefer Tailwind utility classes.
  • Never commit secrets (API keys, Discord credentials, Sentry DSN, etc.).

🌍 Internationalization (i18n)

  • Core translations live in resources/lang/{en,fr}.
  • Convertor & domain dictionaries live in resources/translations and feature files (e.g., resources/lang/en/convertor.php).
  • Language is selected in the navbar; middleware aids detection and persistence via cookie.

🧩 Pages & Scripts Mapping

Page Blade View Page Script Notes
Homeresources/views/index.blade.php(landing logic / optional prism.js)Hero + top maps
Leaderboardresources/views/leaderboard.blade.phpresources/js/pages/leaderboard.jsfilters, ranks, WR
Search / Mapsresources/views/search.blade.phpresources/js/pages/search.jstabs: Search / Completions / Guides / PR
Submit & Playtestresources/views/submit.blade.phpresources/js/pages/submit.jscustom dropdowns, difficulty pills
Statisticsresources/views/statistics.blade.phpresources/js/pages/statistics.jscharts & insights
Newsfeedresources/views/newsfeed.blade.phpresources/js/pages/newsfeed.jstags, community picks, changelogs
Dashboardresources/views/dashboard.blade.phpresources/js/pages/dashboard.jspersonal aggregation
Lootboxresources/views/lootbox.blade.phpresources/js/pages/lootbox.jseffects, rarities, keys
Rank Cardresources/views/rank_card.blade.phpresources/js/pages/rank_card.jsskeleton + render
Convertorresources/views/convertor.blade.phpresources/js/pages/convertor.jsOverPy → Workshop, translations

🔌 API Usage

The UI is API-first. Requests include an API-KEY header and use same-origin credentials when relevant.

async function api(path, opts = {}) {
  const headers = {
    Accept: 'application/json',
    'X-Requested-With': 'XMLHttpRequest',
    'API-KEY': (import.meta.env && import.meta.env.VITE_API_KEY) ?? window.API_KEY,
    ...(opts.headers || {}),
  };

  return fetch(`${window.API_ROOT}${path}`, {
    method: 'GET',
    credentials: 'same-origin',
    ...opts,
    headers,
  }).then((r) => (r.ok ? r.json() : Promise.reject(r)));
}

For POST/PUT/DELETE from Blade pages, also include the CSRF header from the meta tag and the XSRF-TOKEN cookie (Laravel defaults).

🧪 Testing

Add PHPUnit/Pest for backend and Vitest/Playwright for UI as needed. For now, rely on npm run build, php artisan optimize, and visual verification of core pages.

📜 License & Trademarks

  • Code: MIT unless otherwise stated for specific assets.
  • This project is not affiliated with Blizzard Entertainment. Overwatch™ and related marks are the property of their respective owners.

🙏 Acknowledgements

  • Laravel and its community.
  • Tailwind CSS.
  • OverPy by Zezombye (used by the Convertor).
  • All map creators, playtesters, and contributors of the Genji Parkour community.

📬 Support

Open an issue or discussion for bugs and feature requests. For sensitive matters (security, API keys), contact the maintainers privately.

TL;DR

  • API-first by default: set API_ROOT + API_KEY. Local DB is optional.
  • Start: composer installnpm installphp artisan key:generatenpm run dev + php artisan serve.
  • CSP: always use the nonce and avoid inline styles.

About

Genji Parkour Community Website

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •