Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
040b5d77f5 | ||
|
|
49f08ce13b | ||
|
|
c5bf54fca9 | ||
|
|
af24b7eba2 | ||
|
|
622a065aa2 | ||
|
|
926425bc8b | ||
|
|
dc4d8287fc | ||
|
|
951364e274 | ||
|
|
83c170d32e | ||
|
|
a93b076803 | ||
|
|
a0b731f3c7 | ||
|
|
a5d2cd52ee | ||
|
|
ffb913426e | ||
|
|
287abfb9b6 | ||
|
|
f14b71c171 | ||
|
|
ca17509448 | ||
|
|
dcae7b5688 | ||
|
|
b4d89ef147 | ||
|
|
419ae34d04 | ||
|
|
0b62a113bb | ||
|
|
3957cab101 | ||
|
|
72ed5d1e68 | ||
|
|
e89a5eff14 | ||
|
|
1ea6457072 | ||
|
|
14b1d29106 | ||
|
|
57cf58d420 | ||
|
|
17f5a5b927 | ||
|
|
aee18cdddd | ||
|
|
9660fa5949 | ||
|
|
fc8ff7de91 | ||
|
|
dbde2759c3 | ||
|
|
316ba24b79 | ||
|
|
155caeaaa1 | ||
|
|
bdd025d1bb | ||
|
|
61b03a45e9 | ||
|
|
59e2ff9614 | ||
|
|
b78d9b1817 | ||
|
|
32290a8b6f | ||
|
|
110a0f0665 | ||
|
|
e87ea8d2d0 | ||
|
|
105dd9ed21 | ||
|
|
f5f15998be | ||
|
|
1d27d4d21a | ||
|
|
9525858608 | ||
|
|
bd18dffbba | ||
|
|
4cf8178c38 | ||
|
|
35c095a27b | ||
|
|
f27896ad3b | ||
|
|
3a0da3cd67 | ||
|
|
dd0f94116f | ||
|
|
6c4dcefcc6 | ||
|
|
038e675d2b | ||
|
|
ca299ce958 | ||
|
|
a206ccb004 | ||
|
|
5ef0254d97 | ||
|
|
9e77bb538f | ||
|
|
a20d6ef326 | ||
|
|
4a837d4543 | ||
|
|
88717a5eff | ||
|
|
dd80edafc8 | ||
|
|
b576ce4808 | ||
|
|
9918f4a047 | ||
|
|
084d9371eb | ||
|
|
64645a4047 | ||
|
|
7b4fb78b11 | ||
|
|
3a24dc582c | ||
|
|
82efbc011b | ||
|
|
e873fc1627 | ||
|
|
a52ad83d51 | ||
|
|
5d1c2d11ae | ||
|
|
47463777c6 | ||
|
|
26e00da63f | ||
|
|
e3c5d1d93c | ||
|
|
a88d0c4796 | ||
|
|
6ad3927d91 | ||
|
|
5069b9c7ee | ||
|
|
c28eab495c | ||
|
|
1b11a2a6d0 | ||
|
|
d01d698132 | ||
|
|
6f4f838b74 | ||
|
|
232b8e2372 | ||
|
|
818a68da99 | ||
|
|
507623b333 | ||
|
|
5cd2029229 | ||
|
|
f0206c08ae | ||
|
|
c11fc81cff | ||
|
|
23f98240cb | ||
|
|
1f2fa53407 | ||
|
|
4e49afc95c | ||
|
|
6a3b0a1936 | ||
|
|
0500867a59 | ||
|
|
d139d12c42 | ||
|
|
c9e566c002 | ||
|
|
0d37f27953 | ||
|
|
677baed7b1 | ||
|
|
0b0c79b742 | ||
|
|
ddf6950ec5 | ||
|
|
97c9a5772e | ||
|
|
c09acbe6ec | ||
|
|
63abeaf9f7 | ||
|
|
cfd810670e | ||
|
|
5de0804edc | ||
|
|
50e1b8ab50 | ||
|
|
c923e2a4a1 | ||
|
|
9b85dab732 | ||
|
|
9af75eba2d | ||
|
|
cde2fd6e11 | ||
|
|
9d7c7f7dba | ||
|
|
940c4d5969 | ||
|
|
fee64de30e | ||
|
|
d453d036fc | ||
|
|
eab88d1bdf | ||
|
|
aff424c00a | ||
|
|
ace5ca489e | ||
|
|
6bd7bbe929 | ||
|
|
28b6bfa6dc | ||
|
|
185a6065fc | ||
|
|
af432580e8 | ||
|
|
544ec5a0cc | ||
|
|
f86d110312 | ||
|
|
9b72dff649 | ||
|
|
5c377d82c6 | ||
|
|
1484d50eba | ||
|
|
54e02bf6c3 | ||
|
|
2fdd56679a | ||
|
|
9e60edd307 | ||
|
|
204a24a1db | ||
|
|
019818f615 | ||
|
|
2e6f6edf99 | ||
|
|
e10d477a40 | ||
|
|
3dc4a8524c | ||
|
|
9202a8c08f | ||
|
|
19ae50f95d | ||
|
|
6e168bbe08 | ||
|
|
6c8dc900a4 | ||
|
|
1473413d7d | ||
|
|
d94cc09de7 | ||
|
|
f767377854 | ||
|
|
ac80a7b7a4 | ||
|
|
902e9f3da7 | ||
|
|
17e3b06b3d | ||
|
|
8c979ebcf8 | ||
|
|
3ca38489b2 | ||
|
|
70e1717064 | ||
|
|
97dd0dab0a | ||
|
|
6926df9337 | ||
|
|
be93c3b2bd | ||
|
|
468aa18542 | ||
|
|
35d7fb58be |
No files matched your search
@@ -30,22 +30,29 @@ jobs:
|
||||
name: Deploy to GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b
|
||||
|
||||
- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b
|
||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 22
|
||||
cache: yarn
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
|
||||
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57
|
||||
with:
|
||||
path: |
|
||||
${{ github.workspace }}/.docusaurus
|
||||
@@ -71,4 +78,4 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@decdde0ac072f6dcbe43649d82d9c635fff5b4e4
|
||||
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e
|
||||
@@ -8,19 +8,26 @@ jobs:
|
||||
name: Build PR
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b
|
||||
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 22
|
||||
cache: yarn
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
|
||||
- uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
|
||||
with:
|
||||
path: |
|
||||
${{ github.workspace }}/.docusaurus
|
||||
|
||||
@@ -26,4 +26,9 @@ vendor
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
package-lock.json
|
||||
package-lock.json
|
||||
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/versions
|
||||
@@ -0,0 +1 @@
|
||||
nodeLinker: node-modules
|
||||
@@ -224,12 +224,12 @@ Geyser initially rolled out a fix that forced these defaults, but has since been
|
||||
These defaults may present an issue to those running a reverse proxy in front of their Geyser instance, particularly those utilizing DDoS mitigation services like TCPShield and CosmicGuard, as to Network it will appear that all connections are originating from the same IP. To make configuration on these services easier, Geyser will disable these rate limits provided proxy protocol is enabled for the bedrock connection, and the Geyser instance is properly configured to only accept connections from the IPs of the proxy. To simplify this configuration, Geyser’s config can now accept a URL to specify proxy server IP ranges. Many DDoS mitigation providers have a static link to an always up to date text file of these.
|
||||
|
||||
```yaml
|
||||
bedrock:
|
||||
advanced.bedrock:
|
||||
# ...
|
||||
enable-proxy-protocol: true
|
||||
proxy-protocol-whitelisted-ips: [ "https://cosmic.global/ips/", "https://tcpshield.com/v4/" ]
|
||||
use-haproxy-protocol: true
|
||||
haproxy-protocol-whitelisted-ips: [ "https://cosmic.global/ips/", "https://tcpshield.com/v4/" ]
|
||||
```
|
||||
*Geyser configuration using a URL pointing a new-line separated text file containing allowed IPs for proxy-protocol usage.*
|
||||
*Geyser configuration using a URL pointing a new-line separated text file containing allowed IPs for haproxy-protocol usage.*
|
||||
|
||||
|
||||
## Long Term Impact
|
||||
|
||||
@@ -0,0 +1,472 @@
|
||||
---
|
||||
title: "Bedrock Early Packet Handling DoS Attack Summary and Response"
|
||||
slug: "early-packet-handling-attack"
|
||||
authors: Kas-tle
|
||||
hide_table_of_contents: false
|
||||
description: "A summary of how we addressed a series of exploits targeting Geyser's early handling of Bedrock game packets"
|
||||
---
|
||||
|
||||
Back in July, we received reports of multiple Geyser instances experiencing targeted Denial of Service (DoS) attacks exhibiting similar characteristics. Out of an abundance of caution, we delayed making this post to ensure that users had adequate time to upgrade. The bugs that allowed for this string of attacks were patched on Geyser builds numbered 897 and later. In the unlikely event you are still running an outdated build of Geyser from many months ago, you should update immediately by downloading the latest build from [https://geysermc.org/download](https://geysermc.org/download). The original [security advisory](https://github.com/GeyserMC/Geyser/security/advisories/GHSA-m2q6-2hwr-643w) for this vulnerability was published on the [GeyserMC/Geyser](https://github.com/GeyserMC/Geyser) repository. This response will detail the timeline, attack vectors, how they were patched, and additional measures we took to prevent future attacks.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
## Timeline (UTC)
|
||||
|
||||
- **July 29th, 9:40PM:** Server being attacked privately reports the issue to Geyser and shares logs
|
||||
- **July 29th, 11:45PM:** Preemptive patch is released to limit the number of authenticated connections per address
|
||||
- **July 30th, 5:36PM:** Large servers continue to report attacks with newer builds of Geyser
|
||||
- **July 30th, 6:20PM:** A server being attacked provides us with packet logs, illustrating what Bedrock packets malicious clients are using to carry out the attack
|
||||
- **July 30th, 6:52PM:** Second patch is released to ensure the Bedrock client can only signal complete of resource pack sending once per session
|
||||
- **July 30th, 7:45PM:** Issue regarding connections failing to close out is reported to upstream Bedrock protocol library
|
||||
- **July 30th, 9:35PM:** Upstream Bedrock protocol library publishes patch to ensure connections are properly closed when Bedrock users are disconnected
|
||||
- **July 30th, 10:45PM:** Third patch is released updating the upstream Bedrock protocol library and ensuring Bedrock connections that cause exceptions are closed immediately
|
||||
- **July 31st, 11:24PM:** An @everyone ping is made in the Geyser Discord advising users to update their Geyser instances, and the initial security advisory is published to GitHub.
|
||||
|
||||
## Initial Disclosure
|
||||
|
||||
Use of this attack was first privately reported to us by multiple larger servers using Geyser. We were provided server logs showing a single user appearing to be authenticated multiple times. The logs generally took a form of:
|
||||
|
||||
```log
|
||||
[17:26:09.183 GeyserServerChild-4-1/INFO] Player connected with username BedrockPleyer
|
||||
[17:26:09.183 GeyserServerChild-4-1/INFO] Player connected with username BedrockPleyer
|
||||
[17:26:09.183 GeyserServerChild-4-1/INFO] Player connected with username BedrockPleyer
|
||||
[17:26:09.183 GeyserServerChild-4-1/ERROR] BedrockPleyer is already logged in!
|
||||
[17:26:09.183 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[17:26:09.183 clientNetworkSession-6-3/INFO] BedrockPlayer (logged in as: BedrockPlayer) has connected to remote java server on address 127.0.0.1
|
||||
[17:26:09.183 clientNetworkSession-6-1/INFO] BedrockPlayer (logged in as: BedrockPlayer) has connected to remote java server on address 127.0.0.1
|
||||
[17:26:09.183 clientNetworkSession-6-2/INFO] BedrockPlayer (logged in as: BedrockPlayer) has connected to remote java server on address 127.0.0.1
|
||||
[17:26:09.184 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!
|
||||
[17:26:09.184 clientNetworkSession-6-4/INFO] BedrockPlayer (logged in as: BedrockPlayer) has connected to remote java server on address 127.0.0.1
|
||||
[17:26:09.184 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[17:26:09.184 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!
|
||||
[17:26:09.184 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[17:26:09.184 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!
|
||||
[17:26:09.184 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[17:26:09.184 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!
|
||||
[17:26:09.185 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[17:26:09.185 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!
|
||||
```
|
||||
|
||||
Based on the content of these logs, we initially suspected that packets in the early phase of the Bedrock connection were being exploited. However, we were not yet sure of what specific packets the attacker was sending. Based on these logs, we released a preemptive patch to ensure that the number of authenticated users from a single IP address at any given time was limited. This alone, however, would prove to be insufficient to mitigate the attack.
|
||||
|
||||
## Game Packet and Code Analysis of the First Attack Vector
|
||||
|
||||
Understanding this attack requires a basic understanding of the general Bedrock login process. This is detailed below:
|
||||
|
||||

|
||||
|
||||
In order to fully mitigate this attack, we required packet capture samples from a server being actively exploited. This is somewhat challenging to achieve, as traffic at the Bedrock protocol level is generally encrypted after the player has logged into the server. As a result, a modified build of Geyser is required to capture this traffic. We were fortunate to have the cooperation of a server being targeted with this attack, who installed a build of Geyser we provided to log packets. This was the resulting log, with IP addresses and usernames redacted:
|
||||
|
||||
```log
|
||||
[18:16:37.767 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ClientToServerHandshakePacket
|
||||
[18:16:37.795 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.808 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.808 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.809 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.809 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.809 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.809 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.810 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.810 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.810 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.810 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.810 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.810 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.811 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.811 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.811 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.811 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.811 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.811 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.812 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.812 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.820 clientNetworkSession-6-2/INFO] BedrockPlayer (logged in as: BedrockPlayer) has connected to remote java server on address 127.0.0.1
|
||||
[18:16:37.820 clientNetworkSession-6-1/INFO] BedrockPlayer (logged in as: BedrockPlayer) has connected to remote java server on address 127.0.0.1
|
||||
[18:16:37.820 clientNetworkSession-6-4/INFO] BedrockPlayer (logged in as: BedrockPlayer) has connected to remote java server on address 127.0.0.1
|
||||
[18:16:37.820 clientNetworkSession-6-3/INFO] BedrockPlayer (logged in as: BedrockPlayer) has connected to remote java server on address 127.0.0.1
|
||||
[18:16:37.848 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.849 GeyserServerChild-4-1/INFO] BedrockPlayer /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.849 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!
|
||||
[18:16:37.849 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.849 GeyserServerChild-4-1/INFO] BedrockPlayer /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.850 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!
|
||||
[18:16:37.850 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
[18:16:37.850 GeyserServerChild-4-1/INFO] BedrockPlayer /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)
|
||||
[18:16:37.850 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!
|
||||
[18:16:37.850 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer
|
||||
```
|
||||
|
||||
The above log clearly indicates that the packet being exploited is the [ResourcePackClientResponsePacket](https://mojang.github.io/bedrock-protocol-docs/html/ResourcePackClientResponsePacket.html). This leads to code paths in Geyser being called multiple times a way that is not intended, ultimately leading to increased resource consumption. We can essentially summarize the attack as follows:
|
||||
|
||||

|
||||
|
||||
The initial response to the ResourcePackClientResponsePacket is handled by `UpstreamPacketHandler`:
|
||||
|
||||
```java
|
||||
package org.geysermc.geyser.network;
|
||||
// ...
|
||||
public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
// ...
|
||||
public PacketSignal handle(ResourcePackClientResponsePacket packet) {
|
||||
// ...
|
||||
switch (packet.getStatus()) {
|
||||
case COMPLETED -> {
|
||||
if (geyser.getConfig().getRemote().authType() != AuthType.ONLINE) {
|
||||
session.authenticate(session.getAuthData().name());
|
||||
} else if (!couldLoginUserByName(session.getAuthData().name())) {
|
||||
// We must spawn the white world
|
||||
session.connect();
|
||||
}
|
||||
geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.connect", session.getAuthData().name()));
|
||||
}
|
||||
// ...
|
||||
}
|
||||
return PacketSignal.HANDLED;
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
We see in the code above that this will lead to the invocation of `GeyserSession#authenticate` for most connections, as most Geyser instances use `AuthType.FLOODGATE`:
|
||||
|
||||
```java
|
||||
package org.geysermc.geyser.session;
|
||||
// ...
|
||||
public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
// ...
|
||||
public void authenticate(String username) {
|
||||
if (loggedIn) {
|
||||
geyser.getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.auth.already_loggedin", username));
|
||||
return;
|
||||
}
|
||||
|
||||
loggingIn = true;
|
||||
// Always replace spaces with underscores to avoid illegal nicknames, e.g. with GeyserConnect
|
||||
protocol = new MinecraftProtocol(username.replace(' ', '_'));
|
||||
|
||||
try {
|
||||
connectDownstream();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
This leads to the calling of `GeyserSession#connectDownstream`, which triggers a variety of logic to open a connection to the Java server:
|
||||
|
||||
```java
|
||||
package org.geysermc.geyser.session;
|
||||
// ...
|
||||
public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
// ...
|
||||
private void connectDownstream() {
|
||||
SessionLoginEvent loginEvent = new SessionLoginEvent(this, remoteServer, new Object2ObjectOpenHashMap<>());
|
||||
GeyserImpl.getInstance().eventBus().fire(loginEvent);
|
||||
if (loginEvent.isCancelled()) {
|
||||
String disconnectReason = loginEvent.disconnectReason() == null ?
|
||||
BedrockDisconnectReasons.DISCONNECTED : loginEvent.disconnectReason();
|
||||
disconnect(disconnectReason);
|
||||
return;
|
||||
}
|
||||
|
||||
this.cookies = loginEvent.cookies();
|
||||
// Don't allow changing the remote server when it's not up to us
|
||||
// Just imagine the chaos of using an integrated world manager for an external server :)
|
||||
this.remoteServer = this.geyser.platformType() == PlatformType.STANDALONE ? loginEvent.remoteServer() : remoteServer;
|
||||
|
||||
// Start ticking
|
||||
tickThread = tickEventLoop.scheduleAtFixedRate(this::tick, nanosecondsPerTick, nanosecondsPerTick, TimeUnit.NANOSECONDS);
|
||||
|
||||
ClientSession downstream;
|
||||
if (geyser.getBootstrap().getSocketAddress() != null) {
|
||||
// We're going to connect through the JVM and not through TCP
|
||||
downstream = new LocalSession(geyser.getBootstrap().getSocketAddress(),
|
||||
upstream.getAddress().getAddress().getHostAddress(),
|
||||
this.protocol, this.tickEventLoop);
|
||||
downstream.setFlag(MinecraftConstants.CLIENT_HOST, this.remoteServer.address());
|
||||
downstream.setFlag(MinecraftConstants.CLIENT_PORT, this.remoteServer.port());
|
||||
this.downstream = new DownstreamSession(downstream);
|
||||
} else {
|
||||
downstream = new ClientNetworkSession(new InetSocketAddress(this.remoteServer.address(), this.remoteServer.port()), this.protocol, tickEventLoop, null, null);
|
||||
this.downstream = new DownstreamSession(downstream);
|
||||
|
||||
boolean resolveSrv = false;
|
||||
try {
|
||||
resolveSrv = this.remoteServer.resolveSrv();
|
||||
} catch (AbstractMethodError | NoSuchMethodError ignored) {
|
||||
// Ignore if the method doesn't exist
|
||||
// This will happen with extensions using old APIs
|
||||
}
|
||||
this.downstream.getSession().setFlag(BuiltinFlags.ATTEMPT_SRV_RESOLVE, resolveSrv);
|
||||
}
|
||||
|
||||
// Disable automatic creation of a new TcpClientSession when transferring - we don't use that functionality.
|
||||
this.downstream.getSession().setFlag(MinecraftConstants.FOLLOW_TRANSFERS, false);
|
||||
|
||||
if (geyser.getConfig().getRemote().isUseProxyProtocol()) {
|
||||
downstream.setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress());
|
||||
}
|
||||
if (geyser.getConfig().isForwardPlayerPing()) {
|
||||
// Let Geyser handle sending the keep alive
|
||||
downstream.setFlag(MinecraftConstants.AUTOMATIC_KEEP_ALIVE_MANAGEMENT, false);
|
||||
}
|
||||
// We'll handle this since we have the registry data on hand
|
||||
downstream.setFlag(MinecraftConstants.SEND_BLANK_KNOWN_PACKS_RESPONSE, false);
|
||||
|
||||
// We manually add the default listener to ensure the order of listeners.
|
||||
protocol.setUseDefaultListeners(false);
|
||||
|
||||
// MCPL listener comes first to handle protocol state switching before Geyser translates packets
|
||||
downstream.addListener(new ClientListener(HandshakeIntent.LOGIN));
|
||||
// Geyser adapter second to ensure translating packets in the correct states
|
||||
downstream.addListener(new GeyserSessionAdapter(this));
|
||||
|
||||
downstream.setFlag(BuiltinFlags.CLIENT_TRANSFERRING, loginEvent.transferring());
|
||||
downstream.connect(false);
|
||||
|
||||
if (!daylightCycle) {
|
||||
setDaylightCycle(true);
|
||||
}
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Notably, this allows for multiple downstream sessions (representing Geyser's connection to the Java server per player) to be created for a single Bedrock session. This is not intended behavior, as it leads to significantly increased resource consumption. This is especially true on Geyser Standalone, which, as seen in the code above, must open a TCP session to the Java server. The window of time for an attacker to pull this off is relatively short, as once Geyser completes the Java login process on behalf of the Bedrock client, `GeyserSession.loggedIn` is set to true, preventing further calls to `GeyserSession#connectDownstream`. However, this is still enough time for an attacker to create numerous downstream sessions, leading to a DoS attack. We attempted to mitigate this by disconnecting clients that send multiple ResourcePackClientResponsePacket in a single session. The following class diagram summarizes this:
|
||||
|
||||

|
||||
|
||||
## Code Analysis of the Second Attack Vector
|
||||
|
||||
While we thought we had addressed the root issue and provided the affected users with a patch for testing, we quickly received logs that indicated otherwise:
|
||||
|
||||
```log
|
||||
[18:54:29.235 GeyserServerChild-4-3/INFO] Player connected with username BedrockPlayer
|
||||
[18:54:29.237 clientNetworkSession-6-2/INFO] BedrockPlayer (logged in as: BedrockPlayer) has connected to remote java server on address 127.0.0.1
|
||||
[18:54:49.257 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:54:49.259 GeyserServerChild-4-3/INFO] BedrockPlayer has disconnected from remote Java server on address 127.0.0.1 because of An internal error occurred!
|
||||
[18:54:52.836 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:54:55.620 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:54:56.186 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:54:56.872 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:54:59.508 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:02.551 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:03.025 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:03.619 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:04.254 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:04.922 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:05.435 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:07.662 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:08.139 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:08.650 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:11.066 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:13.498 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:14.023 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:14.466 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:15.057 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:15.712 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:16.211 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:18.431 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:18.966 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:19.443 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:21.599 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:23.904 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:24.409 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:24.971 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:25.539 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
[18:55:26.225 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))
|
||||
```
|
||||
|
||||
These exceptions are thrown by Geyser's InvalidPacketHandler, which is designed to quickly disconnect players that send malformed packets or packets that exceed the expected size limits. This is a security measure to prevent potential exploits or crashes caused by invalid data.
|
||||
|
||||
```java
|
||||
package org.geysermc.geyser.network;
|
||||
// ...
|
||||
public class InvalidPacketHandler extends ChannelInboundHandlerAdapter {
|
||||
public static final String NAME = "rak-error-handler";
|
||||
|
||||
private final GeyserSession session;
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
Throwable rootCause = Stream.iterate(cause, Throwable::getCause)
|
||||
.filter(element -> element.getCause() == null)
|
||||
.findFirst()
|
||||
.orElse(cause);
|
||||
|
||||
GeyserLogger logger = GeyserImpl.getInstance().getLogger();
|
||||
|
||||
if (!(rootCause instanceof IllegalArgumentException)) {
|
||||
// Kick users that cause exceptions
|
||||
logger.warning("Exception caught in session of " + session.bedrockUsername() + ": " + rootCause.getMessage());
|
||||
session.disconnect("An internal error occurred!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Kick users that try to send illegal packets
|
||||
logger.warning("Illegal packet from " + session.bedrockUsername() + ": " + rootCause.getMessage());
|
||||
if (logger.isDebug()) {
|
||||
cause.printStackTrace();
|
||||
}
|
||||
session.disconnect("Invalid packet received!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This makes the aforementioned logs of particular concern, as it should not be possible for any exceptions to be triggered from this handler multiple times. The first exception should be logged and trigger an immediate disconnect, preventing further exceptions from being thrown. Despite this, the log clearly indicates that multiple exceptions are being thrown in quick succession, suggesting that the disconnect is not being handled as intended. This is summarized below:
|
||||
|
||||

|
||||
|
||||
We first followed the chain of `GeyserSession#disconnect`. This invokes Geyser's `UpstreamSession#disconnect`, which contains `BedrockServerSession` and invokes `BedrockServerSession#disconnect`. Beyond this, the disconnect logic is handled by the upstream Bedrock protocol library used by Geyser, [CloudburstMC/Protocol](https://github.com/CloudburstMC/Protocol). The overall logic is summarized below:
|
||||
|
||||

|
||||
|
||||
Upon further investigation, we found that the Bedrock protocol library did not actually close the underlying Netty channel when a disconnect was triggered:
|
||||
|
||||
```java
|
||||
package org.cloudburstmc.protocol.bedrock;
|
||||
// ...
|
||||
public class BedrockServerSession extends BedrockSession {
|
||||
// ...
|
||||
public void disconnect(@Nullable String reason, boolean hideReason) {
|
||||
this.checkForClosed();
|
||||
|
||||
DisconnectPacket packet = new DisconnectPacket();
|
||||
if (reason == null || hideReason) {
|
||||
packet.setMessageSkipped(true);
|
||||
reason = BedrockDisconnectReasons.DISCONNECTED;
|
||||
}
|
||||
packet.setKickMessage(reason);
|
||||
this.sendPacketImmediately(packet);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This allows an attacker that should have been disconnected to continue to send malicous packets that lead to expensive deserialization logic. The result is another potential denial of service (DoS) attack vector.
|
||||
|
||||
## Patch and Mitigation
|
||||
|
||||
We mitigated the first attack vector by ensuring that the Bedrock client can only signal completion of resource pack sending once per session. This was done by modifying the `UpstreamPacketHandler` to check if the `finishedResourcePackSending` flag is already set before proceeding with authentication logic:
|
||||
|
||||
```java
|
||||
package org.geysermc.geyser.network;
|
||||
// ...
|
||||
public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
// ...
|
||||
public PacketSignal handle(ResourcePackClientResponsePacket packet) {
|
||||
// ...
|
||||
// highlight-start
|
||||
if (finishedResourcePackSending) {
|
||||
session.disconnect("Illegal duplicate resource pack response packet received!");
|
||||
return PacketSignal.HANDLED;
|
||||
}
|
||||
// highlight-end
|
||||
// ...
|
||||
switch (packet.getStatus()) {
|
||||
case COMPLETED -> {
|
||||
// highlight-start
|
||||
finishedResourcePackSending = true;
|
||||
// highlight-end
|
||||
if (geyser.getConfig().getRemote().authType() != AuthType.ONLINE) {
|
||||
session.authenticate(session.getAuthData().name());
|
||||
} else if (!couldLoginUserByName(session.getAuthData().name())) {
|
||||
// We must spawn the white world
|
||||
session.connect();
|
||||
}
|
||||
geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.connect", session.getAuthData().name()));
|
||||
}
|
||||
// ...
|
||||
}
|
||||
return PacketSignal.HANDLED;
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
This ensures that any further attempts to send a `ResourcePackClientResponsePacket` after the first one will result in an immediate disconnect, preventing the creation of multiple downstream sessions.
|
||||
|
||||
The second attack vector was mitigated by ensuring that the disconnect logic in the Bedrock protocol library properly closes the underlying Netty channel. This was achieved by modifying the `BedrockServerSession#disconnect` method to schedule a task that closes the session after a timeout, ensuring that the channel is closed after the disconnect packet is sent. Packet serialzation is also stopped immediately for disconnected clients:
|
||||
|
||||
```java
|
||||
package org.cloudburstmc.protocol.bedrock;
|
||||
// ...
|
||||
public class BedrockServerSession extends BedrockSession {
|
||||
private static final int TIMEOUT_SECONDS = SystemPropertyUtil.getInt("org.cloudburstmc.protocol.bedrock.disconnectTimeout", 10);
|
||||
// ...
|
||||
public void disconnect(@Nullable String reason, boolean hideReason) {
|
||||
this.checkForClosed();
|
||||
|
||||
DisconnectPacket packet = new DisconnectPacket();
|
||||
String finalReason;
|
||||
if (reason == null || hideReason) {
|
||||
packet.setMessageSkipped(true);
|
||||
finalReason = BedrockDisconnectReasons.DISCONNECTED;
|
||||
} else {
|
||||
finalReason = reason;
|
||||
}
|
||||
packet.setKickMessage(finalReason);
|
||||
this.sendPacketImmediately(packet);
|
||||
|
||||
// highlight-start
|
||||
if (!this.isSubClient()) {
|
||||
this.getPeer().blackholeInboundPackets();
|
||||
}
|
||||
|
||||
this.getPeer().channel.eventLoop().schedule(() -> {
|
||||
if (this.isConnected()) {
|
||||
this.close(finalReason);
|
||||
}
|
||||
}, TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
// highlight-end
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Logic was also added to Geyser's `InvalidPacketHandler` to ensure that invalid packets result in an immediate closing of the underlying Netty channel:
|
||||
|
||||
```java
|
||||
package org.geysermc.geyser.network;
|
||||
// ...
|
||||
public class InvalidPacketHandler extends ChannelInboundHandlerAdapter {
|
||||
public static final String NAME = "rak-error-handler";
|
||||
|
||||
private final GeyserSession session;
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
Throwable rootCause = Stream.iterate(cause, Throwable::getCause)
|
||||
.filter(element -> element.getCause() == null)
|
||||
.findFirst()
|
||||
.orElse(cause);
|
||||
|
||||
GeyserLogger logger = GeyserImpl.getInstance().getLogger();
|
||||
|
||||
if (!(rootCause instanceof IllegalArgumentException)) {
|
||||
// Kick users that cause exceptions
|
||||
logger.error("Exception caught in session of " + session.bedrockUsername(), cause);
|
||||
session.disconnect("An internal error occurred!");
|
||||
// highlight-start
|
||||
session.forciblyCloseUpstream();
|
||||
// highlight-end
|
||||
return;
|
||||
}
|
||||
|
||||
// Kick users that try to send illegal packets
|
||||
logger.error("Illegal packet from " + session.bedrockUsername(), cause);
|
||||
session.disconnect("Invalid packet received!");
|
||||
// highlight-start
|
||||
session.forciblyCloseUpstream();
|
||||
// highlight-end
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Long Term Impact
|
||||
|
||||
All users of Geyser running outdated builds should update as soon as possible to ensure they are not vulnerable to the attacks described in this post. During the process of investigating this attack, we were made aware of multiple servers being exploited, meaning this is being exploited in the wild. Unlike the previous RakNet amplification attack, this attack is limited in scope to the selected Geyser instance. We expect the number of unpatched instances to decrease over time as Bedrock updates require server owners to update their Geyser instances. As of November 2025, we have not received any recent reports of Geyser instances being targeted by this attack vector, indicating that most instances have been patched.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
We thank the community for their patience as we addressed this issue, the server owners who responsibly disclosed this issue to us, the developers at Cloudburst and Geyser that worked to mitigate the issue, all donors for their financial support of Geyser, and Cubecraft and Open Collaboration for their continued financial and operational support of the project.
|
||||
@@ -134,11 +134,6 @@ const config: Config = {
|
||||
className: 'header-utilities-link',
|
||||
position: 'left',
|
||||
items: [
|
||||
{
|
||||
|
||||
to: 'utilities/config-editor',
|
||||
label: 'Config Editor',
|
||||
},
|
||||
{
|
||||
|
||||
to: 'utilities/dump-viewer',
|
||||
@@ -152,12 +147,12 @@ const config: Config = {
|
||||
position: 'left',
|
||||
className: 'header-download-link'
|
||||
},
|
||||
{
|
||||
{ // Name on mobile sidebar specified in custom.scss
|
||||
href: 'https://github.com/GeyserMC/Geyser',
|
||||
position: 'right',
|
||||
className: 'header-github-link'
|
||||
},
|
||||
{
|
||||
{ // Name on mobile sidebar specified in custom.scss
|
||||
href: 'https://discord.gg/geysermc',
|
||||
position: 'right',
|
||||
className: 'header-discord-link'
|
||||
@@ -175,6 +170,7 @@ const config: Config = {
|
||||
href: '/',
|
||||
width: 430,
|
||||
},
|
||||
copyright: `Copyright © ${new Date().getFullYear()} GeyserMC. Built with Docusaurus.<br>This website is not an official Minecraft website and is not associated with Mojang Studios or Microsoft. All product and company names are trademarks or registered trademarks of their respective holders. Use of these names does not imply any affiliation or endorsement by them.`,
|
||||
links: [
|
||||
{
|
||||
title: 'Wiki',
|
||||
@@ -193,7 +189,7 @@ const config: Config = {
|
||||
},
|
||||
{
|
||||
label: 'Other',
|
||||
to: 'wiki/other/geyseroptionalpack',
|
||||
to: 'wiki/other/geyserintegratedpack',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -252,7 +248,11 @@ const config: Config = {
|
||||
},
|
||||
{
|
||||
label: 'Global Linking',
|
||||
to: 'https://link.geysermc.org/',
|
||||
href: 'https://link.geysermc.org/',
|
||||
},
|
||||
{
|
||||
label: 'Privacy Policy',
|
||||
href: 'https://ziax.com/terms/privacy-policy/',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
"message": "Enable `clone-remote-port` (or manually set `bedrock port` to the Java port), and connect with the Java IP and port."
|
||||
},
|
||||
"providers.templates.ip_and_port": {
|
||||
"message": "Enable `clone-remote-port` (or manually set `bedrock port` to the Java port), uncomment `bedrock address`, and change `0.0.0.0` to your Java server's IP. Connect with the Java IP and port."
|
||||
"message": "Enable `clone-remote-port` (or manually set `bedrock port` to the Java port) and change `bedrock address` from `0.0.0.0` to your Java server's IP. Connect with the Java IP and port."
|
||||
},
|
||||
"providers.templates.forwarding_option": {
|
||||
"message": "Offers a working port forwarding option."
|
||||
},
|
||||
"providers.templates.java_ip": {
|
||||
"message": "Make sure your remote address is 'auto', uncomment `bedrock address`, and change `0.0.0.0` to your Java server's IP."
|
||||
"message": "Change `bedrock address` from `0.0.0.0` to your Java server's IP."
|
||||
},
|
||||
"providers.provider.apex_hosting.description": {
|
||||
"message": "Full auto installation. Go to the Customizations tab in the panel and select 'Enabled' under the 'Geyser Auto Installer' option. Then, restart and connect to your server with your Java IP and port. See [Apex's article](https://apexminecrafthosting.com/geysermc/) for more details."
|
||||
@@ -53,11 +53,14 @@
|
||||
"providers.provider.minehut.description": {
|
||||
"message": "Connect via `bedrock.minehut.com` and do `/join [servername]`, or connect directly via `[servername].bedrock.minehut.gg`."
|
||||
},
|
||||
"providers.provider.omgserv.description": {
|
||||
"message": "Select Geyser in the [Install Menu](https://i.imgur.com/Gewpsrq.png), it will be automatically installed. You can enable floodgate in the [server properties on the dashboard](https://i.imgur.com/jg5mzNj.png)."
|
||||
},
|
||||
"providers.provider.piglinhost.description": {
|
||||
"message": "Order from the [cross-platform servers page](https://piglinhost.com/minecraft-java-hosting.html). Alternatively, contact their support by creating a [support ticket](https://billing.piglinhost.com/submitticket.php?step=2&deptid=5) or via discord for installation and configuration help."
|
||||
},
|
||||
"providers.provider.omgserv.description": {
|
||||
"message": "Select Geyser in the [Install Menu](https://i.imgur.com/Gewpsrq.png), it will be automatically installed. You can enable floodgate in the [server properties on the dashboard](https://i.imgur.com/jg5mzNj.png)."
|
||||
"providers.provider.playhosting.description": {
|
||||
"message": "Tick the 'Enable Bedrock crossplay?' option when changing your server software to automatically install and configure Geyser + Floodgate. For more details, navigate to [help.play.hosting/minecraft/crossplay](https://help.play.hosting/minecraft/crossplay)."
|
||||
},
|
||||
"providers.provider.pufferfish_host.description": {
|
||||
"message": "Geyser is installed and configured on all servers by default."
|
||||
@@ -65,6 +68,9 @@
|
||||
"providers.provider.server.pro.description": {
|
||||
"message": "Different instructions for different plans: On VPS, select Geyser in the [Service Type Menu](https://i.imgur.com/loSNmvu.png), Floodgate can be enabled on the dashboard configuration. For manual installation: Using a Premium or Free plan, use the same port as your Java server for the Bedrock port in the configuration file and connect that; for the Free plan, also enable the `clone-remote-port` option. If you are using a PRO or a VPS plan, you can use any port, which can be opened on the Firewall tab."
|
||||
},
|
||||
"providers.provider.serverprism.description": {
|
||||
"message": "Order a [Minecraft server](https://serverprism.com/minecraft-server-hosting) on any plugin-compatible runtime (Paper, Spigot, Purpur, etc.), then install Geyser from the panel's plugin installer. Connect with the same IP and port as your Java server."
|
||||
},
|
||||
"providers.provider.snakecraft_hosting.description": {
|
||||
"message": "Select 'Paper + Geyser with Floodgate' under the Jar Type at checkout to install the Geyser plugin. Players will Connect with the same IP and port as you would on Java."
|
||||
},
|
||||
@@ -75,7 +81,7 @@
|
||||
"message": "Find the plugin in the control panel under the 'VG Recommended' category and restart your server. IP and port are the same as Java."
|
||||
},
|
||||
"providers.provider.wisehosting.description": {
|
||||
"message": "Both auto and manual installation available. Find the GeyserMC presets from the `Properties` tab in the Game Panel. There, click `Install` and restart your server. See [Crossplay FAQ](https://help.wisehosting.com/en/articles/13-how-to-install-geysermc-java-bedrock-crossplay-to-your-server) for additional details."
|
||||
"message": "Both auto and manual installation available. Find the GeyserMC presets from the `Addons` tab in the Game Panel. There, click `Install` and restart your server. See [Crossplay FAQ](https://wisehosting.com/help/how-to-install-geysermc-to-your-minecraft-server) for additional details."
|
||||
},
|
||||
"providers.provider.zaphosting.description": {
|
||||
"message": "Find the plugin in the control panel and restart your server. IP and port are the same as Java."
|
||||
@@ -87,10 +93,10 @@
|
||||
"message": "Need to open a support ticket to get a UDP port, then use that as the `bedrock port`."
|
||||
},
|
||||
"providers.provider.bisecthosting.description": {
|
||||
"message": "You must have a plan with a dedicated IP. In Geyser's config, uncomment the `bedrock address` and set it to the public IP of your server (e.g. `address: 51.79.129.18`). Leave the port as `19132`. Under the home tab, select 'Enable UDP Network' and restart the server. See Bisect's [article](https://www.bisecthosting.com/clients/index.php?rp=/knowledgebase/193/How-to-install-Geyser-and-Floodgate-on-a-Minecraft-Java-server.html) for full instructions. If you still cannot connect after following these instructions, contact Bisect Support as they reportedly have UDP disabled on some nodes."
|
||||
"message": "Go to the Network tab and copy an available port not in use by other mods. In Geyser's config, under the bedrock section, on the port: line, edit the value to the port you copied. See Bisect's [article](https://www.bisecthosting.com/clients/index.php?rp=/knowledgebase/193/How-to-install-Geyser-and-Floodgate-on-a-Minecraft-Java-server.html) for full instructions. If you still cannot connect after following these instructions, contact Bisect Support, as they reportedly have UDP disabled on some nodes."
|
||||
},
|
||||
"providers.provider.bloomhost.description": {
|
||||
"message": "See [Bloom's documentation](https://docs.bloom.host/plugins/geysermc/) for setup instructions."
|
||||
"message": "See [Bloom's documentation](https://docs.bloom.host/multiplatform/geysermc) for setup instructions."
|
||||
},
|
||||
"providers.provider.craft-hosting.description": {
|
||||
"message": "Set the Bedrock port to the Java server's port and connect with that port; note that this provider appears to only provide service in Russia."
|
||||
@@ -108,7 +114,7 @@
|
||||
"message": "Set the `bedrock port` in the config to the Java server's port or use one of the available ports allocated to your server, and connect with that port."
|
||||
},
|
||||
"providers.provider.falixnodes.description": {
|
||||
"message": "Open a port yourself on the network page in the game panel, then use that port in the bedrock section of the Geyser config."
|
||||
"message": "Enable `clone-remote-port` (or manually set `bedrock port` to the Java port), and connect with the Java IP and port."
|
||||
},
|
||||
"providers.provider.ferox_hosting.description": {
|
||||
"message": "Open a port yourself in their panel and check out the [knowledgebase article](https://feroxhosting.nl/kb/) for how to install and configure Geyser."
|
||||
@@ -137,6 +143,9 @@
|
||||
"providers.provider.humbleservers.description": {
|
||||
"message": "Set the Bedrock port to the Java server's port, or to one of the two extra ports, and connect with that port. If the subdomain doesn't work, use your regular numbered IP address."
|
||||
},
|
||||
"providers.provider.kaashosting.description": {
|
||||
"message": "Automatic and manual installation supported. Go to the `Plugin Installer` tab, search for Geyser and click `Install Automatically`. Connect with the Java IP and port. See [KaasHosting's article](https://www.kaashosting.nl/help/nl/minecraft/hoe-maak-ik-mijn-minecraft-server-crossplay-met-geysermc) for more details."
|
||||
},
|
||||
"providers.provider.kekshost.description": {
|
||||
"message": "Use the default bedrock port (19132) and the server ip to connect on Bedrock edition. No changes to the Geyser config are needed. You can also ask for a new port and use it instead."
|
||||
},
|
||||
@@ -153,7 +162,7 @@
|
||||
"message": "Install Geyser with the dedicated Plugin installer. Use the same port as your Java server in your config. Connect with the same address and port as your Java server."
|
||||
},
|
||||
"providers.provider.nfoservers.description": {
|
||||
"message": "Uncomment and set `bedrock address` to the server IP in the Geyser config file. As an alternative, you can run Geyser standalone separately on an Unmanaged VDS."
|
||||
"message": "Set `bedrock address` to the server IP in the Geyser config file. As an alternative, you can run Geyser standalone separately on an Unmanaged VDS."
|
||||
},
|
||||
"providers.provider.nitrado.description": {
|
||||
"message": "Get Geyser as a plugin. Add 4 to the Port of the Java server. See [here](https://wiki.nitrado.net/en/How_to_install_GeyserMC_and_Floodgate) for specific instructions."
|
||||
@@ -161,6 +170,9 @@
|
||||
"providers.provider.nodecraft.description": {
|
||||
"message": "Use the default server port and `0.0.0.0` or your server IP as the host address."
|
||||
},
|
||||
"providers.provider.nolimithost.description": {
|
||||
"message": "Check [NolimitHost's documentation](https://nolimithost.cc/docs/minecraft/geyser) for specific instructions."
|
||||
},
|
||||
"providers.provider.pebblehost.description": {
|
||||
"message": "Enable `clone-remote-port` (or manually set `bedrock port` to the Java port), and connect with the Java IP and port. See [this video](https://youtu.be/v9lC80UBZF4) for a PebbleHost-specific tutorial."
|
||||
},
|
||||
@@ -195,7 +207,7 @@
|
||||
"message": "Set the Bedrock port to the Java server's port and connect with that port. Alternatively, request an additional port, or buy a dedicated IP address."
|
||||
},
|
||||
"providers.provider.witherhosting.description": {
|
||||
"message": "Either use the Java server's port, or create a port in the ports manager on the panel and use that for Bedrock. Refer to the hosts [support article](https://support.witherhosting.com/en/article/how-to-install-and-use-geysermc-1xn5l6v/) for further info."
|
||||
"message": "Either use the Java server's port, or create a port in the ports manager on the panel and use that for Bedrock. Refer to the hosts [support article](https://my.witherhosting.com/kb/how-to-install-and-use-geysermc-java) for further info."
|
||||
},
|
||||
"providers.provider.myarena.description": {
|
||||
"message": "Does seem to be working, but the Java version is too old in order for Geyser to run properly."
|
||||
@@ -203,23 +215,44 @@
|
||||
"providers.provider.nicraft.description": {
|
||||
"message": "Does not provide Bedrock support, and are affected by a [firewall configuration issue](https://wiki.geysermc.org/geyser/port-forwarding/#ovh-and-soyoustart), which prohibits most players from joining."
|
||||
},
|
||||
"providers.provider.feather.description": {
|
||||
"providers.provider.dawn.description": {
|
||||
"message": "Their proxy network does not support UDP. Therefore, Geyser is not supported. As an alternative, set up a paper server with e.g. playit.gg instead of port forwarding."
|
||||
},
|
||||
"providers.provider.freemcserver_net.description": {
|
||||
"message": "Install Geyser from the Plugins tab, then connect to your server using your Java IP and port."
|
||||
},
|
||||
"providers.provider.ultraservers.description": {
|
||||
"message": "Select 'Paper + Geyser' under the Change version tab. You can connect to your server using the same IP and port as you would on Java. Existing servers can use the Plugins/Minecraft mods tab to install Geyser. See [Crossplay](https://docs.ultraservers.com/minecraft/plugins-mods/crossplay-on-java-and-bedrock) for more information."
|
||||
},
|
||||
"providers.provider.bedrockhost.description": {
|
||||
"message": "Easiest solution is: Go to hosting panel > install new engine > Ready-made solutions and select Geyser. This will install Paper & Geyser-Spigot - no setup needed, just connect with your Java IP and port. See [BedrockHost's article](https://bedrockhost.pl/w/geyser-czyli-serwer-minecraft-java-i-bedrock-w-jednym) for more details or for custom setup instructions (available in Polish)."
|
||||
},
|
||||
"providers.provider.simplegamehosting.description": {
|
||||
"message": "Contact live chat support to open a port and check out the [help center guide](https://help.simplegamehosting.com/how-to-enable-crossplay-with-geyser-on-your-minecraft-server/) for how to install and configure Geyser on your server."
|
||||
},
|
||||
"providers.provider.axenthost.description": {
|
||||
"message": "For a quick installation, navigate to your server Variants tab and select GeyserMC. The server will be automatically reinstalled with Geyser-Spigot alongside a Paper server. For a manual install using any other variant such as Paper, you will need to upload the GeyserMC jar to your server and set the the clone-remote-port option to true. See AxentHost's [guide](https://axenthost.com/knowledgebase/categories/minecraft/create-a-crossplay-server-with-geyser/) to see all the steps."
|
||||
},
|
||||
"pages.main.title": {
|
||||
"message": "Revolutionize Your Minecraft Server"
|
||||
},
|
||||
"pages.main.subtitle": {
|
||||
"message": "Enable clients from Minecraft Bedrock Edition to join your Minecraft Java server"
|
||||
},
|
||||
"components.homepage_features.1": {
|
||||
"message": "Geyser is a program that allows Minecraft: Bedrock Edition clients to join Minecraft: Java Edition servers, allowing for true crossplay between both editions of the game. The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible."
|
||||
"components.homepage_features.1.line1": {
|
||||
"message": "Geyser is a program that allows Minecraft: Bedrock Edition clients to join Minecraft: Java Edition servers, allowing for true crossplay between both editions of the game."
|
||||
},
|
||||
"components.homepage_features.features.2": {
|
||||
"components.homepage_features.1.line2": {
|
||||
"message": "The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible."
|
||||
},
|
||||
"components.homepage_features.2": {
|
||||
"message": "Geyser acts as a translator which sits between the Bedrock client and the Java server. It takes data from the Bedrock client and translates it into a format the Java server understands and vice versa. Geyser works with any modern Minecraft version and can be installed either as a plugin or ran as a standalone program."
|
||||
},
|
||||
"components.homepage_features.features.3": {
|
||||
"message": "Geyser can be joined from Bedrock clients on Windows 10/11, iOS, Android, and even consoles. Geyser works with a wide array of hosting providers, but can also be used as its own standalone proxy to join any Minecraft server! If you are a server owner, you can install our Floodgate plugin which allows Xbox Live authenticated Bedrock users to join without a Java Edition account!"
|
||||
"components.homepage_features.3.line1": {
|
||||
"message": "Geyser can be joined from Bedrock clients on Windows 10/11, iOS, Android, and even consoles. Geyser works with a wide array of hosting providers, but can also be used as its own standalone proxy to join any Minecraft server!"
|
||||
},
|
||||
"components.homepage_features.3.line2": {
|
||||
"message": "If you are a server owner, you can install our Floodgate plugin which allows Xbox Live authenticated Bedrock users to join without a Java Edition account!"
|
||||
},
|
||||
"pages.download.title": {
|
||||
"message": "Download"
|
||||
@@ -236,32 +269,11 @@
|
||||
"pages.download.description.geyserconnect": {
|
||||
"message": "A plugin to allow for Geyser players to connect to your server without needing to use a proxy."
|
||||
},
|
||||
"pages.download.description.geyseroptionalpack": {
|
||||
"message": "An optional Bedrock resource pack to extend Geyser functionality."
|
||||
},
|
||||
"pages.download.description.thirdpartycosmetics": {
|
||||
"message": "An extension that adds support for loading ears and other third party cosmetics on java players"
|
||||
},
|
||||
"pages.configeditor.noconfigselected.heading": {
|
||||
"message": "No config selected."
|
||||
},
|
||||
"pages.configeditor.noconfigselected.subheading": {
|
||||
"message": "Upload a file or get started with the default config!"
|
||||
},
|
||||
"pages.configeditor.button.defaultconfig": {
|
||||
"message": "Default"
|
||||
},
|
||||
"pages.configeditor.button.upload": {
|
||||
"message": "Upload"
|
||||
},
|
||||
"pages.configeditor.button.export": {
|
||||
"message": "Export"
|
||||
},
|
||||
"pages.configeditor.title": {
|
||||
"message": "Config Editor"
|
||||
},
|
||||
"pages.configeditor.subheading": {
|
||||
"message": "Edit your Geyser configuration."
|
||||
"pages.download.description.emoteoffhand": {
|
||||
"message": "An extension that allows Bedrock players to switch their offhand and mainhand item by emoting."
|
||||
},
|
||||
"pages.dumpviewer.title": {
|
||||
"message": "Dump Viewer"
|
||||
@@ -770,5 +782,97 @@
|
||||
"theme.unlistedContent.message": {
|
||||
"message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
|
||||
"description": "The unlisted content banner message"
|
||||
},
|
||||
"providers.provider.not_listed.description": {
|
||||
"message": "If your hosting provider is not listed, try using [Warden Signalling](/wiki/geyser/nethernet/setup#warden-signalling). If this doesn't work, ask your hosting provider for a TCP and UDP port and use that. For VPS/KVM servers please follow the self-hosting steps."
|
||||
},
|
||||
"providers.provider.wasabihosting.description": {
|
||||
"message": "Install Geyser with the plugin installer. Use the same port as your Java server in the Geyser config. Connect with the same address and port as your Java server."
|
||||
},
|
||||
"pages.download.description.hurricane": {
|
||||
"message": "A plugin with various workarounds for Geyser players that modify the server in order to achieve their goal."
|
||||
},
|
||||
"theme.blog.author.pageTitle": {
|
||||
"message": "{authorName} - {nPosts}",
|
||||
"description": "The title of the page for a blog author"
|
||||
},
|
||||
"theme.blog.authorsList.pageTitle": {
|
||||
"message": "Authors",
|
||||
"description": "The title of the authors page"
|
||||
},
|
||||
"theme.blog.authorsList.viewAll": {
|
||||
"message": "View all authors",
|
||||
"description": "The label of the link targeting the blog authors page"
|
||||
},
|
||||
"theme.blog.author.noPosts": {
|
||||
"message": "This author has not written any posts yet.",
|
||||
"description": "The text for authors with 0 blog post"
|
||||
},
|
||||
"theme.contentVisibility.unlistedBanner.title": {
|
||||
"message": "Unlisted page",
|
||||
"description": "The unlisted content banner title"
|
||||
},
|
||||
"theme.contentVisibility.unlistedBanner.message": {
|
||||
"message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
|
||||
"description": "The unlisted content banner message"
|
||||
},
|
||||
"theme.contentVisibility.draftBanner.title": {
|
||||
"message": "Draft page",
|
||||
"description": "The draft content banner title"
|
||||
},
|
||||
"theme.contentVisibility.draftBanner.message": {
|
||||
"message": "This page is a draft. It will only be visible in dev and be excluded from the production build.",
|
||||
"description": "The draft content banner message"
|
||||
},
|
||||
"providers.provider.arth_hosting.description": {
|
||||
"message": "Geyser is installed and configured on all servers by default. You can disable it in the 'Manage Plugins' menu."
|
||||
},
|
||||
"providers.provider.mcserverhost.description": {
|
||||
"message": "Under the server configuration, select 'Crossplay' to automatically install Geyser and Floodgate. Join with the connection address. To update Geyser and Floodgate, replace the plugin jars in the server manager and restart the server."
|
||||
},
|
||||
"providers.provider.vemox_hosting.description": {
|
||||
"message": "Full automatic installation. Go to one of the panel options and select the option to enable GeyserMC. Then, restart and connect to your server using your Java IP and port."
|
||||
},
|
||||
"providers.provider.mcforfree.de.description": {
|
||||
"message": "Create an extra port in the game panel, then change the `port` in the `bedrock` section to the newly created port. To connect on Bedrock edition, use the Java server's IP and the port you've created. It may take a few minutes for the port to become active."
|
||||
},
|
||||
"providers.provider.modrinth.description": {
|
||||
"message": "Check [Modrinth's documentation](https://support.modrinth.com/en/articles/10986613-adding-geyser-to-your-server) for specific instructions."
|
||||
},
|
||||
"providers.provider.orionnodes.description": {
|
||||
"message": "Open a port yourself from the network page in the game panel, use that port in the bedrock section of the Geyser config."
|
||||
},
|
||||
"providers.provider.papernodes.description": {
|
||||
"message": "Enable clone-remote-port (or manually set the Bedrock port to the Java port), and connect with the Java IP and port. Alternatively, you can contact the host to request an additional port or a dedicated IP."
|
||||
},
|
||||
"providers.provider.wepwawet.description": {
|
||||
"message": "Add a new port in the Network tab. Use this new port as the bedrock port."
|
||||
},
|
||||
"pages.download.description.offhandextension": {
|
||||
"message": "An extension that allows Bedrock players to switch their offhand and mainhand item by emoting."
|
||||
},
|
||||
"pages.download.description.rainbow": {
|
||||
"message": "A Minecraft mod to generate Geyser item mappings and bedrock resourcepacks for use with Geyser's custom item API (v2)."
|
||||
},
|
||||
"pages.download.description.hydraulic": {
|
||||
"message": "A companion mod to Geyser which allows for Bedrock players to join modded Minecraft: Java Edition servers."
|
||||
},
|
||||
"pages.download.description.thunder": {
|
||||
"message": "A java application to convert simple Java Edition resource packs to Bedrock Edition ones."
|
||||
},
|
||||
"pages.dumpviewer.extensions": {
|
||||
"message": "Extensions"
|
||||
},
|
||||
"pages.dumpviewer.extensions.noextensions": {
|
||||
"message": "No extensions to show."
|
||||
},
|
||||
"pages.dumpviewer.extensions.helptext": {
|
||||
"message": "Click on an extension to view more information."
|
||||
},
|
||||
"providers.provider.consulhosting.description": {
|
||||
"message": "GeyserMC can be installed with a single click on ConsulHosting's Minecraft server hosting. Head to your server panel, find the GeyserMC option at Software, and install it automatically — no manual configuration needed. For step-by-step instructions, see [ConsulHosting's GeyserMC installation tutorial](https://consulhosting.com/help/install-geysermc/)."
|
||||
},
|
||||
"pages.download.description.floodgatedatabases": {
|
||||
"message": "Database extension jars for Floodgate local linking."
|
||||
}
|
||||
}
|
||||
@@ -182,5 +182,25 @@
|
||||
"sidebar.geyserSidebar.category.Geyser API": {
|
||||
"message": "Geyser API",
|
||||
"description": "The label for category Geyser API in sidebar geyserSidebar"
|
||||
},
|
||||
"sidebar.geyserSidebar.category.Custom Resource Packs": {
|
||||
"message": "Custom Resource Packs",
|
||||
"description": "The label for category Custom Resource Packs in sidebar geyserSidebar"
|
||||
},
|
||||
"sidebar.geyserSidebar.category.Nethernet": {
|
||||
"message": "Nethernet",
|
||||
"description": "The label for category Nethernet in sidebar geyserSidebar"
|
||||
},
|
||||
"sidebar.geyserSidebar.category.Nethernet.link.generated-index.title": {
|
||||
"message": "Nethernet",
|
||||
"description": "The generated-index page title for category Nethernet in sidebar geyserSidebar"
|
||||
},
|
||||
"sidebar.geyserSidebar.category.Nethernet.link.generated-index.description": {
|
||||
"message": "An explanation of Nethernet",
|
||||
"description": "The generated-index page description for category Nethernet in sidebar geyserSidebar"
|
||||
},
|
||||
"sidebar.geyserSidebar.category.Custom Content": {
|
||||
"message": "Custom Content",
|
||||
"description": "The label for category Custom Content in sidebar geyserSidebar"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,78 @@
|
||||
{
|
||||
"link.title.Wiki": {
|
||||
"message": "Wiki",
|
||||
"description": "The title of the footer links column with title=Wiki in the footer"
|
||||
},
|
||||
"link.title.Downloads": {
|
||||
"message": "Downloads",
|
||||
"description": "The title of the footer links column with title=Downloads in the footer"
|
||||
},
|
||||
"link.title.Community": {
|
||||
"message": "Community",
|
||||
"description": "The title of the footer links column with title=Community in the footer"
|
||||
},
|
||||
"link.title.More": {
|
||||
"message": "More",
|
||||
"description": "The title of the footer links column with title=More in the footer"
|
||||
},
|
||||
"link.item.label.Geyser": {
|
||||
"message": "Geyser",
|
||||
"description": "The label of footer link with label=Geyser linking to download?project=geyser"
|
||||
},
|
||||
"link.item.label.Floodgate": {
|
||||
"message": "Floodgate",
|
||||
"description": "The label of footer link with label=Floodgate linking to download?project=floodgate"
|
||||
},
|
||||
"link.item.label.REST APIs": {
|
||||
"message": "REST APIs",
|
||||
"description": "The label of footer link with label=REST APIs linking to wiki/api/api.geysermc.org/global-api"
|
||||
},
|
||||
"link.item.label.Other": {
|
||||
"message": "Other",
|
||||
"description": "The label of footer link with label=Other linking to download?project=other-projects"
|
||||
},
|
||||
"link.item.label.Crowdin": {
|
||||
"message": "Crowdin",
|
||||
"description": "The label of footer link with label=Crowdin linking to https://translate.geysermc.org/"
|
||||
},
|
||||
"link.item.label.Discord": {
|
||||
"message": "Discord",
|
||||
"description": "The label of footer link with label=Discord linking to https://discord.gg/geysermc"
|
||||
},
|
||||
"link.item.label.GitHub": {
|
||||
"message": "GitHub",
|
||||
"description": "The label of footer link with label=GitHub linking to https://github.com/GeyserMC/Geyser"
|
||||
},
|
||||
"link.item.label.Reddit": {
|
||||
"message": "Reddit",
|
||||
"description": "The label of footer link with label=Reddit linking to https://www.reddit.com/r/GeyserMC/"
|
||||
},
|
||||
"link.item.label.Twitter": {
|
||||
"message": "Twitter",
|
||||
"description": "The label of footer link with label=Twitter linking to https://twitter.com/Geyser_MC"
|
||||
},
|
||||
"link.item.label.Blog": {
|
||||
"message": "Blog",
|
||||
"description": "The label of footer link with label=Blog linking to blog"
|
||||
},
|
||||
"link.item.label.Donate": {
|
||||
"message": "Donate",
|
||||
"description": "The label of footer link with label=Donate linking to https://opencollective.com/geysermc"
|
||||
},
|
||||
"link.item.label.Global Linking": {
|
||||
"message": "Global Linking",
|
||||
"description": "The label of footer link with label=Global Linking linking to https://link.geysermc.org/"
|
||||
},
|
||||
"link.item.label.Privacy Policy": {
|
||||
"message": "Privacy Policy",
|
||||
"description": "The label of footer link with label=Privacy Policy linking to https://ziax.com/terms/privacy-policy/"
|
||||
},
|
||||
"logo.alt": {
|
||||
"message": "GeyserMC logo",
|
||||
"description": "The alt text of footer logo"
|
||||
},
|
||||
"copyright": {
|
||||
"message": "Copyright © 2024 GeyserMC. Built with Docusaurus.",
|
||||
"message": "Copyright © 2026 GeyserMC. Built with Docusaurus.<br>This website is not an official Minecraft website and is not associated with Mojang Studios or Microsoft. All product and company names are trademarks or registered trademarks of their respective holders. Use of these names does not imply any affiliation or endorsement by them.",
|
||||
"description": "The footer copyright"
|
||||
}
|
||||
}
|
||||
@@ -39,10 +39,6 @@
|
||||
"message": "Other",
|
||||
"description": "Navbar item with label Other"
|
||||
},
|
||||
"item.label.Config Editor": {
|
||||
"message": "Config Editor",
|
||||
"description": "Navbar item with label Config Editor"
|
||||
},
|
||||
"item.label.Dump Viewer": {
|
||||
"message": "Dump Viewer",
|
||||
"description": "Navbar item with label Dump Viewer"
|
||||
|
||||
@@ -23,31 +23,33 @@
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^3.4.0",
|
||||
"@docusaurus/preset-classic": "^3.4.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"@docusaurus/core": "3.6.3",
|
||||
"@docusaurus/preset-classic": "3.6.3",
|
||||
"@fortawesome/fontawesome-svg-core": "6.5.1",
|
||||
"@fortawesome/free-brands-svg-icons": "6.5.1",
|
||||
"@fortawesome/free-regular-svg-icons": "6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "6.5.1",
|
||||
"@fortawesome/react-fontawesome": "0.2.0",
|
||||
"@kas-tle/docusaurus-og": "https://github.com/Kas-tle/docusaurus-og",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
"docusaurus-plugin-openapi-docs": "^3.0.1",
|
||||
"docusaurus-theme-openapi-docs": "^3.0.1",
|
||||
"prism-react-renderer": "^2.1.0",
|
||||
"react": "^18.0.0",
|
||||
"react-decision-tree-flow": "^2.1.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"@mdx-js/react": "3.0.0",
|
||||
"clsx": "1.2.1",
|
||||
"docusaurus-plugin-openapi-docs": "4.3.0",
|
||||
"docusaurus-theme-openapi-docs": "4.3.0",
|
||||
"prism-react-renderer": "2.1.0",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-markdown": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "^3.4.0",
|
||||
"@docusaurus/tsconfig": "^3.4.0",
|
||||
"@docusaurus/types": "^3.4.0",
|
||||
"docusaurus-plugin-sass": "^0.2.5",
|
||||
"sass": "^1.77.8",
|
||||
"typescript": "~5.2.2"
|
||||
"@docusaurus/module-type-aliases": "^3.6.3",
|
||||
"@docusaurus/tsconfig": "^3.6.3",
|
||||
"@docusaurus/types": "^3.6.3",
|
||||
"docusaurus-plugin-sass": "0.2.5",
|
||||
"sass": "1.77.8",
|
||||
"typescript": "5.7.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"postman-code-generators": "1.14.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
@@ -62,6 +64,7 @@
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
"node": ">=22.0"
|
||||
},
|
||||
"packageManager": "yarn@4.5.3"
|
||||
}
|
||||
@@ -54,6 +54,19 @@ const sidebars: SidebarsConfig = {
|
||||
'geyser/port-forwarding'
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Nethernet',
|
||||
link: {
|
||||
type: "generated-index",
|
||||
title: "Nethernet",
|
||||
description: "An explanation of Nethernet",
|
||||
slug: "/geyser/nethernet",
|
||||
},
|
||||
items: [
|
||||
'geyser/nethernet/setup'
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Common Issues',
|
||||
@@ -68,10 +81,6 @@ const sidebars: SidebarsConfig = {
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Configuring Geyser',
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'geyser/understanding-the-config',
|
||||
},
|
||||
items: [
|
||||
'geyser/commands',
|
||||
'geyser/translations',
|
||||
@@ -93,15 +102,18 @@ const sidebars: SidebarsConfig = {
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Custom Resource Packs',
|
||||
label: 'Custom Content',
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'geyser/custom-resource-packs'
|
||||
id: 'geyser/custom-content'
|
||||
},
|
||||
items: [
|
||||
'geyser/packs',
|
||||
'geyser/custom-items',
|
||||
'geyser/custom-blocks',
|
||||
'geyser/custom-skulls',
|
||||
'geyser/custom-waypoints',
|
||||
'geyser/custom-entities'
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -135,10 +147,12 @@ const sidebars: SidebarsConfig = {
|
||||
'other/index',
|
||||
'other/geyserconnect',
|
||||
'other/thirdpartycosmetics',
|
||||
'other/geyseroptionalpack',
|
||||
'other/geyserintegratedpack',
|
||||
'other/community-geyser-projects',
|
||||
'other/hurricane',
|
||||
'other/rainbow',
|
||||
'other/hydraulic',
|
||||
'other/thunder',
|
||||
'other/test-server',
|
||||
'other/developer-guide',
|
||||
'other/discord-bot-usage'
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import clsx from 'clsx';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import styles from "./styles.module.scss";
|
||||
|
||||
interface HomepageFeatureProps {
|
||||
title: string;
|
||||
image?: string;
|
||||
flipped?: boolean;
|
||||
}
|
||||
|
||||
export const HomepageFeature: React.FC<PropsWithChildren<HomepageFeatureProps>> = ({ title, image, flipped, children }) => {
|
||||
return (
|
||||
<div className={clsx(styles.feature, { [styles.flipped]: flipped })}>
|
||||
<div className={clsx(styles.content, "text--left padding-horiz--md")}>
|
||||
<h3 className={styles.title}>{title}</h3>
|
||||
{children}
|
||||
</div>
|
||||
{image && (
|
||||
<div>
|
||||
<img src={image} alt={title} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
.feature {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.feature.flipped > *:first-child {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.feature.flipped > *:last-child {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.feature {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.feature > *:first-child {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.feature > *:last-child {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
import clsx from 'clsx';
|
||||
import Heading from '@theme/Heading';
|
||||
import styles from './styles.module.scss';
|
||||
import Crossplatform0Img from '@site/static/img/site/crossplatform_0.png';
|
||||
import Crossplatform1Img from '@site/static/img/site/crossplatform_1.png';
|
||||
import Crossplatform2Img from '@site/static/img/site/crossplatform_2.png';
|
||||
import Translate from '@docusaurus/Translate';
|
||||
|
||||
type FeatureItem = {
|
||||
title: string;
|
||||
image?: string;
|
||||
description: JSX.Element;
|
||||
index?: number;
|
||||
};
|
||||
|
||||
const FeatureList: FeatureItem[] = [
|
||||
{
|
||||
title: 'What is Geyser?',
|
||||
image: Crossplatform2Img,
|
||||
description: (
|
||||
<>
|
||||
<Translate id="components.homepage_features.1">Geyser is a program that allows Minecraft: Bedrock Edition clients to join Minecraft: Java Edition servers, allowing for true crossplay between both editions of the game. The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible.</Translate>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'How does it work?',
|
||||
image: Crossplatform1Img,
|
||||
description: (
|
||||
<>
|
||||
<Translate id='components.homepage_features.features.2'>Geyser acts as a translator which sits between the Bedrock client and the Java server. It takes data from the Bedrock client and translates it into a format the Java server understands and vice versa. Geyser works with any modern Minecraft version and can be installed either as a plugin or ran as a standalone program.</Translate>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Join from anywhere',
|
||||
image: Crossplatform0Img,
|
||||
description: (
|
||||
<>
|
||||
<Translate id='components.homepage_features.features.3'>Geyser can be joined from Bedrock clients on Windows 10/11, iOS, Android, and even consoles. Geyser works with a wide array of hosting providers, but can also be used as its own standalone proxy to join any Minecraft server! If you are a server owner, you can install our Floodgate plugin which allows Xbox Live authenticated Bedrock users to join without a Java Edition account!</Translate>
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
function Feature({ title, image, description, index }: FeatureItem) {
|
||||
const Content = () => (
|
||||
<div className="text--left padding-horiz--md">
|
||||
<Heading as="h3">{title}</Heading>
|
||||
<p>{description}</p>
|
||||
</div>
|
||||
);
|
||||
const Image = () => (
|
||||
image &&
|
||||
<div className="column text--left">
|
||||
<img src={image} alt={title} />
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={clsx('column')}>
|
||||
{index % 2 === 0 ? <><Image /><Content /></> : <><Content /><Image /></>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function HomepageFeatures(): JSX.Element {
|
||||
return (
|
||||
<section className={styles.features}>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
{FeatureList.map((props, idx) => (
|
||||
<Feature key={idx} {...props} index={idx} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
.features {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2rem 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.featureSvg {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
}
|
||||
@@ -16,9 +16,10 @@ interface ProjectDownloadProps {
|
||||
[key: string]: { url: string, file: string };
|
||||
};
|
||||
gridColumns?: number;
|
||||
warning?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const ProjectDownload: React.FC<ProjectDownloadProps> = ({ projectId, description, setup, downloadsInfo, additionalDownloads, gridColumns }) => {
|
||||
export const ProjectDownload: React.FC<ProjectDownloadProps> = ({ projectId, description, setup, downloadsInfo, additionalDownloads, gridColumns, warning }) => {
|
||||
const [platformInfo, setPlatformInfo] = useState<Downloads.Builds>({
|
||||
project_id: '',
|
||||
project_name: '',
|
||||
@@ -79,6 +80,11 @@ export const ProjectDownload: React.FC<ProjectDownloadProps> = ({ projectId, des
|
||||
<Column>
|
||||
<h3>Build #{latestBuild.build} · {new Date(latestBuild.time).toLocaleDateString()}:</h3>
|
||||
<Grid elementsPerRow={gridColumns || 2} gap="8px">
|
||||
{ warning &&
|
||||
<div className='warning-box'>
|
||||
{ warning }
|
||||
</div>
|
||||
}
|
||||
{ setup &&
|
||||
<a href={setup} className='no-underline setup-button large-button'>
|
||||
<b><FontAwesomeIcon icon={faBook}/> Setup Instructions</b>
|
||||
|
||||
@@ -14,25 +14,37 @@ export const Provider = ({ type }) => {
|
||||
const hostingProviders: HostingProvider[] = providersData[type as ProviderType]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ul>{hostingProviders.map((provider: HostingProvider) => (
|
||||
<li>
|
||||
<a href={provider.url}>{provider.name}</a>
|
||||
{provider.description != null ? (
|
||||
<ReactMarkdown children={` ‐ ${provider.description}`} components={{ p: noP }} />
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</li>
|
||||
))}</ul>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Provider</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{hostingProviders.map((provider: HostingProvider) => (
|
||||
<tr>
|
||||
<td>
|
||||
<a href={provider.url}>{provider.name}</a>
|
||||
</td>
|
||||
<td>
|
||||
{provider.description != null ? (
|
||||
<ReactMarkdown children={provider.description} components={{ p: noP }} />
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
|
||||
export const ProviderSelector = () => {
|
||||
const providers: HostingProvider[] = [
|
||||
...Object.values(providersData.built_in),
|
||||
...Object.values(providersData.support),
|
||||
...Object.values(providersData.support),
|
||||
...Object.values(providersData.no_support)
|
||||
].flat().sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
@@ -40,10 +52,10 @@ export const ProviderSelector = () => {
|
||||
name: 'Not listed',
|
||||
description: translate({
|
||||
id: 'providers.provider.not_listed.description',
|
||||
message: "If your hosting provider is not listed, try enabling the `clone-remote-port` option in the config. Then, restart the server, and try connecting with the same IP and port as on Java Edition. <br> If this does not work, ask your server hosting provider for a UDP port, and use that. For VPS/KVM servers please follow the self-hosting steps."
|
||||
message: "If your hosting provider is not listed, try using [Warden Signalling](/wiki/geyser/nethernet/setup#warden-signalling). If this doesn't work, ask your hosting provider for a TCP and UDP port and use that. For VPS/KVM servers please follow the self-hosting steps.",
|
||||
})
|
||||
} as HostingProvider);
|
||||
|
||||
|
||||
|
||||
const [selectedProvider, setSelectedProvider] = useState(null);
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
export interface StepData {
|
||||
path: string[];
|
||||
}
|
||||
|
||||
export default interface StepProps {
|
||||
data: StepData;
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
import { Controls, Step, useControls, Wizard } from 'react-decision-tree-flow'
|
||||
|
||||
import Step1 from './steps/Step1'
|
||||
import Step2 from './steps/Step2'
|
||||
import Step3 from './steps/Step3'
|
||||
import Error from './steps/Error'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { StepData } from './StepProps'
|
||||
import MarkDownStep from './steps/MarkDownStep'
|
||||
|
||||
|
||||
// React components for each step
|
||||
const stepComponents = [
|
||||
Step1,
|
||||
Step2,
|
||||
Step3,
|
||||
Error
|
||||
]
|
||||
|
||||
// Build the steps object from the stepComponents array
|
||||
function formatStepName(name: string): string {
|
||||
return name.charAt(0).toLowerCase() + name.slice(1)
|
||||
}
|
||||
let steps = Object.fromEntries(stepComponents.map((Component) => [formatStepName(Component.name), Component]))
|
||||
|
||||
// Add the markdown steps
|
||||
steps = {
|
||||
//test: MarkDownStep(Test),
|
||||
...steps
|
||||
}
|
||||
|
||||
|
||||
// Make a tree so all steps can go to all others
|
||||
const tree = Object.fromEntries(Object.keys(steps).map((key, i, arr) => {
|
||||
return [key, arr]
|
||||
}))
|
||||
|
||||
function TreeInternals(): JSX.Element {
|
||||
const [data, setData] = useState<StepData>({
|
||||
path: []
|
||||
})
|
||||
|
||||
const { step } = useControls();
|
||||
useEffect(() => {
|
||||
if (step == 'internalStep') {
|
||||
console.log()
|
||||
}
|
||||
setData(data => ({...data, path: [...data.path, step as string]}))
|
||||
}, [step])
|
||||
|
||||
return (
|
||||
<>
|
||||
{Object.entries(steps).map(([name, Component]) => <Step key={name} name={name}><Component data={data}/></Step>)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default function TroubleshootingTree(): JSX.Element {
|
||||
return (
|
||||
<Wizard tree={tree} first={Object.keys(steps)[0]}>
|
||||
<TreeInternals />
|
||||
</Wizard>
|
||||
)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { useControls } from "react-decision-tree-flow";
|
||||
import StepProps from "../StepProps";
|
||||
|
||||
export default function Error({ data }: StepProps): JSX.Element {
|
||||
const { step, tree, destinations, back } = useControls();
|
||||
|
||||
return (
|
||||
<>
|
||||
I am error
|
||||
<br />
|
||||
Path: {data.path.join(' -> ')}
|
||||
<br />
|
||||
<button onClick={() => destinations.step1({...data, path: [...data.path, step]})}>Go back to start</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { useControls } from "react-decision-tree-flow";
|
||||
import StepProps from "../StepProps";
|
||||
|
||||
export default function MarkDownStep(Component: any): Function {
|
||||
return function InternalStep({ data }: StepProps): JSX.Element {
|
||||
const { step, tree, destinations, back } = useControls();
|
||||
|
||||
return (<Component step={step} tree={tree} destinations={destinations} back={back} data={data}/>)
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import { useControls } from "react-decision-tree-flow";
|
||||
import StepProps from "../StepProps";
|
||||
|
||||
export default function OwnerPrerequesites({ data }: StepProps): JSX.Element {
|
||||
const { step, tree, destinations, back } = useControls();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
# Before we start...
|
||||
|
||||
Are you hosting a Geyser instance yourself?
|
||||
|
||||
You should click "Yes" if you...:
|
||||
- ...own and operate a Minecraft: Java edition server with the Geyser plugin/mod installed.
|
||||
- ...have a Geyser-Standalone / Geyser-ViaProxy instance set up to connect to other servers.
|
||||
- ...use any variant of Geyser on any supported platform.
|
||||
|
||||
If you are NOT hosting your own Geyser instance or server - and are intead connecting to someone's server -
|
||||
then please contact the server administrator for help.
|
||||
|
||||
<br />
|
||||
// TODO add "return" button
|
||||
<button onClick={() => destinations.step2({...data, path: [...data.path, step]})}>Go to Step 2</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { useControls } from "react-decision-tree-flow";
|
||||
import StepProps from "../StepProps";
|
||||
|
||||
export default function Step1({ data }: StepProps): JSX.Element {
|
||||
const { step, tree, destinations, back } = useControls();
|
||||
|
||||
return (
|
||||
<>
|
||||
I am step 1
|
||||
<br />
|
||||
<button onClick={() => destinations.step2({...data, path: [...data.path, step]})}>Go to Step 2</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { useControls } from "react-decision-tree-flow";
|
||||
import StepProps from "../StepProps";
|
||||
|
||||
export default function Step2({ data }: StepProps): JSX.Element {
|
||||
const { step, tree, destinations, back } = useControls();
|
||||
|
||||
return (
|
||||
<>
|
||||
I am step 2
|
||||
<br />
|
||||
<div>
|
||||
<button onClick={() => destinations.error({...data, path: [...data.path, step]})}>Go to error</button>
|
||||
<button onClick={() => destinations.step3({...data, path: [...data.path, step]})}>Go to Step 3</button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { useControls } from "react-decision-tree-flow";
|
||||
import StepProps from "../StepProps";
|
||||
|
||||
export default function Step3({ data }: StepProps): JSX.Element {
|
||||
const { step, tree, destinations, back } = useControls();
|
||||
|
||||
return (
|
||||
<>
|
||||
I am step 3. No steps after me!
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
steps:
|
||||
|
||||
init: u owner?
|
||||
"""
|
||||
|
||||
// TODO figure out steps; simplify language
|
||||
|
||||
# Before we start...
|
||||
|
||||
Are you hosting a Geyser instance yourself?
|
||||
|
||||
You should click "Yes" if you...:
|
||||
- ...own and operate a Minecraft: Java edition server with the Geyser plugin/mod installed.
|
||||
- ...have a Geyser-Standalone / Geyser-ViaProxy instance set up to connect to other servers.
|
||||
- ...use any variant of Geyser on any supported platform.
|
||||
|
||||
If you are NOT hosting your own Geyser instance or server - and are intead connecting to someone's server -
|
||||
then please contact the server administrator for help.
|
||||
|
||||
options: y/n -> y: start troubleshooting; n -> show a link to send to administrator
|
||||
"""
|
||||
|
||||
then: u using right guide?
|
||||
|
||||
"""
|
||||
|
||||
any errors in your log? do you see a connection attempt? conntest command?
|
||||
|
||||
"""
|
||||
|
||||
1. Toubleshooting start
|
||||
|
||||
Self hosting vs minecraft server hosting provider
|
||||
|
||||
"""
|
||||
Hosting provider:
|
||||
Select this option if you are using a Minecraft server hosting provider that
|
||||
provides you with a Minecraft server.
|
||||
|
||||
Self-Hosted @ home:
|
||||
Select this option if you are hosting on your own Windows/Linux/MacOS computer,
|
||||
server located at your location.
|
||||
|
||||
Self-Hosted @ nothome:
|
||||
Applies for KVM/VPS/Bare-Metal servers (and similar) that are not located at your location.
|
||||
"""
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Hosting provider:
|
||||
|
||||
1. Select provider (dropdown w. search / not listed)
|
||||
|
||||
Non-Listed:
|
||||
- recommend clone-remote-port, do basic dump checks for bad options/system properties
|
||||
- pls contact host!
|
||||
|
||||
"""
|
||||
We unfortunately do not have instructions available for the server hosting provider you're using.
|
||||
|
||||
However, we recommend trying these configurations:
|
||||
|
||||
1. Runnning Geyser on the Java server port
|
||||
|
||||
- Open the Geyser configuration, and set `clone-remote-port` to `true`. Then, save the changes, and restart the server.
|
||||
|
||||
- Verify connecting works:
|
||||
-> directly connect with the java server ip and port
|
||||
or
|
||||
-> connectiontest command
|
||||
|
||||
If none of these options work, please contact your server hosting provider for help on how to set up Geyser.
|
||||
|
||||
"""
|
||||
|
||||
Listed:
|
||||
- geyser dump
|
||||
-> configuration check (match with instructions???)
|
||||
-> bad options: proxy protocol; remote address
|
||||
-> check for system properties
|
||||
|
||||
- options:
|
||||
-> re-ask for a geyser dump (verify correct changes)
|
||||
-> still not working; continue troubleshooting
|
||||
-> errors in log?
|
||||
-> else: contact host pls
|
||||
-> works now -> send to feedback page?
|
||||
|
||||
OR: unable to get dump
|
||||
-> is server running? log???
|
||||
|
||||
Options:
|
||||
-> addr. in use -> show setup steps
|
||||
-> port in use (-> check for voice plugins/query???)
|
||||
-> startup errors -> join discord/open github issue
|
||||
-> ...
|
||||
|
||||
IF server running/config correct:
|
||||
-> ensure connection to proper ip/port
|
||||
-> contact server hosting provider for help
|
||||
-> join discord if unclear
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Self-Hosted @ home:
|
||||
|
||||
First stage: Gather information!
|
||||
|
||||
Which OS are you hosting on? Linux/Win/MacOS
|
||||
|
||||
-> Windows
|
||||
-> MacOS
|
||||
-> Linux
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -16,6 +16,7 @@
|
||||
--ifm-color-primary-light: #33925d;
|
||||
--ifm-color-primary-lighter: #359962;
|
||||
--ifm-color-primary-lightest: #3cad6e;
|
||||
--ifm-color-warning: #e4f126;
|
||||
--ifm-code-font-size: 95%;
|
||||
--ifm-footer-color: rgb(238, 249, 253);
|
||||
--ifm-footer-background-color: #303846;
|
||||
@@ -74,6 +75,7 @@ html[data-theme='dark'] {
|
||||
display: inline-block;
|
||||
background-color: var(--ifm-navbar-link-color);
|
||||
mask-image: $url;
|
||||
mask-repeat: no-repeat;
|
||||
transition: background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default);
|
||||
}
|
||||
|
||||
@@ -87,7 +89,11 @@ html[data-theme='dark'] {
|
||||
}
|
||||
|
||||
.header-discord-link {
|
||||
@include header-link(32px, 26px, url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M524.5 69.8a1.5 1.5 0 0 0 -.8-.7A485.1 485.1 0 0 0 404.1 32a1.8 1.8 0 0 0 -1.9 .9 337.5 337.5 0 0 0 -14.9 30.6 447.8 447.8 0 0 0 -134.4 0 309.5 309.5 0 0 0 -15.1-30.6 1.9 1.9 0 0 0 -1.9-.9A483.7 483.7 0 0 0 116.1 69.1a1.7 1.7 0 0 0 -.8 .7C39.1 183.7 18.2 294.7 28.4 404.4a2 2 0 0 0 .8 1.4A487.7 487.7 0 0 0 176 479.9a1.9 1.9 0 0 0 2.1-.7A348.2 348.2 0 0 0 208.1 430.4a1.9 1.9 0 0 0 -1-2.6 321.2 321.2 0 0 1 -45.9-21.9 1.9 1.9 0 0 1 -.2-3.1c3.1-2.3 6.2-4.7 9.1-7.1a1.8 1.8 0 0 1 1.9-.3c96.2 43.9 200.4 43.9 295.5 0a1.8 1.8 0 0 1 1.9 .2c2.9 2.4 6 4.9 9.1 7.2a1.9 1.9 0 0 1 -.2 3.1 301.4 301.4 0 0 1 -45.9 21.8 1.9 1.9 0 0 0 -1 2.6 391.1 391.1 0 0 0 30 48.8 1.9 1.9 0 0 0 2.1 .7A486 486 0 0 0 610.7 405.7a1.9 1.9 0 0 0 .8-1.4C623.7 277.6 590.9 167.5 524.5 69.8zM222.5 337.6c-29 0-52.8-26.6-52.8-59.2S193.1 219.1 222.5 219.1c29.7 0 53.3 26.8 52.8 59.2C275.3 311 251.9 337.6 222.5 337.6zm195.4 0c-29 0-52.8-26.6-52.8-59.2S388.4 219.1 417.9 219.1c29.7 0 53.3 26.8 52.8 59.2C470.7 311 447.5 337.6 417.9 337.6z"/></svg>'));
|
||||
@include header-link(24px, 24px, url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M524.5 69.8a1.5 1.5 0 0 0 -.8-.7A485.1 485.1 0 0 0 404.1 32a1.8 1.8 0 0 0 -1.9 .9 337.5 337.5 0 0 0 -14.9 30.6 447.8 447.8 0 0 0 -134.4 0 309.5 309.5 0 0 0 -15.1-30.6 1.9 1.9 0 0 0 -1.9-.9A483.7 483.7 0 0 0 116.1 69.1a1.7 1.7 0 0 0 -.8 .7C39.1 183.7 18.2 294.7 28.4 404.4a2 2 0 0 0 .8 1.4A487.7 487.7 0 0 0 176 479.9a1.9 1.9 0 0 0 2.1-.7A348.2 348.2 0 0 0 208.1 430.4a1.9 1.9 0 0 0 -1-2.6 321.2 321.2 0 0 1 -45.9-21.9 1.9 1.9 0 0 1 -.2-3.1c3.1-2.3 6.2-4.7 9.1-7.1a1.8 1.8 0 0 1 1.9-.3c96.2 43.9 200.4 43.9 295.5 0a1.8 1.8 0 0 1 1.9 .2c2.9 2.4 6 4.9 9.1 7.2a1.9 1.9 0 0 1 -.2 3.1 301.4 301.4 0 0 1 -45.9 21.8 1.9 1.9 0 0 0 -1 2.6 391.1 391.1 0 0 0 30 48.8 1.9 1.9 0 0 0 2.1 .7A486 486 0 0 0 610.7 405.7a1.9 1.9 0 0 0 .8-1.4C623.7 277.6 590.9 167.5 524.5 69.8zM222.5 337.6c-29 0-52.8-26.6-52.8-59.2S193.1 219.1 222.5 219.1c29.7 0 53.3 26.8 52.8 59.2C275.3 311 251.9 337.6 222.5 337.6zm195.4 0c-29 0-52.8-26.6-52.8-59.2S388.4 219.1 417.9 219.1c29.7 0 53.3 26.8 52.8 59.2C470.7 311 447.5 337.6 417.9 337.6z"/></svg>'));
|
||||
|
||||
&::before { // Fixes the Discord icon being a little shorter than the others causing an offset
|
||||
mask-position: 0 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-utilities-link {
|
||||
@@ -106,6 +112,16 @@ html[data-theme='dark'] {
|
||||
@include header-link(22px, 25px, url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M96 0C43 0 0 43 0 96V416c0 53 43 96 96 96H384h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V384c17.7 0 32-14.3 32-32V32c0-17.7-14.3-32-32-32H384 96zm0 384H352v64H96c-17.7 0-32-14.3-32-32s14.3-32 32-32zm32-240c0-8.8 7.2-16 16-16H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H144c-8.8 0-16-7.2-16-16zm16 48H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H144c-8.8 0-16-7.2-16-16s7.2-16 16-16z"/></svg>'));
|
||||
}
|
||||
|
||||
@media screen and (max-width: 996px) { // Magic numbers! This was the value which caused the site to go to mobile navigation
|
||||
.header-discord-link::after {
|
||||
content: 'Discord'
|
||||
}
|
||||
|
||||
.header-github-link::after {
|
||||
content: 'GitHub'
|
||||
}
|
||||
}
|
||||
|
||||
.api-method>.menu__link {
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
@@ -158,6 +174,7 @@ html[data-theme='dark'] {
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
@@ -303,6 +320,16 @@ html[data-theme='dark'] {
|
||||
}
|
||||
}
|
||||
|
||||
.warning-box {
|
||||
width: 100%;
|
||||
border-left: 3px solid var(--ifm-color-warning);
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
flex-wrap: wrap;
|
||||
border-bottom-color: var(--ifm-horizontal-line-color);
|
||||
@@ -344,4 +371,9 @@ html[data-theme='dark'] {
|
||||
border-radius: var(--ifm-global-radius);
|
||||
color: #fff
|
||||
}
|
||||
}
|
||||
|
||||
[data-theme='light'] img[src$='#gh-dark-mode-only'],
|
||||
[data-theme='dark'] img[src$='#gh-light-mode-only'] {
|
||||
display: none;
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import { translate } from "@docusaurus/Translate"
|
||||
import { Providers } from "../types/providers"
|
||||
|
||||
// Do not modify the structure of this file without updating the extraction logic in create-providers-json.ts
|
||||
|
||||
const descriptionTemplates = {
|
||||
default: translate({
|
||||
id: 'providers.templates.default',
|
||||
@@ -8,7 +10,7 @@ const descriptionTemplates = {
|
||||
}),
|
||||
ipAndPort: translate({
|
||||
id: 'providers.templates.ip_and_port',
|
||||
message: "Enable `clone-remote-port` (or manually set `bedrock port` to the Java port), uncomment `bedrock address`, and change `0.0.0.0` to your Java server's IP. Connect with the Java IP and port."
|
||||
message: "Enable `clone-remote-port` (or manually set `bedrock port` to the Java port) and change `bedrock address` from `0.0.0.0` to your Java server's IP. Connect with the Java IP and port."
|
||||
}),
|
||||
forwardingOption: translate({
|
||||
id: 'providers.templates.forwarding_option',
|
||||
@@ -16,7 +18,7 @@ const descriptionTemplates = {
|
||||
}),
|
||||
javaIp: translate({
|
||||
id: 'providers.templates.java_ip',
|
||||
message: "Make sure your remote address is 'auto', uncomment `bedrock address`, and change `0.0.0.0` to your Java server's IP."
|
||||
message: "Change `bedrock address` from `0.0.0.0` to your Java server's IP."
|
||||
})
|
||||
}
|
||||
|
||||
@@ -33,7 +35,10 @@ export const providersData: Providers = {
|
||||
{
|
||||
name: 'Arth Hosting',
|
||||
url: 'https://arthmc.xyz/',
|
||||
description: "Geyser is installed and configured on all servers by default. You can disable it in the 'Manage Plugins' menu."
|
||||
description: translate({
|
||||
id: 'providers.provider.arth_hosting.description',
|
||||
message: "Geyser is installed and configured on all servers by default. You can disable it in the 'Manage Plugins' menu."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Aternos',
|
||||
@@ -44,13 +49,37 @@ export const providersData: Providers = {
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Cloud Nord',
|
||||
name: 'AxentHost',
|
||||
url: 'https://axenthost.com/games/minecraft/',
|
||||
description: translate({
|
||||
id: 'providers.provider.axenthost.description',
|
||||
message: "For a quick installation, navigate to your server Variants tab and select GeyserMC. The server will be automatically reinstalled with Geyser-Spigot alongside a Paper server. For a manual install using any other variant such as Paper, you will need to upload the GeyserMC jar to your server and set the the clone-remote-port option to true. See AxentHost's [guide](https://axenthost.com/knowledgebase/categories/minecraft/create-a-crossplay-server-with-geyser/) to see all the steps."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'BedrockHost',
|
||||
url: 'https://bedrockhost.pl/',
|
||||
description: translate({
|
||||
id: 'providers.provider.bedrockhost.description',
|
||||
message: "Easiest solution is: Go to hosting panel > install new engine > Ready-made solutions and select Geyser. This will install Paper & Geyser-Spigot - no setup needed, just connect with your Java IP and port. See [BedrockHost's article](https://bedrockhost.pl/w/geyser-czyli-serwer-minecraft-java-i-bedrock-w-jednym) for more details or for custom setup instructions (available in Polish)."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'CloudNord',
|
||||
url: 'https://cloudnord.net/',
|
||||
description: translate({
|
||||
id: 'providers.provider.cloud_nord.description',
|
||||
message: "Go to their [Crossplay Server](https://cloudnord.net/minecraftcrossplay-server-hosting/) hosting section and order your server. Instructions on how to join are provided."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'ConsulHosting',
|
||||
url: 'https://consulhosting.com/minecraft-server-hosting/',
|
||||
description: translate({
|
||||
id: 'providers.provider.consulhosting.description',
|
||||
message: "GeyserMC can be installed with a single click on ConsulHosting's Minecraft server hosting. Head to your server panel, find the GeyserMC option at Software, and install it automatically — no manual configuration needed. For step-by-step instructions, see [ConsulHosting's GeyserMC installation tutorial](https://consulhosting.com/help/install-geysermc/)."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'CreeperHost',
|
||||
url: 'https://www.creeperhost.net/',
|
||||
@@ -75,6 +104,14 @@ export const providersData: Providers = {
|
||||
message: "Install Geyser in the exaroton plugin list and connect to your server with your Java IP and port. See [exaroton's article](https://support.exaroton.com/hc/en-us/articles/360019857918-Geyser) for more details."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'FreeMcServer.net',
|
||||
url: 'https://freemcserver.net',
|
||||
description: translate({
|
||||
id: 'providers.provider.freemcserver_net.description',
|
||||
message: "Install Geyser from the Plugins tab, then connect to your server using your Java IP and port."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'GGServers',
|
||||
url: 'https://ggservers.com',
|
||||
@@ -83,6 +120,14 @@ export const providersData: Providers = {
|
||||
message: "Can be installed to any server from their auto plugin setups. No further configuration needed."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'KaasHosting',
|
||||
url: 'https://www.kaashosting.nl/minecraft-servers',
|
||||
description: translate({
|
||||
id: 'providers.provider.kaashosting.description',
|
||||
message: "Automatic and manual installation supported. Go to the `Plugin Installer` tab, search for Geyser and click `Install Automatically`. Connect with the Java IP and port. See [KaasHosting's article](https://www.kaashosting.nl/help/nl/minecraft/hoe-maak-ik-mijn-minecraft-server-crossplay-met-geysermc) for more details."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Lilypad',
|
||||
url: 'https://lilypad.gg',
|
||||
@@ -92,11 +137,11 @@ export const providersData: Providers = {
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'MCProHosting',
|
||||
url: 'https://mcprohosting.com/',
|
||||
name: 'MCServerHost',
|
||||
url: 'https://mcserverhost.com/',
|
||||
description: translate({
|
||||
id: 'providers.provider.mcprohosting.description',
|
||||
message: "Click 'Enable Bedrock Support' on the server dashboard and follow the steps. For manual installation: Add 'Destination Port' `19132` with 'Protocol UDP' to the port forward mapping and connect to the given source port."
|
||||
id: 'providers.provider.mcserverhost.description',
|
||||
message: "Under the server configuration, select 'Crossplay' to automatically install Geyser and Floodgate. Join with the connection address. To update Geyser and Floodgate, replace the plugin jars in the server manager and restart the server."
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -115,6 +160,14 @@ export const providersData: Providers = {
|
||||
message: "Connect via `bedrock.minehut.com` and do `/join [servername]`, or connect directly via `[servername].bedrock.minehut.gg`."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'OMGServ',
|
||||
url: 'https://www.omgserv.com/en/',
|
||||
description: translate({
|
||||
id: 'providers.provider.omgserv.description',
|
||||
message: "Select Geyser in the [Install Menu](https://i.imgur.com/Gewpsrq.png), it will be automatically installed. You can enable floodgate in the [server properties on the dashboard](https://i.imgur.com/jg5mzNj.png)."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Physgun',
|
||||
url: 'https://physgun.com/',
|
||||
@@ -129,11 +182,11 @@ export const providersData: Providers = {
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'OMGServ',
|
||||
url: 'https://www.omgserv.com/en/',
|
||||
name: 'Play Hosting',
|
||||
url: 'https://play.hosting',
|
||||
description: translate({
|
||||
id: 'providers.provider.omgserv.description',
|
||||
message: "Select Geyser in the [Install Menu](https://i.imgur.com/Gewpsrq.png), it will be automatically installed. You can enable floodgate in the [server properties on the dashboard](https://i.imgur.com/jg5mzNj.png)."
|
||||
id: 'providers.provider.playhosting.description',
|
||||
message: "Tick the 'Enable Bedrock crossplay?' option when changing your server software to automatically install and configure Geyser + Floodgate. For more details, navigate to [help.play.hosting/minecraft/crossplay](https://help.play.hosting/minecraft/crossplay)."
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -153,11 +206,11 @@ export const providersData: Providers = {
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Snakecraft Hosting',
|
||||
url: 'https://snakecrafthosting.com/',
|
||||
name: 'ServerPrism',
|
||||
url: 'https://serverprism.com/',
|
||||
description: translate({
|
||||
id: 'providers.provider.snakecraft_hosting.description',
|
||||
message: "Select 'Paper + Geyser with Floodgate' under the Jar Type at checkout to install the Geyser plugin. Players will Connect with the same IP and port as you would on Java."
|
||||
id: 'providers.provider.serverprism.description',
|
||||
message: "Order a [Minecraft server](https://serverprism.com/minecraft-server-hosting) on any plugin-compatible runtime (Paper, Spigot, Purpur, etc.), then install Geyser from the panel's plugin installer. Connect with the same IP and port as your Java server."
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -169,11 +222,19 @@ export const providersData: Providers = {
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Virtual Gladiators',
|
||||
url: 'https://virtualgladiators.com/',
|
||||
name: 'UltraServers',
|
||||
url: 'https://ultraservers.com/',
|
||||
description: translate({
|
||||
id: 'providers.provider.virtual_gladiators.description',
|
||||
message: "Find the plugin in the control panel under the 'VG Recommended' category and restart your server. IP and port are the same as Java."
|
||||
id: 'providers.provider.ultraservers.description',
|
||||
message: "Select 'Paper + Geyser' under the Change version tab. You can connect to your server using the same IP and port as you would on Java. Existing servers can use the Plugins/Minecraft mods tab to install Geyser. See [Crossplay](https://docs.ultraservers.com/minecraft/plugins-mods/crossplay-on-java-and-bedrock) for more information."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'VemoxHost',
|
||||
url: 'https://vemoxhost.com/',
|
||||
description: translate({
|
||||
id: 'providers.provider.vemox_hosting.description',
|
||||
message: "Full automatic installation. Go to one of the panel options and select the option to enable GeyserMC. Then, restart and connect to your server using your Java IP and port."
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -181,7 +242,7 @@ export const providersData: Providers = {
|
||||
url: 'https://wisehosting.com',
|
||||
description: translate({
|
||||
id: 'providers.provider.wisehosting.description',
|
||||
message: "Both auto and manual installation available. Find the GeyserMC presets from the `Properties` tab in the Game Panel. There, click `Install` and restart your server. See [Crossplay FAQ](https://help.wisehosting.com/en/articles/13-how-to-install-geysermc-java-bedrock-crossplay-to-your-server) for additional details."
|
||||
message: "Both auto and manual installation available. Find the GeyserMC presets from the `Addons` tab in the Game Panel. There, click `Install` and restart your server. See [Crossplay FAQ](https://wisehosting.com/help/how-to-install-geysermc-to-your-minecraft-server) for additional details."
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -192,14 +253,6 @@ export const providersData: Providers = {
|
||||
message: "Find the plugin in the control panel and restart your server. IP and port are the same as Java."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: '365Hosts',
|
||||
url: 'https://365hosts.com',
|
||||
description: translate({
|
||||
id: 'providers.provider.365hosts.description',
|
||||
message: "Go to their [Minecraft: Crossplay](https://www.365hosts.com/gaming/crossplayminecraft) hosting section and order your server. Instructions on how to join are provided."
|
||||
})
|
||||
}
|
||||
],
|
||||
support: [
|
||||
{
|
||||
@@ -220,7 +273,7 @@ export const providersData: Providers = {
|
||||
url: 'https://www.bisecthosting.com/',
|
||||
description: translate({
|
||||
id: 'providers.provider.bisecthosting.description',
|
||||
message: "You must have a plan with a dedicated IP. In Geyser's config, uncomment the `bedrock address` and set it to the public IP of your server (e.g. `address: 51.79.129.18`). Leave the port as `19132`. Under the home tab, select 'Enable UDP Network' and restart the server. See Bisect's [article](https://www.bisecthosting.com/clients/index.php?rp=/knowledgebase/193/How-to-install-Geyser-and-Floodgate-on-a-Minecraft-Java-server.html) for full instructions. If you still cannot connect after following these instructions, contact Bisect Support as they reportedly have UDP disabled on some nodes."
|
||||
message: "Go to the Network tab and copy an available port not in use by other mods. In Geyser's config, under the bedrock section, on the port: line, edit the value to the port you copied. See Bisect's [article](https://www.bisecthosting.com/clients/index.php?rp=/knowledgebase/193/How-to-install-Geyser-and-Floodgate-on-a-Minecraft-Java-server.html) for full instructions. If you still cannot connect after following these instructions, contact Bisect Support, as they reportedly have UDP disabled on some nodes."
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -236,7 +289,7 @@ export const providersData: Providers = {
|
||||
url: 'https://www.bloom.host/',
|
||||
description: translate({
|
||||
id: 'providers.provider.bloomhost.description',
|
||||
message: "See [Bloom's documentation](https://docs.bloom.host/plugins/geysermc/) for setup instructions."
|
||||
message: "See [Bloom's documentation](https://docs.bloom.host/multiplatform/geysermc) for setup instructions."
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -244,11 +297,6 @@ export const providersData: Providers = {
|
||||
url: 'https://clovux.net/',
|
||||
description: descriptionTemplates.javaIp
|
||||
},
|
||||
{
|
||||
name: 'Consulhosting',
|
||||
url: 'https://consulhosting.nl/',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'Craft-Hosting',
|
||||
url: 'https://craft-hosting.ru/',
|
||||
@@ -304,7 +352,7 @@ export const providersData: Providers = {
|
||||
url: 'https://falixnodes.net/',
|
||||
description: translate({
|
||||
id: 'providers.provider.falixnodes.description',
|
||||
message: "Open a port yourself on the network page in the game panel, then use that port in the bedrock section of the Geyser config."
|
||||
message: "Enable `clone-remote-port` (or manually set `bedrock port` to the Java port), and connect with the Java IP and port."
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -325,29 +373,11 @@ export const providersData: Providers = {
|
||||
url: 'https://freakhosting.com/',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'FreeMcServer.net',
|
||||
url: 'https://freemcserver.net',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'Fusion Hosting',
|
||||
url: 'https://fusionhostingltd.co.uk',
|
||||
description: translate({
|
||||
id: 'providers.provider.fusion_hosting.description',
|
||||
message: "Get Geyser as a plugin. Use the same port as your Java server for the Bedrock port in your config (either by setting it yourself, or enabling “clone-remote-port”) and connect with the same IP and port as you would on Java or create a port in the Network tab on the panel & use this for Geyser."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'GameHosting.it',
|
||||
url: 'https://www.gamehosting.it/',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'GameProHost',
|
||||
url: 'https://gameprohost.com/',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'GPortal',
|
||||
url: 'https://www.g-portal.com/',
|
||||
@@ -356,14 +386,6 @@ export const providersData: Providers = {
|
||||
message: "You have to adjust the port according to your query port. Scheme: Query port: xxx65. The ports from xxx66 to xxx70 are available. For example, if your query port is 12365, then Geyser can only run under the port range 12366-12370. Furthermore, you have to change the 'Bedrock' 'address' in the Geyser config to your IP address. You can find it above your query port. Don't forget to delete the # in front of `address'."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Heavynode',
|
||||
url: 'https://www.heavynode.com/',
|
||||
description: translate({
|
||||
id: 'providers.provider.heavynode.description',
|
||||
message: "Open a port yourself in the networking section of the control panel. Port `19132` is only available with a dedicated IP (contact support), otherwise you will need to use a randomly assigned port. To resolve further connection issues for servers located in Canada and the UK, contact their support with the info found [here](https://wiki.geysermc.org/geyser/port-forwarding/#ovh-and-soyoustart)."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Hicoria',
|
||||
url: 'https://hicoria.com/en/',
|
||||
@@ -430,11 +452,6 @@ export const providersData: Providers = {
|
||||
url: 'https://mc-host24.de/',
|
||||
description: descriptionTemplates.ipAndPort
|
||||
},
|
||||
{
|
||||
name: 'MCFORFREE.DE',
|
||||
url: 'https://mcforfree.de/',
|
||||
description: 'Create an extra port in the game panel, then change the `port` in the `bedrock` section to the newly created port. To connect on Bedrock edition, use the Java server\'s IP and the port you\'ve created. It may take a few minutes for the port to become active.'
|
||||
},
|
||||
{
|
||||
name: 'MCPEhost.ru',
|
||||
url: 'https://mcpehost.ru',
|
||||
@@ -462,11 +479,11 @@ export const providersData: Providers = {
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'Netbela',
|
||||
url: 'https://netbela.nl/store/minecraft',
|
||||
name: 'Modrinth Hosting',
|
||||
url: 'https://modrinth.com/hosting',
|
||||
description: translate({
|
||||
id: 'providers.provider.netbela.description',
|
||||
message: "Install Geyser with the dedicated Plugin installer. Use the same port as your Java server in your config. Connect with the same address and port as your Java server."
|
||||
id: 'providers.provider.modrinth.description',
|
||||
message: "Check [Modrinth's documentation](https://support.modrinth.com/en/articles/10986613-adding-geyser-to-your-server) for specific instructions."
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -474,7 +491,7 @@ export const providersData: Providers = {
|
||||
url: 'https://nfoservers.com/',
|
||||
description: translate({
|
||||
id: 'providers.provider.nfoservers.description',
|
||||
message: "Uncomment and set `bedrock address` to the server IP in the Geyser config file. As an alternative, you can run Geyser standalone separately on an Unmanaged VDS."
|
||||
message: "Set `bedrock address` to the server IP in the Geyser config file. As an alternative, you can run Geyser standalone separately on an Unmanaged VDS."
|
||||
})
|
||||
},
|
||||
{
|
||||
@@ -493,10 +510,21 @@ export const providersData: Providers = {
|
||||
message: "Use the default server port and `0.0.0.0` or your server IP as the host address."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'NolimitHost',
|
||||
url: 'https://nolimithost.cc',
|
||||
description: translate({
|
||||
id: 'providers.provider.nolimithost.description',
|
||||
message: "Check [NolimitHost's documentation](https://nolimithost.cc/docs/minecraft/geyser) for specific instructions."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'PaperNodes',
|
||||
url: 'https://papernodes.com/',
|
||||
description: 'Enable clone-remote-port (or manually set the Bedrock port to the Java port), and connect with the Java IP and port. Alternatively, you can contact the host to request an additional port or a dedicated IP.'
|
||||
description: translate({
|
||||
id: 'providers.provider.papernodes.description',
|
||||
message: 'Enable clone-remote-port (or manually set the Bedrock port to the Java port), and connect with the Java IP and port. Alternatively, you can contact the host to request an additional port or a dedicated IP.'
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Pebblehost',
|
||||
@@ -520,8 +548,8 @@ export const providersData: Providers = {
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'RamShard',
|
||||
url: 'https://ramshard.com/',
|
||||
name: 'RackGenius',
|
||||
url: 'https://rackgenius.com/',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
@@ -550,6 +578,14 @@ export const providersData: Providers = {
|
||||
message: "The port will be automatically set after you download Geyser and restart the server. Connect with the same IP and port as on Java. For Geyser Standalone installation instructions, see [here](https://shockbyte.com/billing/knowledgebase/173/Introduction-to-GeyserMCorDragonProxy-How-GeyserMC-Works.html)."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'SimpleGameHosting',
|
||||
url: 'https://simplegamehosting.com/',
|
||||
description: translate({
|
||||
id: 'providers.provider.simplegamehosting.description',
|
||||
message: "Contact live chat support to open a port and check out the [help center guide](https://help.simplegamehosting.com/how-to-enable-crossplay-with-geyser-on-your-minecraft-server/) for how to install and configure Geyser on your server."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Skynode.pro',
|
||||
url: 'https://skynode.pro/',
|
||||
@@ -571,14 +607,6 @@ export const providersData: Providers = {
|
||||
message: "Set the Bedrock port to the Java server's port and connect with that port; note that this provider only provides service in Australia."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'SyntexHosting',
|
||||
url: 'https://syntexhosting.com/',
|
||||
description: translate({
|
||||
id: 'providers.provider.syntexhosting.description',
|
||||
message: "Set the Bedrock port to the Java server's port and connect with that port, or request a (free) additional port."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'The Minecraft Hosting',
|
||||
url: 'https://theminecrafthosting.com/',
|
||||
@@ -592,26 +620,11 @@ export const providersData: Providers = {
|
||||
url: 'https://tnahosting.net/',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'TurboHost',
|
||||
url: 'https://turbohost.nl/',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'UltimateSRV',
|
||||
url: 'https://ultimatesrv.com/',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'VexyHost',
|
||||
url: 'https://vexyhost.com/',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'Volcano Hosting',
|
||||
url: 'https://www.volcanohosting.net/',
|
||||
description: descriptionTemplates.default
|
||||
},
|
||||
{
|
||||
name: 'VoltHosting',
|
||||
url: 'https://www.volthosting.co.uk/',
|
||||
@@ -625,13 +638,24 @@ export const providersData: Providers = {
|
||||
url: 'https://vultam.net/',
|
||||
description: translate({
|
||||
id: 'providers.provider.vultam.description',
|
||||
message: "Enable `clone-remote-port` in the Geyser config, and connect with the Java IP and port. Alternatively, allocate an additional port to your server from the Network section of the control panel and set it as the `bedrock.port` in the Geyser config. Use that port to connect from Bedrock. Please contact [Vultam support](https://clients.vultam.net/submitticket.php?step=2&deptid=1) if you need assistance."
|
||||
message: "Enable `clone-remote-port` in the Geyser config, and connect with the Java IP and port. Alternatively, allocate an additional port to your server from the Network section of the control panel and set it as the `bedrock port` in the Geyser config. Use that port to connect from Bedrock. Please contact [Vultam support](https://clients.vultam.net/submitticket.php?step=2&deptid=1) if you need assistance."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Wasabi Hosting',
|
||||
url: 'https://wasabihosting.com',
|
||||
description: translate({
|
||||
id: 'providers.provider.wasabihosting.description',
|
||||
message: "Install Geyser with the plugin installer. Use the same port as your Java server in the Geyser config. Connect with the same address and port as your Java server."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: "Wepwawet",
|
||||
url: "https://wepwawet.net/",
|
||||
description: "Add a new port in the Network tab. Use this new port as the bedrock port."
|
||||
description: translate({
|
||||
id: 'providers.provider.wepwawet.description',
|
||||
message: "Add a new port in the Network tab. Use this new port as the bedrock port."
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'WinterNode',
|
||||
@@ -646,7 +670,7 @@ export const providersData: Providers = {
|
||||
url: 'https://witherhosting.com/',
|
||||
description: translate({
|
||||
id: 'providers.provider.witherhosting.description',
|
||||
message: "Either use the Java server's port, or create a port in the ports manager on the panel and use that for Bedrock. Refer to the hosts [support article](https://support.witherhosting.com/en/article/how-to-install-and-use-geysermc-1xn5l6v/) for further info."
|
||||
message: "Either use the Java server's port, or create a port in the ports manager on the panel and use that for Bedrock. Refer to the hosts [support article](https://my.witherhosting.com/kb/how-to-install-and-use-geysermc-java) for further info."
|
||||
})
|
||||
}
|
||||
],
|
||||
@@ -668,10 +692,10 @@ export const providersData: Providers = {
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'Feather',
|
||||
url: 'https://feathermc.com/',
|
||||
name: 'Dawn',
|
||||
url: 'https://dawn.gg/',
|
||||
description: translate({
|
||||
id: 'providers.provider.feather.description',
|
||||
id: 'providers.provider.dawn.description',
|
||||
message: "Their proxy network does not support UDP. Therefore, Geyser is not supported. As an alternative, set up a paper server with e.g. playit.gg instead of port forwarding."
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"bedrock": {
|
||||
"supported": "1.20.80-1.21.30",
|
||||
"supported": "26.0-26.45",
|
||||
"latest": {
|
||||
"id": 729,
|
||||
"name": "1.21.30"
|
||||
"id": 2169,
|
||||
"name": "26.45"
|
||||
}
|
||||
},
|
||||
"java": {
|
||||
"supported": "1.21/1.21.1"
|
||||
"supported": "26.2"
|
||||
}
|
||||
}
|
||||
@@ -70,15 +70,17 @@ const DownloadPage: React.FC = () => (
|
||||
<TabItem value="other-projects" label="Other Projects">
|
||||
<Collapsibles>
|
||||
<Collapsible
|
||||
title='GeyserOptionalPack'
|
||||
subtitle={<Translate id='pages.download.description.geyseroptionalpack'>An optional Bedrock resource pack to extend Geyser functionality.</Translate>}
|
||||
id='geyseroptionalpack'
|
||||
title='Floodgate Databases'
|
||||
subtitle={<Translate id='pages.download.description.floodgatedatabases'>Database extension jars for Floodgate local linking.</Translate>}
|
||||
id='floodgatedb'
|
||||
inner={
|
||||
<ProjectDownload
|
||||
projectId="geyseroptionalpack"
|
||||
setup='/wiki/other/geyseroptionalpack'
|
||||
projectId="floodgatedb"
|
||||
setup='/wiki/floodgate/linking/#local-linking'
|
||||
downloadsInfo={{
|
||||
geyseroptionalpack: <><FontAwesomeIcon icon={faFileZipper} /> GeyserOptionalPack</>,
|
||||
mongodb: <><FontAwesomeIcon icon={faFileZipper} /> MongoDB</>,
|
||||
mysql: <><FontAwesomeIcon icon={faFileZipper} /> MySQL</>,
|
||||
sqlite: <><FontAwesomeIcon icon={faFileZipper} /> SQLite</>,
|
||||
}}
|
||||
gridColumns={1}
|
||||
/>
|
||||
@@ -99,6 +101,20 @@ const DownloadPage: React.FC = () => (
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Collapsible
|
||||
title='EmoteOffhand'
|
||||
subtitle={<Translate id='pages.download.description.offhandextension'>An extension that allows Bedrock players to switch their offhand and mainhand item by emoting.</Translate>}
|
||||
id='emoteoffhand'
|
||||
inner={
|
||||
<ProjectDownload
|
||||
projectId="emoteoffhand"
|
||||
downloadsInfo={{
|
||||
emoteoffhand: <><FontAwesomeIcon icon={faFileZipper} /> EmoteOffhand</>,
|
||||
}}
|
||||
gridColumns={1}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Collapsible
|
||||
title='Hurricane'
|
||||
subtitle={<Translate id='pages.download.description.hurricane'>A plugin with various workarounds for Geyser players that modify the server in order to achieve their goal.</Translate>}
|
||||
@@ -129,6 +145,21 @@ const DownloadPage: React.FC = () => (
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Collapsible
|
||||
title='Rainbow'
|
||||
subtitle={<Translate id='pages.download.description.rainbow'>A Minecraft mod to generate Geyser item mappings and bedrock resourcepacks for use with Geyser's custom item API (v2). </Translate>}
|
||||
id='rainbow'
|
||||
inner={
|
||||
<ProjectDownload
|
||||
projectId="rainbow"
|
||||
setup='/wiki/other/rainbow'
|
||||
downloadsInfo={{
|
||||
rainbow: <PlatformIcon img={FabricIcon} text="Fabric" />,
|
||||
}}
|
||||
gridColumns={1}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Collapsible
|
||||
title='Hydraulic'
|
||||
subtitle={<Translate id='pages.download.description.hydraulic'>A companion mod to Geyser which allows for Bedrock players to join modded Minecraft: Java Edition servers.</Translate>}
|
||||
@@ -146,6 +177,22 @@ const DownloadPage: React.FC = () => (
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Collapsible
|
||||
title='Thunder'
|
||||
subtitle={<Translate id='pages.download.description.thunder'>A java application to convert simple Java Edition resource packs to Bedrock Edition ones.</Translate>}
|
||||
id='thunder'
|
||||
tags={['Beta']}
|
||||
inner={
|
||||
<ProjectDownload
|
||||
projectId="thunder"
|
||||
setup='/wiki/other/thunder'
|
||||
downloadsInfo={{
|
||||
thunder: <><FontAwesomeIcon icon={faFileZipper} /> Thunder</>,
|
||||
}}
|
||||
gridColumns={1}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Collapsibles>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -66,4 +66,11 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.features {
|
||||
padding: 50px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40px;
|
||||
}
|
||||
@@ -1,18 +1,21 @@
|
||||
import clsx from 'clsx';
|
||||
import Layout from '@theme/Layout';
|
||||
import HomepageFeatures from '@site/src/components/HomepageFeatures';
|
||||
import Crossplatform0Img from '@site/static/img/site/crossplatform_0.png';
|
||||
import Crossplatform1Img from '@site/static/img/site/crossplatform_1.png';
|
||||
import Crossplatform2Img from '@site/static/img/site/crossplatform_2.png';
|
||||
import Heading from '@theme/Heading';
|
||||
import HeroImage from '@site/static/img/site/geyser.png';
|
||||
|
||||
import styles from './index.module.scss';
|
||||
import Translate from '@docusaurus/Translate';
|
||||
import { HomepageFeature } from '../components/HomepageFeature';
|
||||
|
||||
function HomepageHeader() {
|
||||
return (
|
||||
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
||||
<div className={styles.heroContent}>
|
||||
<img src={HeroImage} alt="Geyser Logo" className={styles.heroImage}/>
|
||||
<img src={HeroImage} alt="Geyser Logo" className={styles.heroImageBackgroundBlur}/>
|
||||
<img src={HeroImage} alt="Geyser Logo" className={styles.heroImage} />
|
||||
<img src={HeroImage} alt="Geyser Logo" className={styles.heroImageBackgroundBlur} />
|
||||
<div className={styles.textSection}>
|
||||
<Heading as="h1" className="hero__title">
|
||||
<Translate id='pages.main.title'>Revolutionize Your Minecraft Server</Translate>
|
||||
@@ -33,8 +36,35 @@ export default function Home(): JSX.Element {
|
||||
description="Enable clients from Minecraft Bedrock Edition to join your Minecraft Java server."
|
||||
>
|
||||
<HomepageHeader />
|
||||
|
||||
<main>
|
||||
<HomepageFeatures />
|
||||
<div className={clsx(styles.features, "container")}>
|
||||
<HomepageFeature
|
||||
title="What is Geyser?"
|
||||
image={Crossplatform2Img}
|
||||
>
|
||||
<Translate id="components.homepage_features.1.line1">Geyser is a program that allows Minecraft: Bedrock Edition clients to join Minecraft: Java Edition servers, allowing for true crossplay between both editions of the game.</Translate>
|
||||
<br /><br />
|
||||
<Translate id="components.homepage_features.1.line2">The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible.</Translate>
|
||||
</HomepageFeature>
|
||||
|
||||
<HomepageFeature
|
||||
title="How does it work?"
|
||||
image={Crossplatform1Img}
|
||||
flipped
|
||||
>
|
||||
<Translate id="components.homepage_features.2">Geyser acts as a translator which sits between the Bedrock client and the Java server. It takes data from the Bedrock client and translates it into a format the Java server understands and vice versa. Geyser works with any modern Minecraft version and can be installed either as a plugin or ran as a standalone program.</Translate>
|
||||
</HomepageFeature>
|
||||
|
||||
<HomepageFeature
|
||||
title="Join from anywhere"
|
||||
image={Crossplatform0Img}
|
||||
>
|
||||
<Translate id="components.homepage_features.3.line1">Geyser can be joined from Bedrock clients on Windows 10/11, iOS, Android, and even consoles. Geyser works with a wide array of hosting providers, but can also be used as its own standalone proxy to join any Minecraft server!</Translate>
|
||||
<br /><br />
|
||||
<Translate id="components.homepage_features.3.line2">If you are a server owner, you can install our Floodgate plugin which allows Xbox Live authenticated Bedrock users to join without a Java Edition account!</Translate>
|
||||
</HomepageFeature>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -1,323 +0,0 @@
|
||||
import Translate from '@docusaurus/Translate';
|
||||
import HeroBanner from '@site/src/components/HeroBanner';
|
||||
import HeroBackground from '@site/static/img/site/split-background.webp';
|
||||
import Layout from '@theme/Layout';
|
||||
import styles from './utilities.module.scss';
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
const ConfigEditorPage: React.FC = () => {
|
||||
const [config, setConfig] = useState('');
|
||||
const [parsedConfig, setParsedConfig] = useState<any>({});
|
||||
// match optional key
|
||||
const keyReg = /^#? ?[^:\sA-Z]+:(?!\S)/
|
||||
const editedConfig = useRef<any>({});
|
||||
const uploadRef = useRef<any>(null);
|
||||
|
||||
const loadDefault = async () => {
|
||||
try {
|
||||
const response = await fetch('https://raw.githubusercontent.com/GeyserMC/Geyser/master/core/src/main/resources/config.yml');
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
const text = await response.text();
|
||||
handleConfigLoad(text);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch default config:', error);
|
||||
}
|
||||
}
|
||||
|
||||
const handleUpload = async (e) => {
|
||||
const fileName = e.target.files[0];
|
||||
|
||||
// Makse sure the file is a .yml file
|
||||
if (!fileName.name.endsWith('.yml')) {
|
||||
alert('Please select a .yml config file!');
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the file
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = (e) => {
|
||||
handleConfigLoad(e.target.result as string);
|
||||
}
|
||||
fileReader.readAsText(fileName);
|
||||
}
|
||||
|
||||
const handleConfigLoad = (config: string) => {
|
||||
setConfig(config);
|
||||
setParsedConfig(loadConfig(config));
|
||||
}
|
||||
|
||||
const loadConfig = (config: string) => {
|
||||
const lines = config.split('\n');
|
||||
let currentSection = '';
|
||||
let currentComment = '';
|
||||
|
||||
const newConfig = {};
|
||||
|
||||
// Parse each line of the config
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
let line = lines[i];
|
||||
// Reset the section if we are no indented
|
||||
if (!line.startsWith(' ')) {
|
||||
currentSection = '';
|
||||
}
|
||||
|
||||
// Ignore any empty lines
|
||||
line = line.trim()
|
||||
if (line === '') {
|
||||
currentComment = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
const commented = line.startsWith('#');
|
||||
|
||||
const match = line.match(keyReg)
|
||||
if (match === null) {
|
||||
// Check if we are in a comment
|
||||
if (commented) {
|
||||
currentComment += line.replace(/^# ?/i, '') + '<br>';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if we are in a new section
|
||||
if (line.endsWith(':')) {
|
||||
currentSection = line.replace(':', '');
|
||||
currentComment = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore user auths section
|
||||
if (currentSection === 'saved-user-logins') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the key and value
|
||||
const splitLine = line.split(':');
|
||||
splitLine[0] = splitLine[0].trim();
|
||||
let val = '';
|
||||
for (let j = 1;j<splitLine.length;j++) {
|
||||
val += splitLine[j];
|
||||
}
|
||||
val = val.trim();
|
||||
|
||||
if (splitLine[0].includes('proxy-protocol-whitelisted-ips')) {
|
||||
currentComment = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (commented) {
|
||||
currentComment += '<strong>Note: This option is commented on, and if you change it, it will be automatically uncommented.</strong>' + '<br>';
|
||||
}
|
||||
|
||||
// Add the config option to the config object
|
||||
newConfig[currentSection] = newConfig[currentSection] || {};
|
||||
newConfig[currentSection][splitLine[0]] = {
|
||||
desc: currentComment,
|
||||
value: val,
|
||||
line: i
|
||||
};
|
||||
|
||||
// Reset the comment
|
||||
currentComment = '';
|
||||
}
|
||||
return newConfig;
|
||||
}
|
||||
|
||||
const generateHTML = (config: any) => {
|
||||
return Object.keys(config).map(configKey => (
|
||||
<div key={configKey} className={styles.card}>
|
||||
<div className={styles.cardHeader}>{configKey === '' ? 'Root' : configKey}</div>
|
||||
<div className={styles.cardBody}>
|
||||
{Object.keys(config[configKey]).map(configOption => {
|
||||
const configOptionInfo = config[configKey][configOption];
|
||||
const configOptionKey = configKey === '' ? configOption : `${configKey}.${configOption}`;
|
||||
const showOptionName = configOption.replace('#','').trim()
|
||||
return (
|
||||
<div key={configOptionKey} className={styles.configOption}>
|
||||
<h3>{showOptionName}</h3>
|
||||
<p dangerouslySetInnerHTML={{ __html: configOptionInfo.desc }} />
|
||||
{getInput(configOptionKey, configOptionInfo.value)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
|
||||
const handleExport = () => {
|
||||
let newConfig = config;
|
||||
const lines = newConfig.split('\n');
|
||||
Object.entries(editedConfig.current).forEach(([key, value]) => {
|
||||
const keys = key.split('.');
|
||||
let currentObj = parsedConfig;
|
||||
|
||||
keys.forEach((nestedKey, index) => {
|
||||
if (currentObj.hasOwnProperty(nestedKey)) {
|
||||
if (index === keys.length - 1) {
|
||||
const option = currentObj[nestedKey];
|
||||
const oldValue = option.value;
|
||||
const index = option.line;
|
||||
const newKey = nestedKey.replace('#','').trim();
|
||||
lines[index] = lines[index].replace(` ${nestedKey}: ${oldValue}`,` ${newKey}: ${value}`);
|
||||
} else {
|
||||
currentObj = currentObj[nestedKey];
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
newConfig = lines.join('\n');
|
||||
|
||||
// Trigger a download of the final config
|
||||
downloadString(newConfig, 'text/plain', 'config.yml');
|
||||
}
|
||||
|
||||
function getInput(name, value) {
|
||||
const handleChange = (event) => {
|
||||
const { id, value, type, checked } = event.target;
|
||||
|
||||
editedConfig.current = {
|
||||
...editedConfig.current,
|
||||
[id]: type === 'checkbox' ? checked.toString() : value
|
||||
};
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
// Handle all the dropdowns
|
||||
case 'remote.auth-type':
|
||||
return (
|
||||
<select key={name} className={styles.formInput} id={name} defaultValue={value} onChange={handleChange}>
|
||||
<option value='offline'>offline</option>
|
||||
<option value='online'>online</option>
|
||||
<option value='floodgate'>floodgate</option>
|
||||
</select>
|
||||
);
|
||||
case 'show-cooldown':
|
||||
return (
|
||||
<select key={name} className={styles.formInput} id={name} defaultValue={value} onChange={handleChange}>
|
||||
<option value='title'>title</option>
|
||||
<option value='actionbar'>actionbar</option>
|
||||
<option value='false'>false</option>
|
||||
</select>
|
||||
);
|
||||
case 'emote-offhand-workaround':
|
||||
return (
|
||||
<select key={name} className={styles.formInput} id={name} defaultValue={value} onChange={handleChange}>
|
||||
<option value='disabled'>disabled</option>
|
||||
<option value='no-emotes'>no-emotes</option>
|
||||
<option value='emotes-and-offhand'>emotes-and-offhand</option>
|
||||
</select>
|
||||
);
|
||||
case 'config-version':
|
||||
return <input key={name} className={styles.formInput} type='text' disabled defaultValue={value.replace(/"/g, '')} />;
|
||||
case 'metrics.uuid':
|
||||
return <input key={name} className={styles.formInput} id={name} type='text' disabled defaultValue={value === 'generateduuid' ? crypto.randomUUID() : value} />;
|
||||
|
||||
default:
|
||||
// Handle all the other inputs
|
||||
if (value.toLowerCase() === 'true' || value.toLowerCase() === 'false') {
|
||||
// Boolean
|
||||
return (
|
||||
<div key={name}>
|
||||
<input className={styles.checkbox} type='checkbox' id={name}
|
||||
defaultChecked={value.toLowerCase() === 'true'} onChange={handleChange}/>
|
||||
<label htmlFor={name} className='switch'></label>
|
||||
</div>
|
||||
);
|
||||
} else if (!isNaN(value)) {
|
||||
// Number
|
||||
return <input key={name} className={styles.formInput} type='number' defaultValue={value}
|
||||
id={name} onChange={handleChange}/>;
|
||||
} else {
|
||||
// String
|
||||
return <input key={name} className={styles.formInput} type='text'
|
||||
defaultValue={value.replace(/"/g, '')} id={name} onChange={handleChange}/>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// From https://gist.github.com/danallison/3ec9d5314788b337b682
|
||||
function downloadString(text, fileType, fileName) {
|
||||
const blob = new Blob([text], { type: fileType })
|
||||
|
||||
const a = document.createElement('a')
|
||||
a.download = fileName
|
||||
a.href = URL.createObjectURL(blob)
|
||||
a.dataset.downloadurl = [fileType, a.download, a.href].join(':')
|
||||
a.style.display = 'none'
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
document.body.removeChild(a)
|
||||
|
||||
setTimeout(() => { URL.revokeObjectURL(a.href) }, 1500)
|
||||
}
|
||||
|
||||
const NoConfigSection = () => (
|
||||
<>
|
||||
<h1><Translate id='pages.configeditor.noconfigselected.heading'>No config selected.</Translate></h1>
|
||||
<h3 className={styles.fontNormal}><Translate id='pages.configeditor.noconfigselected.subheading'>Upload a file or get started with the default config!</Translate></h3>
|
||||
|
||||
<div className={styles.buttonsContainer}>
|
||||
<button className={styles.button} onClick={loadDefault}>
|
||||
<Translate id='pages.configeditor.button.defaultconfig'>Default</Translate>
|
||||
</button>
|
||||
|
||||
<button className={styles.button} onClick={() => uploadRef.current.click()}>
|
||||
<input
|
||||
ref={uploadRef}
|
||||
type='file'
|
||||
className={styles.hidden}
|
||||
accept='.yml'
|
||||
onChange={handleUpload}
|
||||
/>
|
||||
<Translate id='pages.configeditor.button.upload'>Upload</Translate>
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
const EditorView = () => (
|
||||
<>
|
||||
<div className={styles.buttonsContainer} style={{ marginBottom: '30px' }}>
|
||||
<button className={styles.button} onClick={handleExport}>
|
||||
<Translate id='pages.configeditor.button.export'>Export</Translate>
|
||||
</button>
|
||||
</div>
|
||||
{generateHTML(parsedConfig)}
|
||||
</>
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeroBanner
|
||||
title={<Translate id='pages.configeditor.title'>Config Editor</Translate>}
|
||||
subheading={<Translate id='pages.configeditor.subheading'>Edit your Geyser configuration.</Translate>}
|
||||
backgroundImage={HeroBackground}
|
||||
/>
|
||||
|
||||
<div className='container' style={{ marginTop: '30px' }}>
|
||||
{Object.keys(parsedConfig).length === 0 ? <NoConfigSection /> : <EditorView />}
|
||||
</div>
|
||||
|
||||
|
||||
<section id='config-options'></section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default function ConfigEditor(): JSX.Element {
|
||||
return (
|
||||
<Layout
|
||||
title={`Config Editor`}
|
||||
description='Edit your Geyser configuration.'
|
||||
>
|
||||
<main>
|
||||
<div className='container container--fluid margin-vert--lg'>
|
||||
<ConfigEditorPage />
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
@@ -8,16 +8,10 @@ import { Grid } from '@site/src/components/Grid';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
import clsx from 'clsx';
|
||||
|
||||
const DumpViewerPage: React.FC = () => {
|
||||
const [dumpId, setDumpId] = useState('');
|
||||
const [data, setData] = useState<any>({});
|
||||
const [statusMessage, setStatusMessage] = useState('');
|
||||
const PluginList = ({plugins}, {}) => {
|
||||
const [activePlugin, setActivePlugin] = useState<any>({});
|
||||
|
||||
const pluginPopoverRef = useRef<any>(null);
|
||||
|
||||
const urlReg = /^(https?:\/\/)?dump\.geysermc\.org/;
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event) => setActivePlugin({});
|
||||
document.addEventListener("mousedown", handleClickOutside);
|
||||
@@ -27,6 +21,37 @@ const DumpViewerPage: React.FC = () => {
|
||||
};
|
||||
}, [pluginPopoverRef]);
|
||||
|
||||
return <Grid elementsPerRow={5}>
|
||||
{plugins.map(plugin => (
|
||||
<div key={plugin.main}>
|
||||
<div onClick={() => setActivePlugin(plugin)} className={styles.pluginName}>
|
||||
<b>{plugin.name}</b> <div className={styles.pluginEnabledIndicator} style={{ backgroundColor: plugin.enabled ? "green" : "red" }} />
|
||||
</div>
|
||||
|
||||
{activePlugin?.main === plugin.main ? (
|
||||
<div ref={pluginPopoverRef} className={styles.pluginInfoPopover}>
|
||||
<p className={styles.pluginNamePopover}>{plugin.name}</p>
|
||||
<p>{plugin.version}</p>
|
||||
<p className={styles.pluginEnabled} style={{ backgroundColor: plugin.enabled ? "green" : "red" }}>{plugin.enabled ? "Enabled" : "Disabled"}</p>
|
||||
|
||||
<p className={styles.pluginAuthorsLabel}>Authors:</p>
|
||||
<ul>
|
||||
{plugin.authors.map(author => <li>{author}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
) : undefined}
|
||||
</div>
|
||||
))}
|
||||
</Grid>
|
||||
};
|
||||
|
||||
const DumpViewerPage: React.FC = () => {
|
||||
const [dumpId, setDumpId] = useState('');
|
||||
const [data, setData] = useState<any>({});
|
||||
const [statusMessage, setStatusMessage] = useState('');
|
||||
|
||||
const urlReg = /^(https?:\/\/)?dump\.geysermc\.org/;
|
||||
|
||||
useEffect(() => {
|
||||
// Get the ID from the URL
|
||||
let id = window.location.href.includes('?') ? window.location.href.split('?').pop() : '';
|
||||
@@ -76,10 +101,6 @@ const DumpViewerPage: React.FC = () => {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1)
|
||||
}
|
||||
|
||||
const handlePluginClick = (plugin) => {
|
||||
setActivePlugin(plugin);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeroBanner
|
||||
@@ -159,7 +180,7 @@ const DumpViewerPage: React.FC = () => {
|
||||
</div>
|
||||
<div>
|
||||
<b><Translate id='pages.dumpviewer.platform.name'>Platform Name</Translate></b><br />
|
||||
<p id='platformName'>{data.bootstrapInfo.platformName ?? capitalizeFirstLetter(data.bootstrapInfo.platform.toLowerCase())}</p>
|
||||
<p id='platformName'>{data.bootstrapInfo.platformName ?? capitalizeFirstLetter(data.bootstrapInfo.platform.platformName.toLowerCase())}</p>
|
||||
</div>
|
||||
<div>
|
||||
<b><Translate id='pages.dumpviewer.platform.version'>Platform Version</Translate></b><br />
|
||||
@@ -211,35 +232,30 @@ const DumpViewerPage: React.FC = () => {
|
||||
</div>
|
||||
<div className={styles.card}>
|
||||
<div className={styles.cardHeader}>
|
||||
<Translate id='pages.dumpviewer.plugins'>Plugins</Translate> ({data.bootstrapInfo.plugins.length})
|
||||
<Translate id='pages.dumpviewer.plugins'>Plugins</Translate> ({data.bootstrapInfo.plugins?.length ?? 0})
|
||||
</div>
|
||||
<div className={styles.cardBody}>
|
||||
{data.bootstrapInfo.plugins.length === 0 ? <p><Translate id='pages.dumpviewer.plugins.noplugins'>No plugins to show.</Translate></p> : (
|
||||
{!data.bootstrapInfo.plugins || data.bootstrapInfo.plugins.length === 0 ? (
|
||||
<p><Translate id='pages.dumpviewer.plugins.noplugins'>No plugins to show.</Translate></p>) : (
|
||||
<>
|
||||
<p><Translate id='pages.dumpviewer.plugins.helptext'>Click on a plugin to view more information.</Translate></p>
|
||||
|
||||
<Grid elementsPerRow={5}>
|
||||
{data.bootstrapInfo.plugins.map(plugin => (
|
||||
<div>
|
||||
<b onClick={() => handlePluginClick(plugin)} className={styles.pluginName}>
|
||||
{plugin.name} <div className={styles.pluginEnabledIndicator} style={{ backgroundColor: plugin.enabled ? "green" : "red" }} />
|
||||
</b>
|
||||
<PluginList plugins={data.bootstrapInfo.plugins}></PluginList>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.card}>
|
||||
<div className={styles.cardHeader}>
|
||||
<Translate id='pages.dumpviewer.extensions'>Extensions</Translate> ({data.extensionInfo?.length ?? 0})
|
||||
</div>
|
||||
<div className={styles.cardBody}>
|
||||
{!data.extensionInfo || data.extensionInfo.length === 0 ? (
|
||||
<p><Translate id='pages.dumpviewer.extensions.noextensions'>No extensions to show.</Translate></p>) : (
|
||||
<>
|
||||
<p><Translate id='pages.dumpviewer.extensions.helptext'>Click on an extension to view more information.</Translate></p>
|
||||
|
||||
{activePlugin?.main === plugin.main ? (
|
||||
<div ref={pluginPopoverRef} className={styles.pluginInfoPopover}>
|
||||
<p className={styles.pluginNamePopover}>{plugin.name}</p>
|
||||
<p>{plugin.version}</p>
|
||||
<p className={styles.pluginEnabled} style={{ backgroundColor: plugin.enabled ? "green" : "red" }}>{plugin.enabled ? "Enabled" : "Disabled"}</p>
|
||||
|
||||
<p className={styles.pluginAuthorsLabel}>Authors:</p>
|
||||
<ul>
|
||||
{plugin.authors.map(author => <li>{author}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
) : undefined}
|
||||
</div>
|
||||
))}
|
||||
</Grid>
|
||||
<PluginList plugins={data.extensionInfo}></PluginList>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -109,41 +109,6 @@
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* https://codepen.io/JAGATHISH1123/pen/PvayMB */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
background-color: var(--switch-background-color);
|
||||
border-radius: 20px;
|
||||
transition: all 0.3s;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
background-color: white;
|
||||
top: 1px;
|
||||
left: 1px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox:checked+.switch::after {
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.checkbox:checked+.switch {
|
||||
background-color: var(--ifm-color-secondary);
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
@@ -199,3 +164,41 @@
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Modified from https://danklammer.com/articles/simple-css-toggle-switch */
|
||||
.checkbox {
|
||||
appearance: none;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
box-sizing: content-box;
|
||||
width: 4.5em;
|
||||
height: 1.8em;
|
||||
padding: 0.2em;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 1.5em;
|
||||
overflow: hidden;
|
||||
background-color: #707070;
|
||||
transition: background ease 0.3s;
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
width: 1.8em;
|
||||
height: 1.8em;
|
||||
background: #fff;
|
||||
color: #fff;
|
||||
border-radius: 1.5em;
|
||||
transition: transform cubic-bezier(0.3, 1.5, 0.7, 1) 0.3s;
|
||||
}
|
||||
|
||||
&:checked {
|
||||
background-color: var(--ifm-color-secondary);
|
||||
}
|
||||
|
||||
&:checked:before {
|
||||
transform: translateX(2.5em);
|
||||
}
|
||||
}
|
||||
@@ -2,38 +2,133 @@ import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { LoadContext, Plugin, PluginOptions } from '@docusaurus/types';
|
||||
import logger from '@docusaurus/logger';
|
||||
import Module from 'module';
|
||||
import ts from "typescript";
|
||||
|
||||
const createProvidersJsonPlugin = (context: LoadContext, options: PluginOptions): Plugin => {
|
||||
return {
|
||||
name: 'docusaurus-plugin-create-providers-json',
|
||||
// Welcome to hell
|
||||
const createProvidersJsonPlugin = (_context: LoadContext, _options: PluginOptions): Plugin => {
|
||||
return {
|
||||
name: 'docusaurus-plugin-create-providers-json',
|
||||
|
||||
async postBuild({ outDir, routes, plugins }) {
|
||||
const originalResolveFilename = Module._resolveFilename
|
||||
async postBuild({ outDir }) {
|
||||
const providersFilePath = path.join(__dirname, '../data/providers.ts');
|
||||
const providersFileContent = fs.readFileSync(providersFilePath, 'utf-8');
|
||||
const providersAst = ts.createSourceFile('providers.ts', providersFileContent, ts.ScriptTarget.Latest, true);
|
||||
|
||||
// This is a hack to allow us to import a custom module instead of the normal translation module
|
||||
Module._resolveFilename = function (request, parent, isMain, options) {
|
||||
if (request == '@docusaurus/Translate') {
|
||||
request = path.resolve(__dirname, 'custom_modules', 'translate.ts');
|
||||
let providersDataNode: ts.ObjectLiteralExpression | null = null;
|
||||
let descriptionTemplatesNode: ts.ObjectLiteralExpression | null = null;
|
||||
|
||||
for (const statement of providersAst.statements) {
|
||||
if (ts.isVariableStatement(statement)) {
|
||||
for (const decl of statement.declarationList.declarations) {
|
||||
if (
|
||||
ts.isIdentifier(decl.name) &&
|
||||
decl.initializer
|
||||
) {
|
||||
if (decl.name.text === 'providersData' && ts.isObjectLiteralExpression(decl.initializer)) {
|
||||
providersDataNode = decl.initializer;
|
||||
} else if (decl.name.text === 'descriptionTemplates' && ts.isObjectLiteralExpression(decl.initializer)) {
|
||||
descriptionTemplatesNode = decl.initializer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!providersDataNode) {
|
||||
logger.error('Could not find providersData in providers.ts');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!descriptionTemplatesNode) {
|
||||
logger.error('Could not find defaultDescriptions in providers.ts');
|
||||
return;
|
||||
}
|
||||
|
||||
function parseDescriptionTemplates(node: ts.ObjectLiteralExpression): Record<string, string> {
|
||||
const map: Record<string, string> = {};
|
||||
for (const prop of node.properties) {
|
||||
if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
|
||||
const key = prop.name.text;
|
||||
const val = extractDescription(prop.initializer);
|
||||
map[key] = val || '';
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
let defaultDescriptionsMap = parseDescriptionTemplates(descriptionTemplatesNode);
|
||||
|
||||
function extractDescription(node: ts.Expression): string {
|
||||
if (ts.isCallExpression(node)) {
|
||||
const expr = node.expression;
|
||||
if (ts.isIdentifier(expr) && expr.text === 'translate') {
|
||||
const arg = node.arguments[0];
|
||||
if (arg && ts.isObjectLiteralExpression(arg)) {
|
||||
for (const prop of arg.properties) {
|
||||
if (
|
||||
ts.isPropertyAssignment(prop) &&
|
||||
ts.isIdentifier(prop.name) &&
|
||||
prop.name.text === 'message' &&
|
||||
ts.isStringLiteral(prop.initializer)
|
||||
) {
|
||||
return prop.initializer.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ts.isPropertyAccessExpression(node)) {
|
||||
if (ts.isIdentifier(node.expression) && node.expression.text === 'descriptionTemplates') {
|
||||
const key = node.name.text;
|
||||
return defaultDescriptionsMap[key] || '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseProvidersArray(prop: ts.PropertyAssignment): {name: string; url: string; description: string;}[] {
|
||||
if (ts.isArrayLiteralExpression(prop.initializer)) {
|
||||
return prop.initializer.elements
|
||||
.filter(ts.isObjectLiteralExpression)
|
||||
.map(element => {
|
||||
let nameVal = '';
|
||||
let urlVal = '';
|
||||
let descVal = '';
|
||||
|
||||
for (const property of element.properties) {
|
||||
if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.name)) {
|
||||
const key = property.name.text;
|
||||
const val = property.initializer;
|
||||
if (key === 'name' && ts.isStringLiteral(val)) {
|
||||
nameVal = val.text;
|
||||
} else if (key === 'url' && ts.isStringLiteral(val)) {
|
||||
urlVal = val.text;
|
||||
} else if (key === 'description') {
|
||||
descVal = extractDescription(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { name: nameVal, url: urlVal, description: descVal };
|
||||
});
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
let providersJson = {};
|
||||
|
||||
for (const prop of providersDataNode.properties) {
|
||||
if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
|
||||
providersJson[prop.name.text] = parseProvidersArray(prop);
|
||||
}
|
||||
}
|
||||
|
||||
const dataDir = path.join(outDir, 'data');
|
||||
if (!fs.existsSync(dataDir)) {
|
||||
fs.mkdirSync(dataDir, { recursive: true });
|
||||
}
|
||||
const outputFilePath = path.join(dataDir, 'providers.json');
|
||||
fs.writeFileSync(outputFilePath, JSON.stringify(providersJson, null, 4), 'utf-8');
|
||||
}
|
||||
return originalResolveFilename.call(this, request, parent, isMain, options);
|
||||
};
|
||||
|
||||
// Import the providers data
|
||||
const { providersData } = await import('../data/providers');
|
||||
|
||||
// Restore the original resolve function
|
||||
Module._resolveFilename = originalResolveFilename
|
||||
|
||||
const providersFilePath = path.join(outDir, 'data/providers.json');
|
||||
|
||||
fs.mkdirSync(path.dirname(providersFilePath), { recursive: true });
|
||||
|
||||
fs.writeFileSync(providersFilePath, JSON.stringify(providersData, null, 2), 'utf-8');
|
||||
|
||||
logger.success(`Created providers.json file at ${providersFilePath}`);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export default createProvidersJsonPlugin;
|
||||
@@ -0,0 +1,102 @@
|
||||
<svg id="export-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="classDiagram" style="max-width: 1267.4666748046875px;" viewBox="0 0 1267.4666748046875 673" role="graphics-document document" aria-roledescription="class"><style xmlns="http://www.w3.org/1999/xhtml">/* Google Inc.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Recursive Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300 1000;
|
||||
src: url("data:font/woff2;base64,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 truncated
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
||||
}</style><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"); p {margin: 0;}</style><style>#export-svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;fill:#28253D;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#export-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#export-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#export-svg .error-icon{fill:#ffffff;}#export-svg .error-text{fill:#000000;stroke:#000000;}#export-svg .edge-thickness-normal{stroke-width:2px;}#export-svg .edge-thickness-thick{stroke-width:3.5px;}#export-svg .edge-pattern-solid{stroke-dasharray:0;}#export-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#export-svg .edge-pattern-dashed{stroke-dasharray:3;}#export-svg .edge-pattern-dotted{stroke-dasharray:2;}#export-svg .marker{fill:#000000;stroke:#000000;}#export-svg .marker.cross{stroke:#000000;}#export-svg svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;}#export-svg p{margin:0;}#export-svg g.classGroup text{fill:#28253D;stroke:none;font-family:"Recursive Variable",arial,sans-serif;font-size:10px;}#export-svg g.classGroup text .title{font-weight:bolder;}#export-svg .nodeLabel,#export-svg .edgeLabel{color:#28253D;}#export-svg .noteLabel .nodeLabel,#export-svg .noteLabel .edgeLabel{color:#28253D;}#export-svg .edgeLabel .label rect{fill:#ffffff;}#export-svg .label text{fill:#28253D;}#export-svg .labelBkg{background:#ffffff;}#export-svg .edgeLabel .label span{background:#ffffff;}#export-svg .classTitle{font-weight:bolder;}#export-svg .node rect,#export-svg .node circle,#export-svg .node ellipse,#export-svg .node polygon,#export-svg .node path{fill:#ffffff;stroke:#28253D;stroke-width:2;}#export-svg .divider{stroke:#28253D;stroke-width:1;}#export-svg g.clickable{cursor:pointer;}#export-svg g.classGroup rect{fill:#ffffff;stroke:#28253D;}#export-svg g.classGroup line{stroke:#28253D;stroke-width:1;}#export-svg .classLabel .box{stroke:none;stroke-width:0;fill:#ffffff;opacity:0.5;}#export-svg .classLabel .label{fill:#28253D;font-size:10px;}#export-svg .relation{stroke:#000000;stroke-width:2;fill:none;}#export-svg .dashed-line{stroke-dasharray:3;}#export-svg .dotted-line{stroke-dasharray:1 2;}#export-svg #compositionStart,#export-svg .composition{fill:#000000!important;stroke:#000000!important;stroke-width:1;}#export-svg #compositionEnd,#export-svg .composition{fill:#000000!important;stroke:#000000!important;stroke-width:1;}#export-svg #dependencyStart,#export-svg .dependency{fill:#000000!important;stroke:#000000!important;stroke-width:1;}#export-svg #dependencyStart,#export-svg .dependency{fill:#000000!important;stroke:#000000!important;stroke-width:1;}#export-svg #extensionStart,#export-svg .extension{fill:transparent!important;stroke:#000000!important;stroke-width:1;}#export-svg #extensionEnd,#export-svg .extension{fill:transparent!important;stroke:#000000!important;stroke-width:1;}#export-svg #aggregationStart,#export-svg .aggregation{fill:transparent!important;stroke:#000000!important;stroke-width:1;}#export-svg #aggregationEnd,#export-svg .aggregation{fill:transparent!important;stroke:#000000!important;stroke-width:1;}#export-svg #lollipopStart,#export-svg .lollipop{fill:#ffffff!important;stroke:#000000!important;stroke-width:1;}#export-svg #lollipopEnd,#export-svg .lollipop{fill:#ffffff!important;stroke:#000000!important;stroke-width:1;}#export-svg .edgeTerminals{font-size:11px;line-height:initial;}#export-svg .classTitleText{text-anchor:middle;font-size:18px;fill:#28253D;}#export-svg .edgeLabel{background-color:hsl(-120, 0%, 80%);text-align:center;}#export-svg .edgeLabel p{background-color:hsl(-120, 0%, 80%);}#export-svg .edgeLabel rect{opacity:0.5;background-color:hsl(-120, 0%, 80%);fill:hsl(-120, 0%, 80%);}#export-svg .cluster rect{fill:#F9F9FB;stroke:#BDBCCC;stroke-width:2px;}#export-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#export-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#export-svg .node .neo-node{stroke:#28253D;}#export-svg [data-look="neo"].node rect,#export-svg [data-look="neo"].cluster rect,#export-svg [data-look="neo"].node polygon{stroke:#28253D;filter:url(#drop-shadow);}#export-svg [data-look="neo"].node path{stroke:#28253D;stroke-width:2;}#export-svg [data-look="neo"].node .outer-path{filter:url(#drop-shadow);}#export-svg [data-look="neo"].node .neo-line path{stroke:#28253D;filter:none;}#export-svg [data-look="neo"].node circle{stroke:#28253D;filter:url(#drop-shadow);}#export-svg [data-look="neo"].node circle .state-start{fill:#000000;}#export-svg [data-look="neo"].statediagram-cluster rect{fill:#F9F9FB;stroke:#28253D;stroke-width:2;}#export-svLine truncated
|
||||
|
After Width: | Height: | Size: 126 KiB |
@@ -0,0 +1,102 @@
|
||||
<svg id="export-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="classDiagram" style="max-width: 1267.47px;" viewBox="0 0 1267.4666748046875 673" role="graphics-document document" aria-roledescription="class"><style xmlns="http://www.w3.org/1999/xhtml">/* Google Inc.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Recursive Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300 1000;
|
||||
src: url("data:font/woff2;base64,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 truncated
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
||||
}</style><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"); p {margin: 0;}</style><style>#export-svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#export-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#export-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#export-svg .error-icon{fill:hsl(20, 1.5873015873%, 12.3529411765%);}#export-svg .error-text{fill:rgb(222.9999999999, 223.6666666666, 223.9999999999);stroke:rgb(222.9999999999, 223.6666666666, 223.9999999999);}#export-svg .edge-thickness-normal{stroke-width:2px;}#export-svg .edge-thickness-thick{stroke-width:3.5px;}#export-svg .edge-pattern-solid{stroke-dasharray:0;}#export-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#export-svg .edge-pattern-dashed{stroke-dasharray:3;}#export-svg .edge-pattern-dotted{stroke-dasharray:2;}#export-svg .marker{fill:#cccccc;stroke:#cccccc;}#export-svg .marker.cross{stroke:#cccccc;}#export-svg svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;}#export-svg p{margin:0;}#export-svg g.classGroup text{fill:#FFFFFF;stroke:none;font-family:"Recursive Variable",arial,sans-serif;font-size:10px;}#export-svg g.classGroup text .title{font-weight:bolder;}#export-svg .nodeLabel,#export-svg .edgeLabel{color:#ccc;}#export-svg .noteLabel .nodeLabel,#export-svg .noteLabel .edgeLabel{color:#28253D;}#export-svg .edgeLabel .label rect{fill:#111113;}#export-svg .label text{fill:#ccc;}#export-svg .labelBkg{background:#111113;}#export-svg .edgeLabel .label span{background:#111113;}#export-svg .classTitle{font-weight:bolder;}#export-svg .node rect,#export-svg .node circle,#export-svg .node ellipse,#export-svg .node polygon,#export-svg .node path{fill:#111113;stroke:#FFFFFF;stroke-width:2;}#export-svg .divider{stroke:#FFFFFF;stroke-width:1;}#export-svg g.clickable{cursor:pointer;}#export-svg g.classGroup rect{fill:#111113;stroke:#FFFFFF;}#export-svg g.classGroup line{stroke:#FFFFFF;stroke-width:1;}#export-svg .classLabel .box{stroke:none;stroke-width:0;fill:#111113;opacity:0.5;}#export-svg .classLabel .label{fill:#FFFFFF;font-size:10px;}#export-svg .relation{stroke:#cccccc;stroke-width:2;fill:none;}#export-svg .dashed-line{stroke-dasharray:3;}#export-svg .dotted-line{stroke-dasharray:1 2;}#export-svg #compositionStart,#export-svg .composition{fill:#cccccc!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #compositionEnd,#export-svg .composition{fill:#cccccc!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #dependencyStart,#export-svg .dependency{fill:#cccccc!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #dependencyStart,#export-svg .dependency{fill:#cccccc!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #extensionStart,#export-svg .extension{fill:transparent!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #extensionEnd,#export-svg .extension{fill:transparent!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #aggregationStart,#export-svg .aggregation{fill:transparent!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #aggregationEnd,#export-svg .aggregation{fill:transparent!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #lollipopStart,#export-svg .lollipop{fill:#111113!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #lollipopEnd,#export-svg .lollipop{fill:#111113!important;stroke:#cccccc!important;stroke-width:1;}#export-svg .edgeTerminals{font-size:11px;line-height:initial;}#export-svg .classTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#export-svg .edgeLabel{background-color:hsl(180, 1.5873015873%, 28.3529411765%);text-align:center;}#export-svg .edgeLabel p{background-color:hsl(180, 1.5873015873%, 28.3529411765%);}#export-svg .edgeLabel rect{opacity:0.5;background-color:hsl(180, 1.5873015873%, 28.3529411765%);fill:hsl(180, 1.5873015873%, 28.3529411765%);}#export-svg .cluster rect{fill:#1E1A2E;stroke:#BDBCCC;stroke-width:2px;}#export-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#export-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#export-svg .node .neo-node{stroke:#FFFFFF;}#export-svg [data-look="neo"].node rect,#export-svg [data-look="neo"].cluster rect,#export-svg [data-look="neo"].node polygon{stroke:#FFFFFF;filter:url(#drop-shadow);}#export-svg [data-look="neo"].node path{stroke:#FFFFFF;stroke-width:2;}#export-svg [data-look="neo"].node .outer-path{filter:url(#drop-shadow);}#export-svg [data-look="neo"].node .neo-line path{stroke:#FFFFFF;filter:none;}#export-svg [data-look="neo"].node circle{stroke:#FFFFFF;filter:url(#drLine truncated
|
||||
|
After Width: | Height: | Size: 126 KiB |
@@ -0,0 +1,102 @@
|
||||
<svg id="export-svg" width="100%" xmlns="http://www.w3.org/2000/svg" style="max-width: 1332px;" viewBox="-50 -10 1332 1090" role="graphics-document document" aria-roledescription="sequence"><style xmlns="http://www.w3.org/1999/xhtml">/* Google Inc.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Recursive Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300 1000;
|
||||
src: url("data:font/woff2;base64,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 truncated
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
||||
}</style><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"); p {margin: 0;}</style><rect x="40" y="618" fill="rgb(255, 235, 235)" width="1138" height="249" class="rect"/><rect x="40" y="346" fill="rgb(255, 245, 235)" width="636" height="213" class="rect"/><rect x="40" y="75" fill="rgb(235, 245, 255)" width="636" height="261" class="rect"/><g><rect x="1082" y="974" fill="#eaeaea" stroke="#666" width="150" height="65" name="JavaServer" rx="6" ry="6" class="actor actor-bottom" data-look="neo" style="stroke: rgb(251, 146, 60); fill: rgb(255, 247, 237);" filter="url(#drop-shadow)"/><text x="1157" y="1006.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="1157" dy="0">Java Server</tspan></text></g><g><rect x="566" y="974" fill="#eaeaea" stroke="#666" width="150" height="65" name="Geyser" rx="6" ry="6" class="actor actor-bottom" data-look="neo" style="stroke: rgb(45, 212, 191); fill: rgb(240, 253, 250);" filter="url(#drop-shadow)"/><text x="641" y="1006.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="641" dy="0">Geyser</tspan></text></g><g><rect x="0" y="974" fill="#eaeaea" stroke="#666" width="150" height="65" name="Client" rx="6" ry="6" class="actor actor-bottom" data-look="neo" style="stroke: rgb(232, 121, 249); fill: rgb(253, 244, 255);" filter="url(#drop-shadow)"/><text x="75" y="1006.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="75" dy="0">Client</tspan></text></g><g><line id="actor222" x1="1157" y1="65" x2="1157" y2="974" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="JavaServer" data-et="life-line" data-id="JavaServer"/><g id="root-222" data-look="neo" data-et="participant" data-id="JavaServer"><rect x="1082" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="JavaServer" rx="6" ry="6" class="actor actor-top" data-look="neo" style="stroke: rgb(251, 146, 60); fill: rgb(255, 247, 237);" filter="url(#drop-shadow)"/><defs><filter id="drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs><text x="1157" y="32.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="1157" dy="0">Java Server</tspan></text></g></g><g><line id="actor221" x1="641" y1="65" x2="641" y2="974" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="Geyser" data-et="life-line" data-id="Geyser"/><g id="root-221" data-look="neo" data-et="participant" data-id="Geyser"><rect x="566" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="Geyser" rx="6" ry="6" class="actor actor-top" data-look="neo" style="stroke: rgb(45, 212, 191); fill: rgb(240, 253, 250);" filter="url(#drop-shadow)"/><defs><filter id="drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs><text x="641" y="32.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="641" dy="0">Geyser</tspan></text></g></g><g><line id="actor220" x1="75" y1="65" x2="75" y2="974" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="Client" data-et="life-line" data-id="Client"/><g id="root-220" data-look="neo" data-et="participant" data-id="Client"><rect x="0" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="Client" rx="6" ry="6" class="actor actor-top" data-look="neo" style="stroke: rgb(232, 121, 249); fill: rgb(253, 244, 255);" filter="url(#drop-shadow)"/><defs><filter id="drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs><text x="75" y="32.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="75" dy="0">Client</tspan></text></g></g><style>#export-svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;fill:#28253D;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#export-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#export-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#export-svg .error-icon{fill:#ffffff;}#export-svg .error-text{fill:#000000;stroke:#000000;}#export-svg .edge-thickness-normal{stroke-width:2pLine truncated
|
||||
|
After Width: | Height: | Size: 117 KiB |
@@ -0,0 +1,102 @@
|
||||
<svg id="export-svg" width="100%" xmlns="http://www.w3.org/2000/svg" style="max-width: 1332px;" viewBox="-50 -10 1332 1090" role="graphics-document document" aria-roledescription="sequence"><style xmlns="http://www.w3.org/1999/xhtml">/* Google Inc.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Recursive Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300 1000;
|
||||
src: url("data:font/woff2;base64,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 truncated
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
||||
}</style><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"); p {margin: 0;}</style><rect x="40" y="618" fill="rgb(1, 50, 50)" width="1138" height="249" class="rect"/><rect x="40" y="346" fill="rgb(1, 25, 50)" width="636" height="213" class="rect"/><rect x="40" y="75" fill="rgb(1, 1, 50)" width="636" height="261" class="rect"/><g><rect x="1082" y="974" fill="#eaeaea" stroke="#666" width="150" height="65" name="JavaServer" rx="6" ry="6" class="actor actor-bottom" data-look="neo" style="stroke: rgb(251, 146, 60);" filter="url(#drop-shadow)"/><text x="1157" y="1006.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="1157" dy="0">Java Server</tspan></text></g><g><rect x="566" y="974" fill="#eaeaea" stroke="#666" width="150" height="65" name="Geyser" rx="6" ry="6" class="actor actor-bottom" data-look="neo" style="stroke: rgb(45, 212, 191);" filter="url(#drop-shadow)"/><text x="641" y="1006.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="641" dy="0">Geyser</tspan></text></g><g><rect x="0" y="974" fill="#eaeaea" stroke="#666" width="150" height="65" name="Client" rx="6" ry="6" class="actor actor-bottom" data-look="neo" style="stroke: rgb(232, 121, 249);" filter="url(#drop-shadow)"/><text x="75" y="1006.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="75" dy="0">Client</tspan></text></g><g><line id="actor5" x1="1157" y1="65" x2="1157" y2="974" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="JavaServer" data-et="life-line" data-id="JavaServer"/><g id="root-5" data-look="neo" data-et="participant" data-id="JavaServer"><rect x="1082" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="JavaServer" rx="6" ry="6" class="actor actor-top" data-look="neo" style="stroke: rgb(251, 146, 60);" filter="url(#drop-shadow)"/><defs><filter id="drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#FFFFFF"/></filter></defs><text x="1157" y="32.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="1157" dy="0">Java Server</tspan></text></g></g><g><line id="actor4" x1="641" y1="65" x2="641" y2="974" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="Geyser" data-et="life-line" data-id="Geyser"/><g id="root-4" data-look="neo" data-et="participant" data-id="Geyser"><rect x="566" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="Geyser" rx="6" ry="6" class="actor actor-top" data-look="neo" style="stroke: rgb(45, 212, 191);" filter="url(#drop-shadow)"/><defs><filter id="drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#FFFFFF"/></filter></defs><text x="641" y="32.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="641" dy="0">Geyser</tspan></text></g></g><g><line id="actor3" x1="75" y1="65" x2="75" y2="974" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="Client" data-et="life-line" data-id="Client"/><g id="root-3" data-look="neo" data-et="participant" data-id="Client"><rect x="0" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="Client" rx="6" ry="6" class="actor actor-top" data-look="neo" style="stroke: rgb(232, 121, 249);" filter="url(#drop-shadow)"/><defs><filter id="drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#FFFFFF"/></filter></defs><text x="75" y="32.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="75" dy="0">Client</tspan></text></g></g><style>#export-svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#export-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#export-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#export-svg .error-icon{fill:hsl(20, 1.5873015873%, 12.3529411765%);}#export-svg .error-text{fill:rgb(222.9999999999, 223.6666666666, 223.9999999999);stroke:rgb(222.9999999999, 223.6666666666, 223.9999999999);}#export-svg .edge-thickness-normal{stroke-width:2px;}#export-svg .edge-thickness-thick{stroke-width:3.5px;}#export-Line truncated
|
||||
|
After Width: | Height: | Size: 117 KiB |
@@ -0,0 +1,102 @@
|
||||
<svg id="export-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="flowchart" style="max-width: 1814.8438720703125px;" viewBox="308.9886474609375 -207.49822998046875 1814.8438720703125 937.8803100585938" role="graphics-document document" aria-roledescription="flowchart-v2"><style xmlns="http://www.w3.org/1999/xhtml">/* Google Inc.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Recursive Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300 1000;
|
||||
src: url("data:font/woff2;base64,d09GMgABAAAAAPP4ABQAAAACC1AAAPOFAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoRTG+58HJRkP01WQVKBEAZgP1NUQVSBYic8AIUuL4EoEQgKgrlQgo1LC4UeADCEmGIBNgIkA4o0BCAFjXYHj1kMB1tP8XFBnDDsYOLjdY5tyxhP1ODemquETQc3Z3pudCVj86rVErZNi3i3Y//2nORI8v//eUljjLWdtR0QKKbl20eS7FRQsiY7ZVRRptH0yqJXr2OtTaO1imIUpLbm1BAmJ01DbFHubzrOejQ6IZzx4KbA1Nb6Uefj6wvCSyqOqh1aZFkSC39rci0YSByiIZTD9Lmpc/ssLQ7lUAp1xX3bL+ReBGUOlM2UwpgsYb4rXVD3N9ygMjLwLTR0RbefbwtNGV09EkQXTH6a43fHVcFbscQThc1CkeLzYWWPfl664n/SvbTyfERbWp/mYTAGF8MMsezJuSqinvr+PL/NP/e+ByIl2jMxhorIGBZzBhYywYlRhYWRMzC3Odbqyrlyrly331X8qHJRMsSf+nePyQv08poU8MCb1Ym/o8vf/AkqOLn14HaoBhZ/VRod9M/bwTtz7tsPM0nnCgYr1+kg7ABNZ9eYNHYxvag3aSoxb6NNzSk1aFEbBYbo5pjYrMjgmcPkYS5sAEW1H2/PvR/WqRgH5FgYQA1AlmWsi3LREYp2eFrO/1+zET/jurOz4tlNsjFSCpSaPzHlTvWratsrr70VBQp18CREB97N6qkxZmfiUD3Rzyf2J6LQVKhiFiAQCAlRIwmmNd+ZticmQ3PpQ0cltlNzGoWdApJ4Yf5PrwCI+XHuc8hCTagjwgLl2lfAhNvmz52UswKF28A71f93uM3WNCUY4UWmz8sPpnUHiMrbUgg7TgwoWxZYFgCbZTuOM19N7atqQIFlyYAJz8wngtNf5Ou/rtWKA0tw37dHQM5wgAwCbKm5AOEF76nYl4eXKzBy8nm5PFw5qZxUVsqRk/DjcA5z1vcqkNiSHQec5pl+ALxMh8tejrufkzR/hCsyDlHCtid1mrNaBQJTALFkxQWA8YGX+SdYCwwBOfrr9LnV/58rNm6ttCk0BIsbIUKMkMYamjadqak8W73av8XGfGtiX0SHoLj07MefPo1DzaKlNZD08WAAPZjVDQdRRN+nTp32af3/71Tv3fg9eyhwrAIalBKAIa6XOHA6d/UYpF/pFw2JQ05lDlIZ/fW//gegUPjju/kfmpN46/igTNSQXVG29ZmYfjkBOJeX9IF4QKxclRyQ8RNKjAB+f/igP4GRuSMuxLw7mrOMOiPuhVGt7dmkjBviTbjEM7MfATzP/9V4MJsLGH58bmXLjlm6LdTJaaE/Uf9/r7Pa6mNwCVxBQGMErq4CU+F/Gdv/Y6jeXnV056qeVDUpdsgr6ekLfQWwEIYSErhAUFUE2yUkcAkJbMDGY1O4QsiuTu5M568vgb+EcH1J4IQ9bXBVB3fVBHdKdqXYIeXd5LCs5cx2diGverYhbzdz9rNejf+fqn4tQP6QcvWbUvbmotyqA+68wQMxGIACRcoiFSk6JclR/oEzoGgQpKI35eqfrUKskuxNud+23abdogyxK7do1/9/XWmrq7sks4KT8B5H54S4NlBTBppm9KVZ7debv1qg2W+i8ZgntGwvnVkDVQEqXaYoPQGEqqOqS5mySlmlD/H405LeaGUpsPN8uHABSzqkXp9Pe09fvjRUm5OOWrvSUgAJwAE8/tdy2tv7vDvS2nhUYiRvUXFolLq2V9mUUlSrNnGAQ7jIYmw6gUaGIQb0/+VPq3pS0zby5xLQD5DJLFbZZlZzxn9izX/PGRnNq/3NzarGkIhKgCAiIrKOiGB3qM3Cm5XGzxUaRESChH/3pI/+0p4d2GXXqFEVFRUVeVF51f3c9xcHkzUpEghgH+yIkd3+Lfe+YUz9/pmA5prR3mpj4sCBDEFEREXh/jRfnK/O32461gAwSC3rkrdCRGt7syqiQCTkudtvgCDwBmBCutEiaGCscSCwBmhBy4a6Lu5unwSp27ihXF4RTFggjL6xMWdV7Dhy5sydkBdfEkvGS6tFSIeKJBdFQSVeigxZshQopVYz1gjRANEE0QLR8Q7RQ4ugT//MoKHxahGs2RHSEUMsxGEilZmM5CoC6aqKUCMfSyyxVLBeEcpGcnugb4BGAgbADngZAot4gL7j6pPl4OP1RAH85v/br9MFUVU7/aO57Pth2Eraz9pVhiqMIuXInUsJNpa8nNZWYGWtDg4Kjjnhm3ZcEimkOLNJFVZSd4H+z14AoAcIHTbifnFeQJAwfpXX0WNxAIq2kKGqEM/Dcmav7WGJuht3u1J6S8/bO/7Gr4OqHoYbT0IaQLzOmctIFbxaKcQsslTwZcRKMsVY3aZwNFnUZzQ9iAvYdB5dxJKwIS68RiegCVRipdyrUOhtJWVl1RNOqkioAiwBeD/dANKmmWACn/kTgY6bInjNtZUJwD5wN40a2JAAgF6PVIDnzpoD9qpVg8Syy8B9Xm63ATMAJHQY/7lAJNHB/1Wr0DDM/4VkY7T85uKRxUrRZ0aT5i8KVwnlAq17h3uSu5PzmrIBuDA08NiLgQ4ewYUEjA/DFwniBp6RANCp617/MoqgnIoNwMfNXqmaMzrpXbKUh0h50wN3wjwgyMvu/IatSIg3KvxzKAOaSnbKe64gmwOO+FAjF9SjIFo+xiRPiupwMRuJmnnNOoqda1EBloMIOslL6DRfTwklqbNx4jLbCT2r/0dk3UMbYu3u6MDmFWexmsOhmOjeOQ1RItmBzWEcsBJEd79r7wpgu/uI5UBG/WpeI1ckCnpqd/IzfwfV1jH+Fh8agy9tBuSaPl/S2LZjjSe71gUTbKPt2bQE7eI0tgYwjYxDEZd1lnWzmTIBituQ6RYvUTsDI09Fqko7dIayzIEPRs3AztEnBbTg/kfOCIstCgxkmX0afxgHnbK9y8CoSygZ52lyqHWRrjc9ALxz3h0x/Lmv9DMiRzQTiXE/ZMcBr2OHMEUqi8dQMzNuwoKopP7zMBE360CYthwnT0opyDnWxxEIA4izAf2Ox9UDTRbumA1P/utnORf9Lt4e7ye1OMAzoi8M3ZgHd5tnpdKKyvYjCzpnEE20QFfQWAqCCfgEeDrBIH7Sr7nk2eNrXupe0peiyXvODexYpqyJESZHaUEKdo1ZE7uaI/TVh6YZN4hlqjh9RLIiW3AQzzBYQ1sfdVPpmxnrTZOINrG736WxCOhMr+AR5IL/B4CUBymQT3y03gtQNKm35jph/ojo1unboTnM0hhF3Jw7tQgtyzzLDKVMyrtjyvphgIDGlOGzZj7m4mClNPP5ek76nhB3fygrJU2OzQNLOAUioJ5JDrrljwhbRiLiM7YYZOu6LMZbI3vyshYgxx/4mG53ceaI2J0uf8R9Ta26hiXblmjR4cW4YvZAu79S5GkdG8jq1nOwLLKnsRWtTpLbaEDt8zWmQKZmrOi2Vmcf5nFJ5rZU4JVB7DaOd1n0VHCwLVSlsjTj7olR+mta8fHMQ6k2heh2/mfBDQefmDNvSwkEKiiHIt0ynio8NzvqpBantxXOZqeLbjC4lZvMKLbZ/d12T7y5uv1Cld1+xkH/V0a98NaYeXo42W8LE1nyg1056GB3/ga59OShvJNCBXcfi1FgwIR3FFiwITDCvI4tQGB5a8+KHdO8c2AIl8Zx7GS3ztwQuIMCH4EHCgJmPNOGkJgR3mnHlx9zEgsswcQfhaUIAhgSxJDgJJCSIYmssZGLglGIQUX1sBWLIy7ZxEuBSMUmrUYnXSYaWfJhCh40CmGK0ChmrCStlapkgJqJKpaq01WNOiY0rNRj05AkjZpgmpNNi1aINnTa5/j50XgFGHQ+OujSjatzYzEgLRxzAotTXJzh7FzdyUWXLHTZNRKuezwe34SM22R8lK5mFRPcJ3hC8JSEZzvBFz5x+EoViS2weNkEZFAirOdvYmuOTl5Z89bhIuWQuu4cbN0uAdZdHVSFTw5OhvBkRVqfZ2lbvbSvDmj6W4GBwZbDJHcOyzxH4JrX8LY9wB6sCj7tqrDB5BuOXVhGZzhAUVECCATbUQhUmQcU4JsPgcCXgtCngkjkFiQqNh+R5JFOPlElMdgk0kBmMwMu3QWBIqkrEoAuR4AGUQQVCaeExStiMlGwHYA2HLErklhEMlkUkUyQAsA3TQW01ZTJmuF2DsDZizKyyS7hgZwtaj+hUhSBGuKE7S3A503wgTKyySaObOKA159WqTSZ8h/iySCdowQqGwIqIGxFNOEsFoy9VhQRRjJZFJEsoI9F0mq/O3oRgAAA3OePgztviUvACRPbwMJ0lJuUs5TDjfdS1lPWUhaO9GGok15zr72GtJo0hRgkuid1osC8aQYWwjSh+ipcW/cSKm6PNxDyfPVmK/jH+K1jjtfiX8AvxW/F2/GY8D1wD+AO4taTVsMybi1uyYWfEM8sAZcQCEEQRUvpp3EN5qbnpNgnXN0Hb96OXYkdwmYfxjUoadkpBtrTNOY7n7sBJTWfLvJX5MNaoJHKI9+o9DORD5AeK2h/NU39V9W5lICuNcylz/uZzEWXoUuj/0YuYOkBRTkDBWFRbYXLhPNUeCMvy/AodAs0b6ne2JaGyEa2sR2JtsR6Y5a3eeQNyz9RZg/38Qi3chvPYI8Vstd6b3wkdx1MF2yQK65Uf4arxzRbrHAdCg+nHBcnZ0+Tc+x8uSAuuuRyueK6Kk5Fij3Ni2le5bwmb1CeilCpSrMWRq1MbPB0IMBq44ScwIMnL958+PLXCepZm9syW/dfmrjz3wx+bR225pprrrnmqm7m/rO5Qil1GN+Pg2xMBJxoZmYiIlJiYmZmZmbe2yykCc4F5ycE4MHNRQCAmbkxgwEAAIBj4Pem3Vjj9Y3aZMKWQSOQTuwT+HFzERHhJucutci2/4PTETsriWkClmLj4OLhf4dcTa2pLine truncated
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
||||
}</style><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"); p {margin: 0;}</style><style>#export-svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;fill:#28253D;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#export-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#export-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#export-svg .error-icon{fill:#ffffff;}#export-svg .error-text{fill:#000000;stroke:#000000;}#export-svg .edge-thickness-normal{stroke-width:2px;}#export-svg .edge-thickness-thick{stroke-width:3.5px;}#export-svg .edge-pattern-solid{stroke-dasharray:0;}#export-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#export-svg .edge-pattern-dashed{stroke-dasharray:3;}#export-svg .edge-pattern-dotted{stroke-dasharray:2;}#export-svg .marker{fill:#000000;stroke:#000000;}#export-svg .marker.cross{stroke:#000000;}#export-svg svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;}#export-svg p{margin:0;}#export-svg .label{font-family:"Recursive Variable",arial,sans-serif;color:#28253D;}#export-svg .cluster-label text{fill:#000000;}#export-svg .cluster-label span{color:#000000;}#export-svg .cluster-label span p{background-color:transparent;}#export-svg .label text,#export-svg span{fill:#28253D;color:#28253D;}#export-svg .node rect,#export-svg .node circle,#export-svg .node ellipse,#export-svg .node polygon,#export-svg .node path{fill:#ffffff;stroke:#28253D;stroke-width:2px;}#export-svg .rough-node .label text,#export-svg .node .label text,#export-svg .image-shape .label,#export-svg .icon-shape .label{text-anchor:middle;}#export-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#export-svg .rough-node .label,#export-svg .node .label,#export-svg .image-shape .label,#export-svg .icon-shape .label{text-align:center;}#export-svg .node.clickable{cursor:pointer;}#export-svg .root .anchor path{fill:#000000!important;stroke-width:0;stroke:#000000;}#export-svg .arrowheadPath{fill:#000000;}#export-svg .edgePath .path{stroke:#000000;stroke-width:2px;}#export-svg .flowchart-link{stroke:#000000;fill:none;}#export-svg .edgeLabel{background-color:hsl(-120, 0%, 80%);text-align:center;}#export-svg .edgeLabel p{background-color:hsl(-120, 0%, 80%);}#export-svg .edgeLabel rect{opacity:0.5;background-color:hsl(-120, 0%, 80%);fill:hsl(-120, 0%, 80%);}#export-svg .labelBkg{background-color:rgba(204, 204, 204, 0.5);}#export-svg .cluster rect{fill:#F9F9FB;stroke:#BDBCCC;stroke-width:2px;}#export-svg .cluster text{fill:#000000;}#export-svg .cluster span{color:#000000;}#export-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"Recursive Variable",arial,sans-serif;font-size:12px;background:#ffffff;border:1px solid hsl(0, 0%, 90%);border-radius:2px;pointer-events:none;z-index:100;}#export-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#28253D;}#export-svg rect.text{fill:none;stroke-width:0;}#export-svg .icon-shape,#export-svg .image-shape{background-color:hsl(-120, 0%, 80%);text-align:center;}#export-svg .icon-shape p,#export-svg .image-shape p{background-color:hsl(-120, 0%, 80%);padding:2px;}#export-svg .icon-shape rect,#export-svg .image-shape rect{opacity:0.5;background-color:hsl(-120, 0%, 80%);fill:hsl(-120, 0%, 80%);}#export-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#export-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#export-svg .node .neo-node{stroke:#28253D;}#export-svg [data-look="neo"].node rect,#export-svg [data-look="neo"].cluster rect,#export-svg [data-look="neo"].node polygon{stroke:#28253D;filter:url(#drop-shadow);}#export-svg [data-look="neo"].node path{stroke:#28253D;stroke-width:2;}#export-svg [data-look="neo"].node .outer-path{filter:url(#drop-shadow);}#export-svg [data-look="neo"].node .neo-line path{stroke:#28253D;filter:none;}#export-svg [data-look="neo"].node circle{stroke:#28253D;filter:url(#drop-shadow);}#export-svg [data-look="neo"].node circle .state-start{fill:#000000;}#export-svg [data-look="neo"].statediagram-cluster rect{fill:#F9F9FB;stroke:#28253D;stroke-width:2;}#export-svg [data-look="neo"].icon-shape .icon{fill:#28253D;filter:url(#drop-shadow);}#export-svg [data-look="neo"].icon-shape .icon-neo path{stroke:#28253D;filter:url(#drop-shadow);}#export-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g><marker id="export-svg_flowchart-v2-pointEnd" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="7.75" refY="7" markerUnits="userSpaceOnUse" markerWidth="10.5" markerHeight="14" orient="auto"><path d="M 0 0 L 11.5 7 L 0 14 z" class="arrowMarkerPath" style="stroke-width: 0pLine truncated
|
||||
|
After Width: | Height: | Size: 115 KiB |
@@ -0,0 +1,102 @@
|
||||
<svg id="export-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="flowchart" style="max-width: 1814.84px;" viewBox="308.9886474609375 -207.49822998046875 1814.8438720703125 937.8803100585938" role="graphics-document document" aria-roledescription="flowchart-v2"><style xmlns="http://www.w3.org/1999/xhtml">/* Google Inc.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Recursive Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300 1000;
|
||||
src: url("data:font/woff2;base64,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 truncated
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
||||
}</style><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"); p {margin: 0;}</style><style>#export-svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#export-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#export-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#export-svg .error-icon{fill:hsl(20, 1.5873015873%, 12.3529411765%);}#export-svg .error-text{fill:rgb(222.9999999999, 223.6666666666, 223.9999999999);stroke:rgb(222.9999999999, 223.6666666666, 223.9999999999);}#export-svg .edge-thickness-normal{stroke-width:2px;}#export-svg .edge-thickness-thick{stroke-width:3.5px;}#export-svg .edge-pattern-solid{stroke-dasharray:0;}#export-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#export-svg .edge-pattern-dashed{stroke-dasharray:3;}#export-svg .edge-pattern-dotted{stroke-dasharray:2;}#export-svg .marker{fill:#cccccc;stroke:#cccccc;}#export-svg .marker.cross{stroke:#cccccc;}#export-svg svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;}#export-svg p{margin:0;}#export-svg .label{font-family:"Recursive Variable",arial,sans-serif;color:#e0dfdf;}#export-svg .cluster-label text{fill:rgb(222.9999999999, 223.6666666666, 223.9999999999);}#export-svg .cluster-label span{color:rgb(222.9999999999, 223.6666666666, 223.9999999999);}#export-svg .cluster-label span p{background-color:transparent;}#export-svg .label text,#export-svg span{fill:#e0dfdf;color:#e0dfdf;}#export-svg .node rect,#export-svg .node circle,#export-svg .node ellipse,#export-svg .node polygon,#export-svg .node path{fill:#111113;stroke:#FFFFFF;stroke-width:2px;}#export-svg .rough-node .label text,#export-svg .node .label text,#export-svg .image-shape .label,#export-svg .icon-shape .label{text-anchor:middle;}#export-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#export-svg .rough-node .label,#export-svg .node .label,#export-svg .image-shape .label,#export-svg .icon-shape .label{text-align:center;}#export-svg .node.clickable{cursor:pointer;}#export-svg .root .anchor path{fill:#cccccc!important;stroke-width:0;stroke:#cccccc;}#export-svg .arrowheadPath{fill:#cccccc;}#export-svg .edgePath .path{stroke:#cccccc;stroke-width:2px;}#export-svg .flowchart-link{stroke:#cccccc;fill:none;}#export-svg .edgeLabel{background-color:hsl(180, 1.5873015873%, 28.3529411765%);text-align:center;}#export-svg .edgeLabel p{background-color:hsl(180, 1.5873015873%, 28.3529411765%);}#export-svg .edgeLabel rect{opacity:0.5;background-color:hsl(180, 1.5873015873%, 28.3529411765%);fill:hsl(180, 1.5873015873%, 28.3529411765%);}#export-svg .labelBkg{background-color:rgba(71.1523809525, 73.4476190477, 73.4476190477, 0.5);}#export-svg .cluster rect{fill:#1E1A2E;stroke:#BDBCCC;stroke-width:2px;}#export-svg .cluster text{fill:rgb(222.9999999999, 223.6666666666, 223.9999999999);}#export-svg .cluster span{color:rgb(222.9999999999, 223.6666666666, 223.9999999999);}#export-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"Recursive Variable",arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#export-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#export-svg rect.text{fill:none;stroke-width:0;}#export-svg .icon-shape,#export-svg .image-shape{background-color:hsl(180, 1.5873015873%, 28.3529411765%);text-align:center;}#export-svg .icon-shape p,#export-svg .image-shape p{background-color:hsl(180, 1.5873015873%, 28.3529411765%);padding:2px;}#export-svg .icon-shape rect,#export-svg .image-shape rect{opacity:0.5;background-color:hsl(180, 1.5873015873%, 28.3529411765%);fill:hsl(180, 1.5873015873%, 28.3529411765%);}#export-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#export-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#export-svg .node .neo-node{stroke:#FFFFFF;}#export-svg [data-look="neo"].node rect,#export-svg [data-look="neo"].cluster rect,#export-svg [data-look="neo"].node polygon{stroke:#FFFFFF;filter:url(#drop-shadow);}#export-svg [data-look="neo"].node path{stroke:#FFFFFF;stroke-width:2;}#export-svg [data-look="neo"].node .outer-path{filter:url(#drop-shadow);}#export-svg [data-look="neo"].node .neo-line path{stroke:#FFFFFF;filter:none;}#export-svg [data-look="neo"].node circle{stroke:#FFFFFF;filter:url(#drop-shadow);}#export-svg [data-look="neo"].node circle .state-start{fill:#000000;}#export-svg [data-look="neo"].statediagram-cluster rect{fill:#16141F;stroke:#FFFFFF;stroke-width:2;}#export-svg [data-look="nLine truncated
|
||||
|
After Width: | Height: | Size: 116 KiB |
@@ -0,0 +1,102 @@
|
||||
<svg id="export-svg" width="100%" xmlns="http://www.w3.org/2000/svg" style="max-width: 816px;" viewBox="-50 -10 816 1062" role="graphics-document document" aria-roledescription="sequence"><style xmlns="http://www.w3.org/1999/xhtml">/* Google Inc.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Recursive Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300 1000;
|
||||
src: url("data:font/woff2;base64,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 truncated
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
||||
}</style><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"); p {margin: 0;}</style><rect x="40" y="617" fill="rgb(255, 235, 235)" width="636" height="309" class="rect"/><rect x="40" y="346" fill="rgb(255, 245, 235)" width="636" height="261" class="rect"/><rect x="40" y="75" fill="rgb(235, 245, 255)" width="636" height="261" class="rect"/><g><rect x="566" y="946" fill="#eaeaea" stroke="#666" width="150" height="65" name="Geyser" rx="6" ry="6" class="actor actor-bottom" data-look="neo" style="stroke: rgb(45, 212, 191); fill: rgb(240, 253, 250);" filter="url(#drop-shadow)"/><text x="641" y="978.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="641" dy="0">Geyser</tspan></text></g><g><rect x="0" y="946" fill="#eaeaea" stroke="#666" width="150" height="65" name="Client" rx="6" ry="6" class="actor actor-bottom" data-look="neo" style="stroke: rgb(232, 121, 249); fill: rgb(253, 244, 255);" filter="url(#drop-shadow)"/><text x="75" y="978.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="75" dy="0">Client</tspan></text></g><g><line id="actor447" x1="641" y1="65" x2="641" y2="946" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="Geyser" data-et="life-line" data-id="Geyser"/><g id="root-447" data-look="neo" data-et="participant" data-id="Geyser"><rect x="566" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="Geyser" rx="6" ry="6" class="actor actor-top" data-look="neo" style="stroke: rgb(45, 212, 191); fill: rgb(240, 253, 250);" filter="url(#drop-shadow)"/><defs><filter id="drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs><text x="641" y="32.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="641" dy="0">Geyser</tspan></text></g></g><g><line id="actor446" x1="75" y1="65" x2="75" y2="946" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="Client" data-et="life-line" data-id="Client"/><g id="root-446" data-look="neo" data-et="participant" data-id="Client"><rect x="0" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="Client" rx="6" ry="6" class="actor actor-top" data-look="neo" style="stroke: rgb(232, 121, 249); fill: rgb(253, 244, 255);" filter="url(#drop-shadow)"/><defs><filter id="drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs><text x="75" y="32.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="75" dy="0">Client</tspan></text></g></g><style>#export-svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;fill:#28253D;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#export-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#export-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#export-svg .error-icon{fill:#ffffff;}#export-svg .error-text{fill:#000000;stroke:#000000;}#export-svg .edge-thickness-normal{stroke-width:2px;}#export-svg .edge-thickness-thick{stroke-width:3.5px;}#export-svg .edge-pattern-solid{stroke-dasharray:0;}#export-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#export-svg .edge-pattern-dashed{stroke-dasharray:3;}#export-svg .edge-pattern-dotted{stroke-dasharray:2;}#export-svg .marker{fill:#000000;stroke:#000000;}#export-svg .marker.cross{stroke:#000000;}#export-svg svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;}#export-svg p{margin:0;}#export-svg .actor{stroke:#28253D;fill:#ffffff;stroke-width:2;}#export-svg rect.actor.outer-path[data-look="neo"]{filter:url(#drop-shadow);}#export-svg rect.note[data-look="neo"]{stroke:#FACC15;fill:#fff5ad;filter:url(#drop-shadow);stroke-width:2;}#export-svg text.actor>tspan{fill:#28253D;stroke:none;}#export-svg .actor-line{stroke:#28253D;}#export-svg .messageLine0{stroke-width:2;stroke-dasharray:none;stroke:#28253D;}#export-svg .messageLine1{stroke-width:2;stroke-dasharray:2,2;stroke:#28253D;}#export-svg #arrowhead path{fill:#28253D;stroke:#28253D;}#export-svg .sequenceNumber{fill:#ffffff;}#export-svg #sequencenumber{fill:#28253D;}#export-svg #crosshead path{fill:#28253D;stroke:#28253D;}#export-svg .messageText{fill:#28253D;stroke:none;}#export-svg .labelBox{stroke:#28253D;fill:#ffffff;filter:url(#drop-shadow);}#export-svg .labelText,#export-svg .labelTexLine truncated
|
||||
|
After Width: | Height: | Size: 116 KiB |
@@ -0,0 +1,102 @@
|
||||
<svg id="export-svg" width="100%" xmlns="http://www.w3.org/2000/svg" style="max-width: 816px;" viewBox="-50 -10 816 1062" role="graphics-document document" aria-roledescription="sequence"><style xmlns="http://www.w3.org/1999/xhtml">/* Google Inc.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Recursive Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300 1000;
|
||||
src: url("data:font/woff2;base64,d09GMgABAAAAAPP4ABQAAAACC1AAAPOFAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoRTG+58HJRkP01WQVKBEAZgP1NUQVSBYic8AIUuL4EoEQgKgrlQgo1LC4UeADCEmGIBNgIkA4o0BCAFjXYHj1kMB1tP8XFBnDDsYOLjdY5tyxhP1ODemquETQc3Z3pudCVj86rVErZNi3i3Y//2nORI8v//eUljjLWdtR0QKKbl20eS7FRQsiY7ZVRRptH0yqJXr2OtTaO1imIUpLbm1BAmJ01DbFHubzrOejQ6IZzx4KbA1Nb6Uefj6wvCSyqOqh1aZFkSC39rci0YSByiIZTD9Lmpc/ssLQ7lUAp1xX3bL+ReBGUOlM2UwpgsYb4rXVD3N9ygMjLwLTR0RbefbwtNGV09EkQXTH6a43fHVcFbscQThc1CkeLzYWWPfl664n/SvbTyfERbWp/mYTAGF8MMsezJuSqinvr+PL/NP/e+ByIl2jMxhorIGBZzBhYywYlRhYWRMzC3Odbqyrlyrly331X8qHJRMsSf+nePyQv08poU8MCb1Ym/o8vf/AkqOLn14HaoBhZ/VRod9M/bwTtz7tsPM0nnCgYr1+kg7ABNZ9eYNHYxvag3aSoxb6NNzSk1aFEbBYbo5pjYrMjgmcPkYS5sAEW1H2/PvR/WqRgH5FgYQA1AlmWsi3LREYp2eFrO/1+zET/jurOz4tlNsjFSCpSaPzHlTvWratsrr70VBQp18CREB97N6qkxZmfiUD3Rzyf2J6LQVKhiFiAQCAlRIwmmNd+ZticmQ3PpQ0cltlNzGoWdApJ4Yf5PrwCI+XHuc8hCTagjwgLl2lfAhNvmz52UswKF28A71f93uM3WNCUY4UWmz8sPpnUHiMrbUgg7TgwoWxZYFgCbZTuOM19N7atqQIFlyYAJz8wngtNf5Ou/rtWKA0tw37dHQM5wgAwCbKm5AOEF76nYl4eXKzBy8nm5PFw5qZxUVsqRk/DjcA5z1vcqkNiSHQec5pl+ALxMh8tejrufkzR/hCsyDlHCtid1mrNaBQJTALFkxQWA8YGX+SdYCwwBOfrr9LnV/58rNm6ttCk0BIsbIUKMkMYamjadqak8W73av8XGfGtiX0SHoLj07MefPo1DzaKlNZD08WAAPZjVDQdRRN+nTp32af3/71Tv3fg9eyhwrAIalBKAIa6XOHA6d/UYpF/pFw2JQ05lDlIZ/fW//gegUPjju/kfmpN46/igTNSQXVG29ZmYfjkBOJeX9IF4QKxclRyQ8RNKjAB+f/igP4GRuSMuxLw7mrOMOiPuhVGt7dmkjBviTbjEM7MfATzP/9V4MJsLGH58bmXLjlm6LdTJaaE/Uf9/r7Pa6mNwCVxBQGMErq4CU+F/Gdv/Y6jeXnV056qeVDUpdsgr6ekLfQWwEIYSErhAUFUE2yUkcAkJbMDGY1O4QsiuTu5M568vgb+EcH1J4IQ9bXBVB3fVBHdKdqXYIeXd5LCs5cx2diGverYhbzdz9rNejf+fqn4tQP6QcvWbUvbmotyqA+68wQMxGIACRcoiFSk6JclR/oEzoGgQpKI35eqfrUKskuxNud+23abdogyxK7do1/9/XWmrq7sks4KT8B5H54S4NlBTBppm9KVZ7debv1qg2W+i8ZgntGwvnVkDVQEqXaYoPQGEqqOqS5mySlmlD/H405LeaGUpsPN8uHABSzqkXp9Pe09fvjRUm5OOWrvSUgAJwAE8/tdy2tv7vDvS2nhUYiRvUXFolLq2V9mUUlSrNnGAQ7jIYmw6gUaGIQb0/+VPq3pS0zby5xLQD5DJLFbZZlZzxn9izX/PGRnNq/3NzarGkIhKgCAiIrKOiGB3qM3Cm5XGzxUaRESChH/3pI/+0p4d2GXXqFEVFRUVeVF51f3c9xcHkzUpEghgH+yIkd3+Lfe+YUz9/pmA5prR3mpj4sCBDEFEREXh/jRfnK/O32461gAwSC3rkrdCRGt7syqiQCTkudtvgCDwBmBCutEiaGCscSCwBmhBy4a6Lu5unwSp27ihXF4RTFggjL6xMWdV7Dhy5sydkBdfEkvGS6tFSIeKJBdFQSVeigxZshQopVYz1gjRANEE0QLR8Q7RQ4ugT//MoKHxahGs2RHSEUMsxGEilZmM5CoC6aqKUCMfSyyxVLBeEcpGcnugb4BGAgbADngZAot4gL7j6pPl4OP1RAH85v/br9MFUVU7/aO57Pth2Eraz9pVhiqMIuXInUsJNpa8nNZWYGWtDg4Kjjnhm3ZcEimkOLNJFVZSd4H+z14AoAcIHTbifnFeQJAwfpXX0WNxAIq2kKGqEM/Dcmav7WGJuht3u1J6S8/bO/7Gr4OqHoYbT0IaQLzOmctIFbxaKcQsslTwZcRKMsVY3aZwNFnUZzQ9iAvYdB5dxJKwIS68RiegCVRipdyrUOhtJWVl1RNOqkioAiwBeD/dANKmmWACn/kTgY6bInjNtZUJwD5wN40a2JAAgF6PVIDnzpoD9qpVg8Syy8B9Xm63ATMAJHQY/7lAJNHB/1Wr0DDM/4VkY7T85uKRxUrRZ0aT5i8KVwnlAq17h3uSu5PzmrIBuDA08NiLgQ4ewYUEjA/DFwniBp6RANCp617/MoqgnIoNwMfNXqmaMzrpXbKUh0h50wN3wjwgyMvu/IatSIg3KvxzKAOaSnbKe64gmwOO+FAjF9SjIFo+xiRPiupwMRuJmnnNOoqda1EBloMIOslL6DRfTwklqbNx4jLbCT2r/0dk3UMbYu3u6MDmFWexmsOhmOjeOQ1RItmBzWEcsBJEd79r7wpgu/uI5UBG/WpeI1ckCnpqd/IzfwfV1jH+Fh8agy9tBuSaPl/S2LZjjSe71gUTbKPt2bQE7eI0tgYwjYxDEZd1lnWzmTIBituQ6RYvUTsDI09Fqko7dIayzIEPRs3AztEnBbTg/kfOCIstCgxkmX0afxgHnbK9y8CoSygZ52lyqHWRrjc9ALxz3h0x/Lmv9DMiRzQTiXE/ZMcBr2OHMEUqi8dQMzNuwoKopP7zMBE360CYthwnT0opyDnWxxEIA4izAf2Ox9UDTRbumA1P/utnORf9Lt4e7ye1OMAzoi8M3ZgHd5tnpdKKyvYjCzpnEE20QFfQWAqCCfgEeDrBIH7Sr7nk2eNrXupe0peiyXvODexYpqyJESZHaUEKdo1ZE7uaI/TVh6YZN4hlqjh9RLIiW3AQzzBYQ1sfdVPpmxnrTZOINrG736WxCOhMr+AR5IL/B4CUBymQT3y03gtQNKm35jph/ojo1unboTnM0hhF3Jw7tQgtyzzLDKVMyrtjyvphgIDGlOGzZj7m4mClNPP5ek76nhB3fygrJU2OzQNLOAUioJ5JDrrljwhbRiLiM7YYZOu6LMZbI3vyshYgxx/4mG53ceaI2J0uf8R9Ta26hiXblmjR4cW4YvZAu79S5GkdG8jq1nOwLLKnsRWtTpLbaEDt8zWmQKZmrOi2Vmcf5nFJ5rZU4JVB7DaOd1n0VHCwLVSlsjTj7olR+mta8fHMQ6k2heh2/mfBDQefmDNvSwkEKiiHIt0ynio8NzvqpBantxXOZqeLbjC4lZvMKLbZ/d12T7y5uv1Cld1+xkH/V0a98NaYeXo42W8LE1nyg1056GB3/ga59OShvJNCBXcfi1FgwIR3FFiwITDCvI4tQGB5a8+KHdO8c2AIl8Zx7GS3ztwQuIMCH4EHCgJmPNOGkJgR3mnHlx9zEgsswcQfhaUIAhgSxJDgJJCSIYmssZGLglGIQUX1sBWLIy7ZxEuBSMUmrUYnXSYaWfJhCh40CmGK0ChmrCStlapkgJqJKpaq01WNOiY0rNRj05AkjZpgmpNNi1aINnTa5/j50XgFGHQ+OujSjatzYzEgLRxzAotTXJzh7FzdyUWXLHTZNRKuezwe34SM22R8lK5mFRPcJ3hC8JSEZzvBFz5x+EoViS2weNkEZFAirOdvYmuOTl5Z89bhIuWQuu4cbN0uAdZdHVSFTw5OhvBkRVqfZ2lbvbSvDmj6W4GBwZbDJHcOyzxH4JrX8LY9wB6sCj7tqrDB5BuOXVhGZzhAUVECCATbUQhUmQcU4JsPgcCXgtCngkjkFiQqNh+R5JFOPlElMdgk0kBmMwMu3QWBIqkrEoAuR4AGUQQVCaeExStiMlGwHYA2HLErklhEMlkUkUyQAsA3TQW01ZTJmuF2DsDZizKyyS7hgZwtaj+hUhSBGuKE7S3A503wgTKyySaObOKA159WqTSZ8h/iySCdowQqGwIqIGxFNOEsFoy9VhQRRjJZFJEsoI9F0mq/O3oRgAAA3OePgztviUvACRPbwMJ0lJuUs5TDjfdS1lPWUhaO9GGok15zr72GtJo0hRgkuid1osC8aQYWwjSh+ipcW/cSKm6PNxDyfPVmK/jH+K1jjtfiX8AvxW/F2/GY8D1wD+AO4taTVsMybi1uyYWfEM8sAZcQCEEQRUvpp3EN5qbnpNgnXN0Hb96OXYkdwmYfxjUoadkpBtrTNOY7n7sBJTWfLvJX5MNaoJHKI9+o9DORD5AeK2h/NU39V9W5lICuNcylz/uZzEWXoUuj/0YuYOkBRTkDBWFRbYXLhPNUeCMvy/AodAs0b6ne2JaGyEa2sR2JtsR6Y5a3eeQNyz9RZg/38Qi3chvPYI8Vstd6b3wkdx1MF2yQK65Uf4arxzRbrHAdCg+nHBcnZ0+Tc+x8uSAuuuRyueK6Kk5Fij3Ni2le5bwmb1CeilCpSrMWRq1MbPB0IMBq44ScwIMnL958+PLXCepZm9syW/dfmrjz3wx+bR225pprrrnmqm7m/rO5Qil1GN+Pg2xMBJxoZmYiIlJiYmZmZmbe2yykCc4F5ycE4MHNRQCAmbkxgwEAAIBj4Pem3Vjj9Y3aZMKWQSOQTuwT+HFzERHhJucutci2/4PTETsriWkClmLj4OLhf4dcTa2pLine truncated
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
||||
}</style><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"); p {margin: 0;}</style><rect x="40" y="617" fill="rgb(1, 50, 50)" width="636" height="309" class="rect"/><rect x="40" y="346" fill="rgb(1, 25, 50)" width="636" height="261" class="rect"/><rect x="40" y="75" fill="rgb(1, 1, 50)" width="636" height="261" class="rect"/><g><rect x="566" y="946" fill="#eaeaea" stroke="#666" width="150" height="65" name="Geyser" rx="6" ry="6" class="actor actor-bottom" data-look="neo" style="stroke: rgb(45, 212, 191);" filter="url(#drop-shadow)"/><text x="641" y="978.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="641" dy="0">Geyser</tspan></text></g><g><rect x="0" y="946" fill="#eaeaea" stroke="#666" width="150" height="65" name="Client" rx="6" ry="6" class="actor actor-bottom" data-look="neo" style="stroke: rgb(232, 121, 249);" filter="url(#drop-shadow)"/><text x="75" y="978.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="75" dy="0">Client</tspan></text></g><g><line id="actor473" x1="641" y1="65" x2="641" y2="946" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="Geyser" data-et="life-line" data-id="Geyser"/><g id="root-473" data-look="neo" data-et="participant" data-id="Geyser"><rect x="566" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="Geyser" rx="6" ry="6" class="actor actor-top" data-look="neo" style="stroke: rgb(45, 212, 191);" filter="url(#drop-shadow)"/><defs><filter id="drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#FFFFFF"/></filter></defs><text x="641" y="32.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="641" dy="0">Geyser</tspan></text></g></g><g><line id="actor472" x1="75" y1="65" x2="75" y2="946" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="Client" data-et="life-line" data-id="Client"/><g id="root-472" data-look="neo" data-et="participant" data-id="Client"><rect x="0" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="Client" rx="6" ry="6" class="actor actor-top" data-look="neo" style="stroke: rgb(232, 121, 249);" filter="url(#drop-shadow)"/><defs><filter id="drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#FFFFFF"/></filter></defs><text x="75" y="32.5" style="text-anchor: middle; font-size: 16px; font-weight: 400;" dominant-baseline="central" alignment-baseline="central" class="actor actor-box"><tspan x="75" dy="0">Client</tspan></text></g></g><style>#export-svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#export-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#export-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#export-svg .error-icon{fill:hsl(20, 1.5873015873%, 12.3529411765%);}#export-svg .error-text{fill:rgb(222.9999999999, 223.6666666666, 223.9999999999);stroke:rgb(222.9999999999, 223.6666666666, 223.9999999999);}#export-svg .edge-thickness-normal{stroke-width:2px;}#export-svg .edge-thickness-thick{stroke-width:3.5px;}#export-svg .edge-pattern-solid{stroke-dasharray:0;}#export-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#export-svg .edge-pattern-dashed{stroke-dasharray:3;}#export-svg .edge-pattern-dotted{stroke-dasharray:2;}#export-svg .marker{fill:#cccccc;stroke:#cccccc;}#export-svg .marker.cross{stroke:#cccccc;}#export-svg svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;}#export-svg p{margin:0;}#export-svg .actor{stroke:#FFFFFF;fill:#111113;stroke-width:2;}#export-svg rect.actor.outer-path[data-look="neo"]{filter:url(#drop-shadow);}#export-svg rect.note[data-look="neo"]{stroke:#FACC15;fill:#FEF9C3;filter:url(#drop-shadow);stroke-width:2;}#export-svg text.actor>tspan{fill:#e0dfdf;stroke:none;}#export-svg .actor-line{stroke:#FFFFFF;}#export-svg .messageLine0{stroke-width:2;stroke-dasharray:none;stroke:#FFFFFF;}#export-svg .messageLine1{stroke-width:2;stroke-dasharray:2,2;stroke:#FFFFFF;}#export-svg #arrowhead path{fill:#FFFFFF;stroke:#FFFFFF;}#export-svg .sequenceNumber{fill:#333333;}#export-svg #sequencenumber{fill:#FFFFFF;}#export-svg #crosshead path{fill:#FFFFFF;stroke:#FFFFFF;}#export-svg .messageText{fill:#ccc;stroke:none;}#export-svg .labelBox{stroke:#BDBCCC;fill:#111113;filter:url(#drop-shadow);}#export-svg .labelText,#export-svg .labelText>Line truncated
|
||||
|
After Width: | Height: | Size: 116 KiB |
@@ -0,0 +1,102 @@
|
||||
<svg id="export-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="classDiagram" style="max-width: 1155.88330078125px;" viewBox="0 0 1155.88330078125 1208" role="graphics-document document" aria-roledescription="class"><style xmlns="http://www.w3.org/1999/xhtml">/* Google Inc.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Recursive Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300 1000;
|
||||
src: url("data:font/woff2;base64,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 truncated
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
||||
}</style><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"); p {margin: 0;}</style><style>#export-svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;fill:#28253D;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#export-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#export-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#export-svg .error-icon{fill:#ffffff;}#export-svg .error-text{fill:#000000;stroke:#000000;}#export-svg .edge-thickness-normal{stroke-width:2px;}#export-svg .edge-thickness-thick{stroke-width:3.5px;}#export-svg .edge-pattern-solid{stroke-dasharray:0;}#export-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#export-svg .edge-pattern-dashed{stroke-dasharray:3;}#export-svg .edge-pattern-dotted{stroke-dasharray:2;}#export-svg .marker{fill:#000000;stroke:#000000;}#export-svg .marker.cross{stroke:#000000;}#export-svg svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;}#export-svg p{margin:0;}#export-svg g.classGroup text{fill:#28253D;stroke:none;font-family:"Recursive Variable",arial,sans-serif;font-size:10px;}#export-svg g.classGroup text .title{font-weight:bolder;}#export-svg .nodeLabel,#export-svg .edgeLabel{color:#28253D;}#export-svg .noteLabel .nodeLabel,#export-svg .noteLabel .edgeLabel{color:#28253D;}#export-svg .edgeLabel .label rect{fill:#ffffff;}#export-svg .label text{fill:#28253D;}#export-svg .labelBkg{background:#ffffff;}#export-svg .edgeLabel .label span{background:#ffffff;}#export-svg .classTitle{font-weight:bolder;}#export-svg .node rect,#export-svg .node circle,#export-svg .node ellipse,#export-svg .node polygon,#export-svg .node path{fill:#ffffff;stroke:#28253D;stroke-width:2;}#export-svg .divider{stroke:#28253D;stroke-width:1;}#export-svg g.clickable{cursor:pointer;}#export-svg g.classGroup rect{fill:#ffffff;stroke:#28253D;}#export-svg g.classGroup line{stroke:#28253D;stroke-width:1;}#export-svg .classLabel .box{stroke:none;stroke-width:0;fill:#ffffff;opacity:0.5;}#export-svg .classLabel .label{fill:#28253D;font-size:10px;}#export-svg .relation{stroke:#000000;stroke-width:2;fill:none;}#export-svg .dashed-line{stroke-dasharray:3;}#export-svg .dotted-line{stroke-dasharray:1 2;}#export-svg #compositionStart,#export-svg .composition{fill:#000000!important;stroke:#000000!important;stroke-width:1;}#export-svg #compositionEnd,#export-svg .composition{fill:#000000!important;stroke:#000000!important;stroke-width:1;}#export-svg #dependencyStart,#export-svg .dependency{fill:#000000!important;stroke:#000000!important;stroke-width:1;}#export-svg #dependencyStart,#export-svg .dependency{fill:#000000!important;stroke:#000000!important;stroke-width:1;}#export-svg #extensionStart,#export-svg .extension{fill:transparent!important;stroke:#000000!important;stroke-width:1;}#export-svg #extensionEnd,#export-svg .extension{fill:transparent!important;stroke:#000000!important;stroke-width:1;}#export-svg #aggregationStart,#export-svg .aggregation{fill:transparent!important;stroke:#000000!important;stroke-width:1;}#export-svg #aggregationEnd,#export-svg .aggregation{fill:transparent!important;stroke:#000000!important;stroke-width:1;}#export-svg #lollipopStart,#export-svg .lollipop{fill:#ffffff!important;stroke:#000000!important;stroke-width:1;}#export-svg #lollipopEnd,#export-svg .lollipop{fill:#ffffff!important;stroke:#000000!important;stroke-width:1;}#export-svg .edgeTerminals{font-size:11px;line-height:initial;}#export-svg .classTitleText{text-anchor:middle;font-size:18px;fill:#28253D;}#export-svg .edgeLabel{background-color:hsl(-120, 0%, 80%);text-align:center;}#export-svg .edgeLabel p{background-color:hsl(-120, 0%, 80%);}#export-svg .edgeLabel rect{opacity:0.5;background-color:hsl(-120, 0%, 80%);fill:hsl(-120, 0%, 80%);}#export-svg .cluster rect{fill:#F9F9FB;stroke:#BDBCCC;stroke-width:2px;}#export-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#export-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#export-svg .node .neo-node{stroke:#28253D;}#export-svg [data-look="neo"].node rect,#export-svg [data-look="neo"].cluster rect,#export-svg [data-look="neo"].node polygon{stroke:#28253D;filter:url(#drop-shadow);}#export-svg [data-look="neo"].node path{stroke:#28253D;stroke-width:2;}#export-svg [data-look="neo"].node .outer-path{filter:url(#drop-shadow);}#export-svg [data-look="neo"].node .neo-line path{stroke:#28253D;filter:none;}#export-svg [data-look="neo"].node circle{stroke:#28253D;filter:url(#drop-shadow);}#export-svg [data-look="neo"].node circle .state-start{fill:#000000;}#export-svg [data-look="neo"].statediagram-cluster rect{fill:#F9F9FB;stroke:#28253D;stroke-width:2;}#export-svLine truncated
|
||||
|
After Width: | Height: | Size: 135 KiB |
@@ -0,0 +1,102 @@
|
||||
<svg id="export-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="classDiagram" style="max-width: 1155.88px;" viewBox="0 0 1155.88330078125 1208" role="graphics-document document" aria-roledescription="class"><style xmlns="http://www.w3.org/1999/xhtml">/* Google Inc.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'Recursive Variable';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300 1000;
|
||||
src: url("data:font/woff2;base64,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 truncated
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
||||
}</style><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"); p {margin: 0;}</style><style>#export-svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#export-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#export-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#export-svg .error-icon{fill:hsl(20, 1.5873015873%, 12.3529411765%);}#export-svg .error-text{fill:rgb(222.9999999999, 223.6666666666, 223.9999999999);stroke:rgb(222.9999999999, 223.6666666666, 223.9999999999);}#export-svg .edge-thickness-normal{stroke-width:2px;}#export-svg .edge-thickness-thick{stroke-width:3.5px;}#export-svg .edge-pattern-solid{stroke-dasharray:0;}#export-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#export-svg .edge-pattern-dashed{stroke-dasharray:3;}#export-svg .edge-pattern-dotted{stroke-dasharray:2;}#export-svg .marker{fill:#cccccc;stroke:#cccccc;}#export-svg .marker.cross{stroke:#cccccc;}#export-svg svg{font-family:"Recursive Variable",arial,sans-serif;font-size:14px;}#export-svg p{margin:0;}#export-svg g.classGroup text{fill:#FFFFFF;stroke:none;font-family:"Recursive Variable",arial,sans-serif;font-size:10px;}#export-svg g.classGroup text .title{font-weight:bolder;}#export-svg .nodeLabel,#export-svg .edgeLabel{color:#ccc;}#export-svg .noteLabel .nodeLabel,#export-svg .noteLabel .edgeLabel{color:#28253D;}#export-svg .edgeLabel .label rect{fill:#111113;}#export-svg .label text{fill:#ccc;}#export-svg .labelBkg{background:#111113;}#export-svg .edgeLabel .label span{background:#111113;}#export-svg .classTitle{font-weight:bolder;}#export-svg .node rect,#export-svg .node circle,#export-svg .node ellipse,#export-svg .node polygon,#export-svg .node path{fill:#111113;stroke:#FFFFFF;stroke-width:2;}#export-svg .divider{stroke:#FFFFFF;stroke-width:1;}#export-svg g.clickable{cursor:pointer;}#export-svg g.classGroup rect{fill:#111113;stroke:#FFFFFF;}#export-svg g.classGroup line{stroke:#FFFFFF;stroke-width:1;}#export-svg .classLabel .box{stroke:none;stroke-width:0;fill:#111113;opacity:0.5;}#export-svg .classLabel .label{fill:#FFFFFF;font-size:10px;}#export-svg .relation{stroke:#cccccc;stroke-width:2;fill:none;}#export-svg .dashed-line{stroke-dasharray:3;}#export-svg .dotted-line{stroke-dasharray:1 2;}#export-svg #compositionStart,#export-svg .composition{fill:#cccccc!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #compositionEnd,#export-svg .composition{fill:#cccccc!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #dependencyStart,#export-svg .dependency{fill:#cccccc!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #dependencyStart,#export-svg .dependency{fill:#cccccc!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #extensionStart,#export-svg .extension{fill:transparent!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #extensionEnd,#export-svg .extension{fill:transparent!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #aggregationStart,#export-svg .aggregation{fill:transparent!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #aggregationEnd,#export-svg .aggregation{fill:transparent!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #lollipopStart,#export-svg .lollipop{fill:#111113!important;stroke:#cccccc!important;stroke-width:1;}#export-svg #lollipopEnd,#export-svg .lollipop{fill:#111113!important;stroke:#cccccc!important;stroke-width:1;}#export-svg .edgeTerminals{font-size:11px;line-height:initial;}#export-svg .classTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#export-svg .edgeLabel{background-color:hsl(180, 1.5873015873%, 28.3529411765%);text-align:center;}#export-svg .edgeLabel p{background-color:hsl(180, 1.5873015873%, 28.3529411765%);}#export-svg .edgeLabel rect{opacity:0.5;background-color:hsl(180, 1.5873015873%, 28.3529411765%);fill:hsl(180, 1.5873015873%, 28.3529411765%);}#export-svg .cluster rect{fill:#1E1A2E;stroke:#BDBCCC;stroke-width:2px;}#export-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#export-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#export-svg .node .neo-node{stroke:#FFFFFF;}#export-svg [data-look="neo"].node rect,#export-svg [data-look="neo"].cluster rect,#export-svg [data-look="neo"].node polygon{stroke:#FFFFFF;filter:url(#drop-shadow);}#export-svg [data-look="neo"].node path{stroke:#FFFFFF;stroke-width:2;}#export-svg [data-look="neo"].node .outer-path{filter:url(#drop-shadow);}#export-svg [data-look="neo"].node .neo-line path{stroke:#FFFFFF;filter:none;}#export-svg [data-look="neo"].node circle{stroke:#FFFFFF;filter:url(#drLine truncated
|
||||
|
After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 237 KiB |
|
Before Width: | Height: | Size: 217 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 193 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 339 KiB |
|
Before Width: | Height: | Size: 250 KiB |
@@ -1,12 +1,13 @@
|
||||
{
|
||||
// This file is not used in compilation. It is here just for a nice editor experience.
|
||||
"extends": "@docusaurus/tsconfig",
|
||||
"esModuleInterop": true,
|
||||
"compilerOptions": {
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||
"target": "ESNext",
|
||||
"baseUrl": "."
|
||||
},
|
||||
"exclude": [
|
||||
"**/node_modules"
|
||||
"**/node_modules",
|
||||
"build",
|
||||
]
|
||||
}
|
||||
@@ -6,7 +6,7 @@ description: 'These REST APIs provide web endpoints to query different informati
|
||||
|
||||
import DocCardList from '@theme/DocCardList'
|
||||
|
||||
# Overview of available REST APIs
|
||||
# Overview of available REST APIs \{#overview-of-available-rest-apis}
|
||||
|
||||
Currently, there are two different Rest APIs you can use.
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ description: 'Floodgate is a hybrid mode plugin that allows Minecraft: Bedrock A
|
||||
---
|
||||
|
||||
# Overview
|
||||
Floodgate is a hybrid mode plugin. It introduces new features:
|
||||
- Ability to join Minecraft: Java Edition servers with Minecraft: Bedrock accounts without needing a paid Minecraft: Java Edition account.
|
||||
Floodgate is a hybrid mode server-plugin. It introduces new features:
|
||||
- Ability for clients to join Minecraft: Java Edition servers with Minecraft: Bedrock accounts without needing a paid Minecraft: Java Edition account.
|
||||
- Ability to [see Bedrock player skins on Java edition](/wiki/floodgate/features#what-is-skin-uploading).
|
||||
- Ability for plugins to [send Bedrock forms](/wiki/geyser/forms/).
|
||||
- Ability to query players through the [Global Api](/wiki/api/api.geysermc.org/global-api/),
|
||||
|
||||
@@ -45,7 +45,7 @@ Set `allow-invalid-usernames` to `true` in LuckPerms' config.
|
||||
|
||||
## Failed to verify username! (with Paper) {#failed-to-verify-username-with-paper}
|
||||
|
||||
To completely mitigate this issue, disable `perform-username-validation` in the [unsupported settings of the `config/paper-global.yml` file](https://paper.readthedocs.io/en/latest/server/configuration.html#unsupported_settings) (`paper.yml` in the root server folder on servers below 1.19). Using Floodgate on the backend servers will also mitigate this issue.
|
||||
To completely mitigate this issue, disable `perform-username-validation` in the [unsupported settings of the `config/paper-global.yml` file](https://docs.papermc.io/paper/reference/global-configuration#unsupported_settings) (`paper.yml` in the root server folder on servers below 1.19). Using Floodgate on the backend servers will also mitigate this issue.
|
||||
|
||||
## Error with Forge or Fabric Bukkit Hybrid {#error-with-forge-or-fabric-bukkit-hybrid}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ You can also set up a local linking database on your server. Local linking can w
|
||||
|
||||
Note that you only have to follow these steps on your proxy (BungeeCord or Velocity), if you have one.
|
||||
|
||||
1. Download one of the linking databases extensions [here](https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/fix-weird-via-issue/).
|
||||
1. Download one of the linking databases extensions [here](https://geysermc.org/download?project=other-projects&floodgatedb=expanded).
|
||||
If you need help picking the right one: choose `mysql` if you already have a database or want to have a multi-proxy setup. For anything else choose `sqlite`. The full name should be `floodgate-*type*-database.jar`.
|
||||
2. Copy the database extension jar you just downloaded *into* the floodgate 2.0 plugin folder (e.g. `/plugins/floodgate/`).
|
||||
3. Enable `enable-own-linking` in the `player-link` section of Floodgate.
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Learn how to set up Floodgate on your Paper or Spigot server.
|
||||
hide_title: true
|
||||
---
|
||||
|
||||
1. Download Floodgate-Spigot from the [download page](https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/latest/downloads/spigot).
|
||||
1. Download Floodgate-Spigot from the [download page](/download/?project=floodgate).
|
||||
2. Place the Floodgate-Spigot.jar in the `plugins` folder, and restart the server.
|
||||
3. Change `auth-type` in Geyser's config to `floodgate`.
|
||||
4. Restart the server.
|
||||
@@ -9,12 +9,12 @@ You only need to install Floodgate on the BungeeCord or Velocity proxy server, u
|
||||
Additionally, it will display Bedrock edition skins properly.
|
||||
:::
|
||||
|
||||
1. Download Floodgate for your proxy software from the [download page](https://geysermc.org/download#floodgate).
|
||||
1. Download Floodgate for your proxy software from the [download page](/download/?project=floodgate).
|
||||
2. Place the Floodgate jar in the `plugins` folder, and restart the proxy server.
|
||||
3. Change `auth-type` in Geyser's config to `floodgate`.
|
||||
4. Restart the server.
|
||||
|
||||
### Installing Floodgate on servers behind the proxy {#installing-floodgate-on-servers-behind-the-proxy}
|
||||
### Installing Floodgate on servers behind the proxy \{#installing-floodgate-on-servers-behind-the-proxy}
|
||||
|
||||
This is only needed when you want to use the Floodgate API on your backend server(s) behind a proxy.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ hide_title: true
|
||||
To be able to use Floodgate authentication, you need to be able to install Floodgate on the Java server you are connecting to.
|
||||
:::
|
||||
|
||||
1. Download and install the platform-specific Floodgate jar (e.g. floodgate-spigot, or floodgate-fabric) [here](https://geysermc.org/download#floodgate).
|
||||
1. Download and install the platform-specific Floodgate jar (e.g. floodgate-spigot, or floodgate-fabric) [here](/download/?project=floodgate).
|
||||
See the platform setup instructions for a detailed, platform specific setup guide. Then, continue with the instructions below.
|
||||
2. Change `auth-type` in Geyser Standalone's config to `floodgate`.
|
||||
3. Copy the `key.pem` file in the Floodgate config folder to the same directory as Geyser Standalone.
|
||||
|
||||
@@ -8,7 +8,7 @@ hide_title: true
|
||||
To be able to use Floodgate authentication, you need to be able to install Floodgate on the Java server you are connecting to.
|
||||
:::
|
||||
|
||||
1. Download and install the platform-specific Floodgate jar (e.g. floodgate-spigot, or floodgate-fabric) [here](https://geysermc.org/download#floodgate).
|
||||
1. Download and install the platform-specific Floodgate jar (e.g. floodgate-spigot, or floodgate-fabric) [here](/download/?project=floodgate).
|
||||
See the platform setup instructions for a detailed, platform specific setup guide. Then, continue with the instructions below.
|
||||
2. Copy the `key.pem` file in the Floodgate config folder to the `/plugins/Geyser/´ directory.
|
||||
3. Restart ViaProxy.
|
||||
|
||||
@@ -14,14 +14,12 @@ This is a community-compiled list and does not indicate any endorsement from Gey
|
||||
|
||||
Full Compatibility (Checks Bedrock Players Accurately)
|
||||
|
||||
- [AntiAura](https://www.spigotmc.org/resources/1368/) (Paid) - Last checked on 24th January 2023
|
||||
- [LightAntiCheat](https://modrinth.com/plugin/lightanticheat) - Last checked on 19rd July 2024
|
||||
- [Spartan: Bedrock Edition](https://builtbybit.com/resources/12832/) (Paid) - Last checked on 18th July 2024
|
||||
- [Boar](https://modrinth.com/plugin/boar) - Last checked on 13th March 2026
|
||||
- [Themis](https://www.spigotmc.org/resources/90766/) - Last checked on 11th July 2024
|
||||
|
||||
Partially Compatible (Does not Check/Ignores Bedrock Players)
|
||||
|
||||
- [GrimAC](https://github.com/MWHunter/Grim) - Last checked on 30th June 2024
|
||||
- [GrimAC](https://github.com/GrimAnticheat/Grim) - Last checked on 8th November 2024
|
||||
- [Intave](https://intave.ac) (Paid) Requires [GeyserMC addon](https://github.com/intave/bedrock) - Last checked on 2nd July 2024
|
||||
- [Matrix](https://matrix.rip/) (Paid) - Last checked on 23rd July 2024
|
||||
- [Spartan: Java Edition](https://www.spigotmc.org/resources/25638/) (Paid) - Last checked on 18th July 2024
|
||||
|
||||
@@ -97,7 +97,7 @@ The skin package contains some records representing skin data. If you want to ch
|
||||
|
||||
#### [Pack](https://github.com/GeyserMC/Geyser/tree/master/api/src/main/java/org/geysermc/geyser/api/pack) {#pack}
|
||||
The pack package contains classes and interfaces related to resource packs in Geyser. You can create custom resource packs and send them to individual sessions before they log in using the [SessionLoadResourcePacksEvent](https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionLoadResourcePacksEvent.java).
|
||||
If you wish to send a resource pack to all sessions, you can use the [GeyserLoadResourcePacksEvent](https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserLoadResourcePacksEvent.java).
|
||||
If you wish to send a resource pack to all sessions, you can use the [GeyserDefineResourcePacksEvent](https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineResourcePacksEvent.java).
|
||||
|
||||
Packs can be created using a [PackCodec](https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/pack/PackCodec.java), such as the provided [PathPackCodec](https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/pack/PathPackCodec.java).
|
||||
This allows you to load a Bedrock resource pack from a file path:
|
||||
|
||||
@@ -31,6 +31,9 @@ on the proxy server to assign permissions to players. Assigning permissions on t
|
||||
| `geyser version` | `geyser.command.version` | Shows the current Geyser version and checks for updates. |
|
||||
| `geyser tooltips` | `geyser.command.tooltips` | Toggle showing Advanced Tooltips (F3 + H on Java) |
|
||||
| `geyser extensions` | `geyser.command.extensions` | Lists all currently loaded extensions. This command is only registered if any extensions are loaded. |
|
||||
| `geyser ping` | `geyser.command.ping` | Shows the ping between the player and the Geyser instance. |
|
||||
| `geyser options` | `geyser.command.options` | Opens the "pause screen additions" dialogue, if sent by the Java server |
|
||||
| `geyser quickactions` | `geyser.command.quickactions` | Opens the "quick actions" dialogue, if sent by the Java server. |
|
||||
|
||||
## Permissions for Geyser extensions {#extension-permissions}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ If you still can't make it work, join [our Discord](https://discord.gg/geysermc)
|
||||
For Floodgate issues see: [Floodgate: Known Issues/Caveats](/wiki/floodgate/issues/).
|
||||
|
||||
# I can't connect! (Either the server doesn't show up in the friends list or I get "Unable to connect to world")
|
||||
* If you don't use a reverse proxy such as TCPShield make sure that `enable-proxy-protocol` is set to false.
|
||||
* If you don't use a reverse proxy such as TCPShield make sure that `advanced.java.use-haproxy-protocol` is set to false.
|
||||
To fix "Unable to connect to world" with no console errors, see [here](/wiki/geyser/fixing-unable-to-connect-to-world/).
|
||||
|
||||
## If the server doesn't show up in the friends list {#if-the-server-doesnt-show-up-in-the-friends-list}
|
||||
@@ -35,9 +35,9 @@ See [here](/wiki/geyser/fixing-unable-to-connect-to-world/) for fixing "Unable t
|
||||
### `java.net.BindException: Address already in use: bind` on startup. {#javanetbindexception-address-already-in-use-bind-on-startup}
|
||||
This means something (likely another instance of Geyser) is running on the port you have specified in the config. Please make sure you close all applications running on this port. If you don't recall opening anything, usually restarting your computer fixes this.
|
||||
|
||||
### [...]` has been compiled by a more recent version of the Java Runtime (class file version 60.0)` {#-has-been-compiled-by-a-more-recent-version-of-the-java-runtime-class-file-version-600}
|
||||
### [...]` has been compiled by a more recent version of the Java Runtime (class file version 65.0)` {#-has-been-compiled-by-a-more-recent-version-of-the-java-runtime}
|
||||
|
||||
See this link for updating to Java 17: https://paper.readthedocs.io/en/latest/java-update/index.html.
|
||||
See this link for updating to Java 21: https://docs.papermc.io/misc/java-install.
|
||||
|
||||
### Hosting provider will not immediately open up UDP. {#hosting-provider-will-not-immediately-open-up-udp}
|
||||
|
||||
@@ -51,7 +51,7 @@ One way to get around this (if you're using an online host) is to shut down your
|
||||
|
||||
You may need to update your Java version. If so, update at [Adoptium.net](https://adoptium.net/).
|
||||
|
||||
Sometimes this happens in poor-network environments. There is an `mtu` option in the Geyser config; lower this number slowly (in batches of 100), restart each time, and re-test joining.
|
||||
Sometimes this happens in poor-network environments. There is an `advanced.bedrock.mtu` option in the Geyser config; lower this number slowly (in batches of 100), restart each time, and re-test joining.
|
||||
|
||||
This option will most likely not help if you are getting "Unable to Connect to World" with no console logs indicating a connection.
|
||||
|
||||
@@ -76,8 +76,6 @@ If you have your configuration set up like this, put simply, it won't work. If a
|
||||
Connection Refused usually means that a Java server could not be found on that port, or the server denied access to the connection on a network level.
|
||||
The latter can happen with anti-DDOS plugins such as TCPShield, but otherwise ensure that the server you're trying to connect to is spelled correctly in the config, is up and is port forwarded correctly.
|
||||
|
||||
If you're updating from an old build of Geyser, set your remote address to `auto` and try again.
|
||||
|
||||
### Floodgate Misconfiguration {#floodgate-misconfiguration}
|
||||
See [this page](/wiki/floodgate/setup/) for more information.
|
||||
|
||||
@@ -99,9 +97,9 @@ It has other benefits too. Here's a plugin that can just do that:
|
||||
[CommandWhitelist](https://www.spigotmc.org/resources/81326/). Alternatively, use the [HideCommands](https://github.com/Redned235/HideCommands) Geyser extension to hide commands just for Bedrock players.
|
||||
|
||||
# Failed to load locale asset cache: Unrecognized token 'Cannot'
|
||||
This or anything else related to failing to download a locale file on startup is usually caused by java trying to connect using IPv6 and Mojadng only use IPv4, so start Geyser or the server up with this flag `-Djava.net.preferIPv4Stack=true`, EG: `java -Xms1024M -Djava.net.preferIPv4Stack=true -jar Geyser.jar`
|
||||
This or anything else related to failing to download a locale file on startup is usually caused by java trying to connect using IPv6 and Mojang only use IPv4, so start Geyser or the server up with this flag `-Djava.net.preferIPv4Stack=true`, EG: `java -Xms1024M -Djava.net.preferIPv4Stack=true -jar Geyser.jar`
|
||||
|
||||
# Outdated client! Please use 1.x.x
|
||||
# Outdated client! Please use 1.x.x
|
||||
|
||||
The server is too new or Geyser is outdated. Make sure you're on the latest Geyser.
|
||||
|
||||
@@ -109,12 +107,6 @@ The server is too new or Geyser is outdated. Make sure you're on the latest Geys
|
||||
|
||||
Update the server or ask them to install [ViaVersion](https://viaversion.com/). You can also try [VIAaaS](https://github.com/ViaVersion/VIAaaS) (ViaVersion as a Service).
|
||||
|
||||
# Query: Incorrect Magic!
|
||||
|
||||
See here: https://www.spigotmc.org/threads/query-incorrect-magic-and-high-cpu-usage.159386/#post-2709057
|
||||
|
||||
* If you don't use a reverse proxy such as TCPShield make sure that `enable-proxy-protocol` is set to false.
|
||||
|
||||
# Only for BungeeCord with floodgate
|
||||
|
||||
If you use floodgate ensure that it is installed on all of your Spigot backend servers as following:
|
||||
@@ -129,6 +121,3 @@ And so on.
|
||||
* Please also make sure that you have the same `key.pem` and `config.yml` on all of your servers.
|
||||
|
||||
If your players can't connect from the lobby to another backend server, check console.
|
||||
|
||||
### Plugins that can cause issues {#plugins-that-can-cause-issues}
|
||||
* `HamsterAPI`
|
||||
@@ -7,7 +7,7 @@ description: Learn how to create a startup script for Geyser-Standalone.
|
||||
|
||||
:::caution
|
||||
|
||||
In order for this to work, you MUST have Java 17 (or higher) installed!
|
||||
In order for this to work, you MUST have Java 21 (or higher) installed!
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@@ -14,16 +14,15 @@ The following things cannot be fixed without changes to Bedrock or the Java prot
|
||||
|
||||
- Clickable links in chat
|
||||
- Glowing effect
|
||||
- Crafting in the 2x2 menu while in creative mode - with the GeyserOptionalPack, this grid is hidden as it does not exist on Java.
|
||||
- Distinguishing between left and right clicks in inventories
|
||||
- Redstone dot blockstates
|
||||
- Potion colors implemented using NBT
|
||||
- Potion colors implemented using the PotionContents data component
|
||||
- Various command arguments for any command that doesn't use the Minecraft Brigadier library
|
||||
- Anything that relies on tab complete or typing in the chat UI (related to the above) - Bedrock sends no packet that indicates they are in this menu
|
||||
- Unable to see banner layers past 6
|
||||
- Movement issues around bamboo due to offset differences between Java and Bedrock. Use [Hurricane](/wiki/other/hurricane) to work around it.
|
||||
- Custom anvil recipes or custom smithing table ingredients/patterns ([GeyserMC/Geyser#4706](https://github.com/GeyserMC/Geyser/issues/4706))
|
||||
- Heights lower than -64 or higher than 320 in the overworld with extended height enabled, and heights lower than 0 or higher than 256 in other dimensions ([GeyserMC/Geyser#3804](https://github.com/GeyserMC/Geyser/issues/3804))
|
||||
- Heights lower than -512 or higher than 512 in the overworld (and custom dimensions mapped by Geyser to the overworld), and heights lower than 0 or higher than 256 in other dimensions ([GeyserMC/Geyser#3804](https://github.com/GeyserMC/Geyser/issues/3804))
|
||||
- Dolphin's Grace potion effect visuals (effects should still work correctly)
|
||||
- Invisible item frames - however, there are Bedrock edition resource packs making *all* item frames invisible
|
||||
- Blocks (excluding jack-o-lantern) on entity heads (E.G. armor stands, players)
|
||||
@@ -31,14 +30,16 @@ The following things cannot be fixed without changes to Bedrock or the Java prot
|
||||
- Custom beacon base blocks ([GeyserMC/Geyser#2301](https://github.com/GeyserMC/Geyser/issues/2301)) - these are hardcoded on Bedrock edition.
|
||||
- Climbable blocks changed by datapacks ([GeyserMC/Geyser#4051](https://github.com/GeyserMC/Geyser/issues/4051))
|
||||
- Custom enchantments/sweeping edge ([GeyserMC/Geyser#3121](https://github.com/GeyserMC/Geyser/issues/3121))
|
||||
- "Bordure Indented" pattern shape not appearing on the Bedrock side in the loom ([GeyserMC/Geyser#3183](https://github.com/GeyserMC/Geyser/issues/3183))
|
||||
- Gliding without elytras/custom elytras (https://github.com/GeyserMC/Geyser/issues/3255, https://github.com/GeyserMC/Geyser/issues/3299)
|
||||
- Custom furnace cook times ([GeyserMC/Geyser#4104](https://github.com/GeyserMC/Geyser/issues/4104))
|
||||
- Maximum sign length different on Java/Bedrock edition ([GeyserMC/Geyser#4130](https://github.com/GeyserMC/Geyser/issues/4130))
|
||||
- Second line on advancement toasts ([GeyserMC/Geyser#3205](https://github.com/GeyserMC/Geyser/issues/3205))
|
||||
- Showing non-vanilla enchantment levels, such as "Silk Touch 2" ([GeyserMC/Geyser#5252](https://github.com/GeyserMC/Geyser/issues/5252))
|
||||
- Test instance blocks are not available in Bedrock ([GeyserMC/Geyser#6164](https://github.com/GeyserMC/Geyser/issues/6164))
|
||||
|
||||
## Fixable With GeyserOptionalPack {#fixable-with-geyseroptionalpack}
|
||||
## Fixed with the included GeyserIntegratedPack {#fixed-with-geyserintegratedpack}
|
||||
|
||||
The following changes **are supported** with the [GeyserOptionalPack](/wiki/other/geyseroptionalpack/), which is a Bedrock resource pack you can install for additional functionality for features Bedrock does not natively support:
|
||||
The following changes **are supported** with the included GeyserIntegratedPack, which is a Bedrock resource pack to add features Bedrock doesn't natively support:
|
||||
- Custom armor stand poses
|
||||
- Illusioners
|
||||
- Hit particles and other miscellaneous particles not natively in Bedrock
|
||||
@@ -52,4 +53,4 @@ The following changes **are supported** with the [GeyserOptionalPack](/wiki/othe
|
||||
|
||||
The following issues can be worked around with the [Hurricane](/wiki/other/hurricane) plugin/mod. However, these involve Java server
|
||||
modifications.
|
||||
- Movement issues around bamboo due to offset differences between Java and Bedrock.
|
||||
- Movement issues around bamboo due to offset differences between Java and Bedrock.
|
||||
@@ -7,9 +7,14 @@ To setup custom blocks in geyser, you have to choose how you are going to regist
|
||||
|
||||
It should be noted that blocks and their associated components are not very stable. Mojang tends to make changes to these much more often than they do for items. This means that any components Geyser allows you to register are liable to break in future versions of Bedrock.
|
||||
|
||||
:::warning
|
||||
Geyser does not convert resource packs from Java Edition, and also does not generate custom block mappings automatically.
|
||||
However, you can use automatic tools such as [Rainbow](/wiki/other/rainbow/) to make converting content simpler.
|
||||
:::
|
||||
|
||||
## Enabling custom blocks {#enabling-custom-blocks}
|
||||
|
||||
Before beginning, ensure that `add-non-bedrock-items` is set to `true` in your `config.yml` file.
|
||||
Before beginning, ensure that `gameplay.enable-custom-content` is set to `true` in your `config.yml` file.
|
||||
|
||||
```yml
|
||||
# Whether to add any items and blocks which normally does not exist in Bedrock Edition.
|
||||
@@ -17,7 +22,7 @@ Before beginning, ensure that `add-non-bedrock-items` is set to `true` in your `
|
||||
# If this is disabled, furnace minecart items will be mapped to hopper minecart items.
|
||||
# Geyser's block, item, and skull mappings systems will also be disabled.
|
||||
# This option requires a restart of Geyser in order to change its setting.
|
||||
add-non-bedrock-items: true
|
||||
enable-custom-content: true
|
||||
```
|
||||
|
||||
## JSON mappings {#json-mappings}
|
||||
@@ -99,12 +104,12 @@ The following details the schema for the mappings file. Only the `name` field is
|
||||
- Default: none
|
||||
- Description: The name of the custom block.
|
||||
- `collision_box`:
|
||||
- Type: `object`
|
||||
- Type: `object` or array of `object`s for multiple collision boxes
|
||||
- `origin`:
|
||||
- Type: `array`
|
||||
- Default: Inferred from overridden block
|
||||
- Description: An array of x, y, and z origin values
|
||||
- Range: Must be in range `[-8, 0, -8]` to `[8, 16, 8]`, inclusive
|
||||
- Range: Must be in range `[-8, 0, -8]` to `[8, 24, 8]`, inclusive
|
||||
- `items`:
|
||||
- Type: `float`
|
||||
- Default: Inferred from overridden block
|
||||
@@ -113,11 +118,12 @@ The following details the schema for the mappings file. Only the `name` field is
|
||||
- Type: `array`
|
||||
- Default: Inferred from overridden block
|
||||
- Description: An array of x, y, and z size values
|
||||
- Range: Must be in range `[0, 0, 0]` to `[16, 24, 16]`, inclusive
|
||||
- `items`:
|
||||
- Type: `float`
|
||||
- Default: Inferred from overridden block
|
||||
- Description: An size value for a single axis
|
||||
- Range: Addittion of `origin` and `size` must be in range `[-8, 0, -8]` to `[8, 16, 8]`, inclusive.
|
||||
- Range: The sum of `origin` and `size` must be in range `[-8, 0, -8]` to `[8, 24, 8]`, inclusive.
|
||||
- `destructible_by_mining`:
|
||||
- Type: `integer`
|
||||
- Default: Inferred from overridden block
|
||||
@@ -126,26 +132,6 @@ The following details the schema for the mappings file. Only the `name` field is
|
||||
- Type: `string`
|
||||
- Default: the name of the custom block
|
||||
- Description: The display name of the block.
|
||||
- `extended_collision_box`:
|
||||
- Type: `object`
|
||||
- `origin`:
|
||||
- Type: `array`
|
||||
- Default: Inferred from overridden block
|
||||
- Description: An array of x, y, and z origin values
|
||||
- Range: Must be in range `[-8, 0, -8]` to `[8, 16, 8]`, inclusive
|
||||
- `items`:
|
||||
- Type: `float`
|
||||
- Default: Inferred from overridden block
|
||||
- Description: An origin value for a single axis
|
||||
- `size`:
|
||||
- Type: `array`
|
||||
- Default: Inferred from overridden block
|
||||
- Description: An array of x, y, and z size values
|
||||
- `items`:
|
||||
- Type: `float`
|
||||
- Default: Inferred from overridden block
|
||||
- Description: An size value for a single axis
|
||||
- Range: Addittion of `origin` and `size` must be in range `[-8, 0, -8]` to `[8, 16, 8]`, inclusive.
|
||||
- `friction`:
|
||||
- Type: `float`
|
||||
- Range: `0.0` to `1.0`
|
||||
@@ -292,12 +278,12 @@ The following details the schema for the mappings file. Only the `name` field is
|
||||
- Type: `string`
|
||||
- Default: `building_blocks`
|
||||
- Description: The creative category to place the block in.
|
||||
- Range: See [Creative Categories](https://wiki.bedrock.dev/documentation/creative-categories.html#list-of-creative-categories) on the Bedrock Wiki.
|
||||
- Range: See [Menu Categories](https://wiki.bedrock.dev/documentation/menu-categories.html#list-of-categories) on the Bedrock Wiki.
|
||||
- `creative_group`:
|
||||
- Type: `string`
|
||||
- Default: none
|
||||
- Description: The creative group to place the block in.
|
||||
- Range: See [Creative Tabs](https://wiki.bedrock.dev/documentation/creative-categories.html#list-of-creative-tabs) on the Bedrock Wiki.
|
||||
- Range: See [Menu Groups](https://wiki.bedrock.dev/documentation/menu-categories.html#list-of-groups) on the Bedrock Wiki.
|
||||
- `included_in_creative_inventory`:
|
||||
- Type: `boolean`
|
||||
- Default: `true`
|
||||
@@ -311,7 +297,7 @@ The following details the schema for the mappings file. Only the `name` field is
|
||||
- Description: An object containing state overrides for the block.
|
||||
- `property1=value1,property2=value2,...`:
|
||||
- Type: `object`
|
||||
- Description: An override for a specific block state. Possible states are listed in Geyser's [Block Mappings](https://raw.githubusercontent.com/GeyserMC/mappings/master/blocks.json)
|
||||
- Description: An override for a specific block state. Possible states are listed in Geyser's [Block Mappings](https://raw.githubusercontent.com/GeyserMC/mappings/6b661f0d517d895aebc1f55a25d2c86f033beb1d/blocks.json)
|
||||
- Accepts all of the same properties as a block definition except `creative_category`, `creative_group`, `included_in_creative_inventory`, `only_override_states`, and `state_overrides`.
|
||||
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: Custom Content
|
||||
description: How to use custom content (requiring resource packs) with Geyser.
|
||||
---
|
||||
|
||||
Geyser supports mapping various custom additions to the game via resource packs and mappings, such as custom items, blocks, and skulls. See:
|
||||
|
||||
- [Custom items](/wiki/geyser/custom-items)
|
||||
- [Custom blocks](/wiki/geyser/custom-blocks)
|
||||
- [Custom skulls](/wiki/geyser/custom-skulls)
|
||||
- [Custom waypoint icons](/wiki/geyser/custom-waypoints)
|
||||
- [Custom entities](/wiki/geyser/custom-entities)
|
||||
|
||||
:::info
|
||||
Geyser does not convert resource packs from Java Edition automatically.
|
||||
However, you can use automatic tools such as [Rainbow](/wiki/other/rainbow/) or [Thunder](/wiki/other/thunder) to make converting custom content simpler.
|
||||
:::
|
||||
|
||||
## JSON mappings {#json-mappings}
|
||||
|
||||
Various custom additions to the game will require writing custom JSON mappings for Geyser. These mappings are placed
|
||||
within the `custom_mappings` folder in Geyser's config directory. To enable the usage of custom JSON mappings, ensure
|
||||
that `gameplay.enable-custom-content` is set to `true` in your `config.yml` file:
|
||||
|
||||
```yaml
|
||||
# Whether to add any items and blocks which normally does not exist in Bedrock Edition.
|
||||
# This should only need to be disabled if using a proxy that does not use the "transfer packet" style of server switching.
|
||||
# If this is disabled, furnace minecart items will be mapped to hopper minecart items.
|
||||
# Geyser's block, item, and skull mappings systems will also be disabled.
|
||||
# This option requires a restart of Geyser in order to change its setting.
|
||||
enable-custom-content: true
|
||||
```
|
||||
|
||||
JSON mappings will always have a `format_version` key defined at the root object. Refer to the documentation of the
|
||||
content you're mapping (items, blocks, etc.) to see what the current `format_version` is.
|
||||
@@ -0,0 +1,234 @@
|
||||
---
|
||||
title: Geyser Entity API
|
||||
description: Geyser extensions can register custom Bedrock entity definitions, modify existing entities, and replace built-in types in entity spawning events.
|
||||
---
|
||||
|
||||
:::warning Experimental API
|
||||
The (Custom) Entity API was introduced with Geyser API **2.11.0** (26.2 update) and is currently marked `@ApiStatus.Experimental`. This means that the API may change or be rewritten in parts in a future version without prior deprecation.
|
||||
If you have feedback on this API, encounter issues, or wish to request further features, please reach out to us!
|
||||
|
||||
The `GeyserDefineEntityPropertiesEvent` has been available since **2.9.0**, but its identifier parameter changed in 2.11.0: it now takes a **Bedrock** entity identifier instead of a Java one. See [Entity Properties](#entity-properties) for details.
|
||||
:::
|
||||
|
||||
:::info
|
||||
This API currently cannot be used via JSON mappings. In the future, we are planning to support entity variants, which would likely also be usable through JSON mappings.
|
||||
:::
|
||||
|
||||
Custom entities currently (as of 26.2) do not exist in Minecraft: Java Edition. Instead, they can be simulated with armor stands holding item models, or item/block display entity combinations.
|
||||
Unlike Java Edition, Bedrock does support custom entity types, but does not have item or block display entities. With this API, Geyser extensions can register custom Bedrock entity definitions to use instead of Java
|
||||
entity types in entity spawning events to properly support custom entities for Bedrock players. Further, it allows modifying entity properties and data for any entity sent to a Bedrock player at runtime.
|
||||
|
||||
Additionally to registering custom entity definitions, you will also need to provide a resource pack to players [defining custom entity textures and animations](https://wiki.bedrock.dev/guide/custom-entity).
|
||||
|
||||
## Prerequisites: Vocabulary {#vocabulary}
|
||||
|
||||
- **Bedrock Entity Definition** (`GeyserEntityDefinition` / `CustomEntityDefinition`): Identifies the Bedrock entity type to spawn, either a built-in type, or a custom type
|
||||
- **Entity Properties**: Bedrock Molang-queryable values (`query.property(...)`) registered per Bedrock entity type. See [here](https://learn.microsoft.com/en-us/minecraft/creator/documents/introductiontoentityproperties?view=minecraft-bedrock-stable) for official documentation.
|
||||
- **Entity Data Types**: Properties on entities that can be changed dynamically, such as scale, size, hitboxes, and color.
|
||||
|
||||
## Registering a Custom Entity Definition {#registering-entity-definition}
|
||||
|
||||
Custom entity definitions are registered using `GeyserDefineEntitiesEvent`, which fires once during Geyser's startup:
|
||||
|
||||
```java
|
||||
@Subscribe
|
||||
public void onDefineEntities(GeyserDefineEntitiesEvent event) {
|
||||
CustomEntityDefinition myEntity = CustomEntityDefinition.of(Identifier.of("mynamespace:my_entity"));
|
||||
event.register(myEntity);
|
||||
}
|
||||
```
|
||||
|
||||
Do note:
|
||||
- Custom entity definition type identifier must not use the `minecraft` namespace
|
||||
- Entity types must have a unique identifier
|
||||
|
||||
## Summoning custom entities {#custom-entity-spawning}
|
||||
|
||||
Whenever the Java server creates a new non-player entity for any connection, a `ServerSpawnEntityEvent` is fired. It can be used to change which Bedrock entity definition is sent to the Bedrock player or cancel the spawn entirely.
|
||||
Each connection has its own entity cache, so different players will never share the same entity instance.
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
private static final Identifier ZOMBIE = Identifier.of("minecraft:zombie");
|
||||
private static final CustomEntityDefinition MY_ENTITY = CustomEntityDefinition.of(Identifier.of("mynamespace:my_entity"));
|
||||
|
||||
@Subscribe
|
||||
public void onDefineEntities(GeyserDefineEntitiesEvent event) {
|
||||
event.register(MY_ENTITY);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onSpawn(ServerSpawnEntityEvent event) {
|
||||
if (event.entityType().is(ZOMBIE)) {
|
||||
event.definition(MY_ENTITY); // definition must be registered beforehand
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This example replaces all spawned zombies with our custom entity, which we registered in `onDefineEntities`.
|
||||
|
||||
:::info
|
||||
The `ServerSpawnEntityEvent` fires before the entity is spawned (since it could be canceled). You can provide a consumer for the resulting `GeyserEntity` to set initial entity data values before the entity is spawned on the client:
|
||||
|
||||
```java
|
||||
private static final Identifier ZOMBIE = Identifier.of("minecraft:zombie");
|
||||
private static final CustomEntityDefinition MY_ENTITY = CustomEntityDefinition.of(Identifier.of("mynamespace:my_entity"));
|
||||
|
||||
@Subscribe
|
||||
public void onSpawn(ServerSpawnEntityEvent event) {
|
||||
if (!event.entityType().is(ZOMBIE)) {
|
||||
return;
|
||||
}
|
||||
event.definition(MY_ENTITY);
|
||||
event.preSpawnConsumer(entity -> {
|
||||
entity.override(GeyserEntityDataTypes.SCALE, 2.0f);
|
||||
entity.override(GeyserEntityDataTypes.COLOR, (byte) 5);
|
||||
});
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### Modifying shoulder parrots {#shoulder-parrots}
|
||||
|
||||
`ServerAttachParrotsEvent` fires when a parrot is attached to a player's shoulder. It extends `ServerSpawnEntityEvent`, so definition replacement, cancellation, and setting a pre spawn consumer for the
|
||||
resulting `GeyserEntity` instance are all available.
|
||||
|
||||
```java
|
||||
@Subscribe
|
||||
public void onParrotAttach(ServerAttachParrotsEvent event) {
|
||||
event.definition(myParrotReplacement); // this entity definition would also be registered previously
|
||||
}
|
||||
```
|
||||
|
||||
## Modifying entity data {#entity-data}
|
||||
|
||||
Entity data consists of runtime-modifiable values such as scale, size, and hitboxes. All constants live in `GeyserEntityDataTypes`. Values for these types can be updated on a `GeyserEntity`
|
||||
at any time using `entity.override(type, value)`, or set inside a pre-spawn consumer in the entity spawn events to modify it before the spawn packet is sent.
|
||||
|
||||
Updating any of these values will override the value sent by the server until the override is removed. To remove an override, a `null` value can be used.
|
||||
|
||||
| Constant | Value Type | Description |
|
||||
|------------------------------------|----------------|------------------------------------------------------------------------------|
|
||||
| `COLOR` | `Byte` | Bedrock color component (0–15) |
|
||||
| `VARIANT` | `Integer` | Numeric variant index, queryable via `query.variant` in resource packs |
|
||||
| `WIDTH` | `Float` | Collision box width |
|
||||
| `HEIGHT` | `Float` | Collision box height |
|
||||
| `VERTICAL_OFFSET` | `Float` | Y-axis offset applied on top of the Java entity position |
|
||||
| `SCALE` | `Float` | Visual scale multiplier |
|
||||
| `HITBOXES` | `List<Hitbox>` | Custom hitboxes. Set an empty list to remove all hitboxes |
|
||||
| `SEAT_OFFSET` | `Vector3f` | Riding position offset |
|
||||
| `ROTATION_LOCKED_TO_VEHICLE` | `Boolean` | Whether the rider's rotation is locked to the vehicle's rotation |
|
||||
| `SEAT_LOCK_RIDER_ROTATION_DEGREES` | `Float` | The degrees of rotation a rider may rotate within when mounted on an entity. |
|
||||
| `SEAT_HAS_ROTATION` | `Boolean` | Whether a seat has rotation |
|
||||
| `ROTATE_RIDER_DEGREES` | `Float` | Rotation offset for the seat in degrees |
|
||||
|
||||
:::info
|
||||
Hitbox `min`, `max` and `pivot` are absolute world coordinates, not relative to the entity's position.
|
||||
:::
|
||||
|
||||
## Entity Properties {#entity-properties}
|
||||
|
||||
Entity properties expose Java-side state to Bedrock resource packs via `query.property('namespace:name')` in Molang. Entity properties can be registered for both custom, and vanilla entity types using the `GeyserDefineEntityPropertiesEvent`, which fires during Geyser startup.
|
||||
|
||||
:::warning Breaking Change in 2.11.0
|
||||
`GeyserDefineEntityPropertiesEvent` has been available since **2.9.0**, but its first parameter changed in 2.11.0: it now takes a **Bedrock** entity type identifier.
|
||||
:::
|
||||
|
||||
A maximum of 32 properties per entity type can be registered.
|
||||
|
||||
```java
|
||||
private GeyserFloatEntityProperty aggression = null;
|
||||
private GeyserIntEntityProperty state = null;
|
||||
private GeyserBooleanEntityProperty enraged = null;
|
||||
private GeyserEnumEntityProperty<Phase> phase = null;
|
||||
private GeyserStringEnumProperty mode = null;
|
||||
|
||||
@Subscribe
|
||||
public void onDefineProperties(GeyserDefineEntityPropertiesEvent event) {
|
||||
Identifier zombieType = Identifier.of("minecraft:zombie");
|
||||
|
||||
// Float property: min, max, default (null default uses min)
|
||||
aggression = event.registerFloatProperty(zombieType, Identifier.of("mynamespace:aggression"), 0f, 1f, 0f);
|
||||
|
||||
// Integer property
|
||||
state = event.registerIntegerProperty(zombieType, Identifier.of("mynamespace:state"), 0, 10, null);
|
||||
|
||||
// Boolean property
|
||||
enraged = event.registerBooleanProperty(zombieType, Identifier.of("mynamespace:enraged"), false);
|
||||
|
||||
// Enum from a Java enum class (max 16 values, names max 32 chars, must start with a letter)
|
||||
phase = event.registerEnumProperty(zombieType, Identifier.of("mynamespace:phase"), Phase.class, Phase.IDLE);
|
||||
|
||||
// Enum from a string list
|
||||
mode = event.registerEnumProperty(zombieType, Identifier.of("mynamespace:mode"), List.of("idle", "active", "fleeing"), "idle");
|
||||
}
|
||||
```
|
||||
|
||||
Properties can be updated on a `GeyserEntity` instance at any time:
|
||||
|
||||
```java
|
||||
// Single property
|
||||
entity.updateProperty(aggression, 0.5f);
|
||||
```
|
||||
|
||||
## Looking up entities {#looking-up-entities}
|
||||
|
||||
After an entity has spawned it can be looked up through `GeyserConnection#entities()`. All lookup methods are thread-safe.
|
||||
|
||||
```java
|
||||
EntityData entityData = connection.entities();
|
||||
|
||||
// By Java entity ID (int)
|
||||
GeyserEntity entity = entityData.byJavaId(javaId);
|
||||
|
||||
// By UUID
|
||||
GeyserEntity entity = entityData.byUuid(uuid);
|
||||
|
||||
// By Geyser/Bedrock runtime ID (long)
|
||||
GeyserEntity entity = entityData.byGeyserId(geyserId);
|
||||
```
|
||||
|
||||
All three return `null` if no entity is found. A `GeyserEntity` exposes various properties, such as the entity uuid, current passengers / vehicle if applicable, and it can further be used to update
|
||||
entity properties or entity data type values.
|
||||
|
||||
## Full Example {#full-example}
|
||||
|
||||
<details>
|
||||
<summary>Expand for a full extension example</summary>
|
||||
|
||||
```java
|
||||
public class MyExtension implements Extension {
|
||||
// Create a custom entity definition
|
||||
private final CustomEntityDefinition enhancedZombie = CustomEntityDefinition.of(Identifier.of("myext:enhanced_zombie"));
|
||||
private GeyserFloatEntityProperty healthFraction = null;
|
||||
|
||||
// Register the custom entity type
|
||||
@Subscribe
|
||||
public void onDefineEntities(GeyserDefineEntitiesEvent event) {
|
||||
event.register(enhancedZombie);
|
||||
}
|
||||
|
||||
// Optionally: Register entity properties (Bedrock identifier)
|
||||
@Subscribe
|
||||
public void onDefineProperties(GeyserDefineEntityPropertiesEvent event) {
|
||||
healthFraction = event.registerFloatProperty(
|
||||
enhancedZombie.identifier(),
|
||||
Identifier.of("myext:health_fraction"),
|
||||
0f, 1f, 1f
|
||||
);
|
||||
}
|
||||
|
||||
// Replace a default Bedrock entity definition with our custom one
|
||||
@Subscribe
|
||||
public void onSpawn(ServerSpawnEntityEvent event) {
|
||||
// Unless you want to replace everything, you should probably add checks for e.g., entity type, or entity UUID
|
||||
event.definition(enhancedZombie);
|
||||
event.preSpawnConsumer(entity -> {
|
||||
entity.override(GeyserEntityDataTypes.SCALE, 1.5f);
|
||||
entity.override(GeyserEntityDataTypes.COLOR, (byte) 4);
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
</details>
|
||||
@@ -1,11 +1,18 @@
|
||||
---
|
||||
title: Custom Items
|
||||
description: Geyser allows custom Bedrock items to be added for an equivalency to Vanilla Java item predicates or modded items.
|
||||
title: Custom Items (v1)
|
||||
description: Legacy documentation for the first version of the custom item API
|
||||
---
|
||||
|
||||
To setup custom items in geyser, you have to choose how you are going to register your items. The easiest is [using a json file](#json-mappings) but you can also [use a Geyser extension](#geyser-extensions).
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
## JSON mappings {#json-mappings}
|
||||
### Format version 1 (legacy)
|
||||
|
||||
:::warning
|
||||
`format_version: 1` is no longer receiving updates. New features will only be added to format version 2.
|
||||
:::
|
||||
|
||||
## JSON mappings (v1)
|
||||
|
||||
1. Start your server, and you should have a folder called `custom_mappings` that is created. That would be with the folder of `Geyser.jar` file for standalone and inside your Geyser data folder for a plugin.
|
||||
2. Create a `.json` file, it can be any name you like and as many files as you like. You don't need to make one file per item. Here is the structure of the file:
|
||||
@@ -41,7 +48,7 @@ To setup custom items in geyser, you have to choose how you are going to registe
|
||||
* `allow_offhand` (boolean) default: false
|
||||
* `texture_size` (int) default: 16
|
||||
* `creative_category` (int) default: not set. This can take values between 1-5, and defines the creative category the item appears in. Note: Adding your item to a creative category is needed if you want recipes that output this custom item to show up in the recipe book! However, including it does NOT mean you can get the custom item from the creative inventory.
|
||||
* `creative_group` (string) default: not set. Requires a creative category to also be set - allows you to group the custom item in a sub-group. See [here](https://wiki.bedrock.dev/documentation/creative-categories.html#list-of-categories) for all categories.
|
||||
* `creative_group` (string) default: not set. Requires a creative category to also be set - allows you to group the custom item in a sub-group. See [here](https://wiki.bedrock.dev/documentation/menu-categories.html#list-of-categories) for all categories.
|
||||
* `render_offsets` (object) It works as follows. Note that all the sub-objects are optional, except x, y and z. You can have for example only a main hand with a position, and noting else. default: no render offset
|
||||
* `tags` (array) default: no tags. Allows defining tags that can be used in Molang queries. Example value: ["test:tag_one", "test:tag_two"].
|
||||
```json
|
||||
@@ -74,9 +81,9 @@ To setup custom items in geyser, you have to choose how you are going to registe
|
||||
}
|
||||
```
|
||||
|
||||
## Geyser extensions {#geyser-extensions}
|
||||
## Geyser extensions (v1)
|
||||
|
||||
### Extending a vanilla item {#extending-a-vanilla-item}
|
||||
### Extending a vanilla item (v1)
|
||||
|
||||
1. Create your custom item options or registrations, to which you can add any of the following. They can be stacked, so that all of the specified types need to match, but you **do NOT need all of them.**
|
||||
```java
|
||||
@@ -109,7 +116,7 @@ public void onGeyserPreInitializeEvent(GeyserDefineCustomItemsEvent event) {
|
||||
}
|
||||
```
|
||||
|
||||
### Non vanilla (modded) items with Geyser extensions (for example to use with Fabric) {#non-vanilla-modded-items-with-geyser-extensions-for-example-to-use-with-fabric}
|
||||
### Non vanilla (modded) items with Geyser extensions (for example to use with Fabric) (v1)
|
||||
|
||||
1. Create your item data:
|
||||
```java
|
||||
@@ -127,28 +134,4 @@ public void onGeyserDefineCustomItemsEvent(GeyserDefineCustomItemsEvent event) {
|
||||
}
|
||||
```
|
||||
|
||||
## Resource pack {#resource-pack}
|
||||
|
||||
1. Setup a basic bedrock resource pack. If you need help, you can find it [here](https://wiki.bedrock.dev/guide/project-setup.html#rp-manifest).
|
||||
2. Make a `textures` folder.
|
||||
3. Create `item_texture.json` in the `textures`, and put this in it:
|
||||
|
||||
```json
|
||||
{
|
||||
"resource_pack_name": "MY_PACK_NAME_HERE",
|
||||
"texture_name": "atlas.items",
|
||||
"texture_data": {
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
4. Inside texture data, you can add your items. The texture name and path must match the name that you set in your mappings.
|
||||
|
||||
```json
|
||||
"my_item": {
|
||||
"textures": [
|
||||
"textures/items/my_item"
|
||||
]
|
||||
}
|
||||
```
|
||||
5. Then you need to put your textures inside the `textures/items`. Make sure to have it match the texture path that you specified in `item_texture.json`!
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
title: Custom Resource Packs
|
||||
description: How to use custom resource packs for Geyser.
|
||||
---
|
||||
|
||||
Geyser supports custom resource packs for use with custom items, blocks, and skulls. See:
|
||||
- [Custom items](/wiki/geyser/custom-items)
|
||||
- [Custom blocks](/wiki/geyser/custom-blocks)
|
||||
- [Custom skulls](/wiki/geyser/custom-skulls)
|
||||
@@ -1,139 +0,0 @@
|
||||
---
|
||||
title: Custom Skulls
|
||||
description: Geyser allows mapping of custom skulls to custom blocks for use in inventories and on entities.
|
||||
---
|
||||
|
||||
Unlike Java Edition, Bedrock does not have native support for custom skull items. As a result, any method to display custom skulls with Geyser is, to some extent, a workaround. Geyser has long supported in-world custom skulls via the spawning of player entities. This, however, does not allow for the use of custom skulls in inventories, nor does it allow them to be worn by entities. To resolve this, Geyser now allows for the pre-registration of custom skulls via a config file. Geyser will then use this config file to generate a custom resource pack on start that contains the geometry and textures for the pre-registered custom skulls. To the client, these skulls are blocks. Therefore, they can be held in player inventories. In additional, attachables are defined for each skull block so that it is displayed correctly when worn and held by entities.
|
||||
|
||||
To setup custom skulls in geyser, you have to choose how you are going to register your blocks. The easiest is [using custom-skulls.yml](#custom-skullsyml), but you can also [use a Geyser extension](#geyser-extensions).
|
||||
|
||||
## Enabling custom skulls {#enabling-custom-skulls}
|
||||
|
||||
To enable custom skulls, you must set `add-non-bedrock-items` to `true` in the `config.yml` file. This will enable the generation of the custom resource pack and the translation of custom skulls to custom blocks. You can then add custom skulls to the `custom-skulls.yml` file.
|
||||
|
||||
```yaml
|
||||
# Whether to add any items and blocks which normally does not exist in Bedrock Edition.
|
||||
# This should only need to be disabled if using a proxy that does not use the "transfer packet" style of server switching.
|
||||
# If this is disabled, furnace minecart items will be mapped to hopper minecart items.
|
||||
# Geyser's block, item, and skull mappings systems will also be disabled.
|
||||
# This option requires a restart of Geyser in order to change its setting.
|
||||
add-non-bedrock-items: true
|
||||
```
|
||||
|
||||
## custom-skulls.yml {#custom-skullsyml}
|
||||
|
||||
The configuration file `custom-skulls.yml` is present in Geyser's configuration folder and is laid out as follows:
|
||||
|
||||
```yml
|
||||
# --------------------------------
|
||||
# Geyser Custom Skull Configuration Files
|
||||
#
|
||||
# This file is ignored with `add-custom-skull-blocks` disabled.
|
||||
# See `config.yml` for the main set of configuration values
|
||||
#
|
||||
# Custom skulls with the player username, UUID, or texture specified in this file
|
||||
# will be translated as custom blocks and be displayed in the inventory and on entities.
|
||||
# --------------------------------
|
||||
|
||||
# Java player usernames
|
||||
# Skins will be updated when Geyser starts and players will have to re-download
|
||||
# the resource pack if any players had changed their skin.
|
||||
player-usernames:
|
||||
- GeyserMC
|
||||
|
||||
# Java player UUIDs
|
||||
# Skins will be updated when Geyser starts and players will have to re-download
|
||||
# the resource pack if any players had changed their skin.
|
||||
player-uuids:
|
||||
- 8b8d8e8f-2759-47c6-acb5-5827de8a72b8
|
||||
|
||||
# The long string of characters found in the NBT of custom player heads
|
||||
player-profiles:
|
||||
- ewogICJ0aW1lc3RhbXAiIDogMTY1NzMyMjIzOTgzMywKICAicHJvZmlsZUlkIiA6ICJjZGRiZTUyMGQwNDM0YThiYTFjYzlmYzkyZmRlMmJjZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJBbWJlcmljaHUiLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTkwNzkwYzU3ZTE4MWVkMTNhZGVkMTRjNDdlZTJmN2M4ZGUzNTMzZTAxN2JhOTU3YWY3YmRmOWRmMWJkZTk0ZiIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9
|
||||
|
||||
# The hash of the skin on Minecraft's skin server
|
||||
skin-hashes:
|
||||
- a90790c57e181ed13aded14c47ee2f7c8de3533e017ba957af7bdf9df1bde94f
|
||||
```
|
||||
|
||||
To add a skull, you need to choose any of the four methods, and add a new entry. The following sections will explain each method:
|
||||
|
||||
### Player usernames {#player-usernames}
|
||||
|
||||
Skulls can be registered in this section via player usernames. These will be updated when Geyser starts. As a result, they may change if the player's username or skin changes.
|
||||
|
||||
### Player UUIDs {#player-uuids}
|
||||
|
||||
Skulls can be registered in this section via player UUIDs. These will be updated when Geyser starts. As a result, they may change if skin changes.
|
||||
|
||||
### Player profiles {#player-profiles}
|
||||
|
||||
Skulls can be registered in this section via the texture string found in the NBT of custom player heads. Unless the value is changed manually, these will not be updated when Geyser starts. As a result, they will not change if the player's username or skin changes. The data is simply base64 encoded JSON. For instance, the example given in the config decodes as follows:
|
||||
|
||||
```json
|
||||
{
|
||||
"timestamp" : 1657322239833,
|
||||
"profileId" : "cddbe520d0434a8ba1cc9fc92fde2bcf",
|
||||
"profileName" : "Amberichu",
|
||||
"textures" : {
|
||||
"SKIN" : {
|
||||
"url" : "http://textures.minecraft.net/texture/a90790c57e181ed13aded14c47ee2f7c8de3533e017ba957af7bdf9df1bde94f",
|
||||
"metadata" : {
|
||||
"model" : "slim"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If on a paper server, this data can be obtained for a skull by holding the item in hand, and running the command `/paper dumpitem`. This will output the NBT data of the item to chat and console. The texture string is found in the `SkullOwner` tag, under the `Properties` tag, under the `textures` tag, under the `Value` tag. For example:
|
||||
|
||||
```log
|
||||
[05:58:07 INFO]: .KastleFirefox issued server command: /paper dumpitem
|
||||
[05:58:07 INFO]: minecraft:player_head{display: {Name: '{"text":"Test"}'}, SkullOwner: {Properties: {textures: [{Value: "ewogICJ0aW1lc3RhbXAiIDogMTY1NzMyMjIzOTgzMywKICAicHJvZmlsZUlkIiA6ICJjZGRiZTUyMGQwNDM0YThiYTFjYzlmYzkyZmRlMmJjZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJkYXZjaG9vIiwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2E5MDc5MGM1N2UxODFlZDEzYWRlZDE0YzQ3ZWUyZjdjOGRlMzUzM2UwMTdiYTk1N2FmN2JkZjlkZjFiZGU5NGYiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ"}]}, Id: [I; -229048314, -553040501, -1407961158, 465313087]}}
|
||||
```
|
||||
|
||||
### Skin Hashes {#skin-hashes}
|
||||
|
||||
Skulls can be registered in this section via the hash of the skin on Minecraft's skin server. This is found at the end of the URL. For example, in the URL `http://textures.minecraft.net/texture/a90790c57e181ed13aded14c47ee2f7c8de3533e017ba957af7bdf9df1bde94f` the hash is `a90790c57e181ed13aded14c47ee2f7c8de3533e017ba957af7bdf9df1bde94f`.Unless the value is changed manually, these will not be updated when Geyser starts. As a result, they will not change if the player's username or skin changes.
|
||||
|
||||
This can be obtained by decoding the base64 data obtained from a player profile.
|
||||
|
||||
## Geyser extensions {#geyser-extensions}
|
||||
|
||||
In this example, we will register a custom skull from a player profile. We will use the player profile from the example above.
|
||||
|
||||
First, create a class that implements Geyser's Extension class:
|
||||
|
||||
```java
|
||||
public class RegisterCustomSkull implements Extension {
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
Next, create a method to register your blocks in the `GeyserDefineCustomSkullsEvent`:
|
||||
|
||||
```java
|
||||
public class RegisterCustomSkull implements Extension {
|
||||
@Subscribe
|
||||
public void onDefineCustomSkulls(GeyserDefineCustomSkullsEvent event) {
|
||||
//...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Finally, register your skull in the event. Use the enum SkullTextureType to specify that the value being passed is a player profile:
|
||||
|
||||
```java
|
||||
public class RegisterCustomSkull implements Extension {
|
||||
@Subscribe
|
||||
public void onDefineCustomSkulls(GeyserDefineCustomSkullsEvent event) {
|
||||
String profile = "ewogICJ0aW1lc3RhbXAiIDogMTY1NzMyMjIzOTgzMywKICAicHJvZmlsZUlkIiA6ICJjZGRiZTUyMGQwNDM0YThiYTFjYzlmYzkyZmRlMmJjZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJkYXZjaG9vIiwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2E5MDc5MGM1N2UxODFlZDEzYWRlZDE0YzQ3ZWUyZjdjOGRlMzUzM2UwMTdiYTk1N2FmN2JkZjlkZjFiZGU5NGYiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ"
|
||||
event.register(profile, SkullTextureType.PROFILE);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Scraping custom skulls from a world {#scraping-custom-skulls-from-a-world}
|
||||
|
||||
Custom skulls can be extracted from an existing world for easy implementation via mappings or API using the tool [HeadExtractor](https://github.com/davchoo/HeadExtractor) made by Amberichu. See the linked repository for usage instructions.
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
title: Custom Skulls
|
||||
description: Geyser allows mapping of custom skulls to custom blocks for use in inventories and on entities.
|
||||
---
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
|
||||
Unlike Minecraft: Java Edition, Bedrock Edition does not have native support for custom skull items.
|
||||
As a result, any method to display custom skulls with Geyser is, to some extent, a workaround.
|
||||
Geyser has long supported in-world custom skulls via the spawning of player entities.
|
||||
This, however, does not allow for the use of custom skulls in inventories, nor does it allow them to be worn by entities.
|
||||
|
||||
To resolve this, Geyser allows for the pre-registration of custom skulls via custom JSON mappings
|
||||
or the Geyser API. Geyser will then generate a custom resource pack on start that contains the geometry and textures
|
||||
for the pre-registered custom skulls.
|
||||
|
||||
To the client, these skulls are blocks. Therefore, they can be held in player inventories.
|
||||
In addition, attachables are defined for each skull block, so that it is displayed correctly when worn and held by entities.
|
||||
|
||||
To set up custom skulls in Geyser, you have to choose how you are going to register them.
|
||||
The easiest is using custom mappings via JSON files. Alternatively, you can also use the Geyser API, for example using a Geyser extension or a plugin.
|
||||
|
||||
:::info
|
||||
You can use tools such as [Rainbow](/wiki/other/rainbow/) to automatically generate custom JSON mappings for skulls.
|
||||
:::
|
||||
|
||||
:::info
|
||||
Custom skulls used to be registered using a YAML file in Geyser's config directory, `custom-skulls.yml`. This file
|
||||
is legacy and its contents will automatically be migrated to custom JSON mappings when Geyser starts.
|
||||
:::
|
||||
|
||||
## Registering custom skulls
|
||||
|
||||
Custom skulls can be registered through 4 methods:
|
||||
|
||||
- By player username. These will be updated when Geyser starts. As a result, they may change if the player's username or skin changes.
|
||||
- Use this option for skulls marked `Dynamic` on Java Edition.
|
||||
- By player UUID. These will also be updated when Geyser starts. As a result, they may change if skin changes.
|
||||
- Use this option for skulls marked `Dynamic` on Java Edition.
|
||||
- By the base-64 encoded `textures` property of game profiles. These will only ever change when the registered value itself changes, as they hold a static reference to a skin.
|
||||
- You can get these values from a custom skull in your hand using the following command in Minecraft: Java Edition: `/data get entity @s SelectedItem.components."minecraft:profile".properties[{name:"textures"}].value`.
|
||||
- Please note that this command has only been tested on Java Edition 26.2. If the command fails, that could mean your custom skull is a dynamic one, and you should register a UUID or username instead.
|
||||
- By skin texture hash. These will also only ever change when the value itself changes. They are a static reference to a skin texture over at `https://textures.minecraft.net/texture/`.
|
||||
- You generally don't need to use this option, as it is often easier to just use the base-64 profile found in a skull.
|
||||
- If you want to publish an extension or custom skull mappings however, this option can be useful to hide player names/UUIDs, if you wish to do so.
|
||||
|
||||
<Tabs groupId="custom-skull-implementation">
|
||||
<TabItem value="json" label="JSON mappings">
|
||||
For setting up JSON mappings, please see the instructions [here](/wiki/geyser/custom-content#json-mappings).
|
||||
|
||||
JSON mappings have to specify the `format_version` set to `1`, and list all custom skulls under the
|
||||
`skulls` key. This key holds an object in which Java Edition usernames, user UUIDs, profile hashes or skin texture
|
||||
hashes can be specified.
|
||||
|
||||
For example, take the following `custom_skulls.json` file:
|
||||
```json
|
||||
{
|
||||
"format_version": 1,
|
||||
"skulls": {
|
||||
"username": [
|
||||
"GeyserMC"
|
||||
],
|
||||
"uuid": [
|
||||
"8b8d8e8f-2759-47c6-acb5-5827de8a72b8"
|
||||
],
|
||||
"profile": [
|
||||
"ewogICJ0aW1lc3RhbXAiIDogMTY1NzMyMjIzOTgzMywKICAicHJvZmlsZUlkIiA6ICJjZGRiZTUyMGQwNDM0YThiYTFjYzlmYzkyZmRlMmJjZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJBbWJlcmljaHUiLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTkwNzkwYzU3ZTE4MWVkMTNhZGVkMTRjNDdlZTJmN2M4ZGUzNTMzZTAxN2JhOTU3YWY3YmRmOWRmMWJkZTk0ZiIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9"
|
||||
],
|
||||
"skin_hash": [
|
||||
"a90790c57e181ed13aded14c47ee2f7c8de3533e017ba957af7bdf9df1bde94f"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These mappings specify skulls for the `GeyserMC` user, the `Camotoy` user (using UUID `8b8d8e8f-2759-47c6-acb5-5827de8a72b8`),
|
||||
and [this](http://textures.minecraft.net/texture/a90790c57e181ed13aded14c47ee2f7c8de3533e017ba957af7bdf9df1bde94f) skin (through the base-64 `profile` entry and the `skin_hash` entry).
|
||||
</TabItem>
|
||||
<TabItem value="api" label="Geyser API">
|
||||
Custom skulls are registered at startup through the `GeyserDefineCustomSkullsEvent`. All skulls are registered
|
||||
through the `register(String texture, SkullTextureType type)` method, in which the `type` parameter defines the
|
||||
type of the string registered, which is one of:
|
||||
|
||||
- `SkullTextureType.USERNAME` for usernames.
|
||||
- `SkullTextureType.UUID` for UUIDs.
|
||||
- `SkullTextureType.PROFILE` for base-64 encoded `textures` properties of game profiles.
|
||||
- `SkullTextureType.SKIN_HASH` for skin texture hashes.
|
||||
|
||||
As an example:
|
||||
|
||||
```java
|
||||
@Subscribe
|
||||
public void onDefineCustomSkulls(GeyserDefineCustomSkullsEvent event) {
|
||||
event.register("GeyserMC", SkullTextureType.USERNAME);
|
||||
event.register("8b8d8e8f-2759-47c6-acb5-5827de8a72b8", SkullTextureType.UUID);
|
||||
event.register("ewogICJ0aW1lc3RhbXAiIDogMTY1NzMyMjIzOTgzMywKICAicHJvZmlsZUlkIiA6ICJjZGRiZTUyMGQwNDM0YThiYTFjYzlmYzkyZmRlMmJjZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJBbWJlcmljaHUiLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTkwNzkwYzU3ZTE4MWVkMTNhZGVkMTRjNDdlZTJmN2M4ZGUzNTMzZTAxN2JhOTU3YWY3YmRmOWRmMWJkZTk0ZiIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9", SkullTextureType.PROFILE);
|
||||
event.register("a90790c57e181ed13aded14c47ee2f7c8de3533e017ba957af7bdf9df1bde94f", SkullTextureType.SKIN_HASH);
|
||||
}
|
||||
```
|
||||
|
||||
This example specifies skulls for the `GeyserMC` user, the `Camotoy` user (using UUID `8b8d8e8f-2759-47c6-acb5-5827de8a72b8`),
|
||||
and [this](http://textures.minecraft.net/texture/a90790c57e181ed13aded14c47ee2f7c8de3533e017ba957af7bdf9df1bde94f) skin (through the base-64 `PROFILE` entry and the `SKIN_HASH` entry).
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
---
|
||||
title: Custom Waypoint Icons
|
||||
description: Geyser supports custom locator bar icons (also known as waypoint icons), though they have to be mapped manually.
|
||||
---
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
|
||||
Minecraft: Java Edition supports showing custom icons on the locator bar. These are known as custom waypoints and, on
|
||||
Java Edition, are implemented through custom "waypoint styles" in a resource pack. These waypoint styles specify a near
|
||||
and far distance in blocks, and a list of sprites to display on the locator bar.
|
||||
|
||||
Bedrock Edition also supports custom waypoint icons through behaviour + resource packs. In Geyser, these are implemented through custom JSON mappings, similar to custom block or item mappings, alongside a Bedrock resource pack.
|
||||
|
||||
Geyser extensions can also make use out of Bedrock's support for custom waypoint icons. Unlike JSON mappings however,
|
||||
extensions have more freedom in how icons are displayed to the client.
|
||||
|
||||
When an unknown custom waypoint style is sent to Geyser by the Java server,
|
||||
Geyser will display the waypoint using vanilla's default icons.
|
||||
|
||||
:::info
|
||||
This guide only describes the steps required to write custom waypoint style mappings. You still need to create a resource pack
|
||||
for Bedrock Edition, add the waypoint icons to it, and use it in Geyser. Geyser cannot automatically pull icons from
|
||||
Java Edition resource packs.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
As with custom blocks and items, Geyser does not convert resource packs from Java Edition, and also does not generate
|
||||
custom waypoint mappings automatically. However, [Rainbow](/wiki/other/rainbow/) has
|
||||
support for these conversions.
|
||||
:::
|
||||
|
||||
## Simple icons
|
||||
|
||||
Custom waypoint icons following Java's system of having a near- and far-distance should be mapped using JSON mappings, or,
|
||||
when using Geyser extensions, Geyser's `CustomWaypointStyle.VanillaBuilder` helper builder. Both of these methods follow
|
||||
the same format as Java's custom waypoint styles and should feel very familiar.
|
||||
|
||||
<Tabs groupId="custom-waypoint-implementation">
|
||||
<TabItem value="json" label="JSON-mappings">
|
||||
For setting up JSON mappings, please see the instructions [here](/wiki/geyser/custom-content#json-mappings).
|
||||
|
||||
JSON mappings have to specify the `format_version` set to `1`, and list all custom waypoint styles under the
|
||||
`waypoint_styles` key. This key holds an object in which keys are identifiers of waypoint styles, and each
|
||||
value is the definition of that waypoint style.
|
||||
|
||||
For example, take the following `waypoint_mappings.json` file:
|
||||
```json
|
||||
{
|
||||
"format_version": 1,
|
||||
"waypoint_styles": {
|
||||
"geyser:my_first_waypoint": {
|
||||
"near_distance": 10,
|
||||
"far_distance": 100,
|
||||
"sprites": [
|
||||
"geyser:custom_waypoint_0",
|
||||
"geyser:custom_waypoint_1"
|
||||
]
|
||||
},
|
||||
"geyser:my_second_waypoint": {
|
||||
"sprites": [
|
||||
"geyser:second_waypoint/texture_1",
|
||||
"geyser:second_waypoint/texture_2",
|
||||
"geyser:second_waypoint/texture_3",
|
||||
"geyser:second_waypoint/texture_4"
|
||||
]
|
||||
},
|
||||
"geyser:the_best_waypoint": {
|
||||
"near_distance": 50,
|
||||
"sprites": [
|
||||
"geyser:ultimate_waypoint/near",
|
||||
"geyser:ultimate_waypoint/far"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These mappings specify 3 custom waypoint styles, `geyser:my_first_waypoint`, `geyser:my_second_waypoint`, and
|
||||
`geyser:the_best_waypoint`.
|
||||
|
||||
Just like on Java Edition, the default value for `near_distance` when not specified is 128, and for `far_distance`
|
||||
it is 332. And, just like on Java Edition, at least one texture sprite must be specified.
|
||||
|
||||
Since namespaces do not exist in Bedrock Edition's resource packs, Geyser must flatten the texture sprite identifier
|
||||
to be used in the resource pack on Bedrock Edition. Geyser does this using the following format:
|
||||
|
||||
> `textures/ui/<namespace>/locator_bar_dot/<path>`
|
||||
|
||||
As such, in the example above, the `geyser:my_first_waypoint` waypoint style refers to the following textures in the Bedrock resource pack:
|
||||
|
||||
- `textures/ui/geyser/locator_bar_dot/custom_waypoint_0`
|
||||
- `textures/ui/geyser/locator_bar_dot/custom_waypoint_1`
|
||||
</TabItem>
|
||||
<TabItem value="api" label="Geyser API">
|
||||
The Geyser API provides a helper builder, called `VanillaBuilder` in `CustomWaypointStyle`, to implement custom
|
||||
waypoint icons that are similar to Java Edition's custom icons. The builder is similar to JSON-mappings in use
|
||||
and requires the same fields to be specified.
|
||||
|
||||
Custom waypoint styles are registered per-connection in the `SessionDefineCustomWaypointsEvent`,
|
||||
and as such you can check the `GeyserConnection` before registering a custom waypoint style. If a custom waypoint
|
||||
style is used across multiple connections, it can be useful to only create it once to save memory.
|
||||
|
||||
`VanillaBuilder` instances are created by using `CustomWaypointStyle#vanillaLike(int nearDistance, int farDistance)`.
|
||||
When not specifying a near- and far-distance, the Java defaults of 128 and 332 are used.
|
||||
|
||||
```java
|
||||
@Subscribe
|
||||
public void onSessionDefineCustomWaypoints(SessionDefineCustomWaypointsEvent event) {
|
||||
event.register(Identifier.of("geyser:my_first_waypoint"), CustomWaypointStyle.vanillaLike(10, 100)
|
||||
.withTexture(Identifier.of("geyser:custom_waypoint_0"))
|
||||
.withTexture(Identifier.of("geyser:custom_waypoint_1"))
|
||||
.build());
|
||||
|
||||
event.register(Identifier.of("geyser:my_second_waypoint"), CustomWaypointStyle.vanillaLike()
|
||||
.withTexture(Identifier.of("geyser:second_waypoint/texture_1"))
|
||||
.withTexture(Identifier.of("geyser:second_waypoint/texture_2"))
|
||||
.withTexture(Identifier.of("geyser:second_waypoint/texture_3"))
|
||||
.withTexture(Identifier.of("geyser:second_waypoint/texture_4"))
|
||||
.build());
|
||||
|
||||
event.register(Identifier.of("geyser:the_best_waypoint"), CustomWaypointStyle.vanillaLike(50, 332)
|
||||
.withTexture(Identifier.of("geyser:ultimate_waypoint/near"))
|
||||
.withTexture(Identifier.of("geyser:ultimate_waypoint/far"))
|
||||
.build());
|
||||
}
|
||||
```
|
||||
|
||||
As with JSON mappings, Geyser flattens the texture identifier into a string using the following format:
|
||||
|
||||
> `textures/ui/<namespace>/locator_bar_dot/<path>`
|
||||
|
||||
However, you can also pass a literal texture string to `withTexture`. This string must not be prefixed with
|
||||
`textures/` and must also not be suffixed with the texture extension (e.g. `.png`).
|
||||
|
||||
You can register the same custom waypoint style for multiple waypoint style identifiers. However, each
|
||||
waypoint style identifier may only have one custom waypoint style attached to it. If a duplicate is registered,
|
||||
a `CustomWaypointStyleRegisterException` will be thrown.
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary>Changing vanilla waypoint styles</summary>
|
||||
Creating custom waypoint styles for vanilla waypoint styles, like `minecraft:default`, is allowed, and can be done
|
||||
as follows:
|
||||
|
||||
<Tabs groupId="custom-waypoint-implementation">
|
||||
<TabItem value="json" label="JSON-mappings">
|
||||
```json
|
||||
{
|
||||
"format_version": 1,
|
||||
"waypoint_styles": {
|
||||
"minecraft:default": {
|
||||
"sprites": [
|
||||
"geyser:custom_vanilla_0",
|
||||
"geyser:custom_vanilla_1",
|
||||
"geyser:custom_vanilla_2",
|
||||
"geyser:custom_vanilla_3",
|
||||
"geyser:custom_vanilla_4"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="api" label="Geyser API">
|
||||
```java
|
||||
@Subscribe
|
||||
public void onSessionDefineCustomWaypoints(SessionDefineCustomWaypointsEvent event) {
|
||||
event.register(Identifier.of("minecraft:default"), CustomWaypointStyle.vanillaLike(128, 332)
|
||||
.withTexture(Identifier.of("geyser:custom_vanilla_0"))
|
||||
.withTexture(Identifier.of("geyser:custom_vanilla_1"))
|
||||
.withTexture(Identifier.of("geyser:custom_vanilla_2"))
|
||||
.withTexture(Identifier.of("geyser:custom_vanilla_3"))
|
||||
.withTexture(Identifier.of("geyser:custom_vanilla_4"))
|
||||
.build());
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
</details>
|
||||
|
||||
## Advanced icons
|
||||
|
||||
Geyser API users may write custom implementations of `CustomWaypointStyle`, to run custom checks for waypoint textures
|
||||
and waypoint icon sizes. Just like waypoint styles created using the `VanillaBuilder`, these can be registered for one
|
||||
or more custom waypoint style identifiers in the `SessionDefineCustomWaypointsEvent`. For example, the following
|
||||
implementation will always use the same texture and icon size, no matter the distance:
|
||||
|
||||
```java
|
||||
public final class MyCustomWaypointStyle implements CustomWaypointStyle {
|
||||
public static final CustomWaypointStyle INSTANCE = new MyCustomWaypointStyle();
|
||||
private static final Vector2f SIZE = Vector2f.from(0.5, 0.5);
|
||||
|
||||
private MyCustomWaypointStyle() {}
|
||||
|
||||
@Override
|
||||
public String texturePath(Identifier style, float distance) {
|
||||
return "ui/geyser/locator_bar_dot/my_icon";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2f textureSize(Identifier style, float distance) {
|
||||
return SIZE;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Implementations must always implement `texturePath(Identifier, float)` and `textureSize(Identifier, float)`. The first
|
||||
returns the texture path to use for that waypoint style and distance (not prefixed with `textures/`), and the second
|
||||
returns the size of the texture to use (where a size of `[1, 1]` is the size icons normally appear as when the waypoint
|
||||
is close to the player).
|
||||
|
||||
Implementations can then be registered through the `SessionDefineCustomWaypointsEvent` as follows:
|
||||
|
||||
```java
|
||||
@Subscribe
|
||||
public void onSessionDefineCustomWaypoints(SessionDefineCustomWaypointsEvent event) {
|
||||
event.register(Identifier.of("geyser:my_style", MyCustomWaypointStyle.INSTANCE));
|
||||
}
|
||||
```
|
||||
|
||||
Like with `VanillaBuilder`, should you use a custom waypoint style across multiple connections,
|
||||
it can be useful to only keep one instance of it, to save memory. Also, avoid running time-taking operations in your
|
||||
`texturePath` or `textureSize` implementations, since these methods are called frequently. For full implementation details,
|
||||
refer to the Javadocs of `CustomWaypointStyle`.
|
||||
@@ -25,20 +25,23 @@ The underlying Geyser API is steadily expanding, creating more and more opportun
|
||||
|
||||
## Which Geyser Extensions exist? {#which-geyser-extensions-exist}
|
||||
|
||||
At the moment, extensions are still a new system, so there is only a small list of known extensions for Geyser.
|
||||
However, new extensions are always being created!
|
||||
|
||||
There is an [official list](https://github.com/GeyserMC/GeyserExtensionList) of available extensions you can check out.
|
||||
If you have an extension you'd like to see on this list, feel free to open a PR!
|
||||
Check out Modrinth's Geyser extensions section under the "plugins" tab!
|
||||
|
||||
## Installing Extensions {#installing-extensions}
|
||||
|
||||
To install an extension, simply put the extension .jar file into Geyser's `extensions` folder.
|
||||
Then, restart Geyser (or the server Geyser runs on).
|
||||
|
||||
## Updating Extensions {#updating-extensions}
|
||||
To update extensions, use the `update` folder within the extensions directory as follows:
|
||||
|
||||
1. Copy the updated versions of your extension jars into the `update` folder inside the `extensions` directory.
|
||||
2. On the next server or application restart, any extensions in the `update` folder will automatically replace the corresponding extensions in the main extensions directory. If an extension is new, it will be added.
|
||||
3. If an update fails, it will be logged, and the server/application will proceed with loading extensions as usual. You can review the logs to address any issues.
|
||||
|
||||
## Creating Geyser Extensions {#creating-geyser-extensions}
|
||||
|
||||
The easiest way to create an extension would be utilizing [this official template](https://github.com/GeyserMC/GeyserExampleExtension/).
|
||||
The easiest way to create an extension would be utilizing [this official template](https://github.com/GeyserMC/GeyserExtensionTemplate/).
|
||||
Simply create a new repository from the template, customize the `extension.yml` & `settings.gradle` files, and get started making the extension.
|
||||
|
||||
Geyser recognizes extensions when they have a file called `extension.yml` in the jars `resources` folder.
|
||||
@@ -47,9 +50,15 @@ Geyser recognizes extensions when they have a file called `extension.yml` in the
|
||||
id: exampleid
|
||||
name: ExampleExtension
|
||||
main: org.geyser.extension.exampleid.ExampleExtension
|
||||
api: 2.4.1
|
||||
api: 2.9.0
|
||||
version: 1.0.0
|
||||
authors: [ExampleAuthor]
|
||||
dependencies: # Optional
|
||||
exampledependency:
|
||||
# When this dependency should be loaded (BEFORE or AFTER your extension)
|
||||
load: BEFORE # Default: BEFORE
|
||||
# This determines whether or not this dependency is required for this extension to load
|
||||
required: true # Default: true
|
||||
```
|
||||
|
||||
Explanations for the individual fields:
|
||||
@@ -58,10 +67,11 @@ Explanations for the individual fields:
|
||||
- main: The main class of your extension.
|
||||
- api: The Geyser API version your extension targets.
|
||||
- authors: The author(s) of the extension. To add more than one entry, separate entries with a comma.
|
||||
- dependencies: The dependencies of the extension. Each dependency has a load order and required property with defaults of `BEFORE` and `true` respectively.
|
||||
|
||||
## Creating the main class {#creating-the-main-class}
|
||||
|
||||
The main class, the entrypoint for the extension, needs to [implement the **Extension** interface provided by Geyser](https://github.com/GeyserMC/GeyserExampleExtension/blob/master/src/main/java/org/geyser/extension/exampleid/ExampleExtension.java#L12).
|
||||
The main class, the entrypoint for the extension, needs to [implement the **Extension** interface provided by Geyser](https://github.com/GeyserMC/GeyserExtensionTemplate/blob/master/src/main/java/org/geyser/extension/exampleid/ExampleExtension.java#L15).
|
||||
That way, Geyser recognizes the extension, and gives you access to important methods - such as `logger()`, to get your extensions logger.
|
||||
To see all the methods provided by that interface, see [here](https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/extension/Extension.java).
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ description: Frequently asked questions about Geyser, including how it works, wh
|
||||
import { Questions, Q, A } from "@site/src/components/Questions";
|
||||
import { Versions } from '@site/src/components/Versions'
|
||||
|
||||
### General Questions {#general-questions}
|
||||
### General Questions \{#general-questions}
|
||||
|
||||
Here you can find answers to frequently asked questions about Geyser - if you have a question that isn't answered here, feel free to ask in our [Discord](https://discord.gg/GeyserMC)!
|
||||
|
||||
@@ -150,7 +150,7 @@ Here you can find answers to frequently asked questions about Geyser - if you ha
|
||||
<Q>
|
||||
Sometimes, when I go really far out, the world starts to experience very odd visual bugs...
|
||||
<A>
|
||||
This is a Bedrock client issue caused by Bedrock being 32-bit and Java being 64-bit. For more information read [here](https://minecraft.wiki/w/Bedrock_Edition_distance_effects).
|
||||
This is a Bedrock client issue caused by Bedrock being 32-bit and Java being 64-bit. For more information read [here](https://minecraft.wiki/w/Bedrock_Edition_distance_effects). This can be worked around using an [unofficial Geyser extension](https://github.com/oryxel1/GeyserFloatingPoints) that spoofs the player position.
|
||||
</A>
|
||||
</Q>
|
||||
<Q>
|
||||
@@ -209,7 +209,7 @@ Here you can find answers to frequently asked questions about Geyser - if you ha
|
||||
|
||||
Note: you need to be running DiscordSRV v1.22.0 or newer. Floodgate 2.0 or GeyserSkinRestorer is still required for skins to show up for Java players and for this to work.
|
||||
|
||||
Alternatively, if you cannot get the above AvatarUrl to work with DiscordSRV, or you'd like to use it with another plugin that does not support texture ids, you can use the [TydiumCraft Skin API.](https://tydiumcraft.net/docs/skinapi)
|
||||
Alternatively, if you cannot get the above AvatarUrl to work with DiscordSRV, or you'd like to use it with another plugin that does not support texture ids, you can use the [Starlight Skin API.](https://docs.lunareclipse.studio/)
|
||||
</A>
|
||||
</Q>
|
||||
<Q>
|
||||
@@ -240,7 +240,7 @@ Here you can find answers to frequently asked questions about Geyser - if you ha
|
||||
</Q>
|
||||
</Questions>
|
||||
|
||||
### Additional Questions {#additional-questions}
|
||||
### Additional Questions \{#additional-questions}
|
||||
|
||||
These additional frequently asked questions are not related to Geyser gameplay.
|
||||
|
||||
@@ -257,4 +257,4 @@ These additional frequently asked questions are not related to Geyser gameplay.
|
||||
No. They have their own bedrock server tech you can find out more info about [here](https://www.cubecraft.net/threads/behind-the-cube-1-feelin-lucky.264600/).
|
||||
</A>
|
||||
</Q>
|
||||
</Questions>
|
||||
</Questions>
|
||||
@@ -3,10 +3,6 @@ title: Fixing 'Unable to Connect to World'
|
||||
description: Common issues and solutions for the 'Unable to Connect to World' error.
|
||||
---
|
||||
|
||||
import TroubleshootingTree from '@site/src/components/TroubleshootingTree';
|
||||
|
||||
<TroubleshootingTree />
|
||||
|
||||
## Fixing 'Unable to Connect to World' errors {#fixing-unable-to-connect-to-world-errors}
|
||||
This is by far the most common error people get when attempting to set up Geyser. Here's some steps on how to solve it.
|
||||
Usually, this error is caused by improper configuration of Geyser, or issues with your network.
|
||||
@@ -102,22 +98,3 @@ Your firewall is likely in the way. Try adding an exception to Java, or disable
|
||||
## As a last resort for troubleshooting... {#as-a-last-resort-for-troubleshooting}
|
||||
|
||||
Minecraft offers a vanilla Bedrock server [here](https://www.minecraft.net/download/server/bedrock). Downloading, running, and attempting to connect to it may help isolate if the issue is on Geyser's end, or your computer/network's end.
|
||||
|
||||
## Using Geyser on the same computer {#using-geyser-on-the-same-computer}
|
||||
|
||||
### Windows 10/11 {#windows-1011}
|
||||
|
||||
_This only affects people trying to join Geyser from Windows 10/11 Edition with Geyser hosted on the same computer._
|
||||
|
||||
This is an issue caused by Loopback restrictions not being lifted. By default, Microsoft Apps have this restriction on all their apps for local connections. Geyser will attempt to resolve this automatically; however, if you're still having connection problems, you can lift it by typing the following in Windows PowerShell in administrator mode: (it should return `OK.` if it worked)
|
||||
```powershell
|
||||
CheckNetIsolation LoopbackExempt -a -n="Microsoft.MinecraftUWP_8wekyb3d8bbwe"
|
||||
```
|
||||
|
||||
Should this not work, you can try this set of steps:
|
||||
|
||||
1. Hold down Windows Key + R
|
||||
2. In the prompt, type `hdwwiz.exe`, then press Enter then Next
|
||||
3. Install the Hardware Manually
|
||||
4. Choose Network Adapter > Next > Microsoft > "Microsoft KM-TEST Loopback Adapter" then hit Next until it's done.
|
||||
|
||||
@@ -23,7 +23,7 @@ Then we'll talk about sending the form, receiving a response and doing advanced
|
||||
While this is the easiest form type it's also the least customisable.
|
||||
You have a title, description (content) and two buttons.
|
||||
|
||||

|
||||

|
||||
|
||||
Code used in the image:
|
||||
|
||||
@@ -40,7 +40,7 @@ ModalForm.builder()
|
||||
While this one is less easy than ModalForm is, it also has more customizability.
|
||||
It's still limited to a title, content and buttons, but these buttons can also have images and do not have a minimum and maximum of two.
|
||||
|
||||

|
||||

|
||||
|
||||
Code used in the image:
|
||||
```java
|
||||
@@ -58,7 +58,7 @@ While the CustomForm is the last one on our list (and thus the least easy one),
|
||||
This form exists of a title, content and a list of different components e.g. label, slider and input.
|
||||
See [Components](https://github.com/GeyserMC/Cumulus/tree/master/src/main/java/org/geysermc/cumulus/component) for more information about every component you can use and in which form type.
|
||||
|
||||

|
||||

|
||||
|
||||
Code used in the image:
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Add Geyser's API codebase as a dependency:
|
||||
<dependency>
|
||||
<groupId>org.geysermc.geyser</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>2.4.2-SNAPSHOT</version>
|
||||
<version>2.11.2-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
@@ -40,7 +40,7 @@ Add Geyser's API codebase as a dependency:
|
||||
**Gradle**
|
||||
```groovy
|
||||
dependencies {
|
||||
compileOnly('org.geysermc.geyser:api:2.4.2-SNAPSHOT')
|
||||
compileOnly('org.geysermc.geyser:api:2.11.2-SNAPSHOT')
|
||||
}
|
||||
```
|
||||
|
||||
@@ -66,7 +66,7 @@ Add Floodgate's API as a dependency:
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>2.2.3-SNAPSHOT</version>
|
||||
<version>2.2.5-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
@@ -74,7 +74,7 @@ Add Floodgate's API as a dependency:
|
||||
**Gradle**
|
||||
```groovy
|
||||
dependencies {
|
||||
compileOnly('org.geysermc.floodgate:api:2.2.3-SNAPSHOT')
|
||||
compileOnly('org.geysermc.floodgate:api:2.2.5-SNAPSHOT')
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@ The Geyser specific properties are prioritized over the plugin properties!
|
||||
- ```server``` means to match the bind address of the TCP server
|
||||
- any other string will be used as-is for the bind address.
|
||||
|
||||
- ```-DgeyserBroadcastPort=19132```
|
||||
- This can be used in cases where the port Geyser runs on does not match the port players use to connect to (e.g. due to port forwarding routings).
|
||||
- When not set or set to 0, it defaults to the same port that Geyser runs on
|
||||
|
||||
## Disabling warnings and advanced configuration {#disabling-warnings-and-advanced-configuration}
|
||||
You may disable some warnings that may be printed to the console by using the following command line arguments. The values shown are the defaults used by Geyser, unless otherwise noted.
|
||||
|
||||
@@ -55,6 +59,9 @@ Disabling Geyser warnings from being logged will not fix the real issue! Only di
|
||||
- `-DGeyser.AddTeamSuggestions=true`
|
||||
- Allows you to turn off suggestions for teams in the scoreboard command. This is enabled by default, disabling this can help with performance if there are a lot of teams defined.
|
||||
Setting "command-suggestions" to false in the config will also disable this.
|
||||
- `-DGeyser.NoPlayerListPS=true`
|
||||
- Enables a less-than-ideal workaround to resolve client crashing when chatting / typing commands on PlayStation consoles with lots of player online.
|
||||
Disabled by default, as it is not needed for most setups.
|
||||
- `-DGeyser.RakPacketLimit=120`
|
||||
- Sets RakNet's per-ip per-tick (10ms) post-connection packet limit.
|
||||
- `-DGeyser.RakGlobalPacketLimit=100000`
|
||||
|
||||
@@ -5,10 +5,10 @@ description: 'Geyser is a bridge between Minecraft: Bedrock Edition and Minecraf
|
||||
---
|
||||
|
||||
import { Versions } from '@site/src/components/Versions'
|
||||
import { useDocById } from '@docusaurus/theme-common/internal'
|
||||
import { useDocById } from '@docusaurus/plugin-content-docs/client'
|
||||
import DocCardList from '@theme/DocCardList'
|
||||
|
||||
# Overview
|
||||
# Overview \{#overview}
|
||||
|
||||
[//]: # ([](LICENSE))
|
||||
[](https://github.com/GeyserMC/Geyser/actions/workflows/build.yml)
|
||||
@@ -23,7 +23,7 @@ Here are a few selected guides that will help you get started with Geyser!
|
||||
<DocCardList items={[
|
||||
'setup',
|
||||
'supported-versions',
|
||||
'understanding-the-config',
|
||||
'commands',
|
||||
'faq',
|
||||
'common-issues',
|
||||
'extensions'
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: Nethernet Setup Guide
|
||||
description: A guide for setting Nethernet up with Geyser.
|
||||
---
|
||||
|
||||
Geyser now supports the new Nethernet mode of transport used by default on Bedrock as of build #1237, this is preferred over Raknet which will be removed in the upcoming 26.60 update (Date TBA).
|
||||
|
||||
## Differences between Nethernet and Raknet
|
||||
|
||||
The important different between Nethernet and Raknet is that Nethernet requires a TCP port **and** a UDP port, compared to Raknet that only needed a UDP port. This makes Nethernet more difficult to setup on certain hosting providers/networking setups.
|
||||
|
||||
Nethernet will do the following with a bedrock server:
|
||||
- Contact the "Signalling" server found on the TCP port in order to get the following:
|
||||
- The MOTD, player count and ping
|
||||
- The connection details with bedrock will use to connect via UDP (WebRTC)
|
||||
- The client then connects to the server via WebRTC which is where the UDP port is required
|
||||
|
||||
Raknet will do the following with a bedrock server:
|
||||
- Make a small connection to the server to get the MOTD, player count and ping
|
||||
- The client then connects to the server properly and starts sending the join data
|
||||
|
||||
This small difference shakes up the entire networking involved when connecting to a server on Bedrock. For this reason, the migration to Nethernet may be difficult for some users; but, we're hoping with the preparation time we've been given, we can make the transition smoother.
|
||||
|
||||
## What does this mean for you?
|
||||
|
||||
Depending on how you host your server, this could mean different things. Generally, you need to redo your network configurations if you made any previously for your server.
|
||||
|
||||
:::caution
|
||||
|
||||
If you used `clone-remote-port` when setting up your Geyser server, it is important to note this option **no longer works**! You must either change the port used, or setup [Nethernet External Signalling](#nethernet-external-signalling), if you do not, the Nethernet TCP port will collide with the Java server's port and the Nethernet signalling server will fail to boot, making it impossible to connect to your server.
|
||||
|
||||
:::
|
||||
|
||||
### Self-hosting
|
||||
|
||||
Ensure you have port forwarded your bedrock port for TCP also, this will allow Geyser to run the signalling server and continue accepting connections successfully. If you cannot do this for some reason, there is another option in order to get Nethernet working, see [Nethernet External Signalling](#nethernet-external-signalling).
|
||||
|
||||
### Hosting provider
|
||||
|
||||
When using a hosting provider, the fix is variable depending on which provider you're using, but we can help a bit here.
|
||||
|
||||
If you manually setup your network for Geyser by assigning a UDP port, good news! There's a good chance Nethernet should just work, as many providers will also allocate a TCP port with it. However, if this is not the case, allocate your UDP port for TCP also.
|
||||
|
||||
If you did not manage the networking, odds are you should be fine, as your hosting provider will hopefully be prepared for Nethernet, as we've given them the tools in order to get Nethernet setup.
|
||||
|
||||
If you only needed to enable `clone-remote-port`, see the caution above, with describes why this option **no longer works**.
|
||||
|
||||
If after this, none of those options worked, you may want to look into [Nethernet External Signalling](#nethernet-external-signalling).
|
||||
|
||||
## Nethernet External Signalling
|
||||
|
||||
Nethernet External Signalling (or NXS for short) is an open standard developed by [Open Collaboration](https://opencollaboration.dev/) alongside [Ziax](https://ziax.com/)! This standard allows you to run the Nethernet signalling server (the TCP port part) away from your server, then have them connect to each other!
|
||||
|
||||
This is good because:
|
||||
- The signalling server can handle multiple servers at once, under a single port, making the networking setup more simple
|
||||
- Any external provider can be used, not just your own, for example, [Warden](#warden-signalling)
|
||||
- A hosting provider can automatically setup a signalling server and tell Geyser to use it, making setup much simpler!
|
||||
|
||||
### Warden Signalling
|
||||
|
||||
Warden Signalling, or just Warden, is a free service offered by [Ziax](https://ziax.com/) which Geyser can connect to in order to be given an IP which can be used to connect to your server!
|
||||
|
||||
What this means:
|
||||
- You do not need to forward a TCP port
|
||||
- You will not have a custom IP address, but something like `turquoisemango.wdn.gg` instead
|
||||
- You **still** need to forward a UDP port for Warden to connect to, otherwise Warden will send the client to an unconnectable address
|
||||
- You do not need any other signalling server, Warden is plug and play with Geyser
|
||||
|
||||
:::info
|
||||
|
||||
Warden is designed for smaller servers, if you own a big server, it is strongly advised you use your own signalling server or use Geyser's built in one.
|
||||
|
||||
:::
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Using Resource Packs with Geyser
|
||||
description: This page explains how to use resource packs with Geyser.
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
Geyser supports sending Bedrock edition resource packs to connecting Bedrock clients.
|
||||
However, Geyser does not convert resource packs from the Java Edition format into the Bedrock edition format.
|
||||
|
||||
Resource packs offer a range of customization options. Just like on Java, they can be used for a wide variety of things:
|
||||
- Texture Modifications: Resource packs can change the look of blocks, items, and entities, providing a unique visual experience.
|
||||
- Sound Changes: Custom sound effects or music tracks can be added to create a more immersive atmosphere.
|
||||
- UI Enhancements: Resource packs can modify the user interface - a popular example would be providing a dark mode UI option.
|
||||
... and much more!
|
||||
|
||||
# Using resource packs
|
||||
|
||||
### Sending local packs
|
||||
The easiest way to send resource packs to Bedrock players is by putting the Bedrock edition resource pack, either as a `.zip` or `.mcpack` file, into Geyser's `packs` folder.
|
||||
|
||||
Location of the 'packs' folder:
|
||||
|
||||
- Fabric/NeoForge: `/config/Geyser-<platform>/packs/`
|
||||
- Geyser Standalone: `/packs/` at the root directory
|
||||
- Other platforms: `/plugins/Geyser-<platform>/packs/`
|
||||
|
||||
After restarting the server (or reloading Geyser), players that connect will receive all packs that are in that folder.
|
||||
|
||||
|
||||
### Remote pack urls (accessible using the Geyser API)
|
||||
As an alternative to sending local packs, you can also send resource packs by sending Bedrock players a link to download the packs from.
|
||||
This works similarly to Java edition's pack downloading. However, there are a few key limitations:
|
||||
|
||||
- The link must be a direct link to the resource pack download (it will follow redirects, but those must result in a file download)
|
||||
- The Content-Length header must specify the exact file size.
|
||||
- The Content-Type application header must be set to `application/zip`.
|
||||
|
||||
Geyser will download your configured remote resource packs once on boot, and warn you if any of these conditions are not met.
|
||||
It is unfortunately not possible to bypass these, as these are restrictions imposed by the Bedrock client.
|
||||
|
||||
To verify headers manually, curl the website and check the values.
|
||||
For example:
|
||||
`curl -I -L https://download.geysermc.org/v2/projects/geyseroptionalpack/versions/1.0.10/builds/11/downloads/geyseroptionalpack` returns the following:
|
||||
- `-I`: This option tells curl to fetch the HTTP response headers in the output.
|
||||
- `-L`: Ensures that curl follows redirects
|
||||
|
||||
The output for this shows the following:
|
||||
```shell
|
||||
HTTP/1.1 200 OK
|
||||
Date: Wed, 03 Jul 2024 23:03:06 GMT
|
||||
Content-Type: application/zip
|
||||
Content-Length: 95400
|
||||
Connection: keep-alive
|
||||
access-control-allow-methods: GET
|
||||
access-control-allow-origin: *
|
||||
Cache-Control: public, s-maxage=1209600
|
||||
content-disposition: attachment; filename="=?UTF-8?Q?GeyserOptionalPack.mcpack?="; filename*=UTF-8''GeyserOptionalPack.mcpack
|
||||
etag: "0258409cde3a2906e1085490fa5b10b77"
|
||||
last-modified: Wed, 03 Jul 2024 08:42:41 GMT
|
||||
CF-Cache-Status: HIT
|
||||
Age: 21500
|
||||
Accept-Ranges: bytes
|
||||
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=DUpNVi9R96y13%2BlJm%2BNTpDLvSt9bw9CFDUh8Qwhpb9SsqjJbuInBGtSM5hiM2dGbSGkUccP4KvSqqD%2FCKrrcQ9ur5at5G0u8FrfooVTKLP%2B4MwGoUl29DwlxeMVg6tX36RjjICmV97M4FlErCZEe%2F3gM%2FA%3D%3D"}],"group":"cf-nel","max_age":604800}
|
||||
NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
|
||||
Server: cloudflare
|
||||
CF-RAY: 89da81ca69c63735-FRA
|
||||
alt-svc: h3=":443"; ma=86400
|
||||
```
|
||||
This shows that the content-length is indeed set correctly, and that the content type indeed is `application/zip`.
|
||||
Further, Geyser will attempt to read the `ETag` to see if the content has changed. To query that, you can use the following:
|
||||
|
||||
`curl -I -L -v https://download.geysermc.org/v2/projects/geyseroptionalpack/versions/1.0.10/builds/11/downloads/geyseroptionalpack 2>&1 | grep ETag`
|
||||
Alternatively, just using the `-v` header will turn on verbose mode that would also display the etag.
|
||||
|
||||
# Common questions
|
||||
|
||||
- **Does Geyser support behavior packs/add-ons?** <br />
|
||||
No. These would require modifications on the Java server side, which isn't possible when Geyser is used on a proxy.
|
||||
However, many things that are possible with add-ons or behavior packs can be done with Geyser's API - such as [custom items](/wiki/geyser/custom-items)
|
||||
or [custom blocks](/wiki/geyser/custom-blocks).
|
||||
|
||||
- **Does Geyser convert Java edition resource packs?** <br />
|
||||
Not currently. For now, you need to manually create a Bedrock edition resource pack equivalent. You can however
|
||||
use automatic tools such as [Rainbow](/wiki/other/rainbow/) or [Thunder](/wiki/other/thunder) to make converting content simpler.
|
||||
|
||||
- **Can I allow players to choose resource packs themselves?** <br />
|
||||
On most Bedrock platforms (except consoles), players are able to download and install resource packs on the client.
|
||||
There is also a Geyser extension, [PickPack](https://github.com/onebeastchris/PickPack) that uses the Geyser API to allow all Bedrock players to choose from a set of resource packs.
|
||||
|
||||
- **On proxy setups: Are per-backend-server resource packs possible?** <br />
|
||||
This unfortunately is not possible natively, as Bedrock edition only allows removing and adding packs when connecting initially to the server.
|
||||
However, with the usage of the transfer packet, it is possible to instruct the Bedrock client to re-connect to the server, and to apply changes then.
|
||||
For per-server-packs, you can use the unofficial [GeyserPackSync](https://github.com/onebeastchris/GeyserPackSync) plugin.
|
||||
|
||||
- **Does Geyser have an API to send resource packs?** <br />
|
||||
Yes! See the [Geyser API docs](/wiki/geyser/api/) for more info on that. There is a `SessionLoadResourcePacksEvent` to determine which
|
||||
packs are sent to each connecting player, or the more general `GeyserDefineResourcePacksEvent` that defines the packs all users receive.
|
||||
|
||||
- **Can I use subpacks or specify the load order of resource packs**? <br />
|
||||
You can! However, this feature requires you to use the Geyser API.
|
||||
|
||||
@@ -13,25 +13,42 @@ You must be able to connect to your Geyser instance locally!
|
||||
The playit.gg Minecraft server plugin does not support UDP tunnels. You will need to use the program agent instead!
|
||||
:::
|
||||
|
||||
- If you already have playit.gg running & set up (for e.g. Minecraft Java edition), skip steps 1 and 2 and proceed with step 3.
|
||||
|
||||
## Setup {#setup}
|
||||
1. Head over to [playit.gg's website](https://playit.gg/) - download the program & run it. It will open the login site in the browser - create an account & sign in. Or, use a guest account.
|
||||
2. Once logged in, make sure to connect the program + site, until step 4 is reached. This should happen automatically, if it does not, follow the instructions on the website and the playit.gg program console.
|
||||

|
||||
3. Click "Create Tunnel" if you see the screen above, or, select the "Tunnels" tab when logged in to your account. There, select "Minecraft Bedrock", leave "Enable Tunnel" ticked, and click "Add tunnel".
|
||||

|
||||
4. Once "Add tunnel" is clicked, it should create a new tunnel, and you are set! Scroll down until you see this:
|
||||

|
||||
If you have Geyser running on a port that is not 19132, update the port there. The "Local Address" does not need to be changed unless you are not running playit.gg and Geyser on the same device.
|
||||
5. Connect to your server - use the IP and Port from the "Allocation" tab. In our example - "180.ip.ply.gg" as the IP, and "17019" as the port. Alternatively, use the Domain it gives you instead of the IP.
|
||||
6. If you join successfully, then you are done! Make sure to leave the playit.gg program running as closing it will close the tunnel. You also may want to ratelimit individual connections - use the "Per Connection Rate Limit" option to do so.
|
||||
1. Head over to [playit.gg's website](https://playit.gg/) - download the program & run it.
|
||||
2. The program will provide a claiming link. Visit that link, log in.
|
||||

|
||||
3. Confirm your agent.
|
||||

|
||||
4. Add the agent.
|
||||

|
||||
5. After the agent is created, create a tunnel.
|
||||

|
||||
6. Name your tunnel and click Next.
|
||||

|
||||
7. Select "Minecraft Bedrock" as the tunnel type and click Next.
|
||||

|
||||
8. Select the Free Network and click Next.
|
||||

|
||||
**Do not change your Geyser port in `config.yml` unless you have a reason (for example, hosting another Geyser server on the same machine).** The Bedrock (Geyser) port in `config.yml` and the playit.gg ports are separate. playit.gg will forward its port to the default Geyser port and should work as-is. Changing it can cause errors. If you have changed your config port, set the Bedrock port back to the default `19132` and ensure `clone-remote-port` is `false`.
|
||||
9. If the playit.gg agent and Geyser are running on the same device, leave the IP as `127.0.0.1` and set the port to whatever you configured in Geyser's config.
|
||||

|
||||
10. Select `proxy-protocol-v2` for the Proxy Protocol section and click Next.
|
||||
11. In the Geyser config, under `advanced:` `bedrock:`, set `use-haproxy-protocol` to `true`.
|
||||
12. Click Create Tunnel and wait for the tunnel to be created.
|
||||

|
||||
13. Copy your tunnel's port. For example, if your tunnel address is `visiting-phone.gl.at.ply.gg:6695`, then `6695` is the tunnel port.
|
||||
14. In the Geyser config under `advanced:` `bedrock:`, set `broadcast-port` to your tunnel port (`6695` in the example).
|
||||
15. Save your config. Start your Minecraft server and connect using your tunnel's IP and port.
|
||||
16. If you join successfully, then you are done! Make sure to leave the playit.gg program running as closing it will close the tunnel. You also may want to ratelimit individual connections - use the "Per Connection Rate Limit" option to do so.
|
||||
(If you failed to join, check out the [troubleshooting](#troubleshooting) section of the page.)
|
||||
|
||||
## Troubleshooting {#troubleshooting}
|
||||
|
||||
### I can't connect to my server! {#i-cant-connect-to-my-server}
|
||||
* *Try going to the Agents page, set your agent to IPv4 only, and change the region. You may need to switch regions a few times before you can connect.*
|
||||
* *Are there errors in your minecraft server console?*
|
||||
* *Make sure to check [here](/wiki/geyser/fixing-unable-to-connect-to-world/) beforehand.*
|
||||
* *If you changed the port that Geyser would bind to, you'll have to tell playit.gg to use that port instead! See step 5 here.*
|
||||
* *(Alternatively: You can try setting the* `bedrock` `port` *in the Geyser configuration to* `19132`.)
|
||||
* *Unless you manually changed the "Local Port" on the playit.gg website, in Geyser config, ensure that the bedrock port is the default of `19132` and that `clone-remote-port` is `false`.*
|
||||
* *If you changed the `bedrock-port` or set `clone-remote-port` to `true` and have a reason for doing so (e.g. hosting another Geyser server on the same machine), you'll have to tell playit.gg to use that port instead! See the last paragraph in step 8.*
|
||||
* *Check that you're joining with playit.gg's IP and port from the "Allocation" tab.*
|
||||
* *Make sure that you have the program agent open while trying to join.*
|
||||
* *See [here](/wiki/geyser/fixing-unable-to-connect-to-world/) for general troubleshooting steps.*
|
||||
@@ -183,8 +183,9 @@ sudo firewall-cmd --reload
|
||||
|
||||
#### Ubuntu {#ubuntu}
|
||||
|
||||
1. Remove/comment out `-A INPUT -j REJECT --reject-with icmp-host-prohibited` in the `/etc/iptables/rules.v4` file.
|
||||
2. Run the following command to fix `ufw`:
|
||||
```bash
|
||||
sudo iptables-restore < /etc/iptables/rules.v4
|
||||
Run the following commands to allow Minecraft and Geyser through the OS firewall:
|
||||
|
||||
```bash
|
||||
sudo ufw allow 25565/tcp
|
||||
sudo ufw allow 19132/udp
|
||||
```
|
||||