Wrap up Docs

This commit is contained in:
Pengu 2024-04-28 13:15:54 -05:00
parent 70221f7498
commit 56575134d2
45 changed files with 118 additions and 3277 deletions

View File

@ -4,9 +4,6 @@ slug: /intro
# Introduction
Welcome to the official source of documentation for the DiskCraft
project.
:::info
This documentation might have missed something, so we'll try and keep it updated as much as possible!
@ -16,8 +13,4 @@ This documentation might have missed something, so we'll try and keep it updated
## Getting Help
If you're ever confused or need help, do not hesitate to join our
[Discord](https://discord.gg/pVH5EMeeEE) for support.
## Purpose of DiskCraft
DiskCraft was created between two companies who needed a billing system and didn't want to pay a ton of money for one. DiskCraft is free because it can be! It's a good solution for Pterodactyl hosting and VPS hosting, and isn't the worst.
[Discord](https://discord.gg/BkmEarDQxq) for support.

View File

@ -1,153 +0,0 @@
---
title: Installing or Updating Java
slug: /java-install-update
description: How to install or update to Java 17 on Linux (apt/rpm), Windows, or Mac.
toc_max_heading_level: 5
---
Installing Java is a critical first step to using or developing plugins for Paper, Velocity, and
Waterfall. This guide will walk you through the recommended installation steps for most major
platforms.
:::tip
This guide focuses on Amazon's Corretto OpenJDK distribution. This is because it offers the best
installation experience on the most platforms. Corretto is, however, not the only OpenJDK vendor to
choose from. Many alternatives exist such as [Eclipse Adoptium](https://adoptium.net/),
[Microsoft](https://www.microsoft.com/openjdk) and
[Azul Zulu](https://www.azul.com/downloads/?package=jdk). Note that the JDK Oracle distributes,
while functionally identical, is **not** recommended due to an extremely unfriendly installer and
previous hostile licensing.
:::
## Linux
### Ubuntu/Debian
Installing Java 17 on Debian-based Linux distributions is very simple. First, ensure your system has
all required tools to successfully install Java.
```bash
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install software-properties-common ca-certificates apt-transport-https curl
```
Second, import the Amazon Corretto public key and apt repository.
```bash
curl https://apt.corretto.aws/corretto.key | sudo apt-key add -
sudo add-apt-repository 'deb https://apt.corretto.aws stable main'
```
Then, install Java 17.
```bash
sudo apt-get update
sudo apt-get install -y java-17-amazon-corretto-jdk
```
Proceed to [verify your installation](#verifying-installation).
### RPM-based
To install Java 17 on CentOS, RHEL, Fedora, openSUSE, SLES, or any other RPM-based Linux
distribution, execute the following commands depending on your package manager. Once you have
finished, precede to [verify your installation](#verifying-installation).
#### DNF
DNF is used on Fedora, CentOS/RHEL 7+, and related distributions.
```bash
sudo rpm --import https://yum.corretto.aws/corretto.key
sudo curl -Lo /etc/yum.repos.d/corretto.repo https://yum.corretto.aws/corretto.repo
sudo dnf -y install java-17-amazon-corretto-devel
```
#### Zypper
Zypper is used on openSUSE, SLES, and related distributions.
```bash
sudo zypper addrepo https://yum.corretto.aws/corretto.repo
sudo zypper refresh
sudo zypper install java-17-amazon-corretto-devel
```
#### YUM
YUM is used on older releases of CentOS/RHEL, and excessively old releases of Fedora.
```bash
sudo rpm --import https://yum.corretto.aws/corretto.key
sudo curl -Lo /etc/yum.repos.d/corretto.repo https://yum.corretto.aws/corretto.repo
sudo yum -y install java-17-amazon-corretto-devel
```
## Windows 10 & 11
If you're on Windows 10 or 11, installing Java is just like installing any other program. Download
the Amazon Corretto installer from
[their website](https://corretto.aws/downloads/latest/amazon-corretto-17-x64-windows-jdk.msi).
Once you have run the installer, it is safe to click "next" through the whole process. No additional
bloatware or toolbars will be installed, and all the required features are enabled out of the box.
Now, open a command prompt and precede to [verify your installation](#verifying-installation).
## macOS/OS X
If you're on macOS, the best way to manage Java installations is with a tool called
[Homebrew](https://brew.sh). Follow the instructions on their homepage to install it. Then, in your
terminal run the following command:
```bash
brew install openjdk@17
```
Once this command has completed, continue to [verify your installation](#verifying-installation).
## Pterodactyl
:::note
On Pterodactyl versions lower than `1.2.0`, an administrator account is required to change the Java
version. These instructions will not apply.
:::
If you have started a Paper server with an incorrect Java version, Pterodactyl will automatically
prompt you to update like this:
![Pterodactyl Automatic Prompt](pterodactyl-prompt.png)
If this does not show up for you, the Java version can be manually changed. Navigate to the
"Startup" tab of your server, select `ghcr.io/pterodactyl/yolks:java_17` from the "Docker Image"
dropdown as shown in the image below.
![Pterodactyl Manual Java Version Change](pterodactyl-manual.png)
The Verifying Installation section does not apply for Pterodactyl.
## Verifying Installation
Now that you have installed Java 17, run this command in your terminal to ensure the process was
successful.
```bash
java -version
```
The output should be similar to this. The important parts to look out for is that it starts with
`openjdk 17` and contains `64-Bit` in the last line. If the output you get is similar to
`java: command not found`, try creating a new terminal session.
```
openjdk 17 2021-09-14 LTS
OpenJDK Runtime Environment Corretto-17.0.0.35.1 (build 17+35-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.0.35.1 (build 17+35-LTS, mixed mode, sharing)
```
If your installation has failed, do not hesitate to reach out in the `#paper-help` channel of our
[Discord](https://discord.gg/papermc) for support.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

View File

@ -1,10 +0,0 @@
# Welcome to the Dino Wiki
Dino is a simple open source billing panel for hosters,
it offers easy integration with Pterodactyl
:::note
Dino Is a re-brand of DiskCraft, you may see terms (Links/Files) that reference DiskCraft. This is normal and can be ignored.
:::

View File

@ -1,214 +0,0 @@
# Getting Started
:::note
This is v1 of Dino, v2 is not publicly released yet. It may be licensed, join our discord to watch for updates.
:::
![Image](https://downloads.diskcraft.xyz/static/img/example02.png)
## Requirements
:::tip
If you need help just join the discord and a developer or owner will be happy to help!
:::
| Dependencies | Recommended Version |
| -------------- | ------------------------ |
| OS | Ubuntu Server 18+ |
| NodeJS | 14.0+ |
| Redis | Latest |
| Nginx | Latest |
| Certbot | Latest |
| PM2 | Latest |
## Installing NodeJS
**1.** `sudo apt update`
**2.** `curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -`
**3.** `sudo apt -y install nodejs`
NodeJS 14 is now installed
### Installing the rest of the dependencies
**1.** `sudo apt install redis-server`
**2.** `sudo apt install nginx`
**3.** `sudo apt install -y python3-certbot-nginx`
**4.** `npm i pm2 -g`
## Downloading Dino
Download the source code for Dino
[Here](https://downloads.dinopanel.net/).
Download the API, WEB, NL, and Configs!
## Configuration
In order for Dino to work you'll need to configure some things
Open your code editor, and navigate to `src/App.vue`
scroll down to `api_default: "null"` and replace null with your subdomain with `/api` at the end (https://billing.yourdomain.com/api)
Open `src/views/admin/log.vue` and navigate to line 141 and change `https://panel.yourdomain.com` to whatever your Pterodactyl panel link is
That's all for Web! (Unless you plan on making some console modifications of your own)
## Settings up MYSQL
Unzip `configs.zip` and grab the file `diskcraft.sql`
Create your database
If your using PHPMyAdmin you can import the file via web after you've created your database
However if your using CLI run this command in the directory your sql file is: `sudo mysql -u <username> -p <database_name> < bil.sql`
once thats done you can open your database via a DB client or PHPMyAdmin and see all the tables, do not remove any of them under any circumstance as it may break your panel.
## Setting up your Certificate
In order to proceed with the rest of the steps, you need to install your domain certificate
Run this command: `sudo certbot certonly --standalone -d yourdomain.com`
## Settings up NGINX
In the configs folder grab `diskcraft`
Find `server_name` under both server for port 80 and 443 and change billing.yourdomain.com to your subdomain
On the ssl_certificate lines change the billing.yourdomain.com pem to your subdomain
Find `proxy_pass` and change the IP to your systems IP address (needs to have http)
Now upload this file to /etc/nginx/sites-available
Run this command: `sudo ln -s /etc/nginx/sites-available/Dino /etc/nginx/sites-enabled/Dino`
Now restart NGINX with `systemctl restart nginx`
## Building and uploading the Panel
Open CMD in the web directory and run the following commands (only after you've added your domain in App.vue)
**1.** `npm i`
**2.** `npm run build`
**3.** `mkdir /var/www/Dino`
**3.** Upload the contents of **/dist** to **/var/www/Dino**
## Setting up PayPal
Head over to [PayPal Developer](https://developer.paypal.com/developer/applications).
Sign into PayPal, then click **My apps & credentials**
Click Live and Create an App
Name the App and click Create
Now Grab your Client ID and Client Secret and keep them noted, you'll need these for the API
## Setting up the API
First do `ufw allow 2250` and `ufw allow 2251`
In **/root** make a folder called **api** and cd into it
Run `sudo npm i secure-random-password jwks-rsa && sudo npm i @paypal/checkout-server-sdk`
Upload the contents of the API zip you downloaded earlier into it
Now open **config.js** and you'll see a blank config. Fill out all the information as it should be (do not touch **api: {
port: 2251,
base_url: "/api")**
Most of these fields are self explanatory, however you should remember to take the PayPal app credentials you got earlier and put them under the `paypal: {` area.
Return URL and Cancel URL should just be the base link of the site
If your just using Pterodactyl make sure under **capabilities: {** that **pterodactylServer:** is set to `true`
:::warning
Discord Auth is not currently finished, so we recommend keeping it set to false.
:::
:::info
There are no VPS documentation, unless you can figure it out for yourself and submit a pull request for documentation it will not be here.
:::
Next go to your Pterodactyl panel and go to **Admin > Application API** and Generate an API key with full permissions.
Put that key in the **Key:** value under **pterodactyl: {**
As for **Server:** that's just your panel link
## Starting the API
**1.** `pm2 start ./index.js --name panel-server`
**2.** `pm2 startup` and `pm2 save`
Now do `pm2 log panel-server` to see if its throwing any errors
If it's not throwing errors your all good to go!
## Setting up NL
Upload the NL file to the root folder of your Pterodactyl nodes (does not have to be on the panel)
Install PM2: `npm i pm2 -g`
Run `chmod a+x NL`
Then `ufw allow 12645`
Now `pm2 start ./NL --name Link`
Finally run `pm2 startup` and `pm2 save`
### The panel is officially running!!!!
## Creating Products and Categories
Other than pages and functions, nothing is hard coded. This means that creating products and categories are immediate and don't require you to rebuild your site.
First open **pterodactyl_package_category**
| code | name | container_template | nodes |
| -------------- | ----------------------| ---------------------------------------------------------------------- |-------- |
| minecraft_java | Minecraft Java | [Click to Download](https://downloads.dinopanel.net/diskcraft/ct.conf) | FQDN |
Categories are made like that, the container template has the egg information as well as startup script and environmental variables
The nodes field is meant for whitelisting, allowing only certain products on certain nodes. If you have two nodes and only one of them is in a minecraft field only one node can have minecraft deployed to it
Now open **pterodactyl_packages**
| code | name | price | ram | disk | cpu | databases | backups | category |
| ---------------- | ------------------------ | ----- | ---- | ---- | --- | --------- | ------- | -------------- |
| minecraft_java_1 | 1GB Java | 1.25 | 1024 | 4096 | 200 | 1 | 1 | minecraft_java |
That is the layout for a game package
**pterodactyl_servers** shows all servers deployed via the billing system
**users** shows all users registered on the billing system. You can change their usernames, emails, account balances, ect. However you cannot and should never attempt to change their passwords. They should do that themselves via a reset email, you cannot view user passwords as they are encrypted.

View File

@ -1,212 +0,0 @@
---
slug: /paper/aikars-flags
---
# Aikar's Flags
## Recommended JVM Startup Flags
Use these flags exactly, only changing Xmx and Xms. These flags work and scale accordingly to any
size of memory, even 500MB but modern Minecraft versions will not do well with such low memory.
```bash
java -Xms10G -Xmx10G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200
-XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch
-XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M
-XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4
-XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90
-XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem
-XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs
-Daikars.new.flags=true -jar paperclip.jar nogui
```
:::caution Do not allocate all of your available memory on a shared host!
When setting the Xms and Xmx values, if your host says you have 8000M memory, DO NOT USE 8000M!
Minecraft (and Java) needs additional memory on top of that Xmx parameter. It is recommended to
reduce your Xmx/Xms by about **1000-1500M** to avoid running out of memory or "OOMKiller" hitting
your server. This also leaves room for the Operating System to use memory too. **Have 8000M memory?
Use 6500M for safety.** _But you may also ask your host if they will cover this overhead for you and
give you 9500M instead. Some hosts will! Just ask._
:::
## Recommended Memory
**We recommend using at least 6-10GB**, no matter how few players! If you can't afford 10GB of
memory, give as much as you can, but ensure you leave the operating system some memory too. G1GC
operates better with more memory.
However, more memory does not mean better performance above a certain point. Eventually you will hit
a point of diminishing returns. Going out and getting 32GB of RAM for a server will only waste your
money with minimal returns.
If you are running with 12GB or less memory for MC, you should not adjust these parameters.
### If you are using an Xmx value greater than 12G
If you have and use more than 12GB of memory, adjust the following:
- `-XX:G1NewSizePercent=40`
- `-XX:G1MaxNewSizePercent=50`
- `-XX:G1HeapRegionSize=16M`
- `-XX:G1ReservePercent=15`
- `-XX:InitiatingHeapOccupancyPercent=20`
:::tip
If you see increase in old generation collections after this, revert to the base flags!
:::
Explanation of these changes:
- Base flag set aims for 30/40 to reduce risk of to space issues. With more memory, less of an
issue. We can give more to new generation with 40/50, as well as reduce reserve percent since the
default reserve will already be larger.
- Region Size increase helps reduce humongous allocations, and speeds up remarking. We need a
smaller region size at smaller heaps to ensure an adequate amount of regions available
- We can start looking for old generation memory to reclaim with more of a delay with IHOP at 20
since we have more old generation available to space on CPU.
## Java GC Logging
Are you having old gen issues with these flags? Add the following flags based on your java version
to enable GC Logging:
**Java 8-10**
```bash
-Xloggc:gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=1M
```
**Java 11+**
```bash
-Xlog:gc*:logs/gc.log:time,uptime:filecount=5,filesize=1M
```
GC logging does not hurt your performance and can be left on at all times. The files will not take
up much space (5MB)
## Technical Explanation of the Flags
1. **-Xms matching -Xmx -- Why:** You should never run your server with the case that -Xmx can run
the system completely out of memory. Your server should always be expected to use the entire
-Xmx! You should then ensure the OS has extra memory on top of that Xmx for non MC/OS level
things. Therefore, you should never run MC with -Xmx settings you can't support if java uses it
all. Now, that means if -Xms is lower than -Xmx **YOU HAVE UNUSED MEMORY! Unused memory is
wasted memory.** G1 operates better with the more memory it's given. G1 adaptively chooses how
much memory to give to each region to optimize pause time. If you have more memory than it needs
to reach an optimal pause time, G1 will simply push that extra into the old generation, and it
will not hurt you The fundamental idea of improving GC behavior is to ensure short-lived objects
die young and never get promoted. With the more memory G1 has, the better assurance you will get
that objects are not getting prematurely promoted to the old generation. G1 Operates differently
than previous collectors and is able to handle larger heaps more efficiently.
If it does not need the memory given to it, it will not use it. The entire engine operates
differently and does not suffer from too large of heaps, and this is industry-wide accepted
information that under G1 to keep Xms and Xmx the same!
2. **UnlockExperimentalVMOptions** -- needed for some the below options
3. **G1NewSizePercent:** These are the important ones. You now can specify percentages of an
overall desired range for the new generation. With these settings, we tell G1 to not use its
default 5% for new gen, and instead give it 40%! **Minecraft has an extremely high a memory
allocation rate, ranging to at least 800 Megabytes a second on a 30 player server! And this is
mostly short-lived objects (Block Position).**
Now, this means MC REALLY needs more focus on New Generation to be able to even support this
allocation rate. If your new gen is too small, you will be running new gen collections 1-2+
times per second, which is awful. You will have so many pauses that TPS has risk of suffering,
and the server will not be able to keep up with the cost of GC's. Then combine the fact that
objects will now promote faster, resulting in your Old Gen growing faster. Given more New Gen,
we are able to slow down the intervals of Young Gen collections, resulting in more time for
short-lived objects to die young and overall more efficient GC behavior.
4. **G1MixedGCLiveThresholdPercent:** Controls when to include regions in Mixed GC's in the Young
GC collection, keeping Old Gen tidy without doing a normal Old Gen GC collection. When your
memory is less than this percent, old gen won't even be included in 'mixed' collections. Mixed
are not as heavy as a full old collection, so having small incremental cleanups of old keeps
memory usage light.
Default is 65 to 85 depending on Java Version, we are setting to 90 to ensure we reclaim garbage
in old gen as fast as possible to retain as much free regions as we can.
5. **G1ReservePercent=20:** MC Memory allocation rate in up-to-date versions is really insane. We
run the risk of a dreaded "to-space exhaustion" not having enough memory free to move data
around. This ensures more memory is waiting to be used for this operation. Default is 10, so we
are giving another 10 to it.
6. **MaxTenuringThreshold=1:** Minecraft has a really high allocation rate of memory. Of that
memory, most is reclaimed in the eden generation. However, transient data will overflow into
survivor. Initially played with completely removing Survivor and had decent results, but does
result in transient data making its way to Old which is not good.Max Tenuring 1 ensures that we
do not promote transient data to old generation, but anything that survives 2 passes of Garbage
Collection is just going to be assumed as longer-lived.
Doing this greatly reduces pause times in Young Collections as copying data up to 15 times in
Survivor space for a tenured object really takes a lot of time for actually old memory. Ideally
the GC engine would track average age for objects instead and tenure out data faster, but that
is not how it works.
Considering average GC rate is 10s to the upwards of minutes per young collection, this does not
result in any 'garbage' being promoted, and just delays longer lived memory to be collected in
Mixed GC's.
7. **SurvivorRatio=32:** Because we drastically reduced MaxTenuringThreshold, we will be reducing
use of survivor space drastically. This frees up more regions to be used by Eden instead.
8. **AlwaysPreTouch:** AlwaysPreTouch gets the memory setup and reserved at process start ensuring
it is contiguous, improving the efficiency of it more. This improves the operating systems
memory access speed. Mandatory to use Transparent Huge Pages
9. **+DisableExplicitGC:** Many plugins think they know how to control memory, and try to invoke
garbage collection. Plugins that do this trigger a full garbage collection, triggering a massive
lag spike. This flag disables plugins from trying to do this, protecting you from their bad
code.
10. **MaxGCPauseMillis=200:** This setting controls how much memory is used in between the Minimum
and Maximum ranges specified for your New Generation. This is a "goal" for how long you want
your server to pause for collections. 200 is aiming for at most loss of 4 ticks. This will
result in a short TPS drop, however the server can make up for this drop instantly, meaning it
will have no meaningful impact to your TPS. 200ms is lower than players can recognize. In
testing, having this value constrained to an even lower number results in G1 not recollecting
memory fast enough and potentially running out of old gen triggering a Full collection. Just
because this number is 200 does not mean every collection will be 200. It means it can use up to
200 if it really needs it, and we need to let it do its job when there is memory to collect.
11. **+ParallelRefProcEnabled:** Optimizes the GC process to use multiple threads for weak reference
checking. Not sure why this isn't default...
12. **G1RSetUpdatingPauseTimePercent=5:** Default is 10% of time spent during pause updating Rsets,
reduce this to 5% to make more of it concurrent to reduce pause durations.
13. **G1MixedGCCountTarget=4:** Default is 8. Because we are aiming to collect slower, with less old
gen usage, try to reclaim old gen memory faster to avoid running out of old.
14. **G1HeapRegionSize=8M+:** Default is auto calculated. SUPER important for Minecraft, especially
1.15, as with low memory situations, the default calculation will in most times be too low. Any
memory allocation half of this size (4MB) will be treated as "Humongous" and promote straight to
old generation and is harder to free. If you allow java to use the default, you will be
destroyed with a significant chunk of your memory getting treated as Humongous.
15. **+PerfDisableSharedMem:** Causes GC to write to file system which can cause major latency if
disk IO is high -- See https://www.evanjones.ca/jvm-mmap-pause.html
## Using Large Pages
For Large Pages -- It's even more important to use -Xms = -Xmx! Large Pages needs to have all the
memory specified for it, or you could end up without the gains. This memory will not be used by the
OS anyway, so use it.
Additionally, use these flags (Metaspace is Java 8 Only, don't use it for Java7):
`-XX:+UseLargePagesInMetaspace`
### Transparent Huge Pages
Controversial feature but may be usable if you can not configure your host for real HugeTLBFS. Try
adding `-XX:+UseTransparentHugePages` but it's extremely important you also have AlwaysPreTouch set.
Otherwise, THP will likely hurt you. We have not measured how THP works for MC or its impact with
AlwaysPreTouch, so this section is for the advanced users who want to experiment.

View File

@ -1,76 +0,0 @@
---
slug: /paper/updating
---
# Updating Paper
Updating Paper is an important part of running every server. With new features and fixes coming
every day, we recommend updating at least once per week to keep your server patched for the latest
bugs. Installing updates is very simple, but it's important to know how to do it correctly.
:::caution Don't replace any JAR in a running server
Unless you know exactly what and why you're doing what you're doing, it's never a good idea to
replace any JAR in a running server, be that plugins, or Paper itself.
:::
## Step 1. Backup
This is the most important step, and yet the most frequently skipped. While it is unlikely that
updating Paper itself will cause any issues requiring you to restore from a backup, plugin
malfunctions or other accidents might! Updating is a great time to work in a backup. Having
functioning backups is essential to every server, big or small.
If you don't already have a backup plan in place, see [Backup and Recovery] where we walk through
multiple different backup or recovery strategies.
## Step 2. Update Plugins
Just like it's important to update Paper, it's equally important to keep plugins up to date. You
never know what plugin authors may be working on, be it bugfixes or new features.
A little known feature of Paper servers is the `update` folder. Here's how you use it.
1. Create a folder called `update` within the `plugins` folder.
2. One by one, download plugins you would like to update and put them in the `update` folder.
3. Restart your server, do not remove or modify any plugins outside the `update` folder.
By doing this, you are able to update all of your plugins at the same time without having the server
off, or replacing plugin JARs while the server is running. You do not need to restart your server
before updating Paper itself. This feature allows you to update both Paper and plugins all at the
same time, without needing any additional downtime.
## Step 3. Update Paper
:::tip
If you are using a shared host, your host may provide a built-in way to update! Consult their
documentation before continuing.
:::
Updating Paper itself is very simple.
1. Download a new JAR from [our downloads page](https://papermc.io/downloads)
2. Stop your server. It is not recommended and may cause issues to replace your Paper JAR while the
server is running.
3. Replace your old Paper JAR file with the new one.
4. Start your server. Watch the startup log to ensure everything goes to plan. If there are any
plugin conflicts or issues, you will see them here.
To minimize downtime caused by updates, some server owners will, rather than replacing their server
JAR, upload a new one and set their start script to use the new one on the next restart. Both of
these are valid update strategies.
:::caution Automatic Updates
While it may be convenient to install updates automatically (and Paper's [downloads api] allows you
to with ease), doing so is not recommended by Paper due to the possibility of plugin conflicts or
other issues that you may not know about. Always be present during updates, and keep a careful watch
on your server's log after the fact.
If you do choose to automatically install updates, ensure you have a functioning backup strategy in
place!
:::

View File

@ -1,98 +0,0 @@
---
slug: /paper/per-world-configuration
---
# Per World Configuration
One of the most powerful yet least understood features of the Paper configuration is setting
configuration options per world. While not every config option can be set per world, everything
under `world-settings` in either `paper.yml` or `spigot.yml` can be configured differently on a per
world basis.
## Default Values
The only world generated out of the box is `default`. Any configuration option set here will apply
to **all** loaded worlds, unless explicitly overridden. Any configuration change that does not need
to be separated by world should be made in this section.
:::info The main world
The `default` section also serves as the place to configure per world settings for the main world
(`level-name` in server.properties). An additional section created for the main world will not
supersede `default`.
:::
## Per World Values
A new section must be manually added to the bottom of the configuration file for each world which
requires a unique configuration. This section will not be automatically generated; it must be added.
Remember! YAML (the configuration format used by Paper) cares about spaces. When adding a new world,
ensure there are two spaces behind it.
For example, to disable loading the spawn chunks in `world_nether` and `world_the_end`,
configuration would be added like this:
```yaml title="paper.yml"
world-settings:
default:
keep-spawn-loaded: true
world_nether:
keep-spawn-loaded: false
world_the_end:
keep-spawn-loaded: false
```
This is a very stripped-down example. In reality, the `default` section will be much more extensive
as it contains all possible configuration options. This may look overwhelming at first, but always
remember to put new worlds at the very bottom of the configuration file.
### Inheritance
All configuration not explicitly defined for a world is inherited from the `default` section. This
means there is no need to repeat configuration options with the same value between sections, so
there is no need to copy and paste the entire `default` section into each new world created.
For a more complex real-world example: setting both different `spawn-limits` and `keep-spawn-loaded`
in two worlds.
```yaml title="paper.yml"
world-settings:
default:
spawn-limits:
monster: 70
creature: 10
ambient: 15
axolotls: 5
underground_water_creature: 5
water_creature: 5
water_ambient: 20
keep-spawn-loaded: true
world_nether:
spawn-limits:
monster: 90
resource_world:
spawn-limits:
monster: 2
creature: 15
axolotls: 8
keep-spawn-loaded: false
```
This example demonstrates the concept of inheritance. For each world, this is the effective
configuration which will be applied:
| Configuration Key | world | world_nether | world_the_end | resource_world |
| ----------------------------------------- | ------ | ------------ | ------------- | -------------- |
| `spawn-limits.monster` | `70` | `90` | `70` | `2` |
| `spawn-limits.creature` | `10` | `10` | `10` | `15` |
| `spawn-limits.ambient` | `15` | `15` | `15` | `15` |
| `spawn-limits.axolotls` | `5` | `5` | `5` | `8` |
| `spawn-limits.underground_water_creature` | `5` | `5` | `5` | `5` |
| `spawn-limits.water_creature` | `5` | `5` | `5` | `5` |
| `spawn-limits.water_ambient` | `20` | `20` | `20` | `20` |
| `keep-spawn-loaded` | `true` | `true` | `true` | `false` |
Notice that `world_the_end` was never specified in this configuration. Because of this, it inherits
all the configuration options from the `default` section. Additionally, `keep-spawn-loaded` was only
disabled in `resource_world` because in the `default` section, `keep-spawn-loaded` is set to `true`.

View File

@ -1,226 +0,0 @@
---
slug: /diskcraft/reference/diskcraft-global-configuration
---
![Image](https://downloads.diskcraft.xyz/static/img/example02.png)
# Dino Multi-Instance Config
Dino isn't just standalone, you can configure it to run in a multi instance mode. This means that you can have 1 web server, but several domains all using it and have their own unique views.
This Tutorial will seem very similar to standard installation, however all the things that are needed to run in multi-instance mode are included
## Requirements
:::tip
If you need help just join the discord and a developer or owner will be happy to help!
:::
| Dependencies | Recommended Version |
| -------------- | ------------------------ |
| OS | Ubuntu Server 18+ |
| NodeJS | 14.0+ |
| Redis | Latest |
| Nginx | Latest |
| Certbot | Latest |
| PM2 | Latest |
## Installing NodeJS
**1.** `sudo apt update`
**2.** `curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -`
**3.** `sudo apt -y install nodejs`
NodeJS 14 is now installed
### Installing the rest of the dependencies
**1.** `sudo apt install redis-server`
**2.** `sudo apt install nginx`
**3.** `sudo apt install -y python3-certbot-nginx`
**4.** `npm i pm2 -g`
## Downloading Dino
Download the source code for Dino
[Here](https://downloads.dinopanel.net).
Download the API, WEB, NL, and Configs!
## Configuration
In order for Dino to work you'll need to configure some things
Open your code editor, and navigate to `src/App.vue`
scroll down to `api_default: "null"` and replace null with your subdomain with `/api` at the end (https://test.yourdomain.com/api)
Next go to **knownHosts: {** and add your secondary domain under localhost like this: ![Image](https://downloads.dinopanel.net/static/img/example01.png)
That's all for Web! (Unless you plan on making some console modifications of your own)
## Settings up MYSQL
Unzip `configs.zip` and grab the file `diskcraft.sql`
Create your database
If your using PHPMyAdmin you can import the file via web after you've created your database
However if your using CLI run this command in the directory your sql file is: `sudo mysql -u <username> -p <database_name> < diskcraft.sql`
once thats done you can open your database via a DB client or PHPMyAdmin and see all the tables, do not remove any of them under any circumstance as it may break your panel.
## Setting up your Certificate
In order to proceed with the rest of the steps, you need to install your domain certificate
Run this command: `sudo certbot certonly --standalone -d yourdomain.com`
## Settings up NGINX
In the configs folder grab `diskcraft`
Find `server_name` under both server for port 80 and 443 and change billing.temp to your subdomain
On the ssl_certificate lines change the billing.temp pem to your subdomain
Find `proxy_pass` and change the IP to your systems IP address (needs to have http)
Now upload this file to /etc/nginx/sites-available
Run this command: `sudo ln -s /etc/nginx/sites-available/diskcraft /etc/nginx/sites-enabled/diskcraft`
Now restart NGINX with `systemctl restart nginx`
## Building and uploading the Panel
Open CMD in the web directory and run the following commands (only after you've added your domain in App.vue)
**1.** `npm i`
**2.** `npm run build`
**3.** Upload the contents of **/dist** to **/var/www/html**
## Setting up PayPal
Head over to [PayPal Developer](https://developer.paypal.com/developer/applications).
Sign into PayPal, then click **My apps & credentials**
Click Live and Create an App
Name the App and click Create
Now Grab your Client ID and Client Secret and keep them noted, you'll need these for the API
## Setting up the API
First do `ufw allow 2250` and `ufw allow 2251`
In **/var/www/html** make a folder called **api** and cd into it
Run `npm i secure-random-password jwks-rsa` and `npm i @paypal/checkout-server-sdk`
Upload the contents of the API zip you downloaded earlier into it
Now open **config.js** and you'll see a blank config. Fill out all the information as it should be (do not touch **api: {
port: 2251,
base_url: "/api")**
Most of these fields are self explanatory, however you should remember to take the PayPal app credentials you got earlier and put them under the `paypal: {` area.
Return URL and Cancel URL should just be the base link of the site
If your just using Pterodactyl make sure under **capabilities: {** that **pterodactylServer:** is set to `true`
:::warning
Discord Auth is not currently finished, so we recommend keeping it set to false
:::
We will make another version of documentation for VPS capabilities at some point, however it does indeed work.
Next go to your Pterodactyl panel and go to **Admin > Application API** and Generate an API key with full permissions.
Put that key in the **Key:** value under **pterodactyl: {**
As for **Server:** that's just your panel link
:::note
For the MultiInstance Diskcraft function, all you have to do is add the API to whatever system you want to host it on. As long as the domain your adding matches the one you put in **App.vue** it'll work
:::
## Starting the API
In order to make sure the API starts without issue you need to do this first:
**1.** Do `systemctl stop redis-server`
**2.** In the api directory do `nano redis.sh` and in that file just type `redis-server` and save it
**3.** Now run `pm2 start ./redis.sh --name Redis`
Redis is now running via PM2 instead of systemctl
**4.** `pm2 start ./index.js --name API`
**5.** `pm2 startup` and `pm2 save`
Now do `pm2 log API` to see if its throwing any errors
If it's not throwing errors your all good to go!
## Setting up NL
Upload the NL file to the root folder of your Pterodactyl nodes (does not have to be on the panel)
Install PM2: `npm i pm2 -g`
Run `chmod a+x NL`
Then `ufw allow 12645`
Now `pm2 start ./NL --name Link`
Finally run `pm2 startup` and `pm2 save`
### The panel is officially running!!!!
## Creating Products and Categories
Other than pages and functions, nothing is hard coded. This means that creating products and categories are immediate and don't require you to rebuild your site.
First open **pterodactyl_package_category**
| code | name | container_template | nodes |
| -------------- | ----------------------| ---------------------------------------------------------------------- |-------- |
| minecraft_java | Minecraft Java | [Click to Download](https://downloads.dinopanel.net/diskcraft/ct.conf) | FQDN |
Categories are made like that, the container template has the egg information as well as startup script and environmental variables
The nodes field is meant for whitelisting, allowing only certain products on certain nodes. If you have two nodes and only one of them is in a minecraft field only one node can have minecraft deployed to it
Now open **pterodactyl_packages**
| code | name | price | ram | disk | cpu | databases | backups | category |
| ---------------- | ------------------------ | ----- | ---- | ---- | --- | --------- | ------- | -------------- |
| minecraft_java_1 | 1GB Java | 1.25 | 1024 | 4096 | 200 | 1 | 1 | minecraft_java |
That is the layout for a game package
**pterodactyl_servers** shows all servers deployed via the billing system
**users** shows all users registered on the billing system. You can change their usernames, emails, account balances, ect. However you cannot and should never attempt to change their passwords. They should do that themselves via a reset email, you cannot view user passwords as they are encrypted.

View File

@ -1,31 +0,0 @@
# Art Assets
This page provides the official PaperMC logomark and the terms under which you may use it.
:::warning
The PaperMC logo is subject to its own separate licensing terms and does not inherit any from the
projects it represents.
:::
You may:
- Use the PaperMC logomark to represent the project in blogposts and other places in order to bring
attention to the project.
- Use the PaperMC logomark to represent Paper-Server in downloads, server selectors, and similar
places.
- Crop out extra transparent canvas space behind the PaperMC logomark so it fits better next to
other content.
You may not:
- Alter any of the colors used in the PaperMC logomark.
- Change the dimensions of the PaperMC logomark.
- Create modified versions of the PaperMC logomark or derivative works of it.
- Add your own project images or branding to the PaperMC logomark.
- Claim the logomark as your own work or use it as a representation of your own projects.
- Sell the PaperMC logomark on its own or as part of other products without explicit permission.
- Alter the transparency of any of the elements in the PaperMC logomark
![CCN logomark](ccn.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

View File

@ -1,28 +0,0 @@
# Contact Us
## Discord
The PaperMC project handles most communication via Discord. Use the following invite:
https://discord.gg/papermc
## IRC
Some of our Discord channels are bridged to IRC.
- [#paper on irc.esper.net](https://webchat.esper.net/?channels=paper)
## Forums
Reach out for support, or contact us on our forums.
- [Forums](https://forums.papermc.io)
## Twitter
We often tweet out version release notes, update notices, and other information via our Twitter
page.
- [@PaperPowered](https://twitter.com/PaperPowered)
You should not DM or @ this account for support. It is not checked as regularly as the above
locations.

View File

@ -1,4 +0,0 @@
# Downloads API
PaperMC provides a downloads API to facilitate automated downloads access. Full documentation can be
found on the [Downloads API Docs](https://papermc.io/api/docs).

View File

@ -1,6 +0,0 @@
# Welcome to the Waterfall Wiki
Waterfall is the BungeeCord fork that aims to improve performance and stability.
- [Getting Started](getting-started.md)
- [Configuration](configuration.md)

View File

@ -1,58 +0,0 @@
# Configuration
This page details the various configuration settings exposed by Waterfall. These settings can be
found in waterfall.yml.
If you want information on settings in BungeeCord's config.yml you should see its respective
documentation pages.
## use_netty_dns_resolver
- **default**: `true`
- **description**: Sets whether Netty's async DNS resolver is used for account authentication.
## disable_modern_tab_limiter
- **default**: `true`
- **description**: Disables the tab completion limit for 1.13+ clients.
## log_initial_handler_connections
- **default**: `true`
- **description**: Sets whether to log InitialHandler connections.
## throttling
- tab_complete
- **default**: `1000`
- **description**: How often tab-complete packets can be sent in milliseconds.
## game_version
- **default**: `` (empty string)
- **description**: The supported versions displayed to the client. Default is a comma separated list
of supported versions. For example 1.8.x, 1.9.x, 1.10.x
## disable_tab_list_rewrite
- **default**: `false`
- **description**: This setting disables tablist rewriting, which may resolve issues setting player
profiles when Waterfall is in offline mode.
## disable_entity_metadata_rewrite
- **default**: `false`
- **description**: This setting disables entity metadata rewriting in favor of sending a join packet
to the client. It offers a more robust solution for modded environments but can cause plugins to
break.
## plugin_channel_name_limit
- **default**: `128`
- **description**: The maximum channel identifier length. May be useful for certain broken mods.
## registered_plugin_channels_limit
- **default**: `128`
- **description**: The maximum number of registered plugin channels for a connection. Used by mods
and some plugins. May be useful to fix certain broken modpacks.

View File

@ -1,56 +0,0 @@
# Getting Started
## What is Waterfall?
Waterfall is a fork of BungeeCord, a proxy used primarily to teleport players between multiple
Minecraft servers.
Waterfall focuses on three main areas:
- Stability: Waterfall aims to be stable. We will achieve this through making the code base testable
and discouraging practices that lead to proxy lag.
- Features: Waterfall aims to include more features than canonical BungeeCord.
- Scalability: Waterfall should be able to handle a large number of concurrent players, given a
reasonably modern CPU, memory, and good network connection.
## Requirements
Waterfall requires **Java 8** or newer to run. The Paper team recommends you run on Java 11 or
higher. Generally, LTS versions of Java are targeted, though you may have luck on newer versions.
## Migrating From BungeeCord
Waterfall is a drop in replacements for BungeeCord, you don't need to make any changes to your
configuration.
## Getting A Proxy Jar
Paper provides runnable proxy jars directly from our [downloads
page][https://papermc.io/downloads#waterfall].
Click on the build number to download a file.
## Running The Proxy
To run the proxy, simply start it up like any other Java application.
Open your terminal, navigate to the saved location, and then run
```bash
java -Xms512M -Xmx512M -jar waterfall-###.jar
```
Aikar's recommended flags for Waterfall are as follows:
```bash
java -Xms512M -Xmx512M -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:+UnlockExperimentalVMOptions -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -jar waterfall-###.jar
```
The amount of memory can be set by changing the numbers in the `-Xms` and `-Xmx` flags.
To configure your proxy, see the [configuration](configuration.md) page.
## Updating The Proxy
To update the proxy, first stop it safely by executing the `end` command. Then replace the old proxy
jar with a new one, and start the proxy. That's it.

View File

@ -0,0 +1,3 @@
# Welcome to the Lethal-Extended Wiki
All of this is straight forward, but if you need help don't hesitate to join the Discord!

View File

@ -0,0 +1,87 @@
---
slug: /le/getting-started/addons
---
# Getting Started
:::note
This isn't a simple task and takes some time to get the hang of. If you need any help just ask in the Discord :smile:
:::
![Image](https://cdn.galactiq.net/lethalextended/docs/img/docs.png)
## Creating a name
Creating a name and general topic is an important first step! Come back to these docs when you've got that figured out.
## Packaging the mods
Add-ons should follow a similar folder structure to the base Lethal-Extended modpack, but instead it'll be located **Inside** the plugins folder.
You can download an example layout template that displays 3 additional mods in their properly formatted folders.
When it comes to copying files to the mod subfolders you need to copy 3 of the following:
1. `manifest.json`
2. `<modname>.dll`
3. `<modname>.bundle` (If applicable)
:::warning
Keep in mind, some mods have other mods they depend on. Make sure to download all dependencies and add them to your pack as well! (Also make sure to check to see if the base Lethal-Extended modpack has those dependencies already.)
:::
| layout_template |
| ------------------------------------------------------------------------------------- |
| [Click to Download](https://cdn.galactiq.net/lethalextended/docs/mysupercoolpack.zip) |
![Image](https://cdn.galactiq.net/lethalextended/docs/img/packformat.png)
## Creating your own manifest.json
A manifest file is VERY important when it comes to the upkeep of packs. On Thunderstore it acts as a list for the app to know what exactly needs to be downloaded, however, in this instance, it helps us keep track of mod versions and pack versions.
| manifest_template |
| ------------------------------------------------------------------------------------- |
| [Click to Download](https://cdn.galactiq.net/lethalextended/docs/manifest.json) |
![Image](https://cdn.galactiq.net/lethalextended/docs/img/manifest.png)
### Values:
`name`: The name of your addon.
`version_numer`: Version your addon is on. (Should go up numerically as you update it)
`website_url`: If you have a Discord for your addon you should put the invite here.
`description`: What does your pack add/do?
### The Dependencies field
The final field in your `manifest.json` is the dependencies. This tells us what mods your pack includes. When you download mods from Thunderstore you can see their dependency string.
![Image](https://cdn.galactiq.net/lethalextended/docs/img/depstring.png)
Add it to the list of dependencies and make sure after every single one you add a`,` at the end to tell the file there is another line. Also make sure each dependency string is in a set of quotation marks: ""
![Image](https://cdn.galactiq.net/lethalextended/docs/img/manifestfin.png)
## Publishing your add-on
You can create a thread in the add-ons forum of the Discord community to show off your cool new add-on! By default add-ons will be marked as pending for verification to make sure everything is configured properly and DOESN'T violate any community rules.
This newly created thread will now be your discussion area for everyone who uses or wants to use your add-on. Once approved the add-on will show up on the Lethal-Utility file
## Updating your add-on
We recommend updating your add-on regularly to address bugs. If bugs start to pile up and there hasn't been any updates to the pack after an extended period of time, it'll be removed.
## Publishing on Github
If you use Github to keep track of your commits and create release packages then you can just forward us the link if you don't want to make a post in the forum, which will allow Lethal-Utility to always be up to date on your pack.

View File

@ -1,29 +0,0 @@
# Welcome to the Velocity Wiki
Velocity is the ridiculously scalable, flexible Minecraft proxy.
## Getting started
It is simple to get started with Velocity. Get started with our
[Getting Started guide](getting-started/README.md).
## I need help
If you need some help with Velocity, please seek help in the following places:
### 📖 This Wiki
We have put a lot of effort into documenting Velocity as much as possible with our new website and
our coverage will continue to expand. We strongly encourage you to check the sidebar of the wiki for
relevant resources. Helping yourself using the resources in this wiki saves all of us time.
We recommend you visit the [frequently-asked questions](getting-started/faq.md) to begin your
search. Most common issues with Velocity are answered there.
Please do not be offended if we respond to your question linking back here. Asking us a question
already answered in the documentation doesn't help anyone.
### 💬 Our Discord
If you have searched the wiki and didn't find the answer to your question, then it is time to
[join our Discord](https://discord.gg/papermc) to ask your question.

View File

@ -1,4 +0,0 @@
# Developer's Guide
Welcome to the Velocity Developer's Guide! This guide includes information and tutorials for
developers to create and expand on Velocity plugins.

View File

@ -1,157 +0,0 @@
---
slug: /velocity/developers/command-api
---
# The Command API
The Command API lets you create commands that can be executed by a player connected to the proxy or
the console.
## Creating a command
Each command class needs to implement a `Command` subinterface. The choice depends on the type of
arguments and the granularity of suggestions provided to the client. These include:
### `BrigadierCommand`
Internally, Velocity uses the [Brigadier](https://github.com/Mojang/brigadier) library to register
and dispatch command actions. You can register your own `CommandNode`s by wrapping them in a
`BrigadierCommand`. Let's see an example of a command that will tell whoever executes the command
"Hello World" in light blue text.
```java
package com.example.velocityplugin;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.velocitypowered.api.command.BrigadierCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.plugin.Plugin;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
@Plugin(id = "helloworld")
public class HelloWorldPlugin {
public void createBrigadierCommand() {
LiteralCommandNode<CommandSource> helloNode = LiteralArgumentBuilder
.<CommandSource>literal("test")
.executes(context -> {
Component message = Component.text("Hello World", NamedTextColor.AQUA);
context.getSource().sendMessage(message);
return 1; // indicates success
})
.build();
// BrigadierCommand implements Command
BrigadierCommand command = new BrigadierCommand(helloNode);
}
}
```
Brigadier commands have full backwards-compatibility with 1.12.2 and lower versions.
Custom plugin command argument types are not supported in Velocity, as they would require the client
to also support them. We recommend sticking to the predefined Brigadier types provided.
### `SimpleCommand`
Modelled after the convention popularized by Bukkit and BungeeCord, a `SimpleCommand` has three
methods: one for when the command is executed, one to provide suggestions for tab completion, and
one to check a `CommandSource` has permission to use the command. All methods receive a
`SimpleCommand.Invocation` object, which contains the `CommandSource` that executed the command and
the arguments as an array of strings. The previous example can also be implemented using this
interface:
```java
package com.example.velocityplugin;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.command.SimpleCommand;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
public final class TestCommand implements SimpleCommand {
@Override
public void execute(final Invocation invocation) {
CommandSource source = invocation.source();
// Get the arguments after the command alias
String[] args = invocation.arguments();
source.sendMessage(Component.text("Hello World!").color(NamedTextColor.AQUA));
}
@Override
public boolean hasPermission(final Invocation invocation) {
return invocation.source().hasPermission("command.test");
}
}
```
It's important to note `invocation.arguments()` doesn't include the command alias (e.g. `teleport`
for `/teleport foo bar`). In the event that no arguments are specified, an empty array will be
passed, rather than a null array.
If a player or the console executes the following command: `/stats Player2 kills`, the first
argument will be `Player2`, which we can access using `invocation.arguments()[0]` and the second
argument will be `kills`.
### `RawCommand`
There's certain cases where you don't need to process the arguments. These may include:
- A `/say` style command, where the arguments contain the message as a string; or
- You're using an external command framework to process your commands.
A raw command indicates the proxy to pass the command alias and its arguments directly without
further processing. Let's see an example of a command that echoes the received input:
```java
package com.example.velocityplugin;
import com.velocitypowered.api.command.RawCommand;
import net.kyori.adventure.text.Component;
public final class EchoCommand implements RawCommand {
@Override
public void execute(final Invocation invocation) {
invocation.source().sendMessage(Component.text(invocation.arguments()));
}
@Override
public boolean hasPermission(final Invocation invocation) {
return invocation.source().hasPermission("command.echo");
}
}
```
## Registering a command
Now that we have created a command, we need to register it in order for it to work. To register
commands, you use the Command Manager. We get the command manager by executing
`proxyServer.getCommandManager()` with the proxy instance, or by injecting it using the `@Inject`
annotation in the main class. The register method requires two parameters, the command metadata and
the command object.
The `CommandMeta` contains the case-insensitive aliases and more advanced features. The Command
Manager provides a meta builder via the `#metaBuilder(String alias)` method.
```java
CommandMeta meta = commandManager.metaBuilder("test")
// Specify other aliases (optional)
.aliases("otherAlias", "anotherAlias")
.build();
```
Finally,
```java
commandManager.register(meta, new TestCommand());
```
If you're registering a `BrigadierCommand`, you may prefer to use the `#register(BrigadierCommand)`
method or `#metaBuilder(BrigadierCommand)` to specify additional aliases.

View File

@ -1,280 +0,0 @@
---
slug: /velocity/developers/event-api
---
# Working With Events
Listening to events with Velocity's `@Subscribe` annotation is straightforward. You've already seen
one such listener, using the ProxyInitializeEvent in your main class. Additional events can be found
on the [Javadoc](https://jd.velocitypowered.com/3.0.0/).
## Creating a listener method
To listen to an event, mark the method with `@Subscribe`, like shown. This works similarly to
annotation-driven event listening in other APIs you may be familiar with; it's the equivalent of
Bukkit's/Bungee's `@EventHandler` and Sponge's `@Listener`.
```java
@Subscribe
public void onPlayerChat(PlayerChatEvent event) {
// do stuff
}
```
:::tip
Note that the import is `com.velocitypowered.api.event.Subscribe` and _not_ in
`com.google.common.eventbus`.
:::
## Orders
Every listener has a `PostOrder`. When an event is fired, the order in which listeners are invoked
is defined by their `PostOrder`. Listeners using `PostOrder.FIRST` are called first, then EARLY,
NORMAL, etc.
State the desired order in the `@Subscribe` annotation:
```java
@Subscribe(order = PostOrder.NORMAL)
public void onPlayerChat(PlayerChatEvent event) {
// do stuff
}
```
`NORMAL` is the default value if you do not specify an order.
## Registering listeners
Velocity automatically registers your main plugin class as an event listener. This is handy for
initialization and for simple plugins, but for more complex plugins, you will want to separate your
event handlers from the main plugin class. To do so, you will need to register with the EventManager
any other listeners you have:
The event system supports registering an object as a listener (allowing you to use `@Subscribe` to
mark event handlers) or registering functional listeners.
### Registering an object as a listener
```java
server.getEventManager().register(plugin, listener);
```
Both parameters are `Object`. The first argument is your plugin's object, and the second argument
should be the listener to register. For example:
```java
@Plugin(id = "myfirstplugin", name = "My Plugin", version = "0.1.0", dependencies = {@Dependency(id = "wonderplugin")})
public class VelocityTest {
private final ProxyServer server;
private final Logger logger;
@Inject
public VelocityTest(ProxyServer server, Logger logger) {
this.server = server;
this.logger = logger;
}
@Subscribe
public void onInitialize(ProxyInitializeEvent event) {
server.getEventManager().register(this, new MyListener());
}
}
public class MyListener {
@Subscribe(order = PostOrder.EARLY)
public void onPlayerChat(PlayerChatEvent event) {
// do something here
}
}
```
### Registering a functional-style listener
As an alternative to `@Subscribe`, you can also use the functional `EventHandler` interface and
register yours with `register(Object plugin, Class<E> eventClass, EventHandler<E> handler)`:
```java
server.getEventManager().register(this, PlayerChatEvent.class, event -> {
// do something here
return null;
});
```
## Handling events asynchronously
In Velocity 3.0.0, events can now be handled asynchronously. The event system allows a plugin to
pause sending an event to every listener, perform some unit of computation or I/O asynchronously,
and then resume processing the event. All Velocity events have the ability to be processed
asynchronously, however only some will explicitly wait for events to finish being fired before
continuing.
For an annotation-based listener, all that is needed to process an event asynchronously is to either
return an `EventTask` or add a second `Continuation` parameter:
```java
@Subscribe(order = PostOrder.EARLY)
public void onLogin(LoginEvent event, Continuation continuation) {
doSomeAsyncProcessing().addListener(continuation::resume, continuation::resumeWithException);
}
@Subscribe(order = PostOrder.EARLY)
public EventTask onPlayerChat(PlayerChatEvent event) {
if (mustFurtherProcess(event)) {
return EventTask.async(() => ...);
}
return null;
}
```
A functional listener simply needs to implement `AwaitingEventExecutor` and return an `EventTask`:
```java
server.getEventManager().register(this, PlayerChatEvent.class, (AwaitingEventExecutor) event -> {
if (mustFurtherProcess(event)) {
return EventTask.async(() => ...);
}
return null;
});
```
There are two types of event tasks:
- **Async tasks** simply run a unit of execution asynchronously. To get a basic event task use
`EventTask.async(Runnable)`. Basic event tasks are the closest equivalent for Velocity 1.x.x event
listeners and asynchronous events in the Bukkit API.
- **Continuation tasks** provide the listener with a callback (known as a `Continuation`) to resume
event processing when the (possibly asynchronous) work is completed. To get a continuation-based
event task, use `EventTask.withContinuation(Consumer<Continuation>)`. Continuation-based tasks are
the closest equivalent for listeners that use BungeeCord `AsyncEvent` intents, but have a slightly
different programming model in that each listener still runs sequentially, just that an individual
listener can defer passing control onto the next listener until it is done.
:::caution
To retain compatibility with older versions of Velocity, Velocity 3.0.0 runs all event listeners
asynchronously. This behavior will change in Polymer and will require you to explicitly provide an
event task (or to use continuations) if you need to perform some work asynchronously. All developers
are urged to make the transition now.
:::
## Creating Events
Creating events on Velocity is somewhat different than on other platforms. However, it is very
similar for the most part.
### Creating the Event Class
First we need to create a class for our event. In this tutorial we'll assume you're making a private
messaging plugin, and thus use a `PrivateMessageEvent`. Most of this part is boilerplate.
```java
public class PrivateMessageEvent implements Event {
private final Player sender;
private final Player recipient;
private final String message;
public PrivateMessageEvent(Player sender, Player recipient, String message) {
this.sender = sender;
this.recipient = recipient;
this.message = message;
}
public Player sender() {
return sender;
}
public Player recipient() {
return recipient;
}
public String message() {
return message;
}
// toString, equals, and hashCode may be added as needed
}
```
You'll notice that your events don't need to extend or implement anything. They just work.
### Firing the Event
To fire the event, you'll need to get the server's event manager and use the `fire` method. Note
that this returns a `CompletableFuture`, so if you want to continue logic after the event is handled
by all listeners, use a callback:
```java
server.getEventManager().fire(new PrivateMessageEvent(sender, recipient, message)).thenAccept((event) -> {
// event has finished firing
// do some logic dependent on the result
});
```
### Using ResultedEvent
Velocity uses the generalised `ResultedEvent` for events which have some sort of 'result'. The
result type of the event is defined by its generic type; for example.
`PrivateMessageEvent implements ResultedEvent<ResultType>`.
Some common result types are `GenericResult`, for simple allowed/denied results, and component
results, used for events where the result may be denied with an accompanying reason (such as in a
login event).
Using a general result is far more encompassing than `isCancelled/setCancelled` methods you may be
used to on other platforms, whose meaning is vague and limited to a simple boolean. In this example,
we'll use `GenericResult`, so listeners will be able to mark our `PrivateMessageEvent` as either
allowed or denied.
```java
public class PrivateMessageEvent implements ResultedEvent<GenericResult> {
private final Player sender;
private final Player recipient;
private final String message;
private GenericResult result = GenericResult.allowed(); // Allowed by default
public PrivateMessageEvent(Player sender, Player recipient, String message) {
this.sender = sender;
this.recipient = recipient;
this.message = message;
}
public Player sender() {
return sender;
}
public Player recipient() {
return recipient;
}
public String message() {
return message;
}
@Override
public GenericResult result() {
return result;
}
@Override
public void setResult(GenericResult result) {
this.result = Objects.requireNonNull(result);
}
}
```
Per convention, the result of a `ResultedEvent` should never be null. Here, we assure that using
`Objects.requireNonNull`.
Listeners may 'deny' the event by using `event.setResult(GenericResult.denied())`, and you may check
the result with `event.getResult()`.

View File

@ -1,71 +0,0 @@
---
slug: /velocity/developers/scheduler-api
---
# Using the Scheduler
The Velocity Scheduler lets you decide when and how your plugin tasks run, allowing fine control
over execution. On Velocity, there is no main thread. All tasks run using the Velocity Scheduler are
thus run asynchronously.
## Running a delayed task
All scheduling works by using a `TaskBuilder` returned from the `Scheduler`. This fluent builder may
be chained to configure the details of the scheduling.
```java
server.getScheduler()
.buildTask(plugin, () -> {
// do stuff here
})
.delay(2L, TimeUnit.SECONDS)
.schedule();
```
Here, we are scheduling a task to run 2 seconds later. Velocity requires the instance of your
plugin, `plugin` above. If you are scheduling a task from your main plugin class you may simply use
`this`.
Time arguments are specified as a `long` with a `java.util.concurrent.TimeUnit`. Using time units
makes scheduling delayed tasks more readable and allows for greater precision.
`2L, TimeUnit.SECONDS` is far easier to understand than the ambiguous `2000L`.
## Running a repeating task
Creating a repeating task is similar to a delayed task, but you must also specify
`repeat(long, TimeUnit)`. This example will repeat every 5 minutes.
```java
server.getScheduler()
.buildTask(plugin, () -> {
// do stuff here
})
.repeat(5L, TimeUnit.MINUTES)
.schedule();
```
## Running a task now
Tasks use the scheduler's cached thread pool for all execution, which reuses threads. To take
advantage of this thread pool for running async tasks which run now, simply omit calling the _delay_
and _repeat_ methods of the TaskBuilder.
## Cancellation
The `schedule()` method returns a `ScheduledTask`, which may then be used to cancel the task
involved via the `cancel()` method. Tasks cannot be uncancelled.
Additionally, `task.status()` returns the current status of the task.
```java
ScheduledTask task = server.getScheduler()
.buildTask(plugin, () -> {
// do stuff here
})
.repeat(5L, TimeUnit.MINUTES)
.schedule();
// ...
task.cancel();
// ...
System.out.println(task.status());
```

View File

@ -1,129 +0,0 @@
---
slug: /velocity/developers/api-basics
---
# Velocity Plugin Basics
Now we will lay the groundwork for your first plugin. We will cover how to create your very first
Velocity plugin.
## Create the plugin class
Create a new class (let's say `com.example.velocityplugin.VelocityTest`) and paste this in:
```java
package com.example.velocityplugin;
import com.google.inject.Inject;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.proxy.ProxyServer;
import org.slf4j.Logger;
@Plugin(id = "myfirstplugin", name = "My First Plugin", version = "0.1.0-SNAPSHOT",
url = "https://example.org", description = "I did it!", authors = {"Me"})
public class VelocityTest {
private final ProxyServer server;
private final Logger logger;
@Inject
public VelocityTest(ProxyServer server, Logger logger) {
this.server = server;
this.logger = logger;
logger.info("Hello there! I made my first plugin with Velocity.");
}
}
```
What did you just do there? There's quite a bit to unpack, so let's focus on the Velocity-specific
bits:
```java
@Plugin(id = "myfirstplugin", name = "My First Plugin", version = "0.1.0-SNAPSHOT",
url = "awesome.org", description = "I did it!", authors = {"Me"})
public class VelocityTest {
```
This tells Velocity that this class contains your plugin (myfirstplugin) so that it can be loaded
once the proxy starts up. Velocity will detect where the plugin will reside when you compile your
plugin.
Moving on, what's this?
```java
@Inject
public VelocityTest(ProxyServer server, Logger logger) {
this.server = server;
this.logger = logger;
logger.info("Hello there, it's a test plugin I made!");
}
```
This looks like magic! How is Velocity doing this? The answer lies in the `@Inject`, which indicates
that Velocity should inject a ProxyServer and the Logger when constructing your plugin. These two
interfaces will help you out as you begin working with Velocity. We won't talk too much about
dependency injection: all you need to know is that Velocity will do this.
All you need to do is build your plugin, put it in your `plugins/` directory, and try it! Isn't that
nice? In the next section you'll learn more about how to use the API.
## Choosing `@Plugin` Information
Choose your plugin's ID wisely. Other plugins will use this ID to depend on yours. If you change it,
you could break compatibility.
The plugin name is somewhat less important. It will be shown to users as the display name of your
plugin, but tweaking it will not be catastrophic.
For the version, we recommend sticking to semantic versioning - you can read more about this concept
at [semver.org](https://semver.org). Basically, use 3 numbers in your version, such as 1.4.25.
Increment the major number when you make a backwards-incompatible breaking change, increment the
minor number when you add functionality that is backwards compatible, and increment the patch number
when you fix a bug or make an otherwise unnoticeable change in the implementation.
You can also describe your plugin's URL, authors, and description in your `@Plugin` annotation.
Plugin dependencies are also be specified there, but we'll get to that later.
### A word of caution
In Velocity, plugin loading is split into two steps: construction and initialization. The code in
your plugin's constructor is part of the construction phase. There is very little you can do safely
during construction, especially as the API does not specify which operations are safe to run during
construction. Notably, you can't register an event listener in your constructor, because you need to
have a valid plugin registration, but Velocity can't register the plugin until the plugin has been
constructed, causing a "chicken or the egg" problem.
To break this vicious cycle, you should always wait for initialization, which is indicated when
Velocity fires the ProxyInitializeEvent. We can do things on initialization by adding a listener for
this event, as shown below. Note that Velocity automatically registers your plugin main class as a
listener.
```java
@Subscribe
public void onProxyInitialization(ProxyInitializeEvent event) {
// Do some operation demanding access to the Velocity API here.
// For instance, we could register an event:
server.getEventManager().register(this, new PluginListener());
}
```
## Getting your Plugin's Directory
At some point you may need your plugin's directory. To do this, add
`@DataDirectory Path dataDirectory` to your plugin's constructor parameters:
```java
private final Path dataDirectory;
@Inject
public VelocityTest(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) {
this.server = server;
this.logger = logger;
this.dataDirectory = dataDirectory;
}
```
This will get you a `java.nio.file.Path` of your plugin directory. If you absolutely need a
`java.io.File`, you may use `Path#toFile()`. However, Velocity usually works with `Path`.

View File

@ -1,120 +0,0 @@
---
slug: /velocity/developers/creating-your-first-plugin
---
# Creating Your First Plugin
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
It is very simple to create a plugin for Velocity. This section will teach you how to setup your
IDE, your plugin identifiers, and give you an introduction to the basics of the Velocity API.
## Before you continue...
You will need proficiency in the Java programming language. If you don't know Java yet, we strongly
recommend you learn some basic Java before you continue.
## Set up your environment
You're going to need the [JDK](../../../common/java-install.md) and an IDE. If you don't have an
IDE, IntelliJ IDEA is recommended.
## Creating the project in your IDE
- Open your IDE
- Click `Create New Project` or the equivalent
- Select either `Gradle` or `Maven`
- Make sure your **Project JDK** is Java 8 or later
- **Finish** the dialog and open the project.
Now we have created our project, we need configure our build system.
## I know how to do this. Give me what I need!
### Maven repository
| Name | URL |
| --------- | -------------------------------------------------- |
| `papermc` | `https://papermc.io/repo/repository/maven-public/` |
### Dependency
| Group ID | Artifact ID | Version |
| --------------------- | -------------- | ------- |
| `com.velocitypowered` | `velocity-api` | `3.1.1` |
### Javadocs
Javadocs are available at [jd.velocitypowered.com/3.0.0](https://jd.velocitypowered.com/3.0.0).
## Set up your build system
You will need to setup a build system before you continue. While it is possible to write Velocity
plugins without one, having a build system will make your life a lot less difficult.
How to set up a build system is outside the scope of this page, but you can look at your build
system's documentation ([Gradle](https://docs.gradle.org/current/userguide/userguide.html) or
[Maven](https://maven.apache.org/guides/getting-started/index.html)) for assistance.
### Setting up the dependency
<Tabs groupId="author-front-matter">
<TabItem value="maven" label="Maven POM">
```xml name="pom.xml"
<project>
<repositories>
<repository>
<id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.velocitypowered</groupId>
<artifactId>velocity-api</artifactId>
<version>3.1.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
```
</TabItem>
<TabItem value="gradle-kotlin" label="Gradle Kotlin DSL" default>
```kotlin name="build.gradle.kts"
repositories {
maven {
name = "papermc"
url = uri("https://papermc.io/repo/repository/maven-public/")
}
}
dependencies {
compile("com.velocitypowered:velocity-api:3.1.1")
annotationProcessor("com.velocitypowered:velocity-api:3.1.1")
}
```
</TabItem>
<TabItem value="gradle-groovy" label="Gradle Groovy DSL">
```groovy name="build.gradle"
repositories {
maven {
name 'papermc'
url 'https://papermc.io/repo/repository/maven-public/'
}
}
dependencies {
compile 'com.velocitypowered:velocity-api:3.1.1'
annotationProcessor 'com.velocitypowered:velocity-api:3.1.1'
}
```
</TabItem>
</Tabs>

View File

@ -1,36 +0,0 @@
---
slug: /velocity/developers/pitfalls
---
# Common Pitfalls
While we try to make the API a pleasure to use, there are the occasional rough edges, and you should
be aware of them.
## Accessing the API at construction time
In Velocity, plugin loading is split into two steps: construction and initialization. The code in
your plugin's constructor is part of the construction phase. There is very little you can do safely
during construction, especially as the API does not specify which operations are safe to run during
construction. Notably, you can't register an event listener in your constructor, because you need to
have a valid plugin registration, but Velocity can't register the plugin until the plugin has been
constructed.
To break this cycle, you should always wait for initialization, which is indicated when Velocity
fires the ProxyInitializeEvent. We can do things on initialization by adding a listener for this
event, as shown below. Note that Velocity automatically registers your plugin main class as a
listener.
```java
@Subscribe
public void onProxyInitialization(ProxyInitializeEvent event) {
// Do some operation demanding access to the Velocity API here.
// For instance, we could register an event:
server.getEventManager().register(this, new PluginListener());
}
```
## Audience operations not supported
Velocity only supports sending chat messages, action bar messages, titles, and boss bars through the
Adventure API. No other operations are supported.

View File

@ -1,85 +0,0 @@
---
slug: /velocity/developers/dependency-management
---
# Dependency Management
Dependencies are common. You need to hook into another plugin. You don't want to write the same code
someone else has already solved. Whatever you do, you need a way to manage your dependencies
effectively.
## Plugin dependencies
Adding a dependency on another plugin is done with the `@Plugin` annotation in your main class.
Let's revisit that briefly:
```java
@Plugin(
id = "myfirstplugin",
name = "My Plugin",
version = "0.1.0"
)
public class VelocityTest {
// ...
}
```
Say we have a dependency on another plugin, call it `wonderplugin`. To add it as a dependency, do
the following:
```java
@Plugin(
id = "myfirstplugin",
name = "My Plugin",
version = "0.1.0",
dependencies = {
@Dependency(id = "wonderplugin")
}
)
public class VelocityTest {
// ...
}
```
The id of the dependency is the same as the other plugin's `id` from its `@Plugin` annotation. This
is why having a stable plugin ID is important.
That's it! Now, your plugin will require wonderplugin to load, and when it does, it will load
_after_ wonderplugin.
To specify multiple dependencies, separate them by commas:
`dependencies = {@Dependency(id = "wonderplugin"), @Dependency(id = "otherplugin")}`
## Optional plugin dependencies
To make a dependency optional, add `optional = true`, like shown:
```java
@Plugin(
id = "myfirstplugin",
name = "My Plugin",
version = "0.1.0",
dependencies = {
@Dependency(id = "wonderplugin", optional = true)
}
)
public class VelocityTest {
// ...
}
```
## External dependencies
:::caution
Please remember to relocate any dependencies you shade. Failure to relocate will lead to dependency
conflicts with other plugins.
:::
Dependencies on other libraries aren't handled by Velocity. You will need to add them using your
build system.
If your plugin does not shade its dependencies, but rather attaches them from a directory, you may
use the PluginManager's `addToClasspath` method instead of using reflection to access the
ClassLoader.

View File

@ -1,37 +0,0 @@
---
slug: /velocity/developers/porting-plugins-from-velocity-1
---
# Porting Your Plugin from Velocity 1.x.x
Velocity 3.0.0 includes important API changes from the Velocity 1.x.x series. **Please read this
document very carefully**.
## Minimum supported Java version bump
Velocity 3.0.0 now requires Java 11 and above. The Velocity API is compiled for Java 8 for the
convenience of plugins that want to run on older versions of Java, but we may decide to bump this in
a future major release.
## Removal of legacy dependencies
We removed all support for the old `text` 3 library. For `text` 3.x.x (and all the APIs that depend
on it), direct equivalents are available in [Adventure](https://docs.adventure.kyori.net/) which was
introduced in Velocity 1.1.0.
`toml4j`, deprecated in Velocity 1.1.0 (as it is no longer maintained), has not been removed to
provide more time for plugins to migrate to Configurate 3. However, you should prepare to either
switch to Configurate 3 or shade toml4j into your plugin directly.
## New asynchronous event system
Velocity 3.0.0 contains a backport of Velocity Polymer's event system, which differs from Velocity
1.x.x's event system in a number of ways. Velocity 1.x.x's event model forced all events to be
executed asynchronously on a fixed-size thread pool, which has proven over time to be a flawed
model.
Existing event handlers will continue to work unmodified on Velocity 3.0.0, as all event handlers
are assumed to be asynchronous blocking handlers by default. However, there are some new APIs
introduced for handling continuations - see the [event API page](../api/event.md) for more
information. However, you are encouraged to migrate your event listeners to the new event API
paradigms.

View File

@ -1,138 +0,0 @@
# Getting Started
This page covers how to install and set up a minimal configuration of Velocity.
## Installing Java
Velocity is written in Java, so if you do not already have Java installed, you will need to install
it before you continue. Velocity requires Java 11 or newer. See our
[java installation guide](../../common/java-install.md) for detailed instructions.
## Downloading Velocity
Head over to the [downloads](https://papermc.io/downloads#Velocity) page to get the latest version
of Velocity. We recommend getting the latest stable version. After downloading Velocity, move the
JAR file to a dedicated folder for just the proxy or upload it to your server.
## Launching Velocity for the first time
Once you have downloaded Velocity, we will launch it for the first time to generate the
configuration file, `velocity.toml`. You can use the start script created to launch Velocity once
you're done configuring Velocity.
### Launching Velocity under Windows
Create a `start.bat` with the following contents in the same directory where you intend to place the
proxy files.
```batch title="start.bat"
@echo off
java -Xms512M -Xmx512M -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:+UnlockExperimentalVMOptions -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -jar velocity.jar
pause
```
:::tip
Make sure to change the `velocity.jar` to the name of the Velocity JAR that you downloaded, or
rename the Velocity JAR to `velocity.jar`.
:::
Once saved, double-click the `start.bat` file. If it worked, you should now receive a console
similar to the output in the next section.
### Launching Velocity under macOS or Linux
Create a `start.sh` with the following contents in the same directory where you intend to place the
proxy files. You may do this using a file transfer client, or using a text editor running on the
host.
```bash title="start.sh"
#!/bin/sh
java -Xms1G -Xmx1G -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:+UnlockExperimentalVMOptions -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -XX:MaxInlineLevel=15 -jar velocity*.jar
```
Once saved, open a terminal (or log into the machine) if you haven't already, navigate to the
directory where you have placed the Velocity JAR file and the `start.sh` file. Then run
`chmod +x start.sh` and then `./start.sh`. If it worked, you should now receive a console similar to
the output in the next section.
## After launch
Here's a sample of what you'll see once we've started the proxy:
```log
[05:41:13 INFO]: Booting up Velocity 3.1.2-SNAPSHOT (git-b2800087-b112)...
[05:41:13 INFO]: Loading localizations...
[05:41:13 INFO]: Connections will use epoll channels, libdeflate (Linux aarch64) compression, OpenSSL (Linux aarch64) ciphers
[05:41:13 INFO]: Loading plugins...
[05:41:13 INFO]: Loaded 0 plugins
[05:41:13 INFO]: Listening on /[0:0:0:0:0:0:0:0%0]:25577
[05:41:13 INFO]: Done (0.36s)!
```
Velocity has launched, and you are now ready to configure the proxy completely. Go ahead and type
`end` at the console and press enter. The proxy will shut down:
```log
> end
[05:42:10 INFO]: Shutting down the proxy...
[05:42:10 INFO]: Closing endpoint /0.0.0.0:25577
```
If you used the Windows batch script from earlier, the window will ask you to press a key. You can
either press a key or close the command window.
### Configuring your servers
We now need to configure each server to accept connections from the proxy.
Velocity is a highly configurable proxy. While most users will not need to change everything in the
config, there are tons of options covered
[on the configuration wiki page](../reference/configuration.md) along with an explanation on how
each option works. However, in this section we will do the bare minimum to get the proxy up and
running.
Open the `velocity.toml` file in a text editor and search for the `[servers]` section. This section
specifies the servers that Velocity can connect to. Here's what the `[servers]` section will look
like initially:
```toml title="velocity.toml"
[servers]
# Configure your servers here. Each key represents the server's name, and the value
# represents the IP address of the server to connect to.
lobby = "127.0.0.1:30066"
factions = "127.0.0.1:30067"
minigames = "127.0.0.1:30068"
# In what order we should try servers when a player logs in or is kicked from a server.
try = [
"lobby"
]
```
On the left side, you will specify a name for the server (for example, `lobby`) and on right is a
string indicating the IP address and port for the server. You will now need to add your servers to
the list. You can change the list of servers as needed.
The `try` setting is special. It is a list of servers Velocity should try to connect the player to
when the player first logs onto the proxy or gets kicked from a server. If you decided to change the
name of the `lobby` server, then you should replace `lobby` in this list with the name you chose for
the first server the player should log into first.
:::caution
The following setup is generic and is intended to apply to any Minecraft server. This setup is not
only not ergonomic (players will lack skins, proper UUIDs, and all connections will appear to come
from the proxy) but also **dangerously insecure**. After you place your servers in offline mode, you
**must** follow the "Player Information Forwarding" and "Securing Your Servers" topics to complete
your setup.
:::
Open the `server.properties` file for each of your servers and set the `online-mode` setting to
`false`. This allows Velocity to connect to your server. Once you're done, restart your server.
While Velocity is now ready for use, you will almost certainly want to
[secure your servers](../how-to/security.md) and
[configure player information forwarding](forwarding.md).

View File

@ -1,106 +0,0 @@
---
slug: /velocity/faq
---
# Frequently Asked Questions
Over the years, we've been asked many of the same questions by users. This FAQ attempts to answer as
many of these questions from the user perspective.
## What version of Java does Velocity require?
Velocity 3.0.0 requires Java 11 or above.
## Where can I find Velocity plugins?
A good source for finding plugins compatible with Velocity would be our
[forums](https://forums.velocitypowered.com/c/plugins/plugin-releases/6).
## Does Velocity support plugins developed for BungeeCord or Waterfall?
No. Many of the things Velocity can do could not be done if we decided to support BungeeCord
plugins.
However, certain plugins may have Velocity ports available or alternatives are available. In
addition, plugins that support BungeeCord but only require that they are installed on the server
(nothing on the proxy) typically use the BungeeCord plugin messaging channel, which is supported
natively by the latest versions of Velocity.
## Help, I can't connect to my server!
There are a few common causes for why you can't connect to the server.
### Basic Troubleshooting
As a first step, you should verify:
- that your servers are started and are responsive to console input
- that the proxy is started
- that the server and proxy are bound to the appropriate port and IP
### Improper Player Information Forwarding Errors
```
Can't connect to server lobby: If you wish to use IP forwarding, please enable it in your Bungeecord config as well!
```
```
Can't connect to server lobby: Your server did not send a forwarding request to the proxy. Is it set up correctly?
```
These errors are result of improper configuration. See
[Player Information Forwarding](forwarding.md) to learn how to properly set up player information
forwarding.
### Improper Modern Player Information Forwarding
```
Can't connect to server lobby: This server requires you to connect with Velocity.
```
This error is a result of enabling Velocity modern forwarding on your backend server but not
enabling it in Velocity. To fix this error, ensure that you have set up the correct player
information forwarding method on the proxy. See [Player Information Forwarding](forwarding.md) for
more information.
### Invalid Payload Register
```
[server connection] player1 -> hub has connected
[connected player] player1 (/localhost:58943): kicked from server hub: Invalid payload REGISTER!
```
This error typically occurs on Spigot-based servers when someone connects with a modded client. You
can fix this issue if you use Paper (or a fork of Paper) 1.12.2 or above by adding the startup flag
`-Dpaper.disableChannelLimit=true` to the server's startup flags and restarting the server.
### Argument type identifier XXX unknown
```
Argument type identifier <namespace>:<name> unknown.
```
If you receive this message, there are two possibilities. If you run a modded server and are using
Fabric 1.16+ and above, update to at least Velocity 1.1.2 and install
[CrossStitch](https://www.curseforge.com/minecraft/mc-mods/crossstitch). (If you are running any
other kind of modded server and have it working with Velocity, let us know!)
If you receive this message but run a vanilla server,
[please report a bug to the Velocity issue tracker](https://github.com/PaperMC/Velocity/issues/new).
### Read time out while switching to a Forge server
Particularly for some very large mod packs, there is an elevated risk of the connection between the
player and the proxy dropping. There is not much we can do on the proxy end to alleviate this. We
suggest either reducing the number of mods your server uses, or raise the `read-timeout` setting in
`velocity.toml` and add the `-Dfml.readTimeout` startup flag to your Forge server and setting it to
the value (in seconds) you chose for the proxy. For instance, if you determine that 120 seconds is
the best read timeout to use, use `-Dfml.readTimeout=120` and set `read-timeout = 120000` in
`velocity.toml`.
### My forced hosts are not working!
First, double-check that you properly set up DNS records pointing to your proxy for the forced hosts
you have selected. Forced hosts are _not_ compatible with SRV records, so if you are relying on SRV
records to direct the player to the proxy, you will need to find a way to get the proxy running on
the default Minecraft port, 25565.

View File

@ -1,105 +0,0 @@
---
slug: /velocity/player-information-forwarding
---
# Configuring player information forwarding
Velocity supports forwarding information about your players to your servers, such as IP addresses,
UUIDs and skins. Velocity supports three forwarding formats:
- **Velocity modern forwarding** is a custom forwarding format (modern forwarding) that is more
secure.
- **BungeeCord forwarding** (also known as _legacy forwarding_) which has better compatibility but
is less secure.
- **BungeeGuard**, which is the same as BungeeCord forwarding but includes a secret key. It is
better than BungeeCord forwarding alone, but it is less ideal than Velocity modern forwarding.
:::info
You may choose between only one of these forwarding formats. It is not currently possible to "mix
and match" forwarding modes or use all the forwarding formats together. In general, if you are
supporting clients using Minecraft 1.13 and newer only, use Velocity modern forwarding, else you
must use BungeeCord forwarding.
:::
## Configuring modern forwarding
`modern` forwarding is a Velocity-native format. It forwards all player information in an efficient
binary format and employs a MAC code to make it much more difficult to trick the server into
impersonating your Velocity proxy. However, it is only available for Minecraft 1.13 or higher.
:::caution
Modern forwarding is incompatible with Minecraft versions below 1.13, Minecraft Forge, and the
ProtocolSupport plugin. If you use any of these, you will need to use legacy BungeeCord-compatible
forwarding instead.
:::
To use modern forwarding with any supported server implementation, set the `player-info-forwarding`
setting in `velocity.toml` to `modern`. Then, you need to ensure your server is properly configured
to use Velocity forwarding.
### Configuring modern forwarding for Paper
Paper 1.14+ and above, along with Paper 1.13.1/1.13.2 build 377 and above support Velocity modern
forwarding natively.
First, you need to disable BungeeCord forwarding if you had it enabled beforehand. Make sure
`settings.bungeecord` is set to `false` in your `spigot.yml`.
In `paper.yml`, set `settings.velocity-support.enabled` to true and
`settings.velocity-support.secret` to match the secret in your `velocity.toml`. You must also set
`settings.velocity-support.online-mode` to the `online-mode` setting in your `velocity.toml`. Once
you're done editing `paper.yml`, reboot your server.
## Configuring modern forwarding for Fabric
A mod called [FabricProxy-Lite](https://modrinth.com/mod/fabricproxy-lite) allows you to use
Velocity modern forwarding with a modded server using Fabric.
## Configuring legacy BungeeCord-compatible forwarding
:::danger
Legacy forwarding is **fundamentally insecure**. If you must use it, you should understand
[how to secure your server properly](../how-to/security.md). That page reviews all the possible
options to secure your server so that nothing aside from the proxy can connect to your server.
:::
`legacy` forwarding is the player information forwarding protocol that is used by BungeeCord when
enabling IP forwarding from BungeeCord. Due to this, it is ubiquitous and well-supported by most
server implementations. It has excellent compatibility (supporting versions as old as 1.7.2,
released in 2013) and will work with Forge if you also install SpongeForge on your modded server and
configure it correctly. However, it is not secure.
If you must use BungeeCord-compatible forwarding, simply set your `player-info-forwarding` setting
in `velocity.toml` to `legacy`. You will also need to make sure your server can accept the forwarded
player data sent by Velocity.
To add some security, particularly for proxies hosted on shared hosting, Velocity optionally
supports the [BungeeGuard](https://www.spigotmc.org/resources/bungeeguard.79601/) plugin. To use it,
set the `player-info-forwarding` setting in `velocity.toml` to `bungeeguard`, then add the value in
`forwarding-secret` to the token section in the BungeeGuard configuration.
### Configuring legacy forwarding for Spigot / Paper
To make Spigot or Paper understand the data forwarded from Velocity, set `settings.bungeecord` to
`true` in your `spigot.yml` and then reboot your server.
### Configuring legacy forwarding for Sponge
To configure Sponge to understand the data forwarded from Velocity, you will need to stop the server
first, set `modules.bungeecord` to `true` and `bungeecord.ip-forwarding` to true in your
`config/sponge/global.conf` file, and then restart your Sponge server.
### Configuring legacy forwarding for Fabric
:::caution
There are no longer any actively supported mods that support legacy forwarding. Please use Velocity
modern forwarding instead.
:::

View File

@ -1,89 +0,0 @@
---
slug: /velocity/why-velocity
---
# What Does Velocity Do For Me?
We believe that Velocity is one of the best proxies for _Minecraft_ around, and there's not much
that can top it. However, we do diverge from more established, mainstream solutions in some
important ways. That can make Velocity a bit hard to sell. We are frequently asked "why?" so often.
This page is our answer to that question.
## Strong experience
The founder and primary developer of Velocity (Tux) has been active in developing proxy software for
_Minecraft: Java Edition_ since 2013. They created the RedisBungee plugin, contributed to BungeeCord
from 2014 to 2017, and also founded the Waterfall project and led it from 2016 to 2017. In fact, the
current maintainer of Waterfall helped encourage them to start a brand new proxy from the ground up!
## Leading performance
Velocity powers several highly-populated Minecraft networks, while using fewer resources than the
competition. The recipe to the sauce is simple.
### No entity ID rewriting
When a Minecraft client connects to another Minecraft server, the server will send back an ID that
uniquely identifies a specific player connection. This ID is used in packets that target the player
that the server may send. But what happens when they're actually connecting a proxy that has the
ability to change what server the player is connected to?
Other proxy solutions try to solve this problem by rewriting entity IDs that reference the current
player, changing it from the entity ID assigned by the server the player is currently connected to,
to the entity ID that the player got when they connected to the first server they connected to
through the proxy. This approach is often complicated, leads to bugs, reduces performance, breaks
mods, and ultimately cannot be a complete solution.
However, the Minecraft client actually supports changing its entity ID with a special packet
sequence. Velocity takes advantage of this and forces the client to change its entity ID. This
approach improves performance, improves mod compatibility, and reduces issues caused by incomplete
entity ID rewrites.
### Going deep
Velocity goes deeper than optimizing the handling of the Minecraft protocol. Smart handling of the
protocol produces incredible performance gains but for more performance, we need to go much deeper.
One way in which we drastically improve performance and throughput is by improving the speed of
compressing packets to be sent to the client. On supported platforms (Linux x86_64 and aarch64),
Velocity is able to replace the zlib library ( which implements the compression algorithm used by
the Minecraft protocol) with [libdeflate](https://github.com/ebiggers/libdeflate) which is twice as
fast as zlib while delivering a similar compression ratio.
Velocity also employs several tricks to get the JIT (just-in-time) compiler on our side. Those
tricks require deep understanding of how Java works, but we put in the work to apply those tricks
which translate to increased performance.
### Internal stability policies
Finally, Velocity does not attempt to maintain a stable internal API between minor and major
releases. This allows Velocity to be more flexible and still deliver performance improvements and
new features with each release. For instance, Velocity 1.1.0 delivered massive performance
improvements and added many significant new features by breaking parts of the internal API while
still keeping full compatibility with older plugins. Compare to BungeeCord which is often very
conservative about API breaks and when it does so, provides little notice of the break, and even
when doing a break, does not take the opportunity to seriously improve the API being broken (for
instance, adding RGB support to `ChatColor`).
### Control is in your hands
We take pride in tuning Velocity to be the most performant proxy, but in case the speed provided
out-of-the-box is not good enough, you can easily tweak several performance-related settings in
`velocity.toml`.
## Improved security
Velocity also features more security features, some of which are unique to Velocity. We proactively
foreclose as many denial-of-service attacks as soon as possible and feature a unique player info
forwarding system for Minecraft 1.13+ that requires the server and proxy to know a pre-arranged key.
## Standards and mod support
Unlike certain platforms which only provide lip service to the modding community (and can be at time
hostile to them), Velocity embraces the richness of the platform Minecraft provides. As just a small
example, we have a Fabric mod that
[helps bridge the gap between Velocity itself and mods that extend the Minecraft protocol](https://www.curseforge.com/minecraft/mc-mods/crossstitch)
and feature full Forge support for 1.7 through 1.12.2, with support for newer versions in
development. Velocity also supports emerging standard libraries in the community such as Kyori's
[Adventure](https://github.com/KyoriPowered/adventure) library. We collaborate with the Minecraft
modding community.

View File

@ -1,15 +0,0 @@
---
slug: /velocity/migration
---
# Migration Guide
New to Velocity, or upgrading to a new version of Velocity? This page will briefly explore what you
need to be aware of for a successful migration
## Migrating from Velocity 1.0.x to Velocity 1.1.0
Moving from Velocity 1.0.x to Velocity 1.1.0 should be as simple as just replacing the Velocity JAR
and restarting the proxy. You may want to back up your `velocity.toml` and then delete the current
`velocity.toml` and let Velocity regenerate it to add the new settings that Velocity 1.1.0
introduces.

View File

@ -1,142 +0,0 @@
---
slug: /velocity/security
---
# Securing Your Servers
It is vital that you secure your backend servers. As part of setting up Velocity, you will put your
server into offline mode, which means in theory, someone could impersonate any player on your
server. This is extremely dangerous, so it is important to make sure only the proxy can connect to
your servers.
This guide will explore the various options for securing your backend servers so only your proxy can
connect to them. Note that this is an _exploration_ of options, aiming to review the various options
and give you advantages and disadvantages to them so you can make an informed decision.
This list is not in any particular order, and almost all of these methods can be combined as needed.
## Operating System Firewalls
When properly configured, using the firewall facilities provided by your server's operating system
is a highly effective way to protect your servers. The Velocity project **strongly recommends the
use of a firewall**.
Instructions for your operating system may vary. Solutions for major server OSes include:
- Windows: Windows Firewall
- Linux: iptables, nftables
**Advantages**:
- Fool-proof if you do not give untrusted servers access to your servers
- Does not require any extra Minecraft server configuration
- Part of good system hardening advice for any operating system
**Disadvantages**:
- Tricky first-time setup
- May be difficult to use with multiple proxies
- Firewall configuration must be kept in sync with new servers and proxies
- Not viable on a shared host
## Velocity Modern Forwarding
If your server only supports Minecraft 1.13 and above, Velocity's modern forwarding can forward
player information to your servers and provide a second layer of protection against someone trying
to impersonate as your proxy.
:::caution
Velocity modern forwarding is not a replacement for a firewall. We strongly recommend using a
firewall with any Minecraft proxy setup.
:::
**Advantages**:
- Get player info forwarding for free
- Secure on a shared host, provided the host has implemented proper protections
- Works if you host your server on multiple physical servers
**Disadvantages**:
- Only works for Minecraft 1.13 and above
- Requires Paper 1.13 or above, or FabricProxy-Lite if you use Fabric
- Relies on the forwarding secret being kept secret
## Binding To `localhost`
If you are hosting your proxy on the same physical computer as your other servers (and nobody else
is hosting servers on them), binding your servers to `localhost` is a very simple way of protecting
them from getting connected to by anything other than the proxy.
For each server, open the `server.properties` file. Find the line that starts with `server-ip` and
change the line to `server-ip=127.0.0.1`. Save the file and restart the server.
Afterwards, open your `velocity.toml` file and ensure all the servers are pointing to
`127.0.0.1:<port>`.
**Advantages**:
- Trivial setup compared to other methods discussed
- Fool-proof if you do not give untrusted users access to your server
**Disadvantages**:
- Setup must be reversed (and an alternate method used) if you move any of the servers to a
different physical server ( such that the proxy and the server are not on the same physical
server)
- Not viable on a shared host
## Using an Encrypted Tunnel
This is a variation on "Binding To `localhost`", but instead of hosting all your servers on a single
physical server, you will set up an encrypted tunnel between each of your servers, and make sure the
server only listens for incoming connections from the tunnel. There are many different solutions,
ranging from VPN solutions such as [WireGuard](https://www.wireguard.com),
[OpenVPN](https://openvpn.net/), and [tinc](https://www.tinc-vpn.org/) to encrypted tunnels such as
[spiped](https://www.tarsnap.com/spiped.html). This guide will not go into details of how to set up
each of these solutions.
**Advantages**:
- Encrypts traffic between your proxy and your servers while ensuring only authorized clients can
connect to your servers
**Disadvantages**:
- Very complex setup
- Impossible to use on a shared host
## IP Whitelisting Plugins
As a last line of defense, you can choose to restrict logins to users on an IP whitelist using a
plugin like [IPWhitelist](https://www.spigotmc.org/resources/ipwhitelist.61/).
**Advantages**:
- May be your only solution if none of the other solutions will work (especially on a shared host)
**Disadvantages**:
- Vulnerable to attack if the attacker can get a server on the same node as your proxy is on
## Other Important Security Advice
This common-sense general advice goes without saying:
- Keep frequent backups of your server
- Set up a firewall on your server
- Run your servers as an unprivileged user (this means no `sudo` access or running as `root` for
Linux users!)
- Update Velocity, your Minecraft server and server plugins, and your server's operating system
frequently
- Use strong passwords
- Carefully think about the potential impacts of installing any plugins or software before actually
doing so
- Secure any and all other services you may be running on your server
- Follow all system hardening advice for your operating system
We will not provide a full treatment to the advice given above, so please do some research of your
own. Your setup will vary - there is no "one size fits all" advice we can give other than these
general guidelines.

View File

@ -1,149 +0,0 @@
---
slug: /velocity/tuning
---
# Tuning Velocity
Velocity comes with good performance out of the box. We go in deep, starting from smart algorithmic
choices, making strategic usage of native libraries, all the way to the JVM level, optimizing the
proxy so that the JVM will make better decisions when optimizing the code.
## Host the proxy on Linux
Velocity comes with high-performance, specially tuned native libraries for compression and
encryption, along with including native transports from Netty. However, due to support constraints,
the compiled natives are only verified to work on Linux x86_64 and aarch64. While Velocity does not
require the natives to work, you will suffer from degraded performance. For this reason, we strongly
recommend that all production deployments of Velocity run on x86-64 Linux.
## Allocate server resources appropriately
You should always make sure to allocate the correct amount of heap, network bandwidth, and get the
right CPU for the amount of players you want to have on your proxy at a given time. For instance, it
is unlikely you'll be able to get 1,000 players on a Raspberry Pi Zero, but you'll have a much
better chance if you have a recent high-end server CPU from Intel or AMD.
There is no "one-size-fits-all" hardware recommendation, only general guidelines for the amount of
players you can expect:
- Prefer lots of cores but lower clock speeds. Unlike the Minecraft server, Velocity can actually
benefit from the extra cores and single-threaded performance is not as important.
- You should always have enough memory to run Velocity, including room for JVM overhead and for your
operating system. For a rough minimum recommended memory amount, double the size of the proxy heap
and then add 2GB. For instance, for a proxy with a 2GB heap, plan on getting at least 6GB of
memory.
- Disk speed is unimportant. A solid-state drive is nice to have but not strictly required.
Likewise, disk capacity is unimportant as well.
### Special notes regarding speculative execution security vulnerabilities
Starting in 2018, a number of security vulnerabilities with regard to
[speculative execution](https://en.wikipedia.org/wiki/Speculative_execution) used by modern CPUs
have been discovered.
The mitigations to these vulnerabilities can have painful performance implications, especially on
processors vulnerable to Meltdown and further compounded if running in a virtual machine. Velocity,
as a network application, is particularly sensitive to the performance hits that the mitigations
introduce.
To minimize these hits, we recommend hosting your proxy on a machine with a CPU that has mitigations
against Spectre and Meltdown. Processors released in 2019 and onwards typically contain mitigations
to protect against Spectre and Meltdown.
If you are using a CPU vulnerable to Spectre and/or Meltdown and are willing to risk security for
performance, it is also possible to disable Spectre/Meltdown mitigations depending on the operating
system you use. Note however that you disable these security mitigations _at your own risk_. The
Velocity project does not recommend that you disable these mitigations.
## Allocate enough heap
Alongside having enough CPU, memory, and network bandwidth, you must also allocate enough Java heap
to the proxy. Not doing this can induce lag and in severe cases may result in the proxy being
terminated by the Java Virtual Machine because it ran out of memory.
The general rule of thumb is that you allocate 512MB per 500 players, plus some extra to allow for
some room for error ( typically 1GB extra). For instance, if you want to handle 1,000 on a single
proxy, plan to allocate 2GB of heap.
### Special notes for containers
**If you use a containerized setup (such as using Kubernetes, Pterodactyl, or Docker directly), you
should not allocate the entirety of your memory allocation to the heap!** Doing so _will_ likely
cause the proxy to be killed by the kernel's out-of-memory killer, which will result in your proxy
going down, likely at the worst possible time.
A safe (albeit conservative) setting for the heap would be to allocate half of the memory you
allocate to the proxy container in total. For instance, if you know the proxy will need to hold
1,000 players, then allocate 4GB to the container and give the proxy 2GB of heap.
## Tune your startup flags
We also recommend tuning your startup flags. The current recommendation is:
```
-XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:+UnlockExperimentalVMOptions -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -XX:MaxInlineLevel=15
```
You will add these flags after the `java` command but before the `-jar` parameter.
### Explanation of the flags
Most of these flags focus on tuning the G1 garbage collector to be more friendly to Velocity's
workload. One of these flags (`-XX:MaxInlineLevel=15`) tends to improve performance in general.
Before the release of Java 9, the default Java garbage collector was the Parallel GC. This is a
stop-the-world collector that does its work in parallel. The problem is that its pause times tend to
be long, and are not suitable for Minecraft (often showing up as seemingly unexplainable lag
spikes).
The recommended garbage collector for Velocity is the G1 region-based collector. There are several
reasons for us to recommend G1:
- It strikes the right balance between throughput and pause times. Throughput is roughly how much
work the proxy can achieve.
- It is compatible with most setups (it is available in Java 8, the earliest Java version we
support).
Setups using these flags tend have very low (less than 10 millisecond) GC pauses every few minutes,
which is very good for Minecraft.
### Other configurations
:::caution
Deviating from the configuration we recommend is done solely at your own risk.
:::
Velocity is an application that tends to follow the generational hypothesis quite closely. It has
also been tuned to reduce load on the garbage collector as much as possible.
#### ZGC
ZGC (the Z Garbage Collector), introduced with Java 11 and stabilized with Java 15, has proven to be
successful for one large-scale deployment of Velocity.
At its core, ZGC is a concurrent, generation-less garbage collector emphasizing low latency at the
expense of throughput. Given the nature of Velocity as a network proxy where low throughput and high
throughput are important, we recommend using ZGC with caution, and only if you use Java 15 or above.
The primary tuning flag for ZGC is heap size - if ZGC cannot collect garbage faster than the proxy
can allocate it, the threads generating garbage will be temporarily paused, causing the proxy to
appear to be laggy. Our heap size recommendations still apply, but prepare to give the proxy more
memory if necessary.
#### Shenandoah
Introduced in Java 11 and declared stable in Java 15, Shenandoah is similar to G1 in being a
concurrent, generational garbage collector, but it does more work in parallel.
The Velocity team is not aware of any successful deployments of Shenandoah with Velocity in the
wild.
#### OpenJ9
OpenJ9 is an alternative to the HotSpot JVM derived from IBM's J9 JVM, focused primarily on cloud
workloads. As a result, it behaves very differently from HotSpot. Correspondingly, it has a
completely different set of garbage collectors.
The default `gencon` garbage collector should work fine with Velocity.

View File

@ -1,68 +0,0 @@
---
slug: /velocity/built-in-commands
---
# Built-In Commands
Velocity includes a few commands in the core of the proxy by default. These commands were chosen
based on how generally useful they are to most users.
Of course, you can always install plugins to add more commands if you want.
## The `/velocity` command
The `/velocity` command contains a number of subcommands to manage the proxy.
### `/velocity plugins`
If the user has the `velocity.command.plugins` permission, they can view all the plugins currently
active on the proxy using `/velocity plugins`, including the name, authors, and version.
### `/velocity version`
Displays the version of Velocity running on the proxy.
### `/velocity reload`
If the user has the `velocity.command.reload` permission, the proxy will read and reconfigure itself
from the `velocity.toml` on disk. If there are problems with parsing the file, no changes will be
applied.
### `/velocity dump`
:::caution
This command will send some basic information to a web service maintained by the Velocity project
(`dump.velocitypowered.com`). While we anonymize potentially sensitive details in the proxy such as
external IP addresses and all dumps expire after 3 days, we do not take responsibility for any
potential misuse of the data provided. Use this command with caution and after you have considered
the privacy and security concerns.
:::
If the user has the `velocity.command.plugins` permission, they can use this command to get an
anonymized dump of details on the proxy. This can be sent to the Velocity Discord to help us provide
support.
## `/server`
If the user has the `velocity.command.server` permission (by default, this is granted to all users),
players can use this command to view and switch to another server.
Executing just `/server` will send the user the name of the server they are currently on, along with
options to move to other servers configured on the proxy.
If a server name has been provided, Velocity will attempt to connect to the server.
## `/shutdown`
When executed from the console, this will gracefully shut down the Velocity proxy. All players will
be disconnected from the proxy and plugins will have a chance to finish up before the proxy shuts
down. An optional reason can be given, either as JSON or with legacy color codes, in the same format
as the MOTD in `velocity.toml`.
## `/glist`
If the user has the `velocity.command.glist` permission (by default, this is granted to nobody),
players can use this command to view the number of players currently on the proxy and use
`/glist all` to get a listing of players per server.

View File

@ -1,90 +0,0 @@
---
slug: /velocity/comparisons-to-other-proxies
---
# Comparing With Other Proxies
Presumably, you've read up about what Velocity can do for you. But how does it stack up against
other solutions out there? We're biased, so we'll try to be as honest as possible by fully
acknowledging our bias in advance. We are the developers of Velocity and we're trying to convince
you to use Velocity, after all.
## BungeeCord and derivatives
We can't treat the full history of Minecraft proxy software with justice we recommend
[Me4502's excellent article](https://madelinemiller.dev/blog/decade-of-minecraft-multiplayer/) that
covers the multiplayer Minecraft world in great detail. Needless to say, Velocity was influenced by
a desire to avoid all the faults we perceived that needed to be resolved with BungeeCord.
### BungeeCord
There are several reasons why we can't just "improve BungeeCord":
- BungeeCord is very conservative with regard to API changes. If it breaks some plugin developed 5
years ago from an inactive developer, you can forget about it.
- The changes that _do_ change the API are often quite particular and niche use cases and changing
the API in substantial ways is frowned upon (witness the support for RGB colors in `ChatColor`).
- The project is essentially run like a cathedral. In BungeeCord (and its sister project, Spigot),
the word of md_5 is king. Contributing a simple security fix to BungeeCord earned the primary
developer of Velocity at least two beratings.
- BungeeCord is actively hostile to continued support for Minecraft modding.
- We have seen new modding APIs for _Minecraft_ since the first version of BungeeCord released
in 2012. It's time for a new and improved API that does not make the mistakes the BungeeCord API
makes, and to draw influence from the new modding APIs that Minecraft now boasts.
### Waterfall
The founder of the Velocity project also founded the Waterfall project. The natural question, then,
is why they couldn't just have improved Waterfall. Why start on a new API with no plugins lined up
and a very uncertain chance of success, let alone an user base willing to take their chances on such
new software, when you can have access to the rich plugin ecosystem that BungeeCord boasts?
Unfortunately, that attempt fell to the scythe of [Hyrum's Law](https://www.hyrumslaw.com/):
> With a sufficient number of users of an API, it does not matter what you promise in the contract:
> all observable behaviors of your system will be depended on by somebody.
Here's Hyrum's law in comic format, in case that eases getting the point across:
> [![xkcd #1172](https://imgs.xkcd.com/comics/workflow.png)](https://xkcd.com/1172/)
> ["Workflow"](https://xkcd.com/1172/) from [xkcd](https://xkcd.com/) by Randal Munroe,
> [licensed](https://xkcd.com/license.html) under
> [CC BY-NC 2.5](https://creativecommons.org/licenses/by-nc/2.5/)
Most BungeeCord plugins are deeply dependent on the specific behaviors and quirks BungeeCord
exposes, which Velocity cannot perfectly emulate. I'll use an example of a video game. One day, a
game studio A publishes a video game X that you really like. You run it on operating system Y made
by company B, and it works great. Sometime after, studio A goes out of business. You are sad but
continue life because at least game X works just fine. One day, company B releases a new version of
operating system Y. You upgrade to it and discover that your game doesn't work. Who are you going to
blame, company B for breaking the game, or company A for shipping a defective project? Chances are,
the average consumer will blame company B. This isn't new —
[witness Raymond Chen, who documents the sad compatibility history of Windows, saying essentially the same thing](https://devblogs.microsoft.com/oldnewthing/20110131-00/?p=11633)
.
We can point to one example where
[an attempt](https://github.com/PaperMC/Waterfall/commit/c8eb6aec7bac82fd309fa6d6113b8a0418317b01)
to improve scoreboard handling on 1.13 and above
[was reversed](https://github.com/PaperMC/Waterfall/issues/255) thanks to plugins expecting
BungeeCord's broken behavior. At this point, it is fairly obvious why making a clean break was
better. Given that this happened near the start of the Velocity project's lifetime, it was probably
a quite powerful motivator, although it certainly wasn't the only motivator.
### Hypothetical BungeeCord API-based Velocity
We are compelled to mention this briefly as this was a topic brought up in the early days of the
project. We could have based Velocity on the BungeeCord API (or a derivative thereof, such as the
Waterfall API) instead.
This is a fool's ploy. Let us revisit the video game example from earlier. One day, you discover a
new operating system, Z. You really like it more than operating system Y, and it has tool T that can
run programs meant for operating system Y. You install it and your favorite game, X. You then launch
game X to be disappointed with all the glitched out textures and borderline broken gameplay. You
feel quite hurt by it. This is a real world example too, just substitute Y for "Windows", Z for "any
Linux distribution", and T for "Wine", and there you have it. We would essentially have to have a
convincing decoy to pretend Velocity looked and smelled like a BungeeCord implementation to a
plugin, while not actually being based on BungeeCord. This would force us to introduce ever more
elaborate decoys to pretend to be bug-for-bug and binary compatible with BungeeCord, which would
force us to spend time on ensuring compatibility with every BungeeCord plugin ever rather than
delivering new features. At that point, Velocity winds up just being a slightly better optimized
Waterfall.

View File

@ -1,92 +0,0 @@
---
slug: /velocity/configuration
---
# Configuring Velocity
Velocity is designed to be easy to configure and set up. Every Velocity file is stored in
`velocity.toml`, located in the directory where you started the proxy. Velocity uses the
[TOML](https://github.com/toml-lang/toml) file format, as it is easy to understand and avoids
pitfalls of YAML and other configuration formats common in the community.
An up-to-date version of the default configuration can be found on
[GitHub](https://github.com/PaperMC/Velocity/blob/dev/3.0.0/proxy/src/main/resources/default-velocity.toml).
## Data types
There are a few "special" data types in the Velocity configuration.
### Chat
Chat messages may be provided in legacy color code format or in JSON format.
RGB support (using the `&#rrggbb` format) is available and JSON messages are deserialized for
Minecraft 1.16.
### Address
An address is a pairing of an IP address or hostname, and a port, separated by a colon (`:`). For
instance, `127.0.0.1:25577` and `server01.example.com:25565` are valid addresses.
## Root section
These settings mostly cover the basic, most essential settings of the proxy.
| Setting Name | Type | Description |
| ----------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `config-version` | String | This is the current config version used by Velocity. You should not alter this setting. |
| `bind` | Address | This tells the proxy to accept connections on a specific IP. By default, Velocity will listen for connections on all IP addresses on the computer on port 25577. |
| `motd` | Chat | This allows you to change the message shown to players when they add your server to their server list. You can use legacy Minecraft color codes or JSON chat. |
| `show-max-players` | Integer | This allows you to customize the number of "maximum" players in the player's server list. Note that Velocity doesn't have a maximum number of players it supports. |
| `player-info-forwarding-mode` | Enum | See [Configuring player information forwarding](../getting-started/forwarding.md) for more information. |
| `forwarding-secret` | String | This setting is used as a secret to ensure that player info forwarded by Velocity comes from your proxy and not from someone pretending to run Velocity. See the "Player info forwarding" section for more info. |
| `announce-forge` | Boolean | This setting determines whether Velocity should present itself as a Forge/FML-compatible server. By default, this is disabled. |
| `kick-existing-players` | Boolean | Allows restoring the vanilla behavior of kicking users on the proxy if they try to reconnect (e.g. lost internet connection briefly). |
| `ping-passthrough` | String | Allows forwarding nothing (the default), the `MODS` (for Forge), the `DESCRIPTION`, or everything (`ALL`) from the `try` list (or forced host server connection order). |
## `server` section
| Setting Name | Type | Description |
| ------------- | ------- | -------------------------------------------------------------------------------------------------------------------------- |
| A server name | Address | This makes the proxy aware of a server that it can connect to. |
| `try` | Array | This specifies what servers Velocity should try to connect to upon player login and when a player is kicked from a server. |
## `forced-hosts` section
| Setting Name | Type | Description |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| A host name | Hostname | This configures the proxy to create a forced host for the specified hostname. An array of servers to try for the specified hostname is the value. |
## `advanced` section
| Setting name | Type | Description |
| ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `compression-threshold` | Integer | This is the minimum size (in bytes) that a packet must be before the proxy compresses it. Minecraft uses 256 bytes by default. |
| `compression-level` | Integer | This setting indicates what `zlib` compression level the proxy should use to compress packets. The default value uses the default zlib level. |
| `login-ratelimit` | Integer | This setting determines the minimum amount of time (in milliseconds) that must pass before a connection from the same IP address will be accepted by the proxy. A value of `0` disables the rate limit. |
| `connection-timeout` | Integer | This setting determines how long the proxy will wait to connect to a server before timing out. |
| `read-timeout` | Integer | This setting determines how long the proxy will wait to receive data from the server before timing out. |
| `proxy-protocol` | Boolean | This setting determines whether or not Velocity should receive HAProxy PROXY messages. If you don't use HAProxy, leave this setting off. |
| `tcp-fast-open` | Boolean | This setting allows you to enable TCP Fast Open support in Velocity. Your proxy must run on Linux kernel >=4.14 for this setting to apply. |
| `bungee-plugin-message-channel` | Boolean | This setting allows you to enable or disable support for the BungeeCord plugin messaging channel. |
| `show-ping-requests` | Boolean | This setting allows you to log ping requests sent by clients to the proxy. |
| `announce-proxy-commands` | Boolean | This setting allows you to enable or disable explicitly sending proxy commands to the client (for Minecraft 1.13+ tab completion). |
| `failover-on-unexpected-server-disconnect` | Boolean | This setting allows you to determine if the proxy should failover or disconnect the user in the event of an unclean disconnect. |
| `log-command-executions` | Boolean | Determines whether or not the proxy should log all commands run by the user. |
## `query` section
| Setting name | Type | Description |
| -------------- | ------- | ------------------------------------------------------------------------------------------------------------ |
| `enabled` | Boolean | Whether or not Velocity should reply to Minecraft query protocol requests. You can usually leave this false. |
| `port` | Number | Specifies which port that Velocity should listen on for GameSpy 4 (Minecraft query protocol) requests. |
| `map` | String | Specifies the map name to be shown to clients. |
| `show-plugins` | Boolean | Whether or not Velocity plugins are included in the query responses. |
## `metrics` section
| Setting name | Type | Description |
| ------------- | ------- | --------------------------------------------------------------------------------------------------- |
| `enabled` | Boolean | Whether or not Velocity should send metrics to bStats. |
| `id` | UUID | A randomly generated UUID that uniquely identifies your Velocity server. Do not alter this setting. |
| `log-failure` | Boolean | Whether or not Velocity should log whenever it fails to connect to bStats. |

View File

@ -1,31 +0,0 @@
---
slug: /velocity/credits
---
# Libraries Used
Velocity uses a number of open-source libraries:
| Name | Author | License |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| [Guava](https://github.com/google/guava) | [Google](https://github.com/google) | [Apache License 2.0](https://github.com/google/guava/blob/master/COPYING) |
| [Gson](https://github.com/google/gson) | [Google](https://github.com/google) | [Apache License 2.0](https://github.com/google/gson/blob/master/LICENSE) |
| [Netty](https://github.com/netty/netty) | [Netty Project](https://netty.io) | [Apache License 2.0](https://github.com/netty/netty/blob/4.1/LICENSE.txt) |
| [libdeflate](https://github.com/ebiggers/libdeflate) | [Eric Biggers](https://github.com/ebiggers) | [MIT License](https://github.com/ebiggers/libdeflate/blob/master/COPYING) |
| [text](https://github.com/KyoriPowered/text) | [KyoriPowered](https://github.com/KyoriPowered) | [MIT License](https://github.com/KyoriPowered/text/blob/master/license.txt) |
| [adventure](https://github.com/KyoriPowered/text) | [KyoriPowered](https://github.com/KyoriPowered) | [MIT License](https://github.com/KyoriPowered/adventure/blob/master/license.txt) |
| [Brigadier](https://github.com/Mojang/brigadier) | [Mojang](https://www.minecraft.net) | [MIT License](https://github.com/Mojang/brigadier/blob/master/LICENSE) |
| [event](https://github.com/KyoriPowered/event) | [KyoriPowered](https://github.com/KyoriPowered) | [MIT License](https://github.com/KyoriPowered/event/blob/master/license.txt) |
| [ASM](http://asm.ow2.org/) | [OW2](https://www.ow2.org/) | [BSD 3-Clause License](http://asm.ow2.io/license.html) |
| [SLF4J](https://github.com/qos-ch/slf4j) | [SLF4J](https://www.slf4j.org/) | [MIT License](https://github.com/qos-ch/slf4j/blob/master/LICENSE.txt) |
| [Log4j](https://logging.apache.org/log4j/2.x/) | [Apache Log4j Team](https://logging.apache.org/log4j/2.x/team-list.html) | [Apache License 2.0](https://logging.apache.org/log4j/2.x/license.html) |
| [TerminalConsoleAppender](https://github.com/Minecrell/TerminalConsoleAppender) | [Minecrell](https://github.com/Minecrell) | [MIT License](https://github.com/Minecrell/TerminalConsoleAppender/blob/master/LICENSE) |
| [Configurate](https://github.com/SpongePowered/configurate) | [SpongePowered](https://github.com/SpongePowered) | [Apache License 2.0](https://github.com/SpongePowered/configurate/blob/master/LICENSE) |
| [SnakeYAML](https://bitbucket.org/asomov/snakeyaml) | [Andrey Somov](https://bitbucket.org/asomov) | [Apache License 2.0](https://bitbucket.org/asomov/snakeyaml/src/default/LICENSE.txt) |
| [HOCON](https://github.com/lightbend/config) | [lightbend](https://github.com/lightbend) | [Apache License 2.0](https://github.com/lightbend/config/blob/master/LICENSE-2.0.txt) |
| [toml4j](https://github.com/mwanji/toml4j) | [Moandji Ezana](https://github.com/mwanji) | [MIT License](https://github.com/mwanji/toml4j/blob/master/LICENSE) |
| [Night-Config](https://github.com/TheElectronWill/night-config) | [TheElectronWill](https://github.com/TheElectronWill) | [GNU Lesser General Public License 3.0](https://github.com/TheElectronWill/night-config/blob/master/LICENSE) |
| [fastutil](http://fastutil.di.unimi.it/) | [Sebastiano Vigna](http://vigna.di.unimi.it/) | [Apache License 2.0](https://github.com/vigna/fastutil/blob/master/LICENSE-2.0) |
| [JLine](https://github.com/jline/jline3/blob/master/LICENSE.txt) | [JLine project](https://github.com/jline/jline3) | [BSD 3-Clause License](https://github.com/jline/jline3/blob/master/LICENSE.txt) |
| [AsyncHttpClient](https://github.com/AsyncHttpClient/async-http-client) | [Stephane Landelle](https://github.com/slandelle) | [Apache License 2.0](https://github.com/AsyncHttpClient/async-http-client/blob/master/LICENSE.txt) |
| [completable-futures](https://github.com/spotify/completable-futures) | [Spotify](https://github.com/spotify) | [Apache License 2.0](https://github.com/spotify/completable-futures/blob/master/LICENSE) |

View File

@ -1,90 +0,0 @@
---
slug: /velocity/server-compatibility
---
# Server Compatibility
Velocity is compatible with many Minecraft server implementations. The expectation is that if the
server acts like vanilla, Velocity will work, and we make special provisions for modded setups where
we can.
## Compatible game versions
As of this writing, Velocity is compatible with Minecraft 1.7.2 through 1.18.1.
## Vanilla setups
Velocity is best-tested with implementations derived from the vanilla server by Mojang that do not
add content to the game itself.
### Vanilla servers
The Mojang vanilla software is in a complicated position. It is useful as we often produce protocol
updates using the Mojang server for testing, but in production setups, the lack of player info
forwarding support can induce subtle client problems.
If you plan to run a vanilla server, **the Velocity team strongly recommends that you use Fabric
with the FabricProxy-Lite mod**. Fabric and FabricProxy-Lite do not by themselves change the vanilla
experience, and your server will remain compatible with vanilla clients. If you are unable (or
unwilling) to run Fabric, [VanillaCord](https://github.com/ME1312/VanillaCord) allows you to use
legacy BungeeCord forwarding.
### Spigot
Spigot is not well-tested with Velocity. However, it is based on vanilla and as it is the base for
Paper, it is relatively well-supported.
Spigot does not support Velocity's modern forwarding, but does support legacy BungeeCord forwarding.
### Paper
The Velocity project recommends using Paper for running a public server. Velocity works with all
versions of Paper from 1.7.10 to the latest version.
You can use Velocity's modern forwarding if you run Paper 1.13.2 or higher. If you use Paper 1.12.2
or lower, you must use legacy BungeeCord-style forwarding.
### SpongeVanilla
SpongeVanilla is compatible with legacy BungeeCord-style forwarding. Our Sponge support largely
focuses on Forge compatibility, see below for more information.
## Modded setups
### Fabric
Velocity works with Fabric out of the box, but you should add support for player info forwarding
using a mod like [FabricProxy-Lite](https://modrinth.com/mod/fabricproxy-lite) (which supports
Velocity modern forwarding).
In addition, if you intend to run mods that add new content on top of vanilla, you should install
[CrossStitch](https://modrinth.com/mod/crossstitch), which improves support for certain Minecraft
features that are extended by mods, such as custom argument types. This mod is officially maintained
by the Velocity project.
### Minecraft Forge (1.13 and above)
**Minecraft Forge for Minecraft 1.13 and later is not compatible with Velocity** due to changes made
in the handshake protocol that are difficult for proxies to adapt to. Support is currently a work in
progress, but there is no set time for support to be available.
### Minecraft Forge (1.7.2-1.12.2)
Minecraft Forge for Minecraft 1.7.2-1.12.2 is fully compatible with Velocity, as we make special
provisions to synchronize client state with each server. However, we **strongly** recommend the use
of SpongeForge, as it allows you to use legacy BungeeCord player info forwarding and generally
improves proxy support in general.
Velocity does not support Forge-Bukkit hybrids - they have caused several issues, and the design of
the Bukkit API precludes any notion of sane mod support.
## Proxy-behind-proxy (BungeeCord/Waterfall, Velocity, ...)
These setups are _completely unsupported_. You are best advised to avoid them, as they can cause
lots of issues. Most proxy-behind-proxy setups are either illogical in the first place or can be
handled more gracefully by better, more scalable and performant solutions.
## Other Implementations
This is, naturally, not an exhaustive list. Alternative implementations of the Minecraft protocol
may or may not work. We encourage you to experiment and to contribute back with your results.

View File

@ -5,19 +5,19 @@ const isPreview = process.env.DEPLOY_PREVIEW === "true";
/** @type {import("@docusaurus/types").Config} */
const base = {
title: "Dino Documentation",
tagline: "Documentation for anything Dino.",
title: "Lethal-Extended Documentation",
tagline: "Documentation for Lethal-Extended devs",
customFields: {
description:
"Documentation for all projects under the Dino umbrella.",
"Documentation for all projects under the Extended umbrella.",
},
url: isPreview ? process.env.PREVIEW_URL : "https://docs.dinopanel.net",
url: isPreview ? process.env.PREVIEW_URL : "https://docs.lethal-extended.com",
baseUrl: isPreview ? process.env.PREVIEW_BASE_URL : "/",
onBrokenLinks: isCI ? "throw" : "warn",
onBrokenMarkdownLinks: isCI ? "throw" : "warn",
onDuplicateRoutes: isCI ? "throw" : "error",
favicon: "img/favicon.ico",
organizationName: "DiskCraft",
organizationName: "Lethal-Extended",
projectName: "docs",
trailingSlash: false,
noIndex: isPreview,
@ -54,7 +54,7 @@ const base = {
{
tagName: "link",
rel: "icon",
href: "img/diskcraft3.png",
href: "img/logo.png",
},
{
tagName: "link",
@ -77,7 +77,7 @@ const base = {
colorMode: {
respectPrefersColorScheme: true,
},
image: "img/ccn.png",
image: "img/logo.png",
metadata: [
{
name: "twitter:card",
@ -89,28 +89,28 @@ const base = {
},
{
name: "og:image:alt",
content: "DiskCraft Logo",
content: "LE Logo",
},
],
navbar: {
title: "Dino Docs",
title: "Lethal-Extended Docs",
logo: {
alt: "DiskCraft Logo",
src: "img/Dino-512x-transparent.png",
alt: "LE Logo",
src: "img/logo.png",
},
items: [
{
to: "https://downloads.dinopanel.net",
to: "https://lethal-extended.com/branches.html",
label: "Downloads",
position: "right",
},
{
href: "https://discord.gg/pVH5EMeeEE",
href: "https://discord.gg/BkmEarDQxq",
className: "header-icon-link header-discord-link",
position: "right",
},
{
href: "https://github.com/Dino-Panel",
href: "https://gitea.pengucc.com/Lethal-Extended/",
className: "header-icon-link header-github-link",
position: "right",
},
@ -124,7 +124,7 @@ const base = {
items: [
{
label: "Discord",
href: "https://discord.gg/xte8RZ2AsS",
href: "https://discord.gg/BkmEarDQxq",
},
],
},
@ -133,16 +133,16 @@ const base = {
items: [
{
label: "Main Site",
href: "https://dinopanel.net",
href: "https://lethal-extended.com",
},
{
label: "GitHub",
href: "https://github.com/Dino-Panel",
href: "https://gitea.pengucc.com/Lethal-Extended/",
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} Dino and Contributors`,
copyright: `Copyright © ${new Date().getFullYear()} Lethal-Extended and Contributors`,
},
prism: {
additionalLanguages: [

View File

@ -6,15 +6,15 @@ const sidebars = {
{
type: "link",
label: "Support Discord",
href: "https://discord.gg/pVH5EMeeEE",
href: "https://discord.gg/BkmEarDQxq",
},
"README",
{
type: "category",
label: "diskcraft",
label: "lethal-extended",
link: {
type: "doc",
id: "diskcraft/README",
id: "lethalextended/README",
},
items: [
{
@ -22,16 +22,9 @@ const sidebars = {
label: "Getting Started",
link: {
type: "doc",
id: "diskcraft/getting-started/README",
id: "lethalextended/getting-started/README",
},
items: ["diskcraft/getting-started/README"],
},
{
type: "category",
label: "Reference",
items: [
"diskcraft/reference/diskcraft-global-configuration",
],
items: ["lethalextended/getting-started/README"],
},
],
},

View File

@ -4,11 +4,11 @@ import styles from "../css/projects.module.css";
const projects: Project[] = [
{
title: "Dino v1",
title: "Lethal-Extended Add-Ons",
description:
"Easy to use and open source billing system for Pterodactyl",
repo: "DiskCraft/DiskCraft",
link: "/diskcraft",
"How to create add-on packs for Lethal-Extended",
repo: "Lethal-Extended/Lethal-Extended",
link: "/le/getting-started/addons",
},
];

BIN
static/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB