feat: move to monorepo and update copyright

This commit is contained in:
dvelo 2025-02-13 21:41:10 -06:00
parent 7e7c1a8648
commit 38c10ff5cf
273 changed files with 3343 additions and 38402 deletions

@ -1,8 +0,0 @@
{
"extends": ["next/core-web-vitals"],
"rules": {
"react-hooks/exhaustive-deps": "off",
"react/no-unescaped-entities": "off",
"react/display-name": "off"
}
}

62
.gitignore vendored

@ -1,48 +1,38 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
# Dependencies
node_modules
.pnp
.pnp.js
.yarn/install-state.gz
# Local env files
.env
apps/www/.env.local
.env.development.local
.env.test.local
.env.production.local
# Testing
coverage
# Turbo
.turbo
# contentlayer
.contentlayer
# Vercel
.vercel
# cron
/cron/dist
/cron/node_modules
# Build Outputs
.next/
out/
build
dist
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
css-obfuscator
*.sync-conflict*
# Misc
.DS_Store
*.pem

16
.idea/.gitignore generated vendored

@ -1,8 +1,8 @@
# Ignore everything for IntelliJ except for project essential code-styles
*
!copyright/*
!codeStyles/*
!.gitignore
!*/
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

12
.idea/MHSF-Modern.iml generated Normal file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -1,7 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JSCodeStyleSettings version="0">
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</JSCodeStyleSettings>
</code_scheme>
</component>

@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

@ -1,6 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="MHSF, Minehut Server List&#10;All external content is rather licensed under the ECA Agreement&#10;located here: https://mhsf.app/docs/legal/external-content-agreement&#10;&#10;All code under MHSF is licensed under the MIT License&#10;by open source contributors&#10;&#10;Copyright (c) 2024 dvelo&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy &#10;of this software and associated documentation files (the &quot;Software&quot;), to &#10;deal in the Software without restriction, including without limitation the&#10;rights to use, copy, modify, merge, publish, distribute, sublicense, and/or &#10;sell copies of the Software, and to permit persons to whom the Software is &#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in all &#10;copies or substantial portions of the Software.&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, &#10;EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES &#10;OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND &#10;NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT &#10;HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, &#10;WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING &#10;FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR &#10;OTHER DEALINGS IN THE SOFTWARE." />
<option name="notice" value="MHSF, Minehut Server List&#10;All external content is rather licensed under the ECA Agreement&#10;located here: https://mhsf.app/docs/legal/external-content-agreement&#10;&#10;All code under MHSF is licensed under the MIT License&#10;by open source contributors&#10;&#10;Copyright (c) 2025 dvelo&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy &#10;of this software and associated documentation files (the &quot;Software&quot;), to &#10;deal in the Software without restriction, including without limitation the&#10;rights to use, copy, modify, merge, publish, distribute, sublicense, and/or &#10;sell copies of the Software, and to permit persons to whom the Software is &#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in all &#10;copies or substantial portions of the Software.&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, &#10;EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES &#10;OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND &#10;NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT &#10;HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, &#10;WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING &#10;FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR &#10;OTHER DEALINGS IN THE SOFTWARE." />
<option name="myName" value="MIT License f/ MHSF" />
</copyright>
</component>

@ -1,3 +1,7 @@
<component name="CopyrightManager">
<settings default="MIT License f/ MHSF" />
<settings>
<module2copyright>
<element module="All" copyright="MIT License f/ MHSF" />
</module2copyright>
</settings>
</component>

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

8
.idea/modules.xml generated Normal file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/MHSF-Modern.iml" filepath="$PROJECT_DIR$/.idea/MHSF-Modern.iml" />
</modules>
</component>
</project>

7
.idea/vcs.xml generated Normal file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/apps/www" vcs="Git" />
</component>
</project>

0
.npmrc Normal file

@ -1 +0,0 @@
nodejs 23.3.0

@ -1,2 +0,0 @@
backend-mh-api/
cron/

@ -1,3 +1,3 @@
{
"copyright-header-injector.copyrightText": "/*\n * MHSF, Minehut Server List\n * All external content is rather licensed under the ECA Agreement\n * located here: https://mhsf.app/docs/legal/external-content-agreement\n *\n * All code under MHSF is licensed under the MIT License\n * by open source contributors\n *\n * Copyright (c) 2024 dvelo\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */"
"copyright-header-injector.copyrightText": "/*\n * MHSF, Minehut Server List\n * All external content is rather licensed under the ECA Agreement\n * located here: https://mhsf.app/docs/legal/external-content-agreement\n *\n * All code under MHSF is licensed under the MIT License\n * by open source contributors\n *\n * Copyright (c) 2025 dvelo\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */"
}

21
LICENSE

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2024 dvelo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,27 +0,0 @@
import * as express from "express";
import { config } from "dotenv";
config();
const app = express();
app.get("/", (req, res) => {
res.send({ status: "up" });
});
app.get("/servers", (req, res) => {
if (
req.headers.Authentication !==
`MHSF-Backend-Server ${process.env.MHSF_SECRET}`
)
res.status(401).send({ error: "Unauthorized" });
else
fetch("https://api.minehut.com/servers").then((c) => {
c.json().then((v) => {
res.send(v);
});
});
});
app.listen(6080, () => {
console.log("Backend API listening on port 6080");
});

@ -1,18 +0,0 @@
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"linter": {
"rules": {
"style": {
"useTemplate": "off",
"useImportType": "warn"
},
"suspicious": {
"noExplicitAny": "off",
"noDoubleEquals": "warn"
},
"complexity": {
"noForEach": "off"
}
}
}
}

@ -1,17 +0,0 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}

@ -1,84 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import { defineDocumentType, makeSource } from "contentlayer/source-files";
import rehypeSlug from "rehype-slug";
import GithubSlugger from "github-slugger";
export const Docs = defineDocumentType(() => ({
name: "Docs",
filePathPattern: `**/*.mdx`,
contentType: "mdx",
fields: {
title: {
type: "string",
required: true,
},
folder: {
type: "string",
required: false,
},
lastUpdated: {
type: "string",
required: false,
},
},
computedFields: {
url: {
type: "string",
resolve: (docs) => `/docs/${docs._raw.flattenedPath}`,
},
toc: {
type: "json",
resolve: async (doc) => {
const headingsRegex = /\n(?<flag>#{1,6})\s+(?<content>.+)/g;
const slugger = new GithubSlugger();
const headings = Array.from(doc.body.raw.matchAll(headingsRegex)).map(
({ groups }) => {
const flag = groups?.flag;
const content = groups?.content;
return {
level: flag.length,
text: content,
slug: content ? slugger.slug(content) : undefined,
};
},
);
return headings;
},
},
},
}));
export default makeSource({
contentDirPath: "docs",
documentTypes: [Docs],
mdx: { rehypePlugins: [rehypeSlug] },
});

@ -1,34 +0,0 @@
---
title: "Achievement Collection"
folder: "Advanced"
---
import { formalNames } from "@/config/achievements"
# Achievements
Achievements are a page that every server gets which contains certain requirements which could be embedded in an servers history.
<Separator/>
These achievements are accessable using the "Achievements" tab on the left of any server page.
Achievements are *not* collected instantly, and are collected every 12 hours when the server is online (this is not timezone dependent).
There are currently {Object.keys(formalNames).length} possible achievements to get, ranging from easiest to hardest.
## 1 thousand favorites achievement
After getting 1 thousand favorites on MHSF, and your server is online during the achievement collection, *you will get this achievement showing* when you got **1,000 users to favorite your server**.
<AchievementPreview title="has1kFavorites"/>
## 1 thousand total joins achievement
After getting 1 thousand total joins on Minehut, and your server is online during the achievement collection, *you will get this achievement showing* when you got **1,000 users to join your server**.
<br/> Here is a preview:
<AchievementPreview title="has1kTotalJoins"/>
## 100 thousand favorites achievement
After getting 100 thousand favorites on MHSF, and your server is online during the achievement collection, *you will get this achievement showing* when you got **100 thousand users to favorite your server**.
<br/> Here is a preview:
<AchievementPreview title="has100kFavorites"/>
## 100 thousand total joins achievement
After getting 100 thousand total joins on Minehut, and your server is online during the achievement collection, *you will get this achievement showing* when you got **100 thousand users to join your server**.
<br/> Here is a preview:
<AchievementPreview title="has100kTotalJoins"/>

@ -1,35 +0,0 @@
---
title: "Using the Command-bar"
folder: "Advanced"
---
# Using the Command-bar
The command-bar has many mods and is a great tool for power-users to use as its built to be fast, while showing optimal information to the scenario
<Separator />
## Triggering the command-bar
There are two ways to trigger the command bar, using `Ctrl+K` and <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>K</kbd>. Both put you in a command-bar, however when using `Ctrl+K`, you go into a general page with other settings.
Using <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>K</kbd> opens a server viewer, and this may be faster then going through the general page.
## Functions using Ctrl+K
- **Servers** opens a server list, same as <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>K</kbd>
- **Sort Servers** allows you to go into a sorted server list quickly
- **Links** shows links useful for MHSF
- **Pick Random Server** picks a random server and shows the user what that server is, is similar to the one on [the server list](/)
<br /> <br />
**Profile (requires log-in):**
- **Favorites** shows the user their favorited servers
- **User Settings** shows the user the settings for Clerk
## Servers
This view shows the most popular 50 servers, and when searching, you can search for any server that exists (offline or online).
When clicking on a server, you see a simple view showing information about the server, along with a link to the server page.
## Trigger from information popover
Click the top-right info button, and click Open Commands. This will open the same `Ctrl+K` command-bar, if you would like to use it on mobile.

@ -1,94 +0,0 @@
---
title: "Troubleshooting: Making external servers on Minehut"
folder: "Advanced"
---
# External Servers on Minehut
I think creating external servers on Minehut is an advanced subject, and it is not documented well enough for the circumstances that
might occur with server owners. This is a [extension/rephrasing of the offical wiki guide](Wiki:External). All points in **bold** are things you shouldn't miss, and are commonly misread.
<br/>
<Separator/>
_Note: This is an unoffical guide, but the offical way of connecting! This is safe!_
## Getting started
You must pick a host that allows the following when making external servers:
- **Editing server flags** Editing flags for the server to run is essential. There are many cases where you were not able to continue because your provider was resetting your flags back
- **A supported server software** For standalone servers, you must run on [Paper](https://papermc.io/software/paper). For proxy networks, you can use [Velocity](https://velocitypowered.com/), [Waterfall](https://papermc.io/software/waterfall) & [Lilypad](https://www.lilypadmc.org/). **BungeeCord is not supported by any means!**
Minehut offically recommends Velocity, which you can find instructions [here](https://docs.papermc.io/velocity/getting-started) to get going! If you do not wish to use a proxy, using Paper is recommended, which you can find a guide [here](https://docs.papermc.io/paper/getting-started).
Before doing below, **make sure your proxy _actually works!_**
## Changing flags
To ensure that Minehut can properly connect your players to your server, you need to add flags when booting up your server. These are commonly in `start.bat` or `start.sh` for Linux-based hosts. **Players cannot join your server from Minehut without adding these flags!**
### Velocity
Add the following `sessionserver` flag to your start script:
```
-Dmojang.sessionserver=https://api.minehut.com/mitm/proxy/session/minecraft/hasJoined
```
All flags put together should look like the following:
```
java -Dmojang.sessionserver=https://api.minehut.com/mitm/proxy/session/minecraft/hasJoined -jar velocity.jar
```
### Paper - standalone
Like said above, if you run a proxy, add the flags for Velocity. **Adding both the Velocity (or any other proxy server) & Paper flags will cause your server to be unauthenticatable!** <br/>
Add the following `auth.host`, `account.host`, `services.host` & `session.host` flags:
```
-Dminecraft.api.auth.host=https://authserver.mojang.com/
-Dminecraft.api.account.host=https://api.mojang.com/
-Dminecraft.api.services.host=https://api.minecraftservices.com/
-Dminecraft.api.session.host=https://api.minehut.com/mitm/proxy
```
All the script together
```
java -Dminecraft.api.auth.host=https://authserver.mojang.com/ -Dminecraft.api.account.host=https://api.mojang.com/ -Dminecraft.api.services.host=https://api.minecraftservices.com/ -Dminecraft.api.session.host=https://api.minehut.com/mitm/proxy -jar paper.jar
```
**Along with this,** make sure to set the `enforce-secure-profile` flag in the `server.properties` file to `false`.
```
enable-status=true
# Set this to false!
enforce-secure-profile=false
enforce-whitelist=false
```
### Lilypad
Set the following environment variable `LILYPAD_MOJANG_SESSIONSERVER_URL` to `https://api.minehut.com/mitm/proxy/session/minecraft/hasJoined`. Environment variables are set as a seperate command in the start script:
```
LILYPAD_MOJANG_SESSIONSERVER_URL="https://api.minehut.com/mitm/proxy/session/minecraft/hasJoined"
```
If above doesn't work, try this:
```
export LILYPAD_MOJANG_SESSIONSERVER_URL="https://api.minehut.com/mitm/proxy/session/minecraft/hasJoined"
```
## Enable Proxy Protocol
_Note: Skip this step if you're using [TCPShield](https://tcpshield.com/) for DDoS protection._
Enable proxy protocol in your proxy's configuration file:
### Velocity
In `velocity.toml` under advanced, set
```
haproxy-protocol = true
```
### Waterfall
In `config.yml` under listeners, set
```
proxy_protocol: true
```
### Paper
In `config/paper-global.yml` under proxies, set
```
proxy-protocol: true
```
## Thats it!
After this, there are mostly no more common issues. Continue on [the wiki](Wiki:External#Connect_Your_External_Server_Plan_on_Minehut)!
## Have any issues?
Go to the offical <Discord/> Minehut Discord server and go into the [#ask-for-help](https://discord.com/channels/239599059415859200/1014801630295760897) channel and create a thread.

@ -1,24 +0,0 @@
---
title: "Tech-stack"
folder: "Advanced"
---
# Teck Stack of MHSF
The tech stack of MHSF is relatively modern to ensure MHSF keeps up with standards set for accessibility and usability.
## Front-end
- **React** is used as a way to replicate components already used, and use the eco-system of pre-existing components
- **shadcn/ui** is the UI framework used to keep the whole website consistent.
- **Contentlayer** manages all the pages used for documentation
- **TailwindCSS** makes MHSF use (mostly) no CSS for better efficency
- **Sonner** provides the Toast used for MHSF
## Back-end
- **Inngest** runs periodic tasks
- **MongoDB** is the database of choice for MHSF
## Both
- **Clerk** is used for authentication of users
- **Next.js** is used to make sure API endpoints and front-end endpoints are on the same domain, along with lots of convient features
- **Vercel** is hosting MHSF (along with non-tracking analytics)

@ -1,31 +0,0 @@
---
title: "Getting Started"
---
# Getting Started to MHSF
MHSF is an open-source wrapper for the traditional Minehut server list, either in the lobby or the one [built-in to the minehut.com website directly](https://app.minehut.com/servers).
The way MHSF communicates with Minehut is using the closed Minehut API discovered by using DevTools on the original Minehut page.
Along with this, there are entries that are completely third-party like for adding descriptions or banners.
## What is a wrapper?
Wrappers are usually free & open-source software that goes on-top of existing software that may be proprietary. There are many reasons for a wrapper to exist (privacy, automation, etc.), in MHSF's case, its because the Minehut server list provided by default just doesn't cut it.
Wrappers usually communicate using an API that was provided by the service its self, making software like MHSF completely legal.
## Why to use MHSF
- **Faster response times** MHSF is completely ad-free, and as a result of being open-source, constantly tries to cut down on unnecessary things slowing down the page.
- **Open-source & no tracking** As a result of being open-source, MHSF will never track or sell your data to advertisers. Anybody can look at the code, and can be verified to be completely secure.
- **Make your server stand out** Server owners can configure after appropriate verification banners, Discord widgets, descriptions & color schemes.
- **Customize your experience** Filters, sorts & different spacing settings can make your experience just how you like it while you are browsing servers.
- **Better & more intuitive UX/UI** UI is a big point for MHSF, using UI designed to be more user friendly, and to be more straight-forward then Minehut's
- **One focus** Because MHSF is only a server-list, it only has to be, _a server list!_ This means more updates and higher quality ones because all MHSF has to worry about, is the server list!
## Will you get banned for this?
No. Your Minehut account is not associated with your MHSF one, and consequently, you cannot be banned. There is no risk of getting banned by Minehut, as we are posing no threat to them. As long as you aren't spamming MHSF (or the API in general), you should be good.
## Conclusion
If you'd like to use MHSF, go to the server list [here](Special:Root) to try it out! You may also give MHSF a star on GitHub if you feel like this project deserves it.

@ -1,26 +0,0 @@
---
title: "Customization"
folder: "Guides"
---
# Customize your server
Customizing your server is very easy after you have [linked your account](Docs:guides/linking). Make sure you have done that before then.
## Getting started
Make sure you've also [owned your server](Docs:guides/owning-a-server).
## Customization Types
### Discord Server
Enable the server widget in your Discord server settings, and copy and paste in the Discord server ID, and your Discord server will appear!
### Banner
Your server must have an image from [Imgur](https://imgur.com), and can be any image type that can be rendered on the web. Copy and paste the link (not the link after uploading the image, but by right clicking and hitting "Copy Image Address") into the input box!
### Color Scheme
You can pick any color in the box and choosing a color scheme to show on your server specificly.
### Description
You can use Markdown formatting to add a description to describe what your server is.
## Thats it!
If you have additional customization types or other things you'd like us to add, [feel free to hit us with an issue on GitHub!](Special:GitHub)

@ -1,29 +0,0 @@
---
title: "Linking your account"
folder: "Guides"
---
# Linking your Minecraft account
MHSF uses a safe & secure system to link your account that **doesn't use your Microsoft account in any way**. MHSF uses a simple system of logging into a server, and then putting a code into the website.
<Separator />
## Prerequisites
- An active account with MHSF (either linked through GitHub or Discord, or just a standard email account)
- A Minecraft Java Edition account (Bedrock accounts are not guaranteed to work, and could malfunction at some times)
## Linking
To get started, go into your account settings (your profile picture in top-right, and Profile & Security) and click Link Account.
Login to the server `MHSFPV.minehut.gg`. (its on a free plan, you may have to start it in the lobby) Take the code shown in chat, and put it into the OTP box. Hit Submit, and if the code is correct, your account will be linked! Congratulations!
## Functions
You can do many things with a linked account:
- [Own a server](Docs:guides/owning-a-server)
- [Customize a server](Docs:guides/customization)
More will be coming in future updates, however the only thing you can do with a linked account is server-based functions.

@ -1,21 +0,0 @@
---
title: "Own a server"
folder: "Guides"
---
# Owning a server
Owning a server is quite simple and allows you to [customize your server](/docs/guides/customization) and make it stand out from other servers. Before owning your server, make sure you agree to the [ECA](Docs:legal/external-content-agreement).
## Linking
Find the server you would like to own (either by looking for it, or using the keyboard shortcut <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>K</kbd> and searching for it), and make sure your account has [already been linked with your Minecraft account](Docs:guides/linking). Go to the server, and hit the Customization tab. If the owner of the server, and the user your linked to match, you will gain access to the server.
If they match, you should see a button named Click to own. Press that button, and you should automagically own the server. Congratulations!
## I can't link my server, because my server doesn't have a author
Your server must have an author in-order to be automagically linked, and if it doesn't have an author, that means you will have to manually link your server. To do that, make an issue on GitHub, showing that your server has no author, but needs to be linked. Show proof that you own the server, along with your account username, and your account will own the server you need.
## There is an error while linking my server!
This most likely is because the Minehut API is blocking the server-side request to verify your the owner of that server, or your server [has no author](#i-cant-link-my-server-because-my-server-doesnt-have-a-author).
Try again in 30 minute intervals, or just make an issue on GitHub to link your server.

@ -1,13 +0,0 @@
---
title: "Reporting a server"
folder: "Guides"
---
# Reporting a server
If you believe a server that you've seen is under breach of the [ECA Agreement](Docs:legal/external-content-agreement), you may request the server in question to be taken down.
Make sure you are logged into a account, and go to the server page and hit the customization tab. Hit the Report button, and add a reason to your report.
Your report will be processed and the appropriate action will be taken.
## Issue inside the server
If an issue is inside of the server, because MHSF doesn't provide the server list source (Minehut API), you must [go to Minehut and make a ticket](https://support.minehut.com/hc/en-us/requests/new?tf_subject=Reporting%20Server&tf_27062997154195=reports_appeals&tf_27063229498259=report_server).

@ -1,51 +0,0 @@
---
title: "External Content Agreement"
folder: "Legal"
lastUpdated: "Sep. 10th 2024"
---
# External Content Agreement (ECA)
By making external content available for anyone to see, there needs to
be an agreement to keep MHSF ("Minehut Server List") a friendly place
for anyone to look at. _As such, this agreement outlines what you can't and can do, when making content on the platform._ The goal by making an agreement like this, is not to make you worried
what you can upload, its just showing what the limits of content
uploaded onto the platform are.
## Source Code
The source code for MHSF is defined by the [MIT License](Special:GitHub/blob/main/LICENSE). You are free to use MHSF for commercial use, and you may modify the software however you'd like. Taking copies of the software (aka _"forking"_) is also freely allowed.
## What your limits are
When creating content, if its a matter of making a profile picture,
or editing the description for a server, (and more), you must follow
the underlying agreements below.<br/>
For making banners & descriptions, you must follow [Minehuts Terms of Service](Wiki:Rules) _as all content made is associated to Minehut (as the server is mostly on a community for Minehut)._<br/>
For making Discord server embeds, you must follow [Discords Terms of Service](https://discord.com/terms/) _as all content made is associated to Discord._
### All other content
For all other content, they must follow the following:
- No inappropriate/adult images
- No swear words of any kind or slurs
- Endorsing unethical client modifications (aka cheating or hacking)
## When you agree to the ECA
When you add customization to your server, or add a profile picture (linking an account is included), you must follow the ECA.
## When linking an account
When linking an account, you must follow the privacy policy and terms of service to the associated service that you linked your MHSF account to. Additionally, if you link an external account{" "}
_after_ account creation, everything said before is still true.
## Violations
Violations from above have 1 warning. Your first interaction is a warning by removing the content from MHSF, and your 2nd is banning/deleting your account. (some violations are an instant delete)
## Reporting
If you personally see a violation of the ECA, you can report it by clicking the customization tab on a server, and hitting the Report
button (it doesn't appear when the server was never owned). If you misuse this feature, you may get your account deleted.

@ -1,30 +0,0 @@
---
title: "Reading the docs"
---
# Reading the docs
The documentation in MHSF has some special symbols used in the docs that might be useful to know.
<Separator/>
## Icons
When looking at a link, there will be symbols used that indicate where the link is going: *(these apply to the whole site)*
- <Notebook className="inline-block mb-1" size={20}/> indicates the link will link to the [official Minehut wiki](Wiki:/)
- <Book className="inline-block mb-1" size={20} /> indicates the link will link to another page on the docs
- <ExternalLink className="inline-block mb-1" size={20}/> indicates the link will go to an external site
When contributing, these links are as follows:
```
Wiki:<wiki url after https://minehut.wiki.gg/wiki/>
Docs:<docs url after /docs/>
Special:Root (links back to /)
https://example.com
**Example:**
[Ranks](Wiki:Ranks)
[Getting Started](Docs:Getting-started)
https://google.com
```
The icons above will be automatically added when using the syntax above. <br/>
<small>The source code for above is stored [here](Special:GitHub/edit/main/src/components/misc/Link.tsx)</small>

@ -1,5 +0,0 @@
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: "https://mhsf.app",
generateRobotsTxt: true
}

@ -1,54 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import { withContentlayer } from "next-contentlayer";
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "img.clerk.com",
},
],
},
async redirects() {
return [
{
source: '/docs',
destination: '/docs/getting-started',
permanent: true,
},
]
},
};
export default withContentlayer(nextConfig);

@ -1,125 +1,23 @@
{
"name": "mh-stats",
"version": "1.3.0",
"private": true,
"packageManager": "yarn@1.22.22",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"obfuscate": "next-css-obfuscator",
"check-types": "tsc --noEmit",
"inngest": "npx inngest-cli@latest dev",
"postbuild": "next-sitemap"
},
"dependencies": {
"@babel/parser": "^7.24.7",
"@biomejs/biome": "^1.8.3",
"@clerk/elements": "^0.22.2",
"@clerk/nextjs": "^6.9.2",
"@emotion/is-prop-valid": "^1.3.0",
"@linear/sdk": "^31.0.0",
"@monaco-editor/react": "^4.6.0",
"@radix-ui/react-aspect-ratio": "^1.1.1",
"@radix-ui/react-avatar": "^1.1.1",
"@radix-ui/react-collapsible": "^1.1.1",
"@radix-ui/react-hover-card": "^1.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-menubar": "^1.1.1",
"@radix-ui/react-primitive": "^2.0.0",
"@radix-ui/react-select": "^2.1.2",
"@radix-ui/react-switch": "^1.1.0",
"@unocss/eslint-plugin": "^0.61.5",
"@unocss/postcss": "^0.61.5",
"@unocss/transformer-directives": "^0.61.5",
"@unocss/webpack": "^0.61.5",
"ag-grid-react": "^33.0.3",
"contentlayer": "^0.3.4",
"cron": "^3.1.7",
"discord.js": "^14.15.3",
"github-slugger": "^2.0.0",
"inngest": "^3.21.2",
"input-otp": "^1.2.4",
"json-beautify": "^1.1.1",
"lucide-react": "^0.454.0",
"minimessage-2-html": "1.6.0",
"minimessage-js": "^1.1.3",
"mongodb": "^6.8.0",
"next": "14.2.10",
"next-contentlayer": "^0.3.4",
"next-css-obfuscator": "^2.2.16",
"next-sitemap": "^4.2.3",
"next-themes": "^0.4.3",
"nextjs-toploader": "^1.6.12",
"nprogress": "^0.2.0",
"postcss-obfuscator": "^1.6.1",
"prettier": "^3.3.1",
"react": "^18",
"react-dom": "^18",
"react-fade-in": "^2.0.1",
"react-fast-marquee": "^1.6.5",
"react-hot-toast": "^2.4.1",
"react-qr-code": "^2.0.15",
"react-snowfall": "^2.2.0",
"rehype-slug": "^6.0.0",
"remark-gfm": "^4.0.0",
"sonner": "^1.7.0",
"stripe-gradient": "^1.0.1",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-patch": "^4.0.0",
"turbo": "^2.4.0",
"unplugin-tailwindcss-mangle": "^3.0.1"
},
"devDependencies": {
"@clerk/themes": "^2.1.19",
"@hookform/resolvers": "^3.9.0",
"@radix-ui/react-checkbox": "^1.1.1",
"@radix-ui/react-context-menu": "^2.1.5",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-radio-group": "^1.2.0",
"@radix-ui/react-scroll-area": "^1.1.0",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.3",
"@tailwindcss/typography": "^0.5.13",
"@types/canvas-confetti": "^1.6.4",
"@types/node": "^20",
"@types/nprogress": "^0.2.3",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/react-twemoji": "^0.4.3",
"@unocss/eslint-config": "^0.61.5",
"@unocss/preset-uno": "^0.61.5",
"@unocss/transformer-compile-class": "^0.61.5",
"@vercel/analytics": "^1.3.1",
"@vercel/speed-insights": "^1.0.12",
"canvas-confetti": "^1.9.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
"eslint": "^8",
"eslint-config-next": "14.2.3",
"framer-motion": "^11.3.8",
"geist": "^1.3.0",
"mangle-css-class-webpack-plugin": "^5.1.0",
"postcss": "^8",
"react-hook-form": "^7.52.2",
"react-hotkeys-hook": "^4.5.0",
"react-infinite-scroll-component": "^6.1.0",
"react-markdown": "^9.0.1",
"react-resizable-panels": "^2.0.23",
"recharts": "^2.12.7",
"shiki": "^1.23.0",
"tailwindcss": "^3.4.1",
"typescript": "^5",
"vaul": "^0.9.1",
"zod": "^3.23.8"
}
"name": "MHSF-Modern",
"private": true,
"scripts": {
"build": "turbo build",
"dev": "turbo dev --filter=!cron",
"lint": "turbo lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\""
},
"devDependencies": {
"prettier": "^3.5.0",
"turbo": "^2.4.2",
"typescript": "5.7.3"
},
"engines": {
"node": ">=18"
},
"packageManager": "yarn@1.22.22",
"workspaces": [
"apps/*",
"packages/*"
]
}

@ -6,7 +6,7 @@
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
* Copyright (c) 2025 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@ -28,22 +28,30 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
import { useEffect, useState } from "react";
import * as express from "express";
import { config } from "dotenv";
export default function useStatus() {
const [loading, setLoading] = useState(true);
const [incidents, setIncidents] = useState(null);
const [statusURL, setStatusURL] = useState(null);
config();
const app = express();
useEffect(() => {
fetch("/api/v1/get-status")
.then((c) => c.json())
.then((d) => {
setLoading(false);
setIncidents(d.incidents);
setStatusURL(d.url);
app.get("/", (req, res) => {
res.send({ status: "up" });
});
app.get("/servers", (req, res) => {
if (
req.headers.Authentication !==
`MHSF-Backend-Server ${process.env.MHSF_SECRET}`
)
res.status(401).send({ error: "Unauthorized" });
else
fetch("https://api.minehut.com/servers").then((c) => {
c.json().then((v) => {
res.send(v);
});
}, []);
});
});
return { loading, incidents, statusURL };
}
app.listen(6080, () => {
console.log("Backend API listening on port 6080");
});

@ -4,7 +4,7 @@
"description": "In version 1.0, MHSF moved from using Inngest to collect statistics to a self-hosted `crontab` Node.js script.",
"main": "dist/index.js",
"scripts": {
"dev": "npx tsx src/index.ts",
"dev": "MHC_DOCKER=true npx tsx src/index.ts",
"build": "npx tsc -p ./tsconfig.json"
},
"author": "",

@ -1,12 +1,12 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
* located here: https://mhsf.app/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
* Copyright (c) 2025 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

@ -1,12 +1,12 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
* located here: https://mhsf.app/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
* Copyright (c) 2025 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

@ -1,12 +1,12 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
* located here: https://mhsf.app/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
* Copyright (c) 2025 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

@ -1,38 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
};
export default config;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 958 KiB

@ -1,9 +0,0 @@
# *
User-agent: *
Allow: /
# Host
Host: https://mhsf.app
# Sitemaps
Sitemap: https://mhsf.app/sitemap.xml

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
</sitemapindex>

@ -1,45 +0,0 @@
<!--
- MHSF, Minehut Server List
- All external content is rather licensed under the ECA Agreement
- located here: https://list.mlnehut.com/docs/legal/external-content-agreement
-
- All code under MHSF is licensed under the MIT License
- by open source contributors
-
- Copyright (c) 2024 dvelo
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-->
<svg width="266" height="265" viewBox="0 0 266 265" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.524048" width="264.939" height="264.939" rx="66" fill="url(#paint0_linear_1_19)"/>
<path d="M104.513 123.27H94.8717C92.3148 123.27 89.8626 122.254 88.0546 120.446C86.2466 118.638 85.2309 116.186 85.2309 113.629V94.3476C85.2309 91.7907 86.2466 89.3385 88.0546 87.5305C89.8626 85.7225 92.3148 84.7068 94.8717 84.7068H171.998C174.555 84.7068 177.007 85.7225 178.815 87.5305C180.623 89.3385 181.639 91.7907 181.639 94.3476V113.629C181.639 116.186 180.623 118.638 178.815 120.446C177.007 122.254 174.555 123.27 171.998 123.27H162.357M104.513 142.552H94.8717C92.3148 142.552 89.8626 143.567 88.0546 145.376C86.2466 147.184 85.2309 149.636 85.2309 152.193V171.474C85.2309 174.031 86.2466 176.483 88.0546 178.291C89.8626 180.099 92.3148 181.115 94.8717 181.115H171.998C174.555 181.115 177.007 180.099 178.815 178.291C180.623 176.483 181.639 174.031 181.639 171.474V152.193C181.639 149.636 180.623 147.184 178.815 145.376C177.007 143.567 174.555 142.552 171.998 142.552H162.357M104.513 103.988H104.561M104.513 161.833H104.561M138.255 103.988L118.974 132.911H147.896L128.615 161.833" stroke="white" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="132.993" cy="132.469" r="91.3779" stroke="url(#paint1_linear_1_19)" stroke-width="8"/>
<defs>
<linearGradient id="paint0_linear_1_19" x1="107.824" y1="54.754" x2="230.579" y2="225.198" gradientUnits="userSpaceOnUse">
<stop stop-color="#007BFF"/>
<stop offset="1" stop-color="#BF00FF" stop-opacity="0.5"/>
</linearGradient>
<linearGradient id="paint1_linear_1_19" x1="132.993" y1="37.0914" x2="132.993" y2="227.847" gradientUnits="userSpaceOnUse">
<stop stop-color="#EFEC32"/>
<stop offset="1" stop-color="#98FF60"/>
</linearGradient>
</defs>
</svg>

@ -1,44 +0,0 @@
<!--
- MHSF, Minehut Server List
- All external content is rather licensed under the ECA Agreement
- located here: https://list.mlnehut.com/docs/legal/external-content-agreement
-
- All code under MHSF is licensed under the MIT License
- by open source contributors
-
- Copyright (c) 2024 dvelo
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-->
<svg width="265" height="266" viewBox="0 0 265 266" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.0612793" y="0.86145" width="264.939" height="264.939" rx="66" fill="url(#paint0_linear_1_20)"/>
<path d="M104.05 124.132H94.4089C91.852 124.132 89.3998 123.116 87.5918 121.308C85.7838 119.5 84.7681 117.048 84.7681 114.491V95.2091C84.7681 92.6522 85.7838 90.2 87.5918 88.392C89.3998 86.584 91.852 85.5683 94.4089 85.5683H171.536C174.092 85.5683 176.545 86.584 178.353 88.392C180.161 90.2 181.176 92.6522 181.176 95.2091V114.491C181.176 117.048 180.161 119.5 178.353 121.308C176.545 123.116 174.092 124.132 171.536 124.132H161.895M104.05 143.413H94.4089C91.852 143.413 89.3998 144.429 87.5918 146.237C85.7838 148.045 84.7681 150.497 84.7681 153.054V172.336C84.7681 174.893 85.7838 177.345 87.5918 179.153C89.3998 180.961 91.852 181.977 94.4089 181.977H171.536C174.092 181.977 176.545 180.961 178.353 179.153C180.161 177.345 181.176 174.893 181.176 172.336V153.054C181.176 150.497 180.161 148.045 178.353 146.237C176.545 144.429 174.092 143.413 171.536 143.413H161.895M104.05 104.85H104.098M104.05 162.695H104.098M137.793 104.85L118.511 133.772H147.433L128.152 162.695" stroke="white" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="132.531" cy="133.331" r="91.3779" stroke="url(#paint1_linear_1_20)" stroke-width="8"/>
<defs>
<linearGradient id="paint0_linear_1_20" x1="107.361" y1="55.6155" x2="230.116" y2="226.059" gradientUnits="userSpaceOnUse">
<stop/>
</linearGradient>
<linearGradient id="paint1_linear_1_20" x1="132.531" y1="37.9529" x2="132.531" y2="228.709" gradientUnits="userSpaceOnUse">
<stop stop-color="#EFEC32"/>
<stop offset="1" stop-color="#98FF60"/>
</linearGradient>
</defs>
</svg>

@ -1,44 +0,0 @@
<!--
- MHSF, Minehut Server List
- All external content is rather licensed under the ECA Agreement
- located here: https://list.mlnehut.com/docs/legal/external-content-agreement
-
- All code under MHSF is licensed under the MIT License
- by open source contributors
-
- Copyright (c) 2024 dvelo
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-->
<svg width="265" height="265" viewBox="0 0 265 265" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.0612793" width="264.939" height="264.939" rx="66" fill="url(#paint0_linear_1_25)"/>
<path d="M104.05 123.27H94.4089C91.852 123.27 89.3998 122.254 87.5918 120.446C85.7838 118.638 84.7681 116.186 84.7681 113.629V94.3476C84.7681 91.7907 85.7838 89.3385 87.5918 87.5305C89.3998 85.7225 91.852 84.7068 94.4089 84.7068H171.536C174.092 84.7068 176.545 85.7225 178.353 87.5305C180.161 89.3385 181.176 91.7907 181.176 94.3476V113.629C181.176 116.186 180.161 118.638 178.353 120.446C176.545 122.254 174.092 123.27 171.536 123.27H161.895M104.05 142.552H94.4089C91.852 142.552 89.3998 143.567 87.5918 145.376C85.7838 147.184 84.7681 149.636 84.7681 152.193V171.474C84.7681 174.031 85.7838 176.483 87.5918 178.291C89.3998 180.099 91.852 181.115 94.4089 181.115H171.536C174.092 181.115 176.545 180.099 178.353 178.291C180.161 176.483 181.176 174.031 181.176 171.474V152.193C181.176 149.636 180.161 147.184 178.353 145.376C176.545 143.567 174.092 142.552 171.536 142.552H161.895M104.05 103.988H104.098M104.05 161.833H104.098M137.793 103.988L118.511 132.911H147.433L128.152 161.833" stroke="black" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="132.531" cy="132.469" r="91.3779" stroke="url(#paint1_linear_1_25)" stroke-width="8"/>
<defs>
<linearGradient id="paint0_linear_1_25" x1="107.361" y1="54.754" x2="230.116" y2="225.198" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
</linearGradient>
<linearGradient id="paint1_linear_1_25" x1="132.531" y1="37.0914" x2="132.531" y2="227.847" gradientUnits="userSpaceOnUse">
<stop stop-color="#EFEC32"/>
<stop offset="1" stop-color="#98FF60"/>
</linearGradient>
</defs>
</svg>

@ -1,55 +0,0 @@
<!--
- MHSF, Minehut Server List
- All external content is rather licensed under the ECA Agreement
- located here: https://list.mlnehut.com/docs/legal/external-content-agreement
-
- All code under MHSF is licensed under the MIT License
- by open source contributors
-
- Copyright (c) 2024 dvelo
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-->
<svg width="265" height="265" viewBox="0 0 265 265" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="264.939" height="264.939" rx="66" fill="url(#paint0_linear_1_30)"/>
<path d="M103.988 123.27H94.3476C91.7907 123.27 89.3385 122.254 87.5305 120.446C85.7225 118.638 84.7068 116.186 84.7068 113.629V94.3476C84.7068 91.7907 85.7225 89.3385 87.5305 87.5305C89.3385 85.7225 91.7907 84.7068 94.3476 84.7068H171.474C174.031 84.7068 176.483 85.7225 178.291 87.5305C180.099 89.3385 181.115 91.7907 181.115 94.3476V113.629C181.115 116.186 180.099 118.638 178.291 120.446C176.483 122.254 174.031 123.27 171.474 123.27H161.833M103.988 142.552H94.3476C91.7907 142.552 89.3385 143.567 87.5305 145.376C85.7225 147.184 84.7068 149.636 84.7068 152.193V171.474C84.7068 174.031 85.7225 176.483 87.5305 178.291C89.3385 180.099 91.7907 181.115 94.3476 181.115H171.474C174.031 181.115 176.483 180.099 178.291 178.291C180.099 176.483 181.115 174.031 181.115 171.474V152.193C181.115 149.636 180.099 147.184 178.291 145.376C176.483 143.567 174.031 142.552 171.474 142.552H161.833M103.988 103.988H104.037M103.988 161.833H104.037M137.731 103.988L118.45 132.911H147.372L128.091 161.833" stroke="white" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="132.469" cy="132.469" r="91.3779" stroke="url(#paint1_linear_1_30)" stroke-width="8"/>
<defs>
<linearGradient id="paint0_linear_1_30" x1="51.6631" y1="26.9354" x2="222.549" y2="213.717" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF0000"/>
<stop offset="0.110405" stop-color="#FF6200"/>
<stop offset="0.225785" stop-color="#FFAE00"/>
<stop offset="0.326294" stop-color="#FFD500"/>
<stop offset="0.422381" stop-color="#99EA00"/>
<stop offset="0.498373" stop-color="#4DF457"/>
<stop offset="0.593491" stop-color="#26D3AB"/>
<stop offset="0.699814" stop-color="#13A9D5"/>
<stop offset="0.805673" stop-color="#A200FF"/>
<stop offset="0.884464" stop-color="#C62AEB"/>
<stop offset="0.957056" stop-color="white"/>
<stop offset="0.997383"/>
</linearGradient>
<linearGradient id="paint1_linear_1_30" x1="132.469" y1="37.0914" x2="132.469" y2="227.847" gradientUnits="userSpaceOnUse">
<stop stop-color="#EFEC32"/>
<stop offset="1" stop-color="#98FF60"/>
</linearGradient>
</defs>
</svg>

@ -1,45 +0,0 @@
<!--
- MHSF, Minehut Server List
- All external content is rather licensed under the ECA Agreement
- located here: https://list.mlnehut.com/docs/legal/external-content-agreement
-
- All code under MHSF is licensed under the MIT License
- by open source contributors
-
- Copyright (c) 2024 dvelo
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-->
<svg width="129" height="128" viewBox="0 0 129 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.775696" width="127.238" height="127.238" rx="63.6192" fill="url(#paint0_linear_1_189)"/>
<path d="M50.7168 59.2012H46.0867C44.8588 59.2012 43.6811 58.7134 42.8128 57.8451C41.9445 56.9768 41.4567 55.7991 41.4567 54.5712V45.311C41.4567 44.0831 41.9445 42.9054 42.8128 42.0371C43.6811 41.1688 44.8588 40.681 46.0867 40.681H83.1273C84.3552 40.681 85.5329 41.1688 86.4012 42.0371C87.2695 42.9054 87.7573 44.0831 87.7573 45.311V54.5712C87.7573 55.7991 87.2695 56.9768 86.4012 57.8451C85.5329 58.7134 84.3552 59.2012 83.1273 59.2012H78.4972M50.7168 68.4614H46.0867C44.8588 68.4614 43.6811 68.9492 42.8128 69.8175C41.9445 70.6858 41.4567 71.8635 41.4567 73.0914V82.3516C41.4567 83.5795 41.9445 84.7572 42.8128 85.6255C43.6811 86.4938 44.8588 86.9816 46.0867 86.9816H83.1273C84.3552 86.9816 85.5329 86.4938 86.4012 85.6255C87.2695 84.7572 87.7573 83.5795 87.7573 82.3516V73.0914C87.7573 71.8635 87.2695 70.6858 86.4012 69.8175C85.5329 68.9492 84.3552 68.4614 83.1273 68.4614H78.4972M50.7168 49.9411H50.7399M50.7168 77.7215H50.7399M66.922 49.9411L57.6619 63.8313H71.5521L62.292 77.7215" stroke="white" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="64.395" cy="63.6192" r="41.8058" stroke="url(#paint1_linear_1_189)" stroke-width="8"/>
<defs>
<linearGradient id="paint0_linear_1_189" x1="52.3073" y1="26.296" x2="111.261" y2="108.153" gradientUnits="userSpaceOnUse">
<stop stop-color="#007BFF"/>
<stop offset="1" stop-color="#BF00FF" stop-opacity="0.5"/>
</linearGradient>
<linearGradient id="paint1_linear_1_189" x1="64.395" y1="17.8134" x2="64.395" y2="109.425" gradientUnits="userSpaceOnUse">
<stop stop-color="#EFEC32"/>
<stop offset="1" stop-color="#98FF60"/>
</linearGradient>
</defs>
</svg>

@ -1,44 +0,0 @@
<!--
- MHSF, Minehut Server List
- All external content is rather licensed under the ECA Agreement
- located here: https://list.mlnehut.com/docs/legal/external-content-agreement
-
- All code under MHSF is licensed under the MIT License
- by open source contributors
-
- Copyright (c) 2024 dvelo
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-->
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.761536" y="0.293091" width="127.238" height="127.238" rx="63.6192" fill="url(#paint0_linear_1_199)"/>
<path d="M50.7026 59.4943H46.0726C44.8446 59.4943 43.6669 59.0065 42.7986 58.1382C41.9303 57.2699 41.4425 56.0922 41.4425 54.8643V45.6041C41.4425 44.3762 41.9303 43.1985 42.7986 42.3302C43.6669 41.4619 44.8446 40.9741 46.0726 40.9741H83.1131C84.3411 40.9741 85.5187 41.4619 86.3871 42.3302C87.2554 43.1985 87.7432 44.3762 87.7432 45.6041V54.8643C87.7432 56.0922 87.2554 57.2699 86.3871 58.1382C85.5187 59.0065 84.3411 59.4943 83.1131 59.4943H78.483M50.7026 68.7545H46.0726C44.8446 68.7545 43.6669 69.2423 42.7986 70.1106C41.9303 70.9789 41.4425 72.1566 41.4425 73.3845V82.6447C41.4425 83.8726 41.9303 85.0503 42.7986 85.9186C43.6669 86.7869 44.8446 87.2747 46.0726 87.2747H83.1131C84.3411 87.2747 85.5187 86.7869 86.3871 85.9186C87.2554 85.0503 87.7432 83.8726 87.7432 82.6447V73.3845C87.7432 72.1566 87.2554 70.9789 86.3871 70.1106C85.5187 69.2423 84.3411 68.7545 83.1131 68.7545H78.483M50.7026 50.2342H50.7258M50.7026 78.0146H50.7258M66.9079 50.2342L57.6477 64.1244H71.5379L62.2778 78.0146" stroke="white" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="64.3808" cy="63.9123" r="41.8058" stroke="url(#paint1_linear_1_199)" stroke-width="8"/>
<defs>
<linearGradient id="paint0_linear_1_199" x1="52.2931" y1="26.589" x2="111.247" y2="108.446" gradientUnits="userSpaceOnUse">
<stop/>
</linearGradient>
<linearGradient id="paint1_linear_1_199" x1="64.3808" y1="18.1065" x2="64.3808" y2="109.718" gradientUnits="userSpaceOnUse">
<stop stop-color="#EFEC32"/>
<stop offset="1" stop-color="#98FF60"/>
</linearGradient>
</defs>
</svg>

@ -1,44 +0,0 @@
<!--
- MHSF, Minehut Server List
- All external content is rather licensed under the ECA Agreement
- located here: https://list.mlnehut.com/docs/legal/external-content-agreement
-
- All code under MHSF is licensed under the MIT License
- by open source contributors
-
- Copyright (c) 2024 dvelo
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-->
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.761536" width="127.238" height="127.238" rx="63.6192" fill="url(#paint0_linear_1_204)"/>
<path d="M50.7026 59.2012H46.0726C44.8446 59.2012 43.6669 58.7134 42.7986 57.8451C41.9303 56.9768 41.4425 55.7991 41.4425 54.5712V45.311C41.4425 44.0831 41.9303 42.9054 42.7986 42.0371C43.6669 41.1688 44.8446 40.681 46.0726 40.681H83.1131C84.3411 40.681 85.5187 41.1688 86.3871 42.0371C87.2554 42.9054 87.7432 44.0831 87.7432 45.311V54.5712C87.7432 55.7991 87.2554 56.9768 86.3871 57.8451C85.5187 58.7134 84.3411 59.2012 83.1131 59.2012H78.483M50.7026 68.4614H46.0726C44.8446 68.4614 43.6669 68.9492 42.7986 69.8175C41.9303 70.6858 41.4425 71.8635 41.4425 73.0914V82.3516C41.4425 83.5795 41.9303 84.7572 42.7986 85.6255C43.6669 86.4938 44.8446 86.9816 46.0726 86.9816H83.1131C84.3411 86.9816 85.5187 86.4938 86.3871 85.6255C87.2554 84.7572 87.7432 83.5795 87.7432 82.3516V73.0914C87.7432 71.8635 87.2554 70.6858 86.3871 69.8175C85.5187 68.9492 84.3411 68.4614 83.1131 68.4614H78.483M50.7026 49.9411H50.7258M50.7026 77.7215H50.7258M66.9079 49.9411L57.6477 63.8313H71.5379L62.2778 77.7215" stroke="black" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="64.3808" cy="63.6192" r="41.8058" stroke="url(#paint1_linear_1_204)" stroke-width="8"/>
<defs>
<linearGradient id="paint0_linear_1_204" x1="52.2931" y1="26.296" x2="111.247" y2="108.153" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
</linearGradient>
<linearGradient id="paint1_linear_1_204" x1="64.3808" y1="17.8134" x2="64.3808" y2="109.425" gradientUnits="userSpaceOnUse">
<stop stop-color="#EFEC32"/>
<stop offset="1" stop-color="#98FF60"/>
</linearGradient>
</defs>
</svg>

@ -1,55 +0,0 @@
<!--
- MHSF, Minehut Server List
- All external content is rather licensed under the ECA Agreement
- located here: https://list.mlnehut.com/docs/legal/external-content-agreement
-
- All code under MHSF is licensed under the MIT License
- by open source contributors
-
- Copyright (c) 2024 dvelo
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-->
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="127.238" height="127.238" rx="63.6192" fill="url(#paint0_linear_1_194)"/>
<path d="M49.9411 59.2012H45.311C44.0831 59.2012 42.9054 58.7134 42.0371 57.8451C41.1688 56.9768 40.681 55.7991 40.681 54.5712V45.311C40.681 44.0831 41.1688 42.9054 42.0371 42.0371C42.9054 41.1688 44.0831 40.681 45.311 40.681H82.3516C83.5795 40.681 84.7572 41.1688 85.6255 42.0371C86.4938 42.9054 86.9816 44.0831 86.9816 45.311V54.5712C86.9816 55.7991 86.4938 56.9768 85.6255 57.8451C84.7572 58.7134 83.5795 59.2012 82.3516 59.2012H77.7215M49.9411 68.4614H45.311C44.0831 68.4614 42.9054 68.9492 42.0371 69.8175C41.1688 70.6858 40.681 71.8635 40.681 73.0914V82.3516C40.681 83.5795 41.1688 84.7572 42.0371 85.6255C42.9054 86.4938 44.0831 86.9816 45.311 86.9816H82.3516C83.5795 86.9816 84.7572 86.4938 85.6255 85.6255C86.4938 84.7572 86.9816 83.5795 86.9816 82.3516V73.0914C86.9816 71.8635 86.4938 70.6858 85.6255 69.8175C84.7572 68.9492 83.5795 68.4614 82.3516 68.4614H77.7215M49.9411 49.9411H49.9643M49.9411 77.7215H49.9643M66.1463 49.9411L56.8862 63.8313H70.7764L61.5163 77.7215" stroke="white" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="63.6193" cy="63.6192" r="41.8058" stroke="url(#paint1_linear_1_194)" stroke-width="8"/>
<defs>
<linearGradient id="paint0_linear_1_194" x1="24.8115" y1="12.9359" x2="106.88" y2="102.639" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF0000"/>
<stop offset="0.110405" stop-color="#FF6200"/>
<stop offset="0.225785" stop-color="#FFAE00"/>
<stop offset="0.326294" stop-color="#FFD500"/>
<stop offset="0.422381" stop-color="#99EA00"/>
<stop offset="0.498373" stop-color="#4DF457"/>
<stop offset="0.593491" stop-color="#26D3AB"/>
<stop offset="0.699814" stop-color="#13A9D5"/>
<stop offset="0.805673" stop-color="#A200FF"/>
<stop offset="0.884464" stop-color="#C62AEB"/>
<stop offset="0.957056" stop-color="white"/>
<stop offset="0.997383"/>
</linearGradient>
<linearGradient id="paint1_linear_1_194" x1="63.6193" y1="17.8134" x2="63.6193" y2="109.425" gradientUnits="userSpaceOnUse">
<stop stop-color="#EFEC32"/>
<stop offset="1" stop-color="#98FF60"/>
</linearGradient>
</defs>
</svg>

Binary file not shown.

@ -1,129 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import TableOfContent from "@/components/docs/TOC";
import { ALegacy } from "@/components/misc/Link";
import { MDXElements } from "@/components/misc/MDXElements";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
import { allDocs } from "contentlayer/generated";
import { useMDXComponent } from "next-contentlayer/hooks";
import NextLink from "next/link";
import { notFound } from "next/navigation";
export const generateStaticParams = async () =>
allDocs.map((post) => ({ slug: [post._raw.flattenedPath] }));
export const generateMetadata = ({
params,
}: {
params: { slug: string[] };
}) => {
const post = allDocs.find(
(post) => post._raw.flattenedPath === params.slug.join("/"),
);
if (!post) notFound();
return { title: post.title + " | MHSF Docs", themeColor: "#000000" };
};
const PostLayout = ({ params }: { params: { slug: string[] } }) => {
const doc = allDocs.find(
(post) => post._raw.flattenedPath === params.slug.join("/"),
);
if (!doc) notFound();
console.log(doc);
const MDXContent = useMDXComponent(doc.body.code);
return (
<main className="relative py-6 lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_300px]">
<div className="mx-auto w-full min-w-0">
<div className="pb-12 pt-8 prose dark:prose-invert">
{doc.folder && <span>{doc.folder}</span>}{" "}
{doc.lastUpdated && <span> - last updated {doc.lastUpdated}</span>}{" "}
<MDXContent
components={{
Separator,
a: (props) => <ALegacy {...props} />,
...MDXElements,
}}
/>
</div>
</div>
{doc.toc && (
<div className="hidden text-sm xl:block">
<div className="sticky top-16 -mt-10 pt-4">
<ScrollArea className="pb-10">
<div className="sticky top-16 -mt-10 h-[calc(100vh-3.5rem)] py-12 space-y-2">
<p className="font-medium">On This Page</p>
{doc.toc.map(
(c: { level: number; text: string; slug: string }) => (
<TableOfContent toc={c} doc={doc} key={c.slug} />
),
)}
<br />
<div className="space-y-2">
<p className="font-medium">Contribute</p>
<ul className="m-0 list-none">
<li className="mt-0 pt-2">
<NextLink
href={
"https://github.com/DeveloLongScript/MHSF/edit/main/docs/" +
doc._raw.flattenedPath +
".mdx"
}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors no-underline"
>
<svg
viewBox="0 0 438.549 438.549"
fontSize={16}
className="mr-2 size-4"
>
<path
fill="currentColor"
d="M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"
/>
</svg>
Edit page on GitHub
</NextLink>
</li>
</ul>
</div>
</div>
</ScrollArea>
</div>
</div>
)}
</main>
);
};
export default PostLayout;

@ -1,102 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
"use client";
import { Sidebar } from "@/components/docs/Sidebar";
import { Button } from "@/components/ui/button";
import { Drawer, DrawerContent, DrawerTrigger } from "@/components/ui/drawer";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
SidebarInset,
SidebarProvider,
SidebarTrigger,
} from "@/components/ui/sidebar";
import { version } from "@/config/version";
import { HamburgerMenuIcon } from "@radix-ui/react-icons";
import { GeistMono } from "geist/font/mono";
import { GeistSans } from "geist/font/sans";
import "../globals.css";
import "../../themes.css";
import { ThemeProvider } from "@/components/ThemeProvider";
import { ClerkThemeProvider } from "@/components/clerk/ClerkThemeProvider";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
import { Separator } from "@/components/ui/separator";
import NextTopLoader from "@/lib/top-loader";
import { useRouter } from "@/lib/useRouter";
import { allDocs } from "contentlayer/generated";
import { GetServerSideProps } from "next";
import { usePathname } from "next/navigation";
interface Props {
pathname: string;
}
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const pathname = usePathname();
return (
<ClerkThemeProvider className="">
<div className="theme-zinc">
<NextTopLoader />
<SidebarProvider>
<Sidebar />
<SidebarInset>
<div className="fixed backdrop-blur w-full flex h-16 z-10 items-center gap-2 px-4 ">
<SidebarTrigger />
<Separator orientation="vertical" className="mr-2 h-4" />
{
allDocs.find(
(c) =>
c._raw.flattenedPath ===
pathname
?.split("/")
.splice(2, pathname?.split("/").length)
.join("/"),
)?.title
}
</div>
<div className="px-[100px] pt-[50px]">{children}</div>
</SidebarInset>
</SidebarProvider>
</div>
</ClerkThemeProvider>
);
}

@ -1,39 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://mhsf.app/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import Embed from "@/components/feat/Embed";
export default function EmbedPage({
params,
}: {
params: { server: string };
}) {
return <Embed params={params} />;
}

@ -1,57 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://mhsf.app/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
"use client";
import { TooltipProvider } from "@/components/ui/tooltip";
import "../globals.css";
import { ThemeProvider } from "@/components/ThemeProvider";
import { useSearchParams } from "next/navigation";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const searchParams = useSearchParams();
const search = searchParams?.get("theme") || "light";
return (
<html lang="en">
<body>
<ThemeProvider
attribute="class"
disableTransitionOnChange
forcedTheme={search}
>
<TooltipProvider>{children}</TooltipProvider>
</ThemeProvider>
</body>
</html>
);
}

@ -1,41 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import FavoritesView from "@/components/FavoritesView";
export default function Favorites() {
return (
<main>
<div className="pt-[60px] p-4">
<FavoritesView />
</div>
</main>
);
}

@ -1,47 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
"use client";
import { Sidebar } from "@/components/PreferencesSidebar";
import { usePathname } from "next/navigation";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const pathname = usePathname();
return (
<span className="pt-[48px] ">
<Sidebar curPage={pathname as string}>{children}</Sidebar>
</span>
);
}

@ -1,53 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
"use client";
import { useClerk, useUser } from "@clerk/nextjs";
import { useEffect, useState } from "react";
import { SLCustomize } from "@/components/SLCustomizePage";
export default function Settings() {
const clerk = useClerk();
const { user, isSignedIn } = useUser();
const [linked, setLinked] = useState(false);
useEffect(() => {
setLinked(user?.publicMetadata.player != undefined);
}, [user, isSignedIn]);
return (
<main className="p-4">
<strong className="text-3xl">Profile Preferences</strong>
<br />
<br />
<SLCustomize />
</main>
);
}

@ -1,137 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
"use client";
import { Button } from "@/components/ui/button";
import { useClerk, useUser } from "@clerk/nextjs";
import { toast } from "sonner";
import { unlinkMCAccount } from "@/lib/api";
import { useEffect, useState } from "react";
import { Dialog } from "@/components/ui/dialog";
import { DialogContent, DialogTrigger } from "@/components/ui/dialog";
import CodeDialog from "@/components/misc/LinkDialog";
export default function Settings() {
const clerk = useClerk();
const { user, isSignedIn } = useUser();
const [linked, setLinked] = useState(false);
useEffect(() => {
setLinked(user?.publicMetadata.player != undefined);
}, [user, isSignedIn]);
const forceUnlink = async () => {
if (!linked) await toast.promise(unlinkMCAccount(), {
success: "Unlinked account!",
loading: "Unlinking...",
error: "Error while unlinking account.",
});
else
await toast.warning("Please use the normal unlink option before using the force unlink one.")
};
return (
<main className="p-4">
<strong className="text-3xl">Linking</strong>
<br />
<br />
<strong className="font-bold">Link Account</strong>
<div className="flex items-center">
<p>
Link a Minecraft account to customize a server you own.
<br />{" "}
{user?.publicMetadata.player != undefined && linked && (
<>Currently linked to {user?.publicMetadata.player as string}</>
)}
</p>
<Dialog>
<DialogTrigger>
{!linked && <Button className="h-[30px] ml-2">Link Account</Button>}
</DialogTrigger>
<DialogContent>
<CodeDialog
linked={linked}
setLinked={(c) => {
setLinked(c);
}}
/>
</DialogContent>
</Dialog>
{linked && (
<Button className="h-[30px] ml-2" disabled>
Already linked
</Button>
)}
</div>
<br />
<strong className="font-bold">Unlink Account</strong>
<div className="flex items-center">
<p>Unlink your Minecraft account if you have already linked one.</p>
{!linked && (
<Button className="h-[30px] ml-2" disabled>
No linked account
</Button>
)}
{linked && (
<Button
className="h-[30px] ml-2"
variant="destructive"
onClick={async () => {
await toast.promise(unlinkMCAccount(), {
success: "Unlinked account!",
loading: "Unlinking...",
error: "Error while unlinking account.",
});
setLinked(false);
}}
>
Unlink account
</Button>
)}
</div>
<small className="mt-0">
All of your customizations stay the same, and can be changed if another
account links your Minecraft account.{" "}
<div
className="cursor-pointer text-blue-600"
onClick={forceUnlink}
onKeyDown={forceUnlink}
onKeyUp={forceUnlink}
>
Still linked in-game? Force unlink your account.
</div>
</small>
</main>
);
}

@ -1,50 +0,0 @@
import { Sidebar } from "@/components/docs/Sidebar";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
import { Separator } from "@/components/ui/separator";
import {
SidebarInset,
SidebarProvider,
SidebarTrigger,
} from "@/components/ui/sidebar";
export default function Page() {
return (
<SidebarProvider>
<Sidebar />
<SidebarInset>
<header className="flex sticky top-0 bg-background h-16 shrink-0 items-center gap-2 border-b px-4">
<SidebarTrigger className="-ml-1" />
<Separator orientation="vertical" className="mr-2 h-4" />
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem className="hidden md:block">
<BreadcrumbLink href="#">
Building Your Application
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator className="hidden md:block" />
<BreadcrumbItem>
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</header>
<div className="flex flex-1 flex-col gap-4 p-4">
{Array.from({ length: 24 }).map((_, index) => (
<div
key={index}
className="aspect-video h-12 w-full rounded-lg bg-muted/50"
/>
))}
</div>
</SidebarInset>
</SidebarProvider>
);
}

@ -1,93 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import { Analytics } from "@vercel/analytics/react";
import { SpeedInsights } from "@vercel/speed-insights/next";
import { GeistSans } from "geist/font/sans";
import "../globals.css";
import { CommandBarer } from "@/components/CommandBar";
import { ThemeProvider } from "@/components/ThemeProvider";
import { ClerkThemeProvider } from "@/components/clerk/ClerkThemeProvider";
import NewDomainDialog from "@/components/misc/NewDomainDialog";
import ThemedToaster from "@/components/misc/ThemedToaster";
import { TooltipProvider } from "@/components/ui/tooltip";
import type { Metadata, Viewport } from "next";
import { Inter as interFont } from "next/font/google";
import LayoutPart from "@/components/feat/LayoutPart";
import AllBanners from "@/components/feat/AllBanners";
import Footer from "@/components/misc/Footer";
import { SwitchEnvPopup } from "@/components/misc/SwitchEnvPopup";
export const extraMetadata = {
twitter: {
images: [
{
url: "/imgs/icon-cf.png",
},
],
},
themeColor: "#000000",
openGraph: {
images: [
{
url: "/imgs/icon-cf.png",
},
],
},
} satisfies Metadata;
export const viewport: Viewport = {
themeColor: "black",
colorScheme: "dark",
};
const inter = interFont({ variable: "--font-inter", subsets: ["latin"] });
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<ClerkThemeProvider className={GeistSans.className}>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<TooltipProvider>
<AllBanners />
<LayoutPart>{children}</LayoutPart>
<ThemedToaster />
<CommandBarer />
<SpeedInsights />
<Analytics />
<NewDomainDialog />
<SwitchEnvPopup />
<Footer />
</TooltipProvider>
</ThemeProvider>
</ClerkThemeProvider>
);
}

@ -1,46 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import Link from "next/link";
export default function NotFound() {
return (
<main>
<div className="pt-[60px] p-4">
<strong>404 - Page not found</strong>
<br />
<p>
We couldn't find the page you were looking for.{" "}
<Link href="/public">Go home</Link>
</p>
</div>
</main>
);
}

@ -1,65 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import ServerList from "@/components/ServerList";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "the MHSF project by dvelo",
description:
process.env.NEXT_PUBLIC_VERCEL_ENV != undefined
? `currently running in ${process.env.NEXT_PUBLIC_VERCEL_ENV} | commit (${(process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA as string).substring(0, 7)}}) "${process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE}" by ${process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME}`
: "currently running in dev",
twitter: {
images: [
{
url: "/imgs/icon-cf.png",
},
],
},
themeColor: "#000000",
openGraph: {
images: [
{
url: "/imgs/icon-cf.png",
},
],
},
};
export default function Home() {
return (
<main>
<div className="pt-[60px]">
<ServerList />
</div>
</main>
);
}

@ -1,98 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import type { Metadata, ResolvingMetadata } from "next";
import CustomizeRoot from "@/components/CustomizeRoot";
type Props = {
params: { server: string };
};
export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
// read route params
const { server } = params;
const json = await (
await fetch("https://api.minehut.com/server/" + server + "?byName=true")
).json();
return {
title:
json.server == null
? "Server doesn't exist | MHSF"
: json.server.name +
", " +
(json.server.online
? json.server.playerCount +
(json.server.maxPlayers != 10
? "/" + json.server.maxPlayers
: "") +
" online"
: "Offline") +
" | MHSF",
description:
json.server == null
? `The server ${server} doesn't exist.`
: `View ${server} on Minehut Server Finder!`,
authors: json.server == null ? undefined : { name: json.server.owner },
applicationName: "MHSF (Minehut Server Finder)",
icons:
json.server == null
? undefined
: "https://mcapi.marveldc.me/item/" +
(json.server.icon == undefined ? "OAK_SIGN" : json.server.icon) +
"?width=64&height=64",
openGraph: {
type: "profile",
siteName: "MHSF (Minehut Server Finder)",
images: [
{
url:
"https://mcapi.marveldc.me/item/" +
json.server.icon +
"?width=64&height=64",
},
{
url: "/favicon.ico",
},
],
},
};
}
export default function ServerPage({ params }: { params: { server: string } }) {
return (
<main>
<CustomizeRoot params={params} />
</main>
);
}

@ -1,51 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://mhsf.app/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
"use client";
import { LoadingSpinner } from "@/components/ui/loading-spinner";
import { useServerExists } from "@/lib/hooks/use-server-exists";
import { notFound } from "next/navigation";
export default function ServerLayout({
params,
children,
}: {
params: { server: string };
children: React.ReactNode;
}) {
const { serverExists, loading } = useServerExists(params.server);
if (loading) return <LoadingSpinner />;
if (!serverExists) notFound();
return children;
}

@ -1,150 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import AfterServerView from "@/components/AfterServerView";
import Banner from "@/components/Banner";
import ColorProvider from "@/components/ColorProvider";
import ServerView from "@/components/ServerView";
import StickyTopbar from "@/components/misc/StickyTopbar";
import TabServer from "@/components/misc/TabServer";
import type { Metadata, ResolvingMetadata } from "next";
type Props = {
params: { server: string };
};
export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
// read route params
const { server } = params;
const json = await (
await fetch("https://api.minehut.com/server/" + server + "?byName=true")
).json();
return {
themeColor: "#000000",
title:
json.server == null
? "Server doesn't exist | MHSF"
: json.server.name +
", " +
(json.server.online
? json.server.playerCount +
(json.server.maxPlayers != 10
? "/" + json.server.maxPlayers
: "") +
" online"
: "Offline") +
" | MHSF",
description:
json.server == null
? `The server ${server} doesn't exist.`
: `View ${server} on Minehut Server Finder!`,
authors: json.server == null ? undefined : { name: json.server.owner },
applicationName: "MHSF (Minehut Server Finder)",
icons:
json.server == null
? undefined
: "https://minehut-server-icons-live.s3.us-west-2.amazonaws.com/" +
(json.server.icon == undefined ? "OAK_SIGN" : json.server.icon) +
".png",
twitter: {
title:
json.server == null
? "Server doesn't exist | MHSF"
: json.server.name +
", " +
(json.server.online
? json.server.playerCount +
(json.server.maxPlayers != 10
? "/" + json.server.maxPlayers
: "") +
" online"
: "Offline") +
" | MHSF",
description:
json.server == null
? `The server ${server} doesn't exist.`
: `View ${server} on Minehut Server Finder!`,
images: [
{
url:
"https://minehut-server-icons-live.s3.us-west-2.amazonaws.com/" +
json.server.icon +
".png",
},
{
url: "/public/imgs/icon-cf.png",
},
],
},
openGraph: {
type: "profile",
siteName: "MHSF (Minehut Server Finder)",
images: [
{
url:
"https://minehut-server-icons-live.s3.us-west-2.amazonaws.com/" +
json.server.icon +
".png",
},
{
url: "/public/imgs/icon-cf.png",
},
],
},
};
}
export default function ServerPage({ params }: { params: { server: string } }) {
return (
<main style={{ "color-scheme": "dark" } as React.CSSProperties}>
<ColorProvider server={params.server}>
<div className={"pt-[300px] xl:px-[100px]"}>
<Banner server={params.server} />
<div className="pt-8 z-8 relative">
<ServerView server={params.server} />
</div>
<StickyTopbar scrollElevation={100} className="pt-4 z-10">
<TabServer server={params.server} tabDef="general" />
</StickyTopbar>
<br />
<div className="z-8 relative">
<AfterServerView server={params.server} />
</div>
</div>
</ColorProvider>
</main>
);
}

@ -1,128 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
import Banner from "@/components/Banner";
import ColorProvider from "@/components/ColorProvider";
import { NewChart } from "@/components/charts/NewChart";
import ServerView from "@/components/ServerView";
import TabServer from "@/components/misc/TabServer";
import type { Metadata, ResolvingMetadata } from "next";
import StickyTopbar from "@/components/misc/StickyTopbar";
import { RelativeChart } from "@/components/charts/RelativeChart";
import { MonthlyChart } from "@/components/charts/MonthlyChart";
import { DailyChart } from "@/components/charts/DailyChart";
type Props = {
params: { server: string };
};
export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
// read route params
const { server } = params;
const json = await (
await fetch("https://api.minehut.com/server/" + server + "?byName=true")
).json();
return {
title:
json.server == null
? "Server doesn't exist | MHSF"
: json.server.name +
", " +
(json.server.online
? json.server.playerCount +
(json.server.maxPlayers != 10
? "/" + json.server.maxPlayers
: "") +
" online"
: "Offline") +
" | MHSF",
description:
json.server == null
? `The server ${server} doesn't exist.`
: `View ${server} on Minehut Server Finder!`,
authors: json.server == null ? undefined : { name: json.server.owner },
applicationName: "MHSF (Minehut Server Finder)",
icons:
json.server == null
? undefined
: "https://mcapi.marveldc.me/item/" +
(json.server.icon == undefined ? "OAK_SIGN" : json.server.icon) +
"?width=64&height=64",
openGraph: {
type: "profile",
siteName: "MHSF (Minehut Server Finder)",
images: [
{
url:
"https://mcapi.marveldc.me/item/" +
json.server.icon +
"?width=64&height=64",
},
{
url: "/favicon.ico",
},
],
},
};
}
export default function ServerPage({ params }: { params: { server: string } }) {
return (
<main style={{ "color-scheme": "dark" } as React.CSSProperties}>
<ColorProvider server={params.server}>
<div className={"pt-[300px] xl:px-[100px]"}>
<Banner server={params.server} />
<div className="pt-8 z-1 relative">
<ServerView server={params.server} />
</div>
<StickyTopbar scrollElevation={100} className="pt-4">
<TabServer server={params.server} tabDef="statistics" />
</StickyTopbar>
<br />
<div className="p-4 gap-4 relative z-1">
<NewChart server={params.server} />
<br />
<RelativeChart server={params.server} />
<br />
<div className="grid grid-cols-2 gap-4">
<MonthlyChart server={params.server} />
<DailyChart server={params.server} />
</div>
</div>
</div>
</ColorProvider>
</main>
);
}

