diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..92d382f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "public/policy"] + path = public/policy + url = https://git.spbr.net/spacebar/policy.git + branch = main diff --git a/app/app.vue b/app/app.vue index 133b620..5ddc353 100644 --- a/app/app.vue +++ b/app/app.vue @@ -12,14 +12,14 @@ useHead({ }) const title = 'Spacebar Network' -const description = 'Spacebar Network(SPBR) is a extension of Splatfestival Network(SPFN), which aims to be a Nintendo Network recreation primarily with the intention of hosting Splatfests with Splatfestival. (Spacebar is seperate from this purpose, however we are still partnered with Splatfestival.)' +const description = 'Spacebar Network, shortened as "Spacebar", "SPBR", or as our former name "Splatfestival Network", is a Nintendo Network continuation with the goal of providing the best experience possible. Our servers are designed to be: (A) Fast, (B) Stable, (C) Secure, AND MOST IMPORTANTLY:, (D) With functionality as close to Nintendo Network as possible.' useSeoMeta({ title, description, ogTitle: title, ogDescription: description, - twitterCard: 'summary_large_image' + ogImage: 'https://git.spbr.net/spacebar/website/raw/branch/master/public/spbr-coloured.png' }) diff --git a/app/assets/css/main.css b/app/assets/css/main.css index 96ec318..e9e8ba3 100644 --- a/app/assets/css/main.css +++ b/app/assets/css/main.css @@ -4,17 +4,17 @@ @theme static { --font-sans: 'Public Sans', sans-serif; - --color-green-50: #EFFDF5; - --color-green-100: #D9FBE8; - --color-green-200: #B3F5D1; - --color-green-300: #75EDAE; - --color-green-400: #00DC82; - --color-green-500: #00C16A; - --color-green-600: #00A155; - --color-green-700: #007F45; - --color-green-800: #016538; - --color-green-900: #0A5331; - --color-green-950: #052E16; + --color-green-50: #eff6ff; + --color-green-100: #dbeafe; + --color-green-200: #bfdbfe; + --color-green-300: #93c5fd; + --color-green-400: #60a5fa; + --color-green-500: #3b82f6; + --color-green-600: #2563eb; + --color-green-700: #1d4ed8; + --color-green-800: #1e40af; + --color-green-900: #1e3a8a; + --color-green-950: #172554; } body { diff --git a/app/components/TheHeader.vue b/app/components/TheHeader.vue index 98c2a3f..d0c33cb 100644 --- a/app/components/TheHeader.vue +++ b/app/components/TheHeader.vue @@ -13,8 +13,8 @@ diff --git a/app/layouts/default.vue b/app/layouts/default.vue deleted file mode 100644 index 943e053..0000000 --- a/app/layouts/default.vue +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/app/locales/message-en.json b/app/locales/message-en.json index 29a7e97..022790f 100644 --- a/app/locales/message-en.json +++ b/app/locales/message-en.json @@ -1,7 +1,7 @@ { "nav": { "supportedGames": "Supported games", - "errorCodes": "Error Codes", + "errorCodes": "View Policies", "discordServer": "Discord Server", "installSpbr": "Install SPBR", "searchPlaceholder": "Search" @@ -9,7 +9,7 @@ "footer": { "siteMaintained": "Site maintained by Spacebar Network", "developedBy": "Developed by our contributors", - "description": "Spacebar Network (SPBR) is an extension of Splatfestival Network (SPFN), which aims to be a Nintendo Network recreation primarily for hosting Splatfests. Spacebar is separate from this purpose, though we remain partnered with Splatfestival.", + "description": "Spacebar Network, shortened as \"Spacebar\", \"SPBR\", or as our former name \"Splatfestival Network\", is a Nintendo Network continuation with the goal of providing the best experience possible. Our servers are designed to be: (A) Fast, (B) Stable, (C) Secure, AND MOST IMPORTANTLY:, (D) With functionality as close to Nintendo Network as possible.", "copyright": "Spacebar Network. All rights reserved." }, "home": { @@ -68,5 +68,32 @@ "aromaTitle": "Aroma", "aromaDesc": "Hacked" } + }, + "policies": { + "sidebarHeader": "Spacebar Network Policies", + "sidebarSubheader": "Game Rules", + "loading": "Loading...", + "errorText": "Error", + "lastUpdated": "Last updated: " + }, + "guides": { + "header": "Guides", + "errorCodesRedir": "Search Error Codes", + "loading": "Loading...", + "lastUpdated": "Last updated: ", + "docs": { + "sssl": { + "name": "SSSL GUIDE", + "version": "1.0.1", + "date": "2026-06-26", + "md": "> [!NOTE]\n> SSSL does not support the full feature set SPFN has to offer, features such as the Miiverse applet and in game posting are not supported through SSSL and can only be used through the Aroma method. We currently don't have Miiverse fully functional on our servers, but once it is available, users connected through SSSL will only be able to view in game posts, not create them.\n\n### Requirements\n- Wii U\n- An internet connection\n\nIf you have a modded console, it is recommended that you use the Aroma method instead, but if you wish to continue with SSSL anyways, ensure you either disable Pretendo's Inkay if present or make a duplicate environment without the Pretendo Inkay plugin and module. Guides to making a duplicate environment can be found in Step 1 of the Aroma guide. Note that when switching between servers, you will have to disable or reenable SSSL by following this guide again.\n\n### Step 1: Console Configuration\n\nSSSL uses the DNS settings of the console to redirect you to our servers. In order to connect, you must configure your active WiFi connection to use this DNS server.\n\nBoot up your Wii U and log in. Open the `System Settings` app and navigate to `Internet`. In here, select `Connect to the Internet`, press `X` to open your Connection List and select your current internet connection.\n\nSelect `Change Settings`, then navigate to `DNS`. Change it to `Do not auto-obtain` and input the following values:\n\n- Primary DNS: 45.85.147.85\n- Secondary DNS: 1.1.1.1\n\nThe Wii U may automatically format the values you inputted so that, for example, the primary DNS may look like `045.085.147.085`. This is normal and will still work correctly.\n\nThen press confirm and press `B` to save the internet settings. The console will prompt you to perform a connection test, select `Perform Test`. The test should pass. Once this is done, exit the System Settings app by repeatedly pressing `B` to return through the menus. You should now be connected to SPFN.\n\n### Step 2: Creating an Account\n\nSPFN's servers are separate from both Nintendo and Pretendo, so you will need to create a new account to access our services. Once you have exited System Settings, tap on your Mii in the top right corner to open User Settings, then select `Switch User`. Press `+` on your gamepad to create a new account. Follow the process of creating the account. Select no when prompted if you have an NNID. Select a Mii for your account. When asked to create an account, press Link.\n\nBefore continuing, confirm that the agreement references Splatfestival Network. If it does not, you may have configured SSSL incorrectly. Return to step 1 and ensure it is correctly configured. If this doesn't resolve it, contact a SPFN developer through the assistance channel of the [Discord server](https://discord.gg/grMSxZf).\n\nIf it does reference Splatfestival Network, read through the agreement and press `Agree`, then enter your account information.\n\n> [!IMPORTANT]\n> DO NOT REUSE PASSWORDS ACROSS MULTIPLE ACCOUNTS INSIDE OR OUTSIDE OF OUR NETWORK\n\nOnce you have created your account, you will be sent a verification code to your registered email address. It may show up in your spam folder, so look around for it before resending a new one. To enter it, log into your account on your Wii U and it will prompt you for the code. If you are already logged in, press on your Mii in the top left of your gamepad and select Switch User. Then, select your SPFN account to log back in. The prompt should appear.\n\nOpen Splatoon and check that you get the news.\n\nYou are now ready to play on the Splatfestival Network! [Join the Discord](https://discord.gg/grMSxZf) for information about upcoming or active Splatfests and other updates." + }, + "aroma": { + "name": "AROMA GUIDE", + "version": "2.0.1", + "date": "2026-06-26", + "md": "### Requirements\n- Modded Wii U with Aroma\n- SD Card (Preferably 32GB)\n- Computer or other device to access SD Card\n- An internet connection\n\nIn order to follow this guide, you must have a modded Wii U console with the latest version of Aroma. If your console isn't modded, [follow this guide](https://wiiu.hacks.guide/). If your console is modded, check for any Aroma updates with the Aroma Updater and install it if any are found. If you are unable to mod your Wii U, follow the SSSL guide instead.\n\nThis guide will create a duplicate Aroma environment which you can use to connect to our servers. Once set up, you will be able to switch between Pretendo and SPFN by switching which environment you launch into when starting your Wii U.\n\nEnsure that you don't have a default user set before setting up SPFN as it could cause you to log in with the wrong account. To disable it, turn on your Wii U and when it logs in, press your Mii in the top left and scroll down to the option labelled \"Default User\" and disable it.\n\nIf you are currently using Pretendo's DNS servers to connect to Pretendo, disable the DNS server before continuing.\n\n### Step 1: SD Card Preparation\n\nPlug your SD card into your computer and navigate to `SD:/wiiu/environments`\n\nMake a copy of your `aroma` environment folder and rename it to `SPFN` - this will be the environment you use for connecting to our servers.\n\nFor users who previously used Pretendo's Inkay plugin, delete the files `plugins/Inkay-pretendo.wps` and `modules/Inkay-pretendo.wms` from the SPFN environment.\n\n> [!WARNING]\n> **Using both Pretendo and Splatfestival Network plugins on the same environment will cause issues! Please do not do this.**\n\nDownload the plugins and modules found on the [Downloads page](/downloads/) - make sure you enable file name extensions in your file browser and take note of the extension.\n\n- `Inkay-spfn.wps` goes into the `plugins` folder\n- `Inkay-spfn.wms` goes into the `modules` folder\n\nWith these files installed, you can eject your SD card and put it into your Wii U.\n\n### Step 2: Setup on Console\n\nPower on the console and hold `X` on the gamepad to open the Environment Loader.\n\nNavigate using the D-Pad to `SPFN` and press `A` to select. Your console will now load into the environment and connect to our servers.\n\nIn the top left of your screen, you should see a message saying \"Using SPFN\".\n\n> [!WARNING]\n> If you see \"Using Pretendo Network\", DO NOT PROGRESS. Turn off the console and delete the Pretendo plugins as mentioned in step 1.\n\n> [!NOTE]\n> If you do not see the \"Using SPFN\" message, you likely didn't install the plugin correctly. Check the locations of the `Inkay-spfn.wps` and `Inkay-spfn.wms` files.\n\nSPFN's servers are separate from both Nintendo and Pretendo, so you will need to create a new account to access our services. Now that your console is connected to our servers, you should be brought to the accounts page. Press `+` on your gamepad to create a new account. Follow the process of creating the account. Select no when prompted if you have an NNID. Select a Mii for your account. When asked to create an account, press Link.\n\nBefore continuing, confirm that the agreement references Splatfestival Network. If it does not, your plugins aren't set up correctly. Return to step 1 and ensure they are correctly placed.\n\nIf it does reference Splatfestival Network, read through the agreement and press `Agree`, then enter your account information.\n\n> [!IMPORTANT]\n> DO NOT REUSE PASSWORDS ACROSS MULTIPLE ACCOUNTS INSIDE OR OUTSIDE OF OUR NETWORK\n\nOnce you have created your account, you will be sent a verification code to your registered email address. It may show up in your spam folder, so look around for it before resending a new one. To enter it, log into your account on your Wii U and it will prompt you for the code. If you are already logged in, press on your Mii in the top left of your gamepad and select Switch User. Then, select your SPFN account to log back in. The prompt should appear.\n\nOpen Splatoon and check that you get the news.\n\nYou are now ready to play on the Splatfestival Network! [Join the Discord](https://discord.gg/grMSxZf) for information about upcoming or active Splatfests and other updates." + } + } } } \ No newline at end of file diff --git a/app/pages/docs/connect/wiiu/[id].vue b/app/pages/docs/connect/wiiu/[id].vue new file mode 100644 index 0000000..f698ad6 --- /dev/null +++ b/app/pages/docs/connect/wiiu/[id].vue @@ -0,0 +1,424 @@ + + + + + diff --git a/app/pages/docs/policy/[id].vue b/app/pages/docs/policy/[id].vue new file mode 100644 index 0000000..dc50bf1 --- /dev/null +++ b/app/pages/docs/policy/[id].vue @@ -0,0 +1,493 @@ + + + + + diff --git a/bun.lock b/bun.lock index c1aee6b..bf6963a 100644 --- a/bun.lock +++ b/bun.lock @@ -10,8 +10,10 @@ "@nuxt/ui": "^4.10.0", "@nuxt/vite-builder": "^4.5.0", "@primer/octicons": "^19.29.2", + "@types/node": "^26.1.1", "@unhead/ssr": "^3.2.1", "@unhead/vue": "^3.2.1", + "marked-alert": "^2.1.2", "nuxt": "^4.5.0", "tailwindcss": "^4.3.3", }, @@ -616,6 +618,8 @@ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + "@types/node": ["@types/node@26.1.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw=="], + "@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="], "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], @@ -1318,6 +1322,8 @@ "marked": ["marked@17.0.6", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA=="], + "marked-alert": ["marked-alert@2.1.2", "", { "peerDependencies": { "marked": ">=7.0.0" } }, "sha512-EFNRZ08d8L/iEIPLTlQMDjvwIsj03gxWCczYTht6DCiHJIZhMk4NK5gtPY9UqAYb09eV5VGT+jD4lp396E0I+w=="], + "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], @@ -1770,6 +1776,8 @@ "undici": ["undici@8.8.0", "", {}, "sha512-ubshXMXwF3MQIMF1y/WxZdNBnjEKeSg2wF5mcGUtU55YTw34tnVVpKRlLf7ruDXZ5344KokPVX4RBx1wJm64Bw=="], + "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], + "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "^2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], "unhead": ["unhead@3.2.1", "", { "dependencies": { "hookable": "^6.1.1", "unplugin": "^3.3.0" }, "peerDependencies": { "vite": ">=6.4.2" }, "optionalPeers": ["vite"] }, "sha512-Z7VNRf0QJlRZmwA1p5gsnmKYkjnbvV/CXdJAL+VMDmMF+RS2P4FqLouEhBA6WOuKPe3ZZ8EZgX2zQm7ZkAGDPg=="], diff --git a/package.json b/package.json index 37a4ff5..4393c8f 100644 --- a/package.json +++ b/package.json @@ -20,11 +20,13 @@ "@iconify-json/lucide": "^1.2.118", "@iconify-json/simple-icons": "^1.2.91", "@nuxt/ui": "^4.10.0", - "@nuxt/vite-builder": "^4.5.0", + "@nuxt/vite-builder": "^4.5.1", "@primer/octicons": "^19.29.2", - "@unhead/ssr": "^3.2.1", - "@unhead/vue": "^3.2.1", - "nuxt": "^4.5.0", + "@types/node": "^26.1.1", + "@unhead/ssr": "^3.2.3", + "@unhead/vue": "^3.2.3", + "marked-alert": "^2.1.2", + "nuxt": "^4.5.1", "tailwindcss": "^4.3.3" }, "devDependencies": { diff --git a/public/policy b/public/policy new file mode 160000 index 0000000..4a501cf --- /dev/null +++ b/public/policy @@ -0,0 +1 @@ +Subproject commit 4a501cf3f23a0b57bc370cc124c1c55e80bba5f7 diff --git a/server/api/policies.ts b/server/api/policies.ts new file mode 100644 index 0000000..ffd589c --- /dev/null +++ b/server/api/policies.ts @@ -0,0 +1,57 @@ +import fs from 'node:fs' +import path from 'node:path' + +export default defineEventHandler(async () => { + const gameRulesDir = path.resolve(process.cwd(), 'public/policy/game-rules') + + const baseRules = [ + { id: 'general', name: 'General Rules' }, + { id: 'conduct', name: 'Code of Conduct' }, + { id: 'privacy', name: 'Privacy Policy' }, + { id: 'service', name: 'Network Service Agreement' } + ] + + const games: Array<{ id: string, name: string, version: string }> = [] + + try { + if (fs.existsSync(gameRulesDir)) { + const folders = await fs.promises.readdir(gameRulesDir) + + for (const folder of folders) { + const folderPath = path.join(gameRulesDir, folder) + + if (!folderPath.startsWith(gameRulesDir)) { + continue + } + + const stat = await fs.promises.stat(folderPath) + + if (stat.isDirectory()) { + const metadataPath = path.join(folderPath, 'metadata.json') + + if (fs.existsSync(metadataPath)) { + try { + const metaContent = await fs.promises.readFile(metadataPath, 'utf-8') + const parsedMeta = JSON.parse(metaContent) + + games.push({ + id: folder, + name: parsedMeta.name || folder, + version: parsedMeta.version || '1.0.0' + }) + } catch (jsonError) { + console.error(`Malformed metadata.json in ${folder}:`, jsonError) + } + } + } + } + } + } catch (error) { + console.error('Error scanning public policy tree:', error) + } + + return { + baseRules, + games + } +})