File diff suppressed because it is too large Load Diff

@ -1,556 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
"use client";
import { getCommunityServerFavorites, getCustomization } from "@/lib/api";
import { MHSF } from "@/lib/mhsf";
import { ServerResponse } from "@/lib/types/mh-server";
import {
MinehutIcon,
getIndexFromRarity,
getMinehutIcons,
} from "@/lib/types/server-icon";
import { Banknote, Copy, Info, QrCode, Share2 } from "lucide-react";
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
import FadeIn from "react-fade-in/lib/FadeIn";
import { CheckmarkIcon } from "react-hot-toast";
import { toast } from "sonner";
import Markdown from "react-markdown";
import IconDisplay from "./IconDisplay";
import AchievementList from "./feat/AchievementList";
import { Button } from "./ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "./ui/card";
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from "./ui/drawer";
import EmbedSelector from "./feat/EmbedSelector";
import { Separator } from "./ui/separator";
import QRCodeGenerator from "./feat/QRCodeGen";
import NoItems from "./misc/NoItems";
export default function AfterServerView({ server }: { server: string }) {
const [description, setDescription] = useState("");
const [discord, setDiscord] = useState("");
const [mhsf, setMHSF] = useState(new MHSF());
const [icons, setIcons] = useState<MinehutIcon[]>();
const { resolvedTheme } = useTheme();
const [loading, setLoading] = useState(true);
const [qrCodeOpen, setQrCodeOpen] = useState(false);
const [view, setView] = useState(
description !== "" || discord !== "" ? "desc" : "extra"
);
const [serverObject, setServerObject] = useState<ServerResponse | undefined>(
undefined
);
const [embedOpened, setEmbedOpened] = useState(false);
const [copied, setCopied] = useState(false);
useEffect(() => {
getCustomization(server).then((b) => {
if (b != null) {
setDescription(b.description == null ? "" : b.description);
setDiscord(b.discord == null ? "" : b.discord);
mhsf.setCustomizations(b);
getCommunityServerFavorites(server).then((c) => {
mhsf.setFavorites(c);
});
setView(description !== "" || discord !== "" ? "desc" : "extra");
}
fetch("https://api.minehut.com/server/" + server + "?byName=true").then(
(c) => c.json().then((n) => setServerObject(n.server))
);
getMinehutIcons().then((i) => {
setIcons(i);
});
setLoading(false);
});
}, [description, discord]);
if (loading) return <></>;
return (
<>
<Drawer open={embedOpened} onOpenChange={setEmbedOpened}>
<DrawerContent className="max-w-md w-full mx-auto rounded-t-[10px]">
<DrawerHeader>
<DrawerTitle>Embed Creator</DrawerTitle>
</DrawerHeader>
<EmbedSelector server={server} />
</DrawerContent>
</Drawer>
<Drawer open={qrCodeOpen} onOpenChange={setQrCodeOpen}>
<DrawerContent className="max-w-md w-full mx-auto rounded-t-[10px]">
<DrawerHeader>
<DrawerTitle>QR Code generator</DrawerTitle>
</DrawerHeader>
<QRCodeGenerator server={server} />
</DrawerContent>
</Drawer>
<FadeIn className="relative z-8">
<div className="grid sm:grid-cols-6 h-full pl-4 pr-4 ">
<div className="ml-5 mb-2 flex items-center sm:hidden overflow-auto w-[calc(100vw-5rem)]">
{(description != "" || discord != "") && (
<Button
variant={view == "desc" ? undefined : "ghost"}
onClick={() => setView("desc")}
>
Description
</Button>
)}
<Button
variant={view == "extra" ? undefined : "ghost"}
onClick={() => setView("extra")}
className="ml-2"
>
Server Information
</Button>
<Button
variant={view == "achievements" ? undefined : "ghost"}
onClick={() => setView("achievements")}
className="ml-2"
>
Achievements
</Button>
<Button
variant={view == "icons" ? undefined : "ghost"}
onClick={() => setView("icons")}
>
Purchased Icons
</Button>
<Separator orientation="vertical" />
<Button variant="ghost" onClick={() => setEmbedOpened(true)}>
<Share2 className="h-[1rem] w-[1rem] mr-2" />
Embeds
</Button>
</div>
<div className="max-sm:hidden">
<div className="grid">
{(description != "" || discord != "") && (
<Button
variant={view == "desc" ? undefined : "ghost"}
onClick={() => setView("desc")}
>
Description
</Button>
)}
<Button
variant={view == "extra" ? undefined : "ghost"}
onClick={() => setView("extra")}
>
Server Information
</Button>
<Button
variant={view == "achievements" ? undefined : "ghost"}
onClick={() => setView("achievements")}
>
Achievements
</Button>
<Button
variant={view == "icons" ? undefined : "ghost"}
onClick={() => setView("icons")}
>
Purchased Icons
</Button>
<br />
<Separator />
<br />
<Button variant="ghost" onClick={() => setEmbedOpened(true)}>
<Share2 className="h-[1rem] w-[1rem] mr-2" />
Embeds
</Button>
<Button variant="ghost" onClick={() => setQrCodeOpen(true)}>
<QrCode className="h-[1rem] w-[1rem] mr-2" />
QR Code
</Button>
</div>
</div>
<div className="grid lg:grid-cols-4 pl-4 pr-4 gap-3.5 col-span-5">
{description != "" && view == "desc" && (
<Card className="sm:col-span-3">
<CardDescription className="p-4 prose dark:prose-invert">
<Markdown
components={{
img(props) {
// wsrv.nl caches images for us AND protects the IP's of users
return (
<img src={`//wsrv.nl/?url=${props.src}`} {...props} />
);
},
}}
>
{description}
</Markdown>
</CardDescription>
</Card>
)}
{discord != "" && view == "desc" && (
<iframe
src={`https://discord.com/widget?id=${discord}&theme=${resolvedTheme}`}
height="500"
allowTransparency={true}
className="rounded-lg max-md:w-full"
sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
/>
)}{" "}
{view == "achievements" && (
<div className="col-span-4">
<AchievementList server={server} />
</div>
)}
{view == "extra" && (
<div className="sm:grid sm:grid-cols-3 col-span-4 gap-4">
<Card>
<CardHeader>
<CardTitle>Plan Details</CardTitle>
<CardDescription>
Information about the plan being used by the server
</CardDescription>
</CardHeader>
{(() => {
console.log(serverObject);
return true;
})()}
<CardContent>
{" "}
<table className="table-auto w-full">
<tr>
<th className="border p-2">Server plan</th>
<td className="border p-2">
{serverObject?.expired == undefined ? (
<div className="flex items-center">
Free{" "}
<Tooltip>
<TooltipTrigger>
<div>
<Info size={16} className="ml-2" />
</div>
</TooltipTrigger>
<TooltipContent>
The plan is really unknown, but in most
scenarios, the Minehut API returns{" "}
<code>undefined</code> if the server is free.
</TooltipContent>
</Tooltip>
</div>
) : (
<>{serverObject?.activeServerPlan}</>
)}
</td>
</tr>
<tr>
<th className="border p-2">Raw plan</th>
<td className="border p-2">
{serverObject?.expired == undefined ? (
"? (unknown)"
) : (
<code>{serverObject?.rawPlan}</code>
)}
</td>
</tr>
<tr>
<th className="border p-2">Credits p/ day</th>
<td className="border p-2 flex items-center">
<Banknote className="mr-1" />
{serverObject?.credits_per_day == undefined
? "? (unknown)"
: Math.floor(serverObject?.credits_per_day)}
</td>
</tr>
<tr>
<th className="border p-2">Server expired</th>
<td className="border p-2">
{serverObject?.expired == undefined
? "? (unknown)"
: toJSX(serverObject?.expired)}
</td>
</tr>
<tr>
<th className="border p-2">Server external</th>
<td className="border p-2">
{serverObject?.rawPlan == undefined
? "? (unknown)"
: toJSX(serverObject?.rawPlan == "EXTERNAL")}
</td>
</tr>
</table>{" "}
</CardContent>
</Card>
<br className="sm:hidden" />
<Card>
<CardHeader>
<CardTitle>Additional Info</CardTitle>
<CardDescription>
Additional info that could be useful{" "}
</CardDescription>
</CardHeader>
<CardContent>
<table className="table-auto w-full">
<tr>
<th className="border p-2">Icon</th>
<td className="border p-2">
{serverObject?.icon == undefined ? (
<>
Default (<code>OAK_SIGN</code>)
</>
) : (
<code>{serverObject?.icon}</code>
)}
</td>
</tr>
<tr>
<th className="border p-2">All-time joins</th>
<td className="border p-2">
{serverObject?.joins == undefined
? "? (unknown)"
: serverObject?.joins}
</td>
</tr>
<tr>
<th className="border p-2">Server Type</th>
<td className="border p-2">
{serverObject?.server_version_type == undefined ? (
"? (unknown)"
) : (
<>
{serverObject?.server_version_type.toLowerCase()}
</>
)}
</td>
</tr>
<tr>
<th className="border p-2">Server Platform</th>
<td className="border p-2">
{serverObject?.platform == undefined
? "? (unknown)"
: serverObject?.platform}
</td>
</tr>
</table>
</CardContent>
</Card>
<br className="sm:hidden" />
<Card>
<CardHeader>
<CardTitle>
<div>
<span>Technical Info</span>
<Tooltip>
<TooltipContent className="font-normal tracking-normal">
Copy JSON data about the server
</TooltipContent>
<TooltipTrigger>
<Button
className="justify-right ml-2"
size="icon"
variant="secondary"
onClick={() => {
setCopied(true);
try {
navigator.clipboard.writeText(
JSON.stringify({
minehut: serverObject,
mhsf: mhsf.getMHSF(),
})
);
} catch {
toast.error(
"Clipboard is inaccessible. Cannot copy"
);
}
toast.success(
<div className="block w-[300px]">
Copied the following: <br />{" "}
<code className="flex items-center">
{JSON.stringify({
minehut: serverObject,
mhsf,
}).substring(0, 36)}
...
</code>
</div>
);
setTimeout(() => setCopied(false), 1000);
}}
>
{!copied && <Copy size={16} />}
{copied && <CheckmarkIcon />}
</Button>
</TooltipTrigger>
</Tooltip>
</div>
</CardTitle>
<CardDescription>
Technical information about the server{" "}
</CardDescription>
</CardHeader>
<CardContent>
<table className="table-auto w-full">
<tr>
<th className="border p-2">Visible</th>
<td className="border p-2">
{serverObject?.visibility == undefined
? "? (unknown)"
: toJSX(serverObject?.visibility)}
</td>
</tr>
<tr>
<th className="border p-2">Server Port</th>
<td className="border p-2">
{serverObject?.port == undefined ? (
"? (unknown)"
) : (
<code>{serverObject?.port}</code>
)}
</td>
</tr>
<tr>
<th className="border p-2">Storage Node</th>
<td className="border p-2">
{serverObject?.storage_node == undefined
? "? (unknown)"
: serverObject?.storage_node.toUpperCase()}
</td>
</tr>
<tr>
<th className="border p-2">Server ID</th>
<td className="border p-2 break-all">
{serverObject?._id == undefined ? (
"? (unknown)"
) : (
<code>{serverObject?._id}</code>
)}
</td>
</tr>
</table>
</CardContent>
</Card>
</div>
)}
{view == "icons" && (
<div className="col-span-4">
<p>
Purchased Icons are icons that are under the server's
ownership, they may or may not available at that certain
moment either.
</p>
{serverObject?.purchased_icons.length == 0 && <NoItems />}
{serverObject?.purchased_icons.map((icon) => (
<Card key={icon} className="my-4">
<CardContent
className="pt-4 flex items-center"
style={{
color: getIndexFromRarity(
icons?.find((c) => c._id === icon)?.rank.toLowerCase()
).text,
}}
>
<IconDisplay
server={{
icon: icons?.find((c) => c._id === icon)?.icon_name,
}}
className="mr-2"
/>
{icons?.find((c) => c._id === icon)?.display_name}
<Tooltip>
<TooltipTrigger>
<Info size={18} className="ml-2" />
</TooltipTrigger>
<TooltipContent>
Just because an item is available, it doesn't directly{" "}
<br />
mean that it can be bought immediately, it just means
its in the <br />
pool of icons that are in the weekly rotation.
<br />
<br />
<span className="flex items-center">
<span className="mr-1">Available currently:</span>
{toJSX(
icons?.find((c) => c._id === icon)?.available
)}
</span>
<span className="flex items-center">
<span className="mr-1">Disabled currently:</span>
{toJSX(
icons?.find((c) => c._id === icon)?.disabled
)}
</span>
<span className="flex items-center">
<span className="mr-1">Price:</span>
<Banknote size={16} className="mr-1" />
{icons?.find((c) => c._id === icon)?.price} credits
</span>
</TooltipContent>
</Tooltip>
<span
className="mx-2 p-1 pr-2 rounded italic font-bold"
style={{
backgroundColor: getIndexFromRarity(
icons
?.find((c) => c._id === icon)
?.rank.toLowerCase()
).bg,
}}
>
{icons
?.find((c) => c._id === icon)
?.rank.toLocaleUpperCase()}
</span>
</CardContent>
</Card>
))}
</div>
)}
</div>
</div>
<br />
<br />
</FadeIn>
</>
);
}
function toJSX(boolean?: boolean) {
if (boolean) {
return <div className="text-green-400">True</div>;
}
if (boolean == undefined) {
return <div className="text-gray-400">N/A</div>;
}
return <div className="text-red-400">False</div>;
}

@ -1,84 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
"use client";
import { getCustomization } from "@/lib/api";
import { useEffect, useState } from "react";
import useTotalBannerSize from "@/lib/hooks/use-total-banner-size";
export default function Banner({ server }: { server: string }) {
const [bannerURL, setBannerURL] = useState("");
const [loading, setLoading] = useState(true);
const { bannerSize } = useTotalBannerSize();
useEffect(() => {
getCustomization(server).then((c) => {
if (c != null) {
setLoading(false);
setBannerURL(c.banner == undefined ? "" : c.banner);
} else {
setLoading(false);
}
});
}, [server]);
if (loading) {
return (
<>
<br />
</>
);
}
return (
<>
{bannerURL != "" && (
<img
src={
bannerURL.startsWith("https://i.imgur.com")
? bannerURL
: "wsrv.nl/?url=" + encodeURIComponent(bannerURL) + "?n=-1"
}
className="rounded align-middle block ml-auto mr-auto absolute left-0 z-0 w-full object-fill"
alt="User-provided banner for this server."
style={
{
"-webkit-mask-image":
"linear-gradient(to top, transparent, black)",
maskImage: "linear-gradient(to top, transparent, black)",
top: `${bannerSize * 32 + 36}px`,
} as React.CSSProperties
}
/>
)}
<br />
</>
);
}

@ -1,267 +0,0 @@
"use client";
import {
ArrowUpToLine,
Bell,
BookIcon,
Check,
Globe,
Home,
Keyboard,
Link,
Lock,
Menu,
MessageCircle,
Paintbrush,
Settings,
Video,
} from "lucide-react";
import * as React from "react";
import Marquee from "@/components/effects/marquee";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Separator } from "@/components/ui/separator";
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarProvider,
SidebarSeparator,
} from "@/components/ui/sidebar";
import { useDepTheme } from "@/lib/getDependentTheming";
import { BorderTopIcon } from "@radix-ui/react-icons";
import { ReactNode, useState } from "react";
import type { SVGProps } from "react";
export function Changelog({
items,
children,
}: {
items: { name: string; id: string; changelog: ReactNode }[];
children: ReactNode;
}) {
const [inTab, setInTab] = useState(false);
const [tab, setTab] = useState("");
const iconTheme = useDepTheme();
return (
<Dialog>
<DialogTrigger asChild>{children}</DialogTrigger>
<DialogContent className="md:overflow-hidden p-0 max-h-[500px] md:max-w-[700px] lg:max-w-[800px]">
<SidebarProvider>
<Sidebar
collapsible="none"
className="hidden md:flex md:max-h-[500px]"
>
<SidebarContent>
<SidebarGroup>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton
isActive={!inTab}
onClick={() => {
setInTab(false);
setTab("");
}}
>
<ArrowUpToLine /> Top
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarSeparator />
{items.map((item) => (
<SidebarMenuItem key={item.name}>
<SidebarMenuButton
asChild
isActive={tab === item.id}
onClick={() => {
setTab(item.id);
setInTab(true);
}}
>
<span>{item.name}</span>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<main className="flex h-[480px] flex-1 flex-col overflow-hidden">
<div className="flex flex-1 flex-col gap-4 overflow-y-auto p-4 pt-4">
<DialogTitle>Changelog</DialogTitle>
{!inTab && (
<>
<div className="md:grid md:grid-cols-3 gap-1.5">
<Button
className="text-sm hover:h-[60px] animate-all group block max-md:w-full max-md:mt-2"
onClick={() =>
window.open(
"https://discord.com/invite/cCyEeUs",
"_blank",
)
}
>
<span className="group-hover:underline flex items-center">
<Discord className="mr-2" /> Discord
</span>
<Marquee
className="hidden group-hover:flex font-normal"
style={{ "--duration": "15s" }}
>
Join the offical Minehut Discord server! Talk to people
that like MHSF too!
</Marquee>
</Button>
<Button
className="text-sm max-md:w-full max-md:mt-2 hover:h-[60px] animate-all group block "
onClick={() =>
window.open(
"https://github.com/DeveloLongScript/MHSF",
"_blank",
)
}
>
<span className="group-hover:underline flex items-center">
<Github className="mr-2" fill={iconTheme} /> Star on
GitHub
</span>
<Marquee
className="hidden group-hover:flex font-normal"
style={{ "--duration": "10s" }}
>
Support the development of MHSF by starring it on
GitHub!
</Marquee>
</Button>
<Button
className="text-sm max-md:w-full max-md:mt-2 hover:h-[60px] animate-all group block "
onClick={() => window.open("/docs", "_blank")}
>
<span className="group-hover:underline flex items-center">
<BookIcon className="mr-2" size={16} /> See the docs
</span>
<Marquee
className="hidden group-hover:flex font-normal"
style={{ "--duration": "10s" }}
>
See more information about MHSF and how to use it
</Marquee>
</Button>
</div>
<div>
Running on commit{" "}
<code>
<a
href={`https://github.com/DeveloLongScript/mhsf/commit/${process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA}`}
>
{(
process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA ||
"unknown"
).substring(0, 7)}
</a>{" "}
{process.env.NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID !=
undefined &&
process.env.NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID !=
"" && (
<>
{" "}
| on PR{" "}
<a
href={`https://github.com/DeveloLongScript/MHSF/pull/${process.env.NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID}`}
>
{
process.env
.NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID
}
</a>{" "}
by{" "}
<a
href={`https://github.com/${process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME}`}
>
{
process.env
.NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME
}
</a>
</>
)}{" "}
{process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE !=
undefined &&
`| ${process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE.substring(0, 24)}`}
</code>
</div>
{items.map((item) => (
<div key={item.id} id={item.id}>
<Separator />
<br />
{item.changelog}
</div>
))}
</>
)}
{inTab && (
<>
<div>{items.find((c) => c.id === tab)?.changelog}</div>
</>
)}
</div>
</main>
</SidebarProvider>
</DialogContent>
</Dialog>
);
}
const Github = (props: SVGProps<SVGSVGElement>) => (
<svg
viewBox="0 0 256 250"
width="1em"
height="1em"
fill="#24292f"
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid"
{...props}
>
<path d="M128.001 0C57.317 0 0 57.307 0 128.001c0 56.554 36.676 104.535 87.535 121.46 6.397 1.185 8.746-2.777 8.746-6.158 0-3.052-.12-13.135-.174-23.83-35.61 7.742-43.124-15.103-43.124-15.103-5.823-14.795-14.213-18.73-14.213-18.73-11.613-7.944.876-7.78.876-7.78 12.853.902 19.621 13.19 19.621 13.19 11.417 19.568 29.945 13.911 37.249 10.64 1.149-8.272 4.466-13.92 8.127-17.116-28.431-3.236-58.318-14.212-58.318-63.258 0-13.975 5-25.394 13.188-34.358-1.329-3.224-5.71-16.242 1.24-33.874 0 0 10.749-3.44 35.21 13.121 10.21-2.836 21.16-4.258 32.038-4.307 10.878.049 21.837 1.47 32.066 4.307 24.431-16.56 35.165-13.12 35.165-13.12 6.967 17.63 2.584 30.65 1.255 33.873 8.207 8.964 13.173 20.383 13.173 34.358 0 49.163-29.944 59.988-58.447 63.157 4.591 3.972 8.682 11.762 8.682 23.704 0 17.126-.148 30.91-.148 35.126 0 3.407 2.304 7.398 8.792 6.14C219.37 232.5 256 184.537 256 128.002 256 57.307 198.691 0 128.001 0Zm-80.06 182.34c-.282.636-1.283.827-2.194.39-.929-.417-1.45-1.284-1.15-1.922.276-.655 1.279-.838 2.205-.399.93.418 1.46 1.293 1.139 1.931Zm6.296 5.618c-.61.566-1.804.303-2.614-.591-.837-.892-.994-2.086-.375-2.66.63-.566 1.787-.301 2.626.591.838.903 1 2.088.363 2.66Zm4.32 7.188c-.785.545-2.067.034-2.86-1.104-.784-1.138-.784-2.503.017-3.05.795-.547 2.058-.055 2.861 1.075.782 1.157.782 2.522-.019 3.08Zm7.304 8.325c-.701.774-2.196.566-3.29-.49-1.119-1.032-1.43-2.496-.726-3.27.71-.776 2.213-.558 3.315.49 1.11 1.03 1.45 2.505.701 3.27Zm9.442 2.81c-.31 1.003-1.75 1.459-3.199 1.033-1.448-.439-2.395-1.613-2.103-2.626.301-1.01 1.747-1.484 3.207-1.028 1.446.436 2.396 1.602 2.095 2.622Zm10.744 1.193c.036 1.055-1.193 1.93-2.715 1.95-1.53.034-2.769-.82-2.786-1.86 0-1.065 1.202-1.932 2.733-1.958 1.522-.03 2.768.818 2.768 1.868Zm10.555-.405c.182 1.03-.875 2.088-2.387 2.37-1.485.271-2.861-.365-3.05-1.386-.184-1.056.893-2.114 2.376-2.387 1.514-.263 2.868.356 3.061 1.403Z" />
</svg>
);
const Discord = (props: SVGProps<SVGSVGElement>) => (
<svg
viewBox="0 0 256 199"
width="1em"
height="1em"
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid"
{...props}
>
<path
d="M216.856 16.597A208.502 208.502 0 0 0 164.042 0c-2.275 4.113-4.933 9.645-6.766 14.046-19.692-2.961-39.203-2.961-58.533 0-1.832-4.4-4.55-9.933-6.846-14.046a207.809 207.809 0 0 0-52.855 16.638C5.618 67.147-3.443 116.4 1.087 164.956c22.169 16.555 43.653 26.612 64.775 33.193A161.094 161.094 0 0 0 79.735 175.3a136.413 136.413 0 0 1-21.846-10.632 108.636 108.636 0 0 0 5.356-4.237c42.122 19.702 87.89 19.702 129.51 0a131.66 131.66 0 0 0 5.355 4.237 136.07 136.07 0 0 1-21.886 10.653c4.006 8.02 8.638 15.67 13.873 22.848 21.142-6.58 42.646-16.637 64.815-33.213 5.316-56.288-9.08-105.09-38.056-148.36ZM85.474 135.095c-12.645 0-23.015-11.805-23.015-26.18s10.149-26.2 23.015-26.2c12.867 0 23.236 11.804 23.015 26.2.02 14.375-10.148 26.18-23.015 26.18Zm85.051 0c-12.645 0-23.014-11.805-23.014-26.18s10.148-26.2 23.014-26.2c12.867 0 23.236 11.804 23.015 26.2 0 14.375-10.148 26.18-23.015 26.18Z"
fill="#5865F2"
/>
</svg>
);

@ -1,48 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
"use client";
import FadeIn from "react-fade-in";
export default function ClientFadeIn({
children,
delay = 0,
id,
}: {
children: React.ReactNode;
delay?: number;
id?: string;
}) {
return (
<div id={id}>
<FadeIn delay={delay}>{children}</FadeIn>
</div>
);
}

@ -1,77 +0,0 @@
/*
* MHSF, Minehut Server List
* All external content is rather licensed under the ECA Agreement
* located here: https://list.mlnehut.com/docs/legal/external-content-agreement
*
* All code under MHSF is licensed under the MIT License
* by open source contributors
*
* Copyright (c) 2024 dvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
"use client";
import { getCustomization } from "@/lib/api";
import { useEffect, useState } from "react";
import "@/themes.css";
import { toast } from "sonner";
import { useRouter } from "@/lib/useRouter";
import { useEffectOnce } from "@/lib/useEffectOnce";
export default function ColorProvider({
server,
children,
fetchV,
}: {
server: string;
children: any;
fetchV?: any;
}) {
const [color, setColor] = useState("zinc");
const nav = useRouter();
useEffectOnce(() => {
fetch("https://api.minehut.com/server/" + server + "?byName=true")
.then((c) => c.json())
.then((c: any) => {
console.log(c.server.name, server);
if (c.server.name !== server) {
toast.warning(
"The capitalization of this server was incorrect. If your using a permanent link resource, please change it to account for a new name. (" +
c.server.name +
") Redirecting now.",
{ duration: 15000 }
);
nav.replace("/server/" + c.server.name);
}
});
});
useEffect(() => {
if (!fetchV)
getCustomization(server).then((v) =>
setColor(v != null ? v.colorScheme : "zinc")
);
else setColor(fetchV.colorScheme);
}, []);
return <div className={`theme-${color}`}>{children}</div>;
}

Some files were not shown because too many files have changed in this diff Show More