<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>GeyserMC Blog</title>
        <link>https://geysermc.org/blog</link>
        <description>GeyserMC Blog</description>
        <lastBuildDate>Sun, 30 Nov 2025 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Bedrock Early Packet Handling DoS Attack Summary and Response]]></title>
            <link>https://geysermc.org/blog/early-packet-handling-attack</link>
            <guid>https://geysermc.org/blog/early-packet-handling-attack</guid>
            <pubDate>Sun, 30 Nov 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[A summary of how we addressed a series of exploits targeting Geyser's early handling of Bedrock game packets]]></description>
            <content:encoded><![CDATA[<p>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 <a href="https://geysermc.org/download" target="_blank" rel="noopener noreferrer">https://geysermc.org/download</a>. The original <a href="https://github.com/GeyserMC/Geyser/security/advisories/GHSA-m2q6-2hwr-643w" target="_blank" rel="noopener noreferrer">security advisory</a> for this vulnerability was published on the <a href="https://github.com/GeyserMC/Geyser" target="_blank" rel="noopener noreferrer">GeyserMC/Geyser</a> repository. This response will detail the timeline, attack vectors, how they were patched, and additional measures we took to prevent future attacks.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="timeline-utc">Timeline (UTC)<a href="https://geysermc.org/blog/early-packet-handling-attack#timeline-utc" class="hash-link" aria-label="Direct link to Timeline (UTC)" title="Direct link to Timeline (UTC)">​</a></h2>
<ul>
<li><strong>July 29th, 9:40PM:</strong> Server being attacked privately reports the issue to Geyser and shares logs</li>
<li><strong>July 29th, 11:45PM:</strong> Preemptive patch is released to limit the number of authenticated connections per address</li>
<li><strong>July 30th, 5:36PM:</strong> Large servers continue to report attacks with newer builds of Geyser</li>
<li><strong>July 30th, 6:20PM:</strong> A server being attacked provides us with packet logs, illustrating what Bedrock packets malicious clients are using to carry out the attack</li>
<li><strong>July 30th, 6:52PM:</strong> Second patch is released to ensure the Bedrock client can only signal complete of resource pack sending once per session</li>
<li><strong>July 30th, 7:45PM:</strong> Issue regarding connections failing to close out is reported to upstream Bedrock protocol library</li>
<li><strong>July 30th, 9:35PM:</strong> Upstream Bedrock protocol library publishes patch to ensure connections are properly closed when Bedrock users are disconnected</li>
<li><strong>July 30th, 10:45PM:</strong> Third patch is released updating the upstream Bedrock protocol library and ensuring Bedrock connections that cause exceptions are closed immediately</li>
<li><strong>July 31st, 11:24PM:</strong> 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.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="initial-disclosure">Initial Disclosure<a href="https://geysermc.org/blog/early-packet-handling-attack#initial-disclosure" class="hash-link" aria-label="Direct link to Initial Disclosure" title="Direct link to Initial Disclosure">​</a></h2>
<p>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:</p>
<div class="language-log codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-log codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.183 GeyserServerChild-4-1/INFO] Player connected with username BedrockPleyer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.183 GeyserServerChild-4-1/INFO] Player connected with username BedrockPleyer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.183 GeyserServerChild-4-1/INFO] Player connected with username BedrockPleyer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.183 GeyserServerChild-4-1/ERROR] BedrockPleyer is already logged in!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.183 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[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</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[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</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[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</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.184 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[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</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.184 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.184 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.184 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.184 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.184 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.184 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.185 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[17:26:09.185 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>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.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="game-packet-and-code-analysis-of-the-first-attack-vector">Game Packet and Code Analysis of the First Attack Vector<a href="https://geysermc.org/blog/early-packet-handling-attack#game-packet-and-code-analysis-of-the-first-attack-vector" class="hash-link" aria-label="Direct link to Game Packet and Code Analysis of the First Attack Vector" title="Direct link to Game Packet and Code Analysis of the First Attack Vector">​</a></h2>
<p>Understanding this attack requires a basic understanding of the general Bedrock login process. This is detailed below:</p>
<p><img decoding="async" loading="lazy" alt="chart_04 Bedrock Login Process" src="https://geysermc.org/assets/images/chart_04-b0753f834cc5614695c4a810fdadbce2.svg#gh-light-mode-only" width="816" height="1062" class="img_ev3q"><img decoding="async" loading="lazy" alt="chart_04 Bedrock Login Process" src="https://geysermc.org/assets/images/chart_04_dark-32c163eb0cb0086a971c93db2ecdaeab.svg#gh-dark-mode-only" width="816" height="1062" class="img_ev3q"></p>
<p>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:</p>
<div class="language-log codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-log codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.767 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ClientToServerHandshakePacket</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.795 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.808 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.808 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.809 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.809 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.809 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.809 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.810 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.810 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.810 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.810 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.810 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.810 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.811 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.811 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.811 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.811 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.811 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.811 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.812 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.812 GeyserServerChild-4-1/INFO] null /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[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</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[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</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[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</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[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</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.848 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.849 GeyserServerChild-4-1/INFO] BedrockPlayer /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.849 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.849 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.849 GeyserServerChild-4-1/INFO] BedrockPlayer /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.850 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.850 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.850 GeyserServerChild-4-1/INFO] BedrockPlayer /XXX.XXX.XXX.XXX ResourcePackClientResponsePacket(packIds=[], status=COMPLETED)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.850 GeyserServerChild-4-1/ERROR] BedrockPlayer is already logged in!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:16:37.850 GeyserServerChild-4-1/INFO] Player connected with username BedrockPlayer</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The above log clearly indicates that the packet being exploited is the <a href="https://mojang.github.io/bedrock-protocol-docs/html/ResourcePackClientResponsePacket.html" target="_blank" rel="noopener noreferrer">ResourcePackClientResponsePacket</a>. 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:</p>
<p><img decoding="async" loading="lazy" alt="chart_02 Attack Summary" src="https://geysermc.org/assets/images/chart_02-24a8951d1c37f2c92d06aeeafb9c0f6d.svg#gh-light-mode-only" width="1332" height="1090" class="img_ev3q"><img decoding="async" loading="lazy" alt="chart_02 Attack Summary" src="https://geysermc.org/assets/images/chart_02_dark-b8e824989987339b6f5456b2c5e20430.svg#gh-dark-mode-only" width="1332" height="1090" class="img_ev3q"></p>
<p>The initial response to the ResourcePackClientResponsePacket is handled by <code>UpstreamPacketHandler</code>:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> </span><span class="token namespace">org</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geysermc</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geyser</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">network</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">UpstreamPacketHandler</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token plain"> </span><span class="token class-name">LoggingPacketHandler</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">PacketSignal</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">handle</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">ResourcePackClientResponsePacket</span><span class="token plain"> packet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getStatus</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">COMPLETED</span><span class="token plain"> </span><span class="token operator">-&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">geyser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getConfig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getRemote</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">authType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token class-name">AuthType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">ONLINE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">authenticate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getAuthData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">else</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token operator">!</span><span class="token function" style="color:rgb(80, 250, 123)">couldLoginUserByName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getAuthData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    </span><span class="token comment" style="color:rgb(98, 114, 164)">// We must spawn the white world</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">connect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                geyser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLogger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">info</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">GeyserLocale</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLocaleStringLog</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"geyser.network.connect"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getAuthData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token class-name">PacketSignal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">HANDLED</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>We see in the code above that this will lead to the invocation of <code>GeyserSession#authenticate</code> for most connections, as most Geyser instances use <code>AuthType.FLOODGATE</code>:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> </span><span class="token namespace">org</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geysermc</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geyser</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">GeyserSession</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">implements</span><span class="token plain"> </span><span class="token class-name">GeyserConnection</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">GeyserCommandSource</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">authenticate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">String</span><span class="token plain"> username</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">loggedIn</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            geyser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLogger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">severe</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">GeyserLocale</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLocaleStringLog</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"geyser.auth.already_loggedin"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> username</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        loggingIn </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// Always replace spaces with underscores to avoid illegal nicknames, e.g. with GeyserConnect</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        protocol </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">MinecraftProtocol</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">username</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">replace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token char" style="color:rgb(255, 121, 198)">' '</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token char" style="color:rgb(255, 121, 198)">'_'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">try</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token function" style="color:rgb(80, 250, 123)">connectDownstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Throwable</span><span class="token plain"> t</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            t</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">printStackTrace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This leads to the calling of <code>GeyserSession#connectDownstream</code>, which triggers a variety of logic to open a connection to the Java server:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> </span><span class="token namespace">org</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geysermc</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geyser</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">GeyserSession</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">implements</span><span class="token plain"> </span><span class="token class-name">GeyserConnection</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">GeyserCommandSource</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">connectDownstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token class-name">SessionLoginEvent</span><span class="token plain"> loginEvent </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">SessionLoginEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> remoteServer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">Object2ObjectOpenHashMap</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&lt;</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token class-name">GeyserImpl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getInstance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">eventBus</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">fire</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">loginEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">loginEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">isCancelled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token class-name">String</span><span class="token plain"> disconnectReason </span><span class="token operator">=</span><span class="token plain"> loginEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">disconnectReason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">==</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"> </span><span class="token operator">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token class-name">BedrockDisconnectReasons</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">DISCONNECTED</span><span class="token plain"> </span><span class="token operator">:</span><span class="token plain"> loginEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">disconnectReason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token function" style="color:rgb(80, 250, 123)">disconnect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">disconnectReason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">cookies </span><span class="token operator">=</span><span class="token plain"> loginEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">cookies</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// Don't allow changing the remote server when it's not up to us</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// Just imagine the chaos of using an integrated world manager for an external server :)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">remoteServer </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">geyser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">platformType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">==</span><span class="token plain"> </span><span class="token class-name">PlatformType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">STANDALONE</span><span class="token plain"> </span><span class="token operator">?</span><span class="token plain"> loginEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">remoteServer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">:</span><span class="token plain"> remoteServer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// Start ticking</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        tickThread </span><span class="token operator">=</span><span class="token plain"> tickEventLoop</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">scheduleAtFixedRate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">tick</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> nanosecondsPerTick</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> nanosecondsPerTick</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">TimeUnit</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">NANOSECONDS</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token class-name">ClientSession</span><span class="token plain"> downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">geyser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getBootstrap</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getSocketAddress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token comment" style="color:rgb(98, 114, 164)">// We're going to connect through the JVM and not through TCP</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            downstream </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">LocalSession</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">geyser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getBootstrap</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getSocketAddress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                upstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getAddress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getAddress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getHostAddress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">protocol</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">tickEventLoop</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MinecraftConstants</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">CLIENT_HOST</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">remoteServer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MinecraftConstants</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">CLIENT_PORT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">remoteServer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">port</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">downstream </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">DownstreamSession</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">else</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            downstream </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">ClientNetworkSession</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">InetSocketAddress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">remoteServer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">remoteServer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">port</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">protocol</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> tickEventLoop</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">downstream </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">DownstreamSession</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">boolean</span><span class="token plain"> resolveSrv </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">try</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                resolveSrv </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">remoteServer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">resolveSrv</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">AbstractMethodError</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token class-name">NoSuchMethodError</span><span class="token plain"> ignored</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token comment" style="color:rgb(98, 114, 164)">// Ignore if the method doesn't exist</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token comment" style="color:rgb(98, 114, 164)">// This will happen with extensions using old APIs</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getSession</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">BuiltinFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">ATTEMPT_SRV_RESOLVE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> resolveSrv</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// Disable automatic creation of a new TcpClientSession when transferring - we don't use that functionality.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getSession</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MinecraftConstants</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">FOLLOW_TRANSFERS</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">geyser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getConfig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getRemote</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">isUseProxyProtocol</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">BuiltinFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">CLIENT_PROXIED_ADDRESS</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> upstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getAddress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">geyser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getConfig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">isForwardPlayerPing</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token comment" style="color:rgb(98, 114, 164)">// Let Geyser handle sending the keep alive</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MinecraftConstants</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">AUTOMATIC_KEEP_ALIVE_MANAGEMENT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// We'll handle this since we have the registry data on hand</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MinecraftConstants</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SEND_BLANK_KNOWN_PACKS_RESPONSE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// We manually add the default listener to ensure the order of listeners.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        protocol</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setUseDefaultListeners</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// MCPL listener comes first to handle protocol state switching before Geyser translates packets</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addListener</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">ClientListener</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">HandshakeIntent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">LOGIN</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// Geyser adapter second to ensure translating packets in the correct states</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addListener</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">GeyserSessionAdapter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">BuiltinFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">CLIENT_TRANSFERRING</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> loginEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">transferring</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        downstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">connect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token operator">!</span><span class="token plain">daylightCycle</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token function" style="color:rgb(80, 250, 123)">setDaylightCycle</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>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, <code>GeyserSession.loggedIn</code> is set to true, preventing further calls to <code>GeyserSession#connectDownstream</code>. 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:</p>
<p><img decoding="async" loading="lazy" alt="chart_05 Multiple Sessions Class Diagram" src="https://geysermc.org/assets/images/chart_05-58e4d56838a24286c6b42596a3e4f02d.svg#gh-light-mode-only" width="1156" height="1208" class="img_ev3q"><img decoding="async" loading="lazy" alt="chart_05 Multiple Sessions Class Diagram" src="https://geysermc.org/assets/images/chart_05_dark-7d084d1607a0804e8f27401c89bfe0ee.svg#gh-dark-mode-only" width="1156" height="1208" class="img_ev3q"></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="code-analysis-of-the-second-attack-vector">Code Analysis of the Second Attack Vector<a href="https://geysermc.org/blog/early-packet-handling-attack#code-analysis-of-the-second-attack-vector" class="hash-link" aria-label="Direct link to Code Analysis of the Second Attack Vector" title="Direct link to Code Analysis of the Second Attack Vector">​</a></h2>
<p>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:</p>
<div class="language-log codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-log codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:54:29.235 GeyserServerChild-4-3/INFO] Player connected with username BedrockPlayer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[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</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:54:49.257 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[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!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:54:52.836 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:54:55.620 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:54:56.186 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:54:56.872 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:54:59.508 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:02.551 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:03.025 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:03.619 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:04.254 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:04.922 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:05.435 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:07.662 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:08.139 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:08.650 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:11.066 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:13.498 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:14.023 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:14.466 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:15.057 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:15.712 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:16.211 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:18.431 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:18.966 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:19.443 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:21.599 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:23.904 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:24.409 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:24.971 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:25.539 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[18:55:26.225 GeyserServerChild-4-3/WARN] Exception caught in session of BedrockPlayer: index: 13, length: 25710 (expected: range(0, 27))</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>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.</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> </span><span class="token namespace">org</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geysermc</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geyser</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">network</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">InvalidPacketHandler</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token plain"> </span><span class="token class-name">ChannelInboundHandlerAdapter</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">NAME</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"rak-error-handler"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">GeyserSession</span><span class="token plain"> session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Override</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">exceptionCaught</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">ChannelHandlerContext</span><span class="token plain"> ctx</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Throwable</span><span class="token plain"> cause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throws</span><span class="token plain"> </span><span class="token class-name">Exception</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token class-name">Throwable</span><span class="token plain"> rootCause </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">Stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">iterate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">cause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Throwable</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">getCause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">filter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">element </span><span class="token operator">-&gt;</span><span class="token plain"> element</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getCause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">==</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">findFirst</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">orElse</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">cause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token class-name">GeyserLogger</span><span class="token plain"> logger </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">GeyserImpl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getInstance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLogger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token operator">!</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">rootCause </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">instanceof</span><span class="token plain"> </span><span class="token class-name">IllegalArgumentException</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token comment" style="color:rgb(98, 114, 164)">// Kick users that cause exceptions</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            logger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">warning</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Exception caught in session of "</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">bedrockUsername</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">": "</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> rootCause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getMessage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">disconnect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"An internal error occurred!"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// Kick users that try to send illegal packets</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        logger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">warning</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Illegal packet from "</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">bedrockUsername</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">": "</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> rootCause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getMessage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">isDebug</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            cause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">printStackTrace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">disconnect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Invalid packet received!"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>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:</p>
<p><img decoding="async" loading="lazy" alt="chart_03 Exception Handler" src="https://geysermc.org/assets/images/chart_03-132777c3450913107932382ff28d591b.svg#gh-light-mode-only" width="1815" height="938" class="img_ev3q"><img decoding="async" loading="lazy" alt="chart_03 Exception Handler" src="https://geysermc.org/assets/images/chart_03_dark-abcf32ae4e50e3caff0edc6c9b365f72.svg#gh-dark-mode-only" width="1815" height="938" class="img_ev3q"></p>
<p>We first followed the chain of <code>GeyserSession#disconnect</code>. This invokes Geyser's <code>UpstreamSession#disconnect</code>, which contains <code>BedrockServerSession</code> and invokes <code>BedrockServerSession#disconnect</code>. Beyond this, the disconnect logic is handled by the upstream Bedrock protocol library used by Geyser, <a href="https://github.com/CloudburstMC/Protocol" target="_blank" rel="noopener noreferrer">CloudburstMC/Protocol</a>. The overall logic is summarized below:</p>
<p><img decoding="async" loading="lazy" alt="chart_01 GeyserSession Disconnect Chain" src="https://geysermc.org/assets/images/chart_01-f920d8a97f47aad6dbecf6f666b55e82.svg#gh-light-mode-only" width="1267" height="673" class="img_ev3q"><img decoding="async" loading="lazy" alt="chart_01 GeyserSession Disconnect Chain" src="https://geysermc.org/assets/images/chart_01_dark-086417a8b7b5bf624fa2b467dcd477b1.svg#gh-dark-mode-only" width="1267" height="673" class="img_ev3q"></p>
<p>Upon further investigation, we found that the Bedrock protocol library did not actually close the underlying Netty channel when a disconnect was triggered:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> </span><span class="token namespace">org</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">cloudburstmc</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">protocol</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">bedrock</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">BedrockServerSession</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token plain"> </span><span class="token class-name">BedrockSession</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">disconnect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Nullable</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> reason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">boolean</span><span class="token plain"> hideReason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">checkForClosed</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token class-name">DisconnectPacket</span><span class="token plain"> packet </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">DisconnectPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">reason </span><span class="token operator">==</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"> </span><span class="token operator">||</span><span class="token plain"> hideReason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            packet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setMessageSkipped</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            reason </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">BedrockDisconnectReasons</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">DISCONNECTED</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        packet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setKickMessage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">reason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">sendPacketImmediately</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>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.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="patch-and-mitigation">Patch and Mitigation<a href="https://geysermc.org/blog/early-packet-handling-attack#patch-and-mitigation" class="hash-link" aria-label="Direct link to Patch and Mitigation" title="Direct link to Patch and Mitigation">​</a></h2>
<p>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 <code>UpstreamPacketHandler</code> to check if the <code>finishedResourcePackSending</code> flag is already set before proceeding with authentication logic:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> </span><span class="token namespace">org</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geysermc</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geyser</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">network</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">UpstreamPacketHandler</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token plain"> </span><span class="token class-name">LoggingPacketHandler</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">PacketSignal</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">handle</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">ResourcePackClientResponsePacket</span><span class="token plain"> packet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">finishedResourcePackSending</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">            session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">disconnect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Illegal duplicate resource pack response packet received!"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token class-name">PacketSignal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">HANDLED</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getStatus</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">COMPLETED</span><span class="token plain"> </span><span class="token operator">-&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">                finishedResourcePackSending </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">geyser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getConfig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getRemote</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">authType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token class-name">AuthType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">ONLINE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">authenticate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getAuthData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">else</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token operator">!</span><span class="token function" style="color:rgb(80, 250, 123)">couldLoginUserByName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getAuthData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    </span><span class="token comment" style="color:rgb(98, 114, 164)">// We must spawn the white world</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">connect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                geyser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLogger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">info</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">GeyserLocale</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLocaleStringLog</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"geyser.network.connect"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getAuthData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token class-name">PacketSignal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">HANDLED</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This ensures that any further attempts to send a <code>ResourcePackClientResponsePacket</code> after the first one will result in an immediate disconnect, preventing the creation of multiple downstream sessions.</p>
<p>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 <code>BedrockServerSession#disconnect</code> 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:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> </span><span class="token namespace">org</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">cloudburstmc</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">protocol</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">bedrock</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">BedrockServerSession</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token plain"> </span><span class="token class-name">BedrockSession</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">TIMEOUT_SECONDS</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">SystemPropertyUtil</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getInt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"org.cloudburstmc.protocol.bedrock.disconnectTimeout"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">10</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">disconnect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Nullable</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> reason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">boolean</span><span class="token plain"> hideReason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">checkForClosed</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token class-name">DisconnectPacket</span><span class="token plain"> packet </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">DisconnectPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token class-name">String</span><span class="token plain"> finalReason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">reason </span><span class="token operator">==</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"> </span><span class="token operator">||</span><span class="token plain"> hideReason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            packet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setMessageSkipped</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            finalReason </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">BedrockDisconnectReasons</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">DISCONNECTED</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">else</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            finalReason </span><span class="token operator">=</span><span class="token plain"> reason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        packet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setKickMessage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">finalReason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">sendPacketImmediately</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">packet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token operator">!</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">isSubClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getPeer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">blackholeInboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getPeer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">channel</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">eventLoop</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">schedule</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">isConnected</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">close</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">finalReason</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">TIMEOUT_SECONDS</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">TimeUnit</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SECONDS</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Logic was also added to Geyser's <code>InvalidPacketHandler</code> to ensure that invalid packets result in an immediate closing of the underlying Netty channel:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">package</span><span class="token plain"> </span><span class="token namespace">org</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geysermc</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">geyser</span><span class="token namespace punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token namespace">network</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">InvalidPacketHandler</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token plain"> </span><span class="token class-name">ChannelInboundHandlerAdapter</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">NAME</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"rak-error-handler"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">GeyserSession</span><span class="token plain"> session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Override</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">exceptionCaught</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">ChannelHandlerContext</span><span class="token plain"> ctx</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Throwable</span><span class="token plain"> cause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throws</span><span class="token plain"> </span><span class="token class-name">Exception</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token class-name">Throwable</span><span class="token plain"> rootCause </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">Stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">iterate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">cause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Throwable</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">getCause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">filter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">element </span><span class="token operator">-&gt;</span><span class="token plain"> element</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getCause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">==</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">findFirst</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">orElse</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">cause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token class-name">GeyserLogger</span><span class="token plain"> logger </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">GeyserImpl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getInstance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLogger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token operator">!</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">rootCause </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">instanceof</span><span class="token plain"> </span><span class="token class-name">IllegalArgumentException</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token comment" style="color:rgb(98, 114, 164)">// Kick users that cause exceptions</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            logger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">error</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Exception caught in session of "</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">bedrockUsername</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> cause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">disconnect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"An internal error occurred!"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">            session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">forciblyCloseUpstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// Kick users that try to send illegal packets</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        logger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">error</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Illegal packet from "</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">bedrockUsername</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> cause</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">disconnect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Invalid packet received!"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain">        session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">forciblyCloseUpstream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="long-term-impact">Long Term Impact<a href="https://geysermc.org/blog/early-packet-handling-attack#long-term-impact" class="hash-link" aria-label="Direct link to Long Term Impact" title="Direct link to Long Term Impact">​</a></h2>
<p>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.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="acknowledgements">Acknowledgements<a href="https://geysermc.org/blog/early-packet-handling-attack#acknowledgements" class="hash-link" aria-label="Direct link to Acknowledgements" title="Direct link to Acknowledgements">​</a></h2>
<p>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.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RakNet Amplification Attack Summary and Response]]></title>
            <link>https://geysermc.org/blog/raknet-amplification-attack</link>
            <guid>https://geysermc.org/blog/raknet-amplification-attack</guid>
            <pubDate>Sun, 05 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[A look at how we dealt with an exploit in the RakNet protocol]]></description>
            <content:encoded><![CDATA[<p>In March, we were made aware of an exploit in the RakNet networking library used by Geyser, making Geyser instances vulnerable to use in a Distributed Denial of Service (DDoS) amplification attack. This bug was patched on all builds of Geyser numbered 478 and later. If you are still running an outdated build of Geyser, you should update immediately by downloading the latest build from <a href="https://geysermc.org/download" target="_blank" rel="noopener noreferrer">https://geysermc.org/download</a>. The original <a href="https://github.com/CloudburstMC/Network/security/advisories/GHSA-6h3m-c6fv-8hvh" target="_blank" rel="noopener noreferrer">security advisory</a> for this vulnerability was published on the <a href="https://github.com/CloudburstMC/Network" target="_blank" rel="noopener noreferrer">CloudburstMC/Network</a> repository. This post will detail the timeline, anatomy of the attack, our response, and additional measures we have taken to prevent similar attacks in the future.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="timeline-utc">Timeline (UTC)<a href="https://geysermc.org/blog/raknet-amplification-attack#timeline-utc" class="hash-link" aria-label="Direct link to Timeline (UTC)" title="Direct link to Timeline (UTC)">​</a></h2>
<ul>
<li><strong>March 24th, 11:00AM</strong>: bStats data begins to show instability in the number of online Geyser instances</li>
<li><strong>March 28th,  5:00AM</strong>: First reported Geyser instance causing server suspension by OVH</li>
<li><strong>March 28th,  4:00PM</strong>: First GitHub issue is opened referencing spamming of suspicious connections</li>
<li><strong>March 28th,  5:00PM</strong>: Attack against the Global Linking Server, which also hosts the Global API and Geyser Test Server, takes all three services offline</li>
<li><strong>March 28th,  6:07PM</strong>: The Global API server is started to begin restoration of the database from the MariaDB log</li>
<li><strong>March 28th,  6:27PM</strong>: The packets sent from Geyser responsible for the suspension of the Geyser Test Server machine are identified as being 134 bytes each sent at a rate of 60,000 packets per second</li>
<li><strong>March 28th,  6:30PM</strong>: A build of Geyser with enhanced logging for the Cloudburst Network library is installed on the test server to gather data about the attack vector.</li>
<li><strong>March 28th,  7:48PM</strong>: Database restoration is completed and the Global API is brought back online, but remains unstable due to the initial backlog of requests from the downtime</li>
<li><strong>March 28th,  8:46PM</strong>: Global API stability returns to normal</li>
<li><strong>March 29th,  1:30AM</strong>: Initial rate limiting is implemented in Geyser from upstream changed in Cloudburst Network, but the specific attack vector is still unclear</li>
<li><strong>March 29th,  3:32AM</strong>: Packet responsible is identified as Connection Request Accepted, sent by Geyser in the initial RakNet handshake</li>
<li><strong>March 29th,  6:00AM</strong>: Initial proof of concept is created showing a client can maliciously spam Connection Request packets, causing the server to reply with larger Connection Request Accepted packets</li>
<li><strong>March 29th, 12:25PM</strong>: Further rate limiting is added to Geyser via Cloudburst Network, particularly for replies to Connection Request packets</li>
<li><strong>March 30th,  9:20AM</strong>: A raw packet capture is obtained from a Geyser instance under attack, unmasking the root cause of the issue as the RakNet reliability setting of the Connection Request Accepted packet in Cloudburst Network</li>
<li><strong>March 30th, 10:30AM</strong>: A final fix to Cloudburst Network is pushed to Geyser, and a previously exploited instance is monitored with full packet dumps to confirm the fix</li>
<li><strong>March 30th, 10:28PM</strong>: Security advisory is published on the Cloudburst Network GitHub repository</li>
<li><strong>March 30th, 10:31PM</strong>: First @everyone ping in 1 year is made in the Geyser Discord announcing the security advisory and requesting all server owners update their instances as soon as possible</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="initial-warning-signs">Initial Warning Signs<a href="https://geysermc.org/blog/raknet-amplification-attack#initial-warning-signs" class="hash-link" aria-label="Direct link to Initial Warning Signs" title="Direct link to Initial Warning Signs">​</a></h2>
<p>Before the issue was initially detected, a suspicious trend can be seen in Geyser’s bStats data. On March 24th starting at approximately 11:00AM UTC, noticeable dips are seen in the total number of online Geyser instances. Normally, the number of online instances smoothly climbs and falls by about 500 instances, likely correlating with when people have free time to play Minecraft. Beginning on March 24th, frequent hourly swings of as much as 2200 instances online are seen. Given hindsight, this is likely when wide scale exploitation of this attack began.</p>
<table><thead><tr><th style="text-align:center"><img decoding="async" loading="lazy" alt="Geyser bStats Usage" src="https://geysermc.org/assets/images/geyser-bstats-usage-0574dd172f3cf90108e8161142590ecd.png" width="1276" height="399" class="img_ev3q"></th></tr></thead><tbody><tr><td style="text-align:center"><em>bStats chart of servers using Geyser over the month of March. Clear instability in the number of online servers reported is seen at the left starting on March 24th, at least three days before any formal reports of the attack were received.</em></td></tr></tbody></table>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="initial-disclosure">Initial Disclosure<a href="https://geysermc.org/blog/raknet-amplification-attack#initial-disclosure" class="hash-link" aria-label="Direct link to Initial Disclosure" title="Direct link to Initial Disclosure">​</a></h2>
<p>Multiple users in the Geyser Discord first brought the attack to our attention by providing us with notices from their hosting provider that their server instances were suspended due to abuse. This means that their Geyser instances were sending outbound traffic interpreted by their hosting provider interpreted as a denial of service attack. Here is a snippet from one of these notices:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">##############################################################################</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">#       DDoS-Attack detected from host XXX.XXX.XXX.XXX                       #</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">##############################################################################</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">TIME                             	SRC       	SRC-PORT  -</span><span class="token operator">&gt;</span><span class="token plain">  DST       	DST-PORT  SIZE  PROT</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">----------------------------------------------------------------------------------------------------------</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token number">2024</span><span class="token plain">-03-28 06:49:06.493070866 +0100  XXX.XXX.XXX.XXX	</span><span class="token number">19132</span><span class="token plain">  -</span><span class="token operator">&gt;</span><span class="token plain">  </span><span class="token number">51.75</span><span class="token plain">.XXX.XXX    	</span><span class="token number">1</span><span class="token plain">   </span><span class="token number">134</span><span class="token plain">   UDP</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token number">2024</span><span class="token plain">-03-28 06:49:06.50822918  +0100  XXX.XXX.XXX.XXX	</span><span class="token number">19132</span><span class="token plain">  -</span><span class="token operator">&gt;</span><span class="token plain">  </span><span class="token number">51.75</span><span class="token plain">.XXX.XXX    	</span><span class="token number">1</span><span class="token plain">   </span><span class="token number">134</span><span class="token plain">   UDP</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token number">2024</span><span class="token plain">-03-28 06:49:06.515954324 +0100  XXX.XXX.XXX.XXX	</span><span class="token number">19132</span><span class="token plain">  -</span><span class="token operator">&gt;</span><span class="token plain">  </span><span class="token number">51.75</span><span class="token plain">.XXX.XXX    	</span><span class="token number">1</span><span class="token plain">   </span><span class="token number">134</span><span class="token plain">   UDP</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token number">2024</span><span class="token plain">-03-28 06:49:06.519665639 +0100  XXX.XXX.XXX.XXX	</span><span class="token number">19132</span><span class="token plain">  -</span><span class="token operator">&gt;</span><span class="token plain">  </span><span class="token number">51.75</span><span class="token plain">.XXX.XXX    	</span><span class="token number">1</span><span class="token plain">   </span><span class="token number">134</span><span class="token plain">   UDP</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token number">2024</span><span class="token plain">-03-28 06:49:06.523410527 +0100  XXX.XXX.XXX.XXX	</span><span class="token number">19132</span><span class="token plain">  -</span><span class="token operator">&gt;</span><span class="token plain">  </span><span class="token number">51.75</span><span class="token plain">.XXX.XXX    	</span><span class="token number">1</span><span class="token plain">   </span><span class="token number">134</span><span class="token plain">   UDP</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token number">2024</span><span class="token plain">-03-28 06:49:06.526647418 +0100  XXX.XXX.XXX.XXX	</span><span class="token number">19132</span><span class="token plain">  -</span><span class="token operator">&gt;</span><span class="token plain">  </span><span class="token number">51.75</span><span class="token plain">.XXX.XXX    	</span><span class="token number">1</span><span class="token plain">   </span><span class="token number">134</span><span class="token plain">   UDP</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token number">2024</span><span class="token plain">-03-28 06:49:06.53355138  +0100  XXX.XXX.XXX.XXX	</span><span class="token number">19132</span><span class="token plain">  -</span><span class="token operator">&gt;</span><span class="token plain">  </span><span class="token number">51.75</span><span class="token plain">.XXX.XXX    	</span><span class="token number">1</span><span class="token plain">   </span><span class="token number">134</span><span class="token plain">   UDP</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token number">2024</span><span class="token plain">-03-28 06:49:06.537470479 +0100  XXX.XXX.XXX.XXX	</span><span class="token number">19132</span><span class="token plain">  -</span><span class="token operator">&gt;</span><span class="token plain">  </span><span class="token number">51.75</span><span class="token plain">.XXX.XXX    	</span><span class="token number">1</span><span class="token plain">   </span><span class="token number">134</span><span class="token plain">   UDP</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><em>Abuse report from OVH regarding the suspension of server running a Geyser instance.</em></p>
<p>This is the first information we were presented with regarding the attack vector. Based on this, we  can determine the rough speed of the attack by subtracting the time of the last packet in the report from the first packet (0.044399613 seconds) and dividing the packets sent in that timeframe (8 packets) by the time, we can see about 180 packets per second are being sent here. We are also given the size of the packet on the wire, which is 134 bytes. It’s important to note that this is the size of the packet as it exits the provider network, so it should only contain the destination headers for the public IP address.</p>
<p>Logs were also provided by another user, which show that after many repeated connection attempts, Cloudburst Network was unable to keep up and packet byte buffer handling was compromised.</p>
<div class="language-log codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-log codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">[nioEventLoopGroup-5-1/ERROR] [org.cloudburstmc.netty.channel.raknet.RakChannelPipeline]: Exception thrown in RakNet pipeline</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">io.netty.handler.codec.DecoderException: java.lang.NullPointerException: Cannot invoke "io.netty.buffer.ByteBuf.release()" because "this.buffer" is null</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:98)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at org.cloudburstmc.netty.handler.codec.raknet.server.RakServerRouteHandler.channelRead(RakServerRouteHandler.java:60)  </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  ...</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at org.cloudburstmc.netty.handler.codec.raknet.AdvancedChannelInboundHandler.channelRead(AdvancedChannelInboundHandler.java:48)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  ...</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at org.geysermc.geyser.network.netty.handler.RakConnectionRequestHandler.channelRead(RakConnectionRequestHandler.java:80)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  ...</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at org.cloudburstmc.netty.handler.codec.raknet.ProxyInboundRouter.channelRead(ProxyInboundRouter.java:66)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  ...</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Caused by: java.lang.NullPointerException: Cannot invoke "io.netty.buffer.ByteBuf.release()" because "this.buffer" is null</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  at org.cloudburstmc.netty.channel.raknet.packet.EncapsulatedPacket.deallocate(EncapsulatedPacket.java:138)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  ... 45 more</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><em>Stacktrace from an attacked server after many hours of connection attempts, showing instability in the ability of Cloudburst Network to process packets.</em></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="reproduction-attempts">Reproduction Attempts<a href="https://geysermc.org/blog/raknet-amplification-attack#reproduction-attempts" class="hash-link" aria-label="Direct link to Reproduction Attempts" title="Direct link to Reproduction Attempts">​</a></h2>
<p>Given that the packet spam was occurring without Bedrock login taking place, the vulnerability was likely in the initial establishment of the RakNet connection. Minecraft Bedrock Edition uses a modified version of the RakNet protocol which has gone largely unchanged for many years and is unofficially documented at <a href="https://wiki.vg/Raknet_Protocol" target="_blank" rel="noopener noreferrer">https://wiki.vg/Raknet_Protocol</a>. Before game packets are sent, the connection is established with 7 packets, four of which are sent by the client and three of which are sent by the server. It was likely that one of these three packets was being spammed by the Geyser instance. The initial RakNet connection follows the sequence:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">Client -</span><span class="token operator">&gt;</span><span class="token plain"> Server</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> Open Connection Request </span><span class="token number">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">Server -</span><span class="token operator">&gt;</span><span class="token plain"> Client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> Open Connection Reply </span><span class="token number">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">Client -</span><span class="token operator">&gt;</span><span class="token plain"> Server</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> Open Connection Request </span><span class="token number">2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">Server -</span><span class="token operator">&gt;</span><span class="token plain"> Client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> Open Connection Reply </span><span class="token number">2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">RakNet connection is established and further messages now wrapped </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">in</span><span class="token plain"> Frame Set Packet</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">FSP</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">Client -</span><span class="token operator">&gt;</span><span class="token plain"> Server</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> Connection Request</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">FSP</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">Server -</span><span class="token operator">&gt;</span><span class="token plain"> Client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> Connection Request Accepted</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">FSP</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">Client -</span><span class="token operator">&gt;</span><span class="token plain"> Server</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> New Incoming Connection</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><em>Summary of the RakNet initial connection sequence. Note that the ability to utilize RakNet reliability settings begin only once packets are wrapped in a Frame Set Packet.</em></p>
<p>Given that the packet being spammed is coming from the server, and given it has a known outbound length of 134 bytes, we can analyze a normal connection to Geyser in Wireshark to determine the most likely responsible packet:</p>
<table><thead><tr><th style="text-align:center"><img decoding="async" loading="lazy" alt="Wireshark Initial RakNet Connection" src="https://geysermc.org/assets/images/wireshark-initial-raknet-connection-5d4aae6dc9622d1596475928edb9538d.png" width="1193" height="714" class="img_ev3q"></th></tr></thead><tbody><tr><td style="text-align:center"><em>Wireshark packet capture of a Geyser server at the initial RakNet connection stage. A hex dump of the Connection Request Accepted packet, sent by the server to the client, is shown. Note that byte numbers start at 0.</em></td></tr></tbody></table>
<p>We can see that on the client end, Connection Request Accepted is 148 bytes over the wire. However, if we subtract the 14 bytes of headers (bytes 0 to 13) added by the local network for routing, we get a size of 134 bytes when the packet left the provider network. Knowing this packet is likely responsible, we can consider how we might get the server to send many of them. One somewhat naive approach we took initially was sending many Connection Request packets once receiving Open Connection Reply 2 from the server. This does indeed result in the server sending many connection request accepted packets, showing there indeed was potential for abuse in Cloudburst Network’s existing implementation:</p>
<table><thead><tr><th style="text-align:center"><img decoding="async" loading="lazy" alt="Wireshark Reproduction Attempt" src="https://geysermc.org/assets/images/wireshark-reproduction-attempt-d53e1ee2667c18b7a75d1b36abfa6fa2.png" width="1189" height="1067" class="img_ev3q"></th></tr></thead><tbody><tr><td style="text-align:center"><em>Wireshark packet capture of a Geyser instance after being sent hundreds of Connection Request packets by a single client. The Geyser instance consequently replies with an equal number of Connection Request Accepted packets.</em></td></tr></tbody></table>
<p>That said, this is at best an amplification factor of two. By now, we had some bandwidth data of the attack, showing an amplification factor of at least 350 in the wild. Given this, there must have been a way to get this packet to be sent many more times.</p>
<table><thead><tr><th style="text-align:center"><img decoding="async" loading="lazy" alt="Pterodactyl Outbound Spike" src="https://geysermc.org/assets/images/pterodactyl-outbound-spike-6188656c37b9a6805e87fee93b1cec32.png" width="1999" height="1125" class="img_ev3q"></th></tr></thead><tbody><tr><td style="text-align:center"><em>Pterodactyl Panel dashboard of a Paper server running Geyser during an attack, showing a large outbound traffic spike. Within the short attack period, inbound traffic is only 819KiB, while outbound traffic is nearly 300MiB.</em></td></tr></tbody></table>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="live-analysis">Live Analysis<a href="https://geysermc.org/blog/raknet-amplification-attack#live-analysis" class="hash-link" aria-label="Direct link to Live Analysis" title="Direct link to Live Analysis">​</a></h2>
<p>One thing that worked in our favor, ironically, was the wide scale exploitation of this vulnerability. Since our own official test server, and even some of our personal servers, were actively being attacked at regular intervals, we had ample locations to gather data about the attack. We began taking full raw packet capture of a server actively being attacked, which would ultimately unveil the root cause of the attack.</p>
<table><thead><tr><th style="text-align:center"><img decoding="async" loading="lazy" alt="Wireshark Live Attack" src="https://geysermc.org/assets/images/wireshark-live-attack-85b0aeb2b2d81f5069fb124f309ed715.png" width="1193" height="1440" class="img_ev3q"></th></tr></thead><tbody><tr><td style="text-align:center"><em>Wireshark packet capture of a Geyser instance under attack. The highlighted packet is a NAK packet sent by the client to the Geyser instance requesting the server resend packets with sequence numbers ranging from 0 to 8191. The immediately following packet is similar, requesting packets 8192 to 16383. The attacker sent these at the beginning of the connection and then simply waited while the Geyser instance continued to send thousands of packets, with each one incrementing the sequence number, leading to yet more packets being sent until the malicious NAK requests were fulfilled.</em></td></tr></tbody></table>
<p>Looking at the packets sent by the attacker, we see that things largely follow the specified connection sequence. But we also see a new type of packet as well: a NAK packet with a range of 0 to 8191. This brings us to the topic of RakNet packet reliability.</p>
<p>Since UDP itself does not have an inbuilt handshake like TCP to ensure all data arrives bit perfect in the correct order, RakNet implements a reliability system as a substitute. For this system, each packet is sent with a reliability type. While RakNet has eight reliability types, understanding this vulnerability only requires us to understand the difference between reliable and unreliable packets. Simply put, the client can request that reliable packets be resent, while it cannot request the resend of unreliable packets. Looking at the Cloudburst Network library, we see that this packet was indeed sent as reliable.</p>
<table><thead><tr><th style="text-align:center"><img decoding="async" loading="lazy" alt="RakServerOnlineInitialHandler" src="https://geysermc.org/assets/images/rak-server-online-initial-handler-9a64078cbe9a631a6579fe6a2757e25f.png" width="1999" height="1125" class="img_ev3q"></th></tr></thead><tbody><tr><td style="text-align:center"><em>RakServerOnlineInitialHandler#sendConnectionRequestAccepted is responsible for sending the Open Connection Request packet in the initial connection sequence. The RakReliability.RELIABLE enum causes the packet to be cached by the server before it is sent, therefore allowing the client to later re-request it via NAK.</em></td></tr></tbody></table>
<p>Because the packet was marked as reliable, this means that Network allows the client to respond with an ACK (Positive Acknowledgement) or NAK (Negative Acknowledgement). At this stage in the connection, this is a vector for abuse because the client has not yet done anything to prove that we are communicating with them directly versus receiving UDP packets with spoofed IP headers. By sending a NAK with the maximum range, they force us to continuously send the Connection Request Accepted packet.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="effects">Effects<a href="https://geysermc.org/blog/raknet-amplification-attack#effects" class="hash-link" aria-label="Direct link to Effects" title="Direct link to Effects">​</a></h2>
<p>This begs the question though: why would an attacker bother doing this? The two leading theories are UDP amplification, meaning the goal is to use Geyser instances as a means to attack other servers, or provider-based suspension, meaning the goal is to get the servers running Geyser instances suspended by their hosting provider.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="udp-amplification">UDP Amplification<a href="https://geysermc.org/blog/raknet-amplification-attack#udp-amplification" class="hash-link" aria-label="Direct link to UDP Amplification" title="Direct link to UDP Amplification">​</a></h3>
<p>As explained earlier, UDP has no inbuilt handshake. This means that UDP allows for traffic to be sent to a given IP address without them acknowledging or accepting it. When the ratio of request size to response size is near one, this is largely a nonissue since an attacker gains very little by going through a third party to send the data. In this case, however, the attacker can send a very small amount of data (~52 bytes) and trigger a response of over 8000 134 byte packets. Because the connection sequence up to Connection Request Accepted is always the same and does not require the attacker to actually see the packets we respond with to respond correctly, the attacker can spoof the source IP header of the UDP packets it sends to the Geyser instance. This means that, because of this amplification vector, the Geyser instance can unwittingly be used to multiply the attacker's traffic by a theoretical maximum factor of 22,000. However, in practice, we saw that in the wild the actual multiplication factor was around 1000.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="provider-based-suspension">Provider-Based Suspension<a href="https://geysermc.org/blog/raknet-amplification-attack#provider-based-suspension" class="hash-link" aria-label="Direct link to Provider-Based Suspension" title="Direct link to Provider-Based Suspension">​</a></h3>
<p>It is also important to consider that servers are generally hosted not locally, but with hosting providers. Hosting providers have a legitimate business interest in preventing their network from being used for abuse, as failing to do so could result in other hosting providers and ISPs blocking their traffic altogether. As a result, many hosting providers employ mechanisms to detect unusual traffic from their servers and will “black hole” traffic to and from servers on their network emitting such traffic. This means that if an attacker wishes to take down a particular server, rather than overwhelm it with a traditional denial of service attack, they can simply make it appear as though the server itself is trying to engage in a denial of service attack. This will result in outbound traffic from the server being dropped by the provider, effectively having the same effect. We saw this occur, for example, with some Geyser services hosted on Hetzer as shown by the below MTR.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">mtr</span><span class="token plain"> pe.minetropical.net </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-rwbc</span><span class="token plain"> </span><span class="token number">10</span><span class="token plain">  	 </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Start: </span><span class="token number">2024</span><span class="token plain">-03-28T18:24:58+0000</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">HOST: MS.local                                             	Loss%   Snt   Last   Avg  Best  Wrst StDev</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token number">1</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- </span><span class="token number">172.16</span><span class="token plain">.0.1                                            	</span><span class="token number">0.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">	</span><span class="token number">0.8</span><span class="token plain">   </span><span class="token number">1.2</span><span class="token plain">   </span><span class="token number">0.3</span><span class="token plain">   </span><span class="token number">4.6</span><span class="token plain">   </span><span class="token number">1.3</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token number">2</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- no-ptr.ziax.ltd </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">XXX.XXX.XXX.XXX</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain">                       	</span><span class="token number">0.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">	</span><span class="token number">0.9</span><span class="token plain">   </span><span class="token number">0.8</span><span class="token plain">   </span><span class="token number">0.6</span><span class="token plain">   </span><span class="token number">1.4</span><span class="token plain">   </span><span class="token number">0.2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token number">3</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- </span><span class="token number">62.7</span><span class="token plain">.117.42                                           	</span><span class="token number">0.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">	</span><span class="token number">7.5</span><span class="token plain">   </span><span class="token number">7.6</span><span class="token plain">   </span><span class="token number">7.2</span><span class="token plain">   </span><span class="token number">8.4</span><span class="token plain">   </span><span class="token number">0.3</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token number">4</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- core2-hu0-3-0-7.colindale.ukcore.bt.net </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">217.32</span><span class="token plain">.170.174</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain">  </span><span class="token number">0.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">	</span><span class="token number">7.1</span><span class="token plain">   </span><span class="token number">7.2</span><span class="token plain">   </span><span class="token number">6.5</span><span class="token plain">   </span><span class="token number">8.2</span><span class="token plain">   </span><span class="token number">0.5</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token number">5</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- core6-hu0-3-0-15.faraday.ukcore.bt.net </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">109.159</span><span class="token plain">.252.134</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token number">20.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">	</span><span class="token number">7.5</span><span class="token plain">   </span><span class="token number">7.7</span><span class="token plain">   </span><span class="token number">7.0</span><span class="token plain">   </span><span class="token number">9.0</span><span class="token plain">   </span><span class="token number">0.6</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token number">6</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- </span><span class="token number">166</span><span class="token plain">-49-209-194.gia.bt.net </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">166.49</span><span class="token plain">.209.194</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain">            	</span><span class="token number">0.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">	</span><span class="token number">7.5</span><span class="token plain">   </span><span class="token number">7.6</span><span class="token plain">   </span><span class="token number">7.2</span><span class="token plain">   </span><span class="token number">8.8</span><span class="token plain">   </span><span class="token number">0.5</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token number">7</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- t2c4-et-5-3-0.de-fra.gia.bt.net </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">166.49</span><span class="token plain">.195.103</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain">      	</span><span class="token number">0.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">   </span><span class="token number">20.5</span><span class="token plain">  </span><span class="token number">21.4</span><span class="token plain">  </span><span class="token number">20.2</span><span class="token plain">  </span><span class="token number">24.5</span><span class="token plain">   </span><span class="token number">1.4</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token number">8</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- decix-gw.hetzner.com </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">80.81</span><span class="token plain">.192.164</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain">                  	</span><span class="token number">0.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">   </span><span class="token number">20.8</span><span class="token plain">  </span><span class="token number">20.8</span><span class="token plain">  </span><span class="token number">20.3</span><span class="token plain">  </span><span class="token number">22.0</span><span class="token plain">   </span><span class="token number">0.4</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token number">9</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- core11.nbg1.hetzner.com </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">213.239</span><span class="token plain">.252.22</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain">              	</span><span class="token number">0.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">   </span><span class="token number">25.8</span><span class="token plain">  </span><span class="token number">26.2</span><span class="token plain">  </span><span class="token number">25.5</span><span class="token plain">  </span><span class="token number">29.3</span><span class="token plain">   </span><span class="token number">1.2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token number">10</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- blocked.hetzner.com </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">88.198</span><span class="token plain">.253.78</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain">                   	</span><span class="token number">0.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">   </span><span class="token number">28.1</span><span class="token plain">  </span><span class="token number">35.7</span><span class="token plain">  </span><span class="token number">28.1</span><span class="token plain">  </span><span class="token number">76.1</span><span class="token plain">  </span><span class="token number">14.4</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token number">11</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- ???                                                  	</span><span class="token number">100.0</span><span class="token plain">	</span><span class="token number">10</span><span class="token plain">	</span><span class="token number">0.0</span><span class="token plain">   </span><span class="token number">0.0</span><span class="token plain">   </span><span class="token number">0.0</span><span class="token plain">   </span><span class="token number">0.0</span><span class="token plain">   </span><span class="token number">0.0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token number">12</span><span class="token plain">.</span><span class="token operator">|</span><span class="token plain">-- blocked.hetzner.com </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">88.198</span><span class="token plain">.253.78</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain">                  	</span><span class="token number">90.0</span><span class="token plain">%	</span><span class="token number">10</span><span class="token plain">  </span><span class="token number">2906</span><span class="token plain">. </span><span class="token number">2906</span><span class="token plain">. </span><span class="token number">2906</span><span class="token plain">. </span><span class="token number">2906</span><span class="token plain">.   </span><span class="token number">0.0</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><em>MTR (My Traceroute) shows the path packets take to a given Geyser server. In the 10th and 12th hop, we can see that the packet is being routed to the hostname blocked.hetzner.com, implying traffic to the server is being null-routed.</em></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="mitigation">Mitigation<a href="https://geysermc.org/blog/raknet-amplification-attack#mitigation" class="hash-link" aria-label="Direct link to Mitigation" title="Direct link to Mitigation">​</a></h2>
<p>Multiple forms of mitigation for this bug, as well as preventive measures to guard against future attacks have been introduced into Geyser and its upstream networking library. These include proper reliability handling during the early RakNet connection, early cookie verification, and rate limiting.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="proper-reliability-handling-in-early-raknet-connection">Proper Reliability Handling in Early RakNet Connection<a href="https://geysermc.org/blog/raknet-amplification-attack#proper-reliability-handling-in-early-raknet-connection" class="hash-link" aria-label="Direct link to Proper Reliability Handling in Early RakNet Connection" title="Direct link to Proper Reliability Handling in Early RakNet Connection">​</a></h3>
<p>The principal mitigation was changing the reliability type of the abused packet to unreliable. This means that the server will no longer respond to NAK requests for it, effectively leading to the attackers requests going unanswered. The packet capture below is taken from an instance with the reliability type of Connection Request Accepted changed to unreliable. We can see that the attacker simply continues to increment their packet range requested by NAK, but no response is provided.</p>
<table><thead><tr><th style="text-align:center"><img decoding="async" loading="lazy" alt="Wireshark Mitigated Attack" src="https://geysermc.org/assets/images/wireshark-mitigated-attack-4cb3252ba5b3d8a080778b7b54066b95.png" width="1193" height="1440" class="img_ev3q"></th></tr></thead><tbody><tr><td style="text-align:center"><em>Wireshark packet capture of a Geyser instance under attack with a build mitigating the original attack vector. The attacker is seen sending NAK packets with a sequence range of as high as 40,959. However, since the packet was not sent as reliable, there is nothing for the Geyser instance to send in response.</em></td></tr></tbody></table>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="early-cookie-verification">Early Cookie Verification<a href="https://geysermc.org/blog/raknet-amplification-attack#early-cookie-verification" class="hash-link" aria-label="Direct link to Early Cookie Verification" title="Direct link to Early Cookie Verification">​</a></h3>
<p>The underlying issue that allows for UDP amplification attacks is a lack of verification at an early stage of the connection. The original RakNet protocol actually specifies an optional solution for this. For context, RakNet was purchased by Oculus in 2014, and open sourced. Given the acquisition of Oculus by Facebook, the code for the original implementation is now archived by them. While Mojang’s implementation of RakNet has some differences from the original, it does share many of the same features. In the packet Open Connection Reply 1, the original specification refers to a boolean HasSecurity, followed by a four byte cookie if the boolean is true.</p>
<table><thead><tr><th style="text-align:center"><img decoding="async" loading="lazy" alt="Original RakNet Packets" src="https://geysermc.org/assets/images/original-raknet-packets-3ea9ef70c8542767ae80b0be6ad69c3e.png" width="1337" height="571" class="img_ev3q"></th></tr></thead><tbody><tr><td style="text-align:center"><em>This is an excerpt from the original RakNet source containing the packet identifier enums. The comments above each enum define the packet structure. These packets from the initial login sequence are largely unchanged in Mojang’s RakNet implementation, though it does not appear that the client has any support for full encryption as defined in the original specification. This can be inferred because when the HasSecurity boolean and cookie is sent by the server in Open Connection Reply 1, Open Connection Request 2 by the client does include the cookie, but sets the clientSupportsSecurity boolean to false.</em></td></tr></tbody></table>
<p>It turns out that if a cookie is supplied by the Bedrock server in Open Connection Reply 1, the Bedrock client will reply with the same cookie. This allows us to effectively verify that the IP of the Bedrock client is not being spoofed by the third packet. Were the IP of the Bedrock client being spoofed, the packet containing the cookie would be sent to the victim’s IP and be unknown to the attacker. If the attacker sends back an incorrect cookie, the connection can be terminated at that point.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="rate-limiting">Rate Limiting<a href="https://geysermc.org/blog/raknet-amplification-attack#rate-limiting" class="hash-link" aria-label="Direct link to Rate Limiting" title="Direct link to Rate Limiting">​</a></h3>
<p>In addition, Cloudburst Network also implemented three main rate limits to prevent further potential abuse of the protocol. These are summarized in the table below.</p>
<table><thead><tr><th>Name</th><th>RakNet Connection Stage</th><th>Description</th><th>Default</th></tr></thead><tbody><tr><td>RAK_PACKET_LIMIT</td><td>post-connection</td><td>per-ip per-tick (10ms) post-connection packet limit</td><td>120</td></tr><tr><td>RAK_GLOBAL_PACKET_LIMIT</td><td>post-connection</td><td>per-tick (10ms) overall packet limit</td><td>1000</td></tr></tbody></table>
<p>Geyser initially rolled out a fix that forced these defaults, but has since been <a href="https://github.com/GeyserMC/Geyser/pull/4532" target="_blank" rel="noopener noreferrer">updated</a> to allow them to be configured with system properties that are documented on the <a href="https://wiki.geysermc.org/geyser/geyser-command-line-arguments-and-system-properties/#disabling-warnings-and-advanced-configuration" target="_blank" rel="noopener noreferrer">Geyser Wiki</a>.</p>
<p>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.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">advanced.bedrock</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">use-haproxy-protocol</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">haproxy-protocol-whitelisted-ips</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://cosmic.global/ips/"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://tcpshield.com/v4/"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><em>Geyser configuration using a URL pointing a new-line separated text file containing allowed IPs for haproxy-protocol usage.</em></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="long-term-impact">Long Term Impact<a href="https://geysermc.org/blog/raknet-amplification-attack#long-term-impact" class="hash-link" aria-label="Direct link to Long Term Impact" title="Direct link to Long Term Impact">​</a></h2>
<p>It is extremely important that all those running vulnerable instances of Geyser update as soon as possible. Failure to do so may result in your Geyser instance being used to harm others via UDP denial of service amplification. We continue to see this issue being exploited in the wild as of the writing of this post, and see no reason that will stop in the foreseeable future. The number of unpatched instances will likely decrease over time as Bedrock updates force server owners to update in order to support players on the latest Bedrock version.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="acknowledgements">Acknowledgements<a href="https://geysermc.org/blog/raknet-amplification-attack#acknowledgements" class="hash-link" aria-label="Direct link to Acknowledgements" title="Direct link to Acknowledgements">​</a></h2>
<p>We thank the community for their patience as we addressed this issue, all those who responsibly disclosed this issue to us, the developers at Cloudburst and Geyser that worked to mitigate the issue, the server hosts that took an active role in ensuring instances on their hosting services were patched as soon as possible, all donors for their financial support of Geyser, and Cubecraft for their continued financial and operational support of the project.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Geyser Available for Java 1.20.5/1.20.6]]></title>
            <link>https://geysermc.org/blog/geyser-1-20-5</link>
            <guid>https://geysermc.org/blog/geyser-1-20-5</guid>
            <pubDate>Thu, 02 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Support for Java 1.20.5 and 1.20.6 has been released]]></description>
            <content:encoded><![CDATA[<p>Support for Java 1.20.5 and 1.20.6 has been released. Thank you for your patience as we work on the update!</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="new-item-components">New: item components<a href="https://geysermc.org/blog/geyser-1-20-5#new-item-components" class="hash-link" aria-label="Direct link to New: item components" title="Direct link to New: item components">​</a></h2>
<p>Gone is the item NBT to serialize extra data over the network. 1.20.5 introduces data components, which replaces the guesswork of NBT with strict objects attached to each class.</p>
<p>We’ve also been able to get rid of unreachable code from before the server inventory rewrite, back when creative mode Bedrock had the potential ability to delete NBT from items just from moving them around.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="nbt-refactor">NBT refactor<a href="https://geysermc.org/blog/geyser-1-20-5#nbt-refactor" class="hash-link" aria-label="Direct link to NBT refactor" title="Direct link to NBT refactor">​</a></h2>
<p>Since items no longer have NBT, we decided it was a good time to switch to using one NBT library. Our Bedrock protocol library used <a href="https://github.com/CloudburstMC/NBT" target="_blank" rel="noopener noreferrer">Cloudburst’s NBT implementation</a>, whereas our Java protocol library used OpenNBT. The latter has been severely neglected, and still has several cases of weird or outdated implementations, such as tag names being present in tag value objects. The entire project now uses Cloudburst’s NBT library, which is far nicer to use overall:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">boolean</span><span class="token plain"> piglinSafe </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Number</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> dimension</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"piglin_safe"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">byteValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">byte</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Changes to:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">boolean</span><span class="token plain"> piglinSafe </span><span class="token operator">=</span><span class="token plain"> dimension</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getBoolean</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"piglin_safe"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="better-tag-extensibility">Better tag extensibility<a href="https://geysermc.org/blog/geyser-1-20-5#better-tag-extensibility" class="hash-link" aria-label="Direct link to Better tag extensibility" title="Direct link to Better tag extensibility">​</a></h2>
<p>Block and item tags are now enums - this example diff to add support for <em>one</em> tag…</p>
<p><img decoding="async" loading="lazy" alt="Tag Enums" src="https://geysermc.org/assets/images/tag-enums-e4df8eb58d85c66a227d08107afc9ec5.png" width="779" height="784" class="img_ev3q"></p>
<p>…would now be adding one line of a new enum in <a href="https://github.com/GeyserMC/Geyser/blob/8b7b8cdffdb7aba97ef817037859d1151f4b2665/core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java" target="_blank" rel="noopener noreferrer">the ItemTag class</a>. And we had to add a handful of enums to add support for <a href="https://github.com/GeyserMC/Geyser/commit/59a2c0dc02abacd00fe3a72788cc9317c891557e" target="_blank" rel="noopener noreferrer">data-driven animal loved foods</a>... imagine the complexity with the first style of code!</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="no-more-trim-recipe-hardcoding">No more trim recipe hardcoding<a href="https://geysermc.org/blog/geyser-1-20-5#no-more-trim-recipe-hardcoding" class="hash-link" aria-label="Direct link to No more trim recipe hardcoding" title="Direct link to No more trim recipe hardcoding">​</a></h2>
<p>Because the server now sends all trim recipes through a packet as a registry, we’re able to get rid of this block of code that was required for trim recipes to be handled. Yay to no hardcoding!</p>
<p><img decoding="async" loading="lazy" alt="Trim Recipes" src="https://geysermc.org/assets/images/trim-recipes-4c04f2b35989ba4ef8096e08dfe4c020.png" width="805" height="454" class="img_ev3q"></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="entity-properties">Entity properties<a href="https://geysermc.org/blog/geyser-1-20-5#entity-properties" class="hash-link" aria-label="Direct link to Entity properties" title="Direct link to Entity properties">​</a></h2>
<p>Bedrock’s newer <a href="https://learn.microsoft.com/en-us/minecraft/creator/documents/introductiontoentityproperties?view=minecraft-bedrock-stable" target="_blank" rel="noopener noreferrer">entity property system</a> has now found a use in vanilla Bedrock - it controls the armadillo’s animation state (and without it, an armadillo will default to staying inside its shell!). <a href="https://github.com/Kas-tle" target="_blank" rel="noopener noreferrer">Kastle</a> came through and <a href="https://github.com/GeyserMC/Geyser/commit/99e6a2981da27a9ec8f09c04cfc8e73a296e4263" target="_blank" rel="noopener noreferrer">ported some work-in-progress code</a> so Geyser is able to work with the new system.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="special-thanks">Special Thanks<a href="https://geysermc.org/blog/geyser-1-20-5#special-thanks" class="hash-link" aria-label="Direct link to Special Thanks" title="Direct link to Special Thanks">​</a></h2>
<p>This update would have been a nightmare without the many hands we had to help implement everything we needed to get done.</p>
<p><a href="https://github.com/basaigh" target="_blank" rel="noopener noreferrer">basaigh</a> implemented the huge item changes in MCProtocolLib in a very timely fashion, meaning that Geyser could get right to updating its own code.</p>
<p><a href="https://github.com/AJ-Ferguson" target="_blank" rel="noopener noreferrer">AJ Ferguson</a> and <a href="https://github.com/onebeastchris" target="_blank" rel="noopener noreferrer">Chris</a> both helped with implementing new features and fixing regressions.</p>
<p><a href="https://github.com/Kas-tle" target="_blank" rel="noopener noreferrer">Kastle</a>, hot off the heels of stronger security protections on the Bedrock side, assisted with custom skull reimplementation and entity properties implementation.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Four Years of Geyser]]></title>
            <link>https://geysermc.org/blog/four-years-of-geyser</link>
            <guid>https://geysermc.org/blog/four-years-of-geyser</guid>
            <pubDate>Sat, 08 Jul 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Geyser is now four years old!]]></description>
            <content:encoded><![CDATA[<p>Hi everyone,</p>
<p>Today is a super special day - it's Geyser's birthday 🥳. Geyser is now four years old and booyyy has it come a long way! This is a huge day for us and an incredible milestone. We're very proud of how far we've been able to come, the amount of servers Geyser has expanded the reach of, and the amazing community behind Geyser. Seeing millions of players being able to play with their Java friends is something I never dreamed Geyser would be able to do. The growth from day one has been amazing and we're all very grateful for everyone's support 💙</p>
<p>Not only is this a special day because it's our birthday, but we have some exiting news and sneak peeks to share with you all, alongside general updates on our project development. Continue reading for more information!</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="project-statistics">Project Statistics<a href="https://geysermc.org/blog/four-years-of-geyser#project-statistics" class="hash-link" aria-label="Direct link to Project Statistics" title="Direct link to Project Statistics">​</a></h2>
<ul>
<li>Since the start of the project, there have been 3,337 commits contributed by 105 contributors</li>
<li>As of just a few days ago, Geyser has hit 4,000 stars on GitHub, making it one of the top open-source Minecraft projects ever, and <em>the</em> #1 Minecraft Bedrock project</li>
<li>Our Discord server has continued to grow, now approaching 25,000 Discord members</li>
</ul>
<p><img decoding="async" loading="lazy" src="https://github.com/GeyserMC/GeyserBlog/assets/29153871/e2d83a49-aa94-46c4-b660-4bc150331818" alt="image" class="img_ev3q"></p>
<p>None of these would have been possible without our amazing community. To that, we owe a debt of gratitude for the years of support from all of you 💙</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="project-development">Project Development<a href="https://geysermc.org/blog/four-years-of-geyser#project-development" class="hash-link" aria-label="Direct link to Project Development" title="Direct link to Project Development">​</a></h2>
<p>It's likely well-known by now that Geyser has hit a state of maturity. Since about 2021, Geyser has reached the point of full survival and creative playability for Bedrock clients on Java servers. This has allowed us to place much more focus on improving stability, fixing bugs and designing a resilient platform. We've spent the latter half of last year designing an API for Geyser, creating an extension system, and ultimately adding more for developers. A couple notable additions include custom item support and a resource pack API.</p>
<p>We've also made some major internal changes, one of the biggest being updating our Bedrock protocol library to version 3.0. This was a massive undertaking by the <a href="https://github.com/CloudburstMC/" target="_blank" rel="noopener noreferrer">CloudburstMC</a> organization, which we work closely with. While a bit bumpy at first, these changes modernized the internal RakNet library and brought along some sweet network optimizations on the Bedrock side.</p>
<p>At a steady pace, we're also working on integrating Floodgate and Geyser together! While Floodgate will still exist as a separate project for proxy and standalone instances, we are working on shipping it inside Geyser to improve setup processes and reduce complexity when creating Geyser servers. One of our goals internally has been to make the Geyser setup as seamless as possible, and this is just one way we're doing that! We'll share more on this once it gets closer to completion.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="whats-next">What's Next?<a href="https://geysermc.org/blog/four-years-of-geyser#whats-next" class="hash-link" aria-label="Direct link to What's Next?" title="Direct link to What's Next?">​</a></h2>
<p>With Geyser being in a state of maturity in terms of vanilla compatibility, we're shifting our attention onto expanding all the "custom" features Bedrock supports. There's a huge and growing demand for utilizing many of Bedrock's custom features, such as resource packs, entities, blocks, items and UIs. One of our biggest goals going forward is to design a platform that allows developers and server owners to bring their server to the next level for Bedrock players.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="api-additions">API Additions<a href="https://geysermc.org/blog/four-years-of-geyser#api-additions" class="hash-link" aria-label="Direct link to API Additions" title="Direct link to API Additions">​</a></h3>
<p>Recently, we added a <a href="https://github.com/GeyserMC/Geyser/pull/3696" target="_blank" rel="noopener noreferrer">resource pack loading API</a> which allows for developers to fine-tune and integrate their resource packs through the Geyser API, and are actively working on even more, such as <a href="https://github.com/GeyserMC/Geyser/pull/3505" target="_blank" rel="noopener noreferrer">custom blocks</a> and <a href="https://github.com/GeyserMC/Geyser/pull/3754" target="_blank" rel="noopener noreferrer">custom entities</a>. These are just a few things we're doing inside the Geyser API, but that's not all we have in store!</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="resource-pack-conversion">Resource Pack Conversion<a href="https://geysermc.org/blog/four-years-of-geyser#resource-pack-conversion" class="hash-link" aria-label="Direct link to Resource Pack Conversion" title="Direct link to Resource Pack Conversion">​</a></h3>
<p>Some of you who were around a few years ago may remember we used to maintain a resource pack conversion project. Well, we've decided to <a href="https://github.com/GeyserMC/PackConverter/tree/feature/refactor" target="_blank" rel="noopener noreferrer">revive this project</a>! While we know that third party projects exist now and handle conversions fairly well, we're working to make this part of mainline Geyser to further simplify the work needed by server owners and plugin developers. This means that once the project is integrated into Geyser, pack conversion will happen automatically. Contributions are most certainly welcome and please do reach out on Discord if you'd like to get involved!</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="wait-theres-more">Wait, there's more???<a href="https://geysermc.org/blog/four-years-of-geyser#wait-theres-more" class="hash-link" aria-label="Direct link to Wait, there's more???" title="Direct link to Wait, there's more???">​</a></h3>
<p>There is! And the exciting news is we're expanding Geyser to Forge! Of all the major platforms we support, Forge is one of the ones we do not support. We want to further expand the Geyser ecosystem, and I'm happy to announce that Geyser is coming to Forge in the next couple of weeks! This will also include some improvements to the Fabric platform as well. One such change is an integrated world manager, which exists only on Spigot platforms currently. This means Geyser will use the server to retrieve things such as blocks, significantly reducing the amount of RAM used for caching world data.</p>
<p>Additionally, since the Forge and Fabric platforms will use a common codebase for 95% of everything, thanks to <a href="https://github.com/architectury/" target="_blank" rel="noopener noreferrer">Architectury</a>, we can update both platforms very easily and changes that happen to one in most cases will carry over to the other.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="one-more-thing">One more thing...<a href="https://geysermc.org/blog/four-years-of-geyser#one-more-thing" class="hash-link" aria-label="Direct link to One more thing..." title="Direct link to One more thing...">​</a></h3>
<p>Not only are we wanting to expand what Geyser can do with custom features on <em>vanilla</em> servers, but there's a <strong>lot</strong> we want to do with both Fabric and Forge in the near future. Keep an eye out for further announcements over the next few weeks 👀🍰🥳</p>
<p><img decoding="async" loading="lazy" src="https://github.com/GeyserMC/GeyserBlog/assets/29153871/5f60d150-3081-4fe8-9dba-ce04d8edcd85" alt="Minecraft 7_8_2023 2_15_26 PM" class="img_ev3q"></p>
<p>And that's all I have to share for today! Once again, thank you all for your continued support over the years and we cannot wait to see the creativity you unleash on your server with these features! In typical Geyser fashion, here is a Gource render of all commits since the start of the project: <a href="https://youtu.be/ss6GlUkVgEE" target="_blank" rel="noopener noreferrer">https://youtu.be/ss6GlUkVgEE</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Looking back at 2022]]></title>
            <link>https://geysermc.org/blog/looking-back-at-2022</link>
            <guid>https://geysermc.org/blog/looking-back-at-2022</guid>
            <pubDate>Mon, 02 Jan 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[A look back at the year of 2022 for Geyser.]]></description>
            <content:encoded><![CDATA[<p>Hi.</p>
<p>2022 for Geyser was, in comparison to other years, rather unremarkable in terms of new features. Whereas 2021 had Bedrock skin support and complete inventory support, and 2020 had movement fixes, this year felt largely like a maintenance year. I think that’s a good thing; it means we’ve reached the point where the only things left to do are bug fixes, niche features/behavior, or updates. Even so, here are some of the notable points from Geyser in 2022, and what’s next.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="yearly-github-stats">Yearly GitHub Stats<a href="https://geysermc.org/blog/looking-back-at-2022#yearly-github-stats" class="hash-link" aria-label="Direct link to Yearly GitHub Stats" title="Direct link to Yearly GitHub Stats">​</a></h2>
<p>In 2022, we had 519 commits from 59 contributors, 85 merged PRs, and 869 new stars on the repository. The reach Geyser continues to get every year is positively astounding.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="nearly-every-floodgate-instance-breaking">(Nearly) Every Floodgate Instance Breaking<a href="https://geysermc.org/blog/looking-back-at-2022#nearly-every-floodgate-instance-breaking" class="hash-link" aria-label="Direct link to (Nearly) Every Floodgate Instance Breaking" title="Direct link to (Nearly) Every Floodgate Instance Breaking">​</a></h2>
<p>On February 2nd, 2022, Mojang snuck in a change to their API which resulted in almost every Floodgate instance involving the Paper server software breaking (likely due to <a href="https://github.com/PaperMC/Paper/blob/0cc2503b88343c4d10d9e6ecf7592d56762b4cae/patches/server/0183-Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch#L38" target="_blank" rel="noopener noreferrer">this</a> Paper patch) - even Floodgate instances only on the proxy. We swiftly put mitigations in place, and while I hope such an issue never has to happen again, the day presented a once-in-a-lifetime unique challenge in fixing a sudden, serious bug that we did not induce, and it’s a reminder that part of the job at Geyser is working around whatever changes Mojang throws at us, inside or outside of updates.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="custom-item-support">Custom Item Support<a href="https://geysermc.org/blog/looking-back-at-2022#custom-item-support" class="hash-link" aria-label="Direct link to Custom Item Support" title="Direct link to Custom Item Support">​</a></h2>
<p>Finally, Java’s CustomModelData system is now supported on Bedrock. This change is largely thanks to <a href="https://github.com/ImDaBigBoss" target="_blank" rel="noopener noreferrer">ImDaBigBoss</a>, who created the <a href="https://github.com/GeyserMC/Geyser/pull/2822" target="_blank" rel="noopener noreferrer">PR</a> back in February, and <a href="https://github.com/Kas-tle" target="_blank" rel="noopener noreferrer">Kastle</a>, who has worked to map Java packs to Bedrock as effortlessly as possible.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="dedicated-wiki">Dedicated Wiki<a href="https://geysermc.org/blog/looking-back-at-2022#dedicated-wiki" class="hash-link" aria-label="Direct link to Dedicated Wiki" title="Direct link to Dedicated Wiki">​</a></h2>
<p>We now have a <a href="https://wiki.geysermc.org/" target="_blank" rel="noopener noreferrer">dedicated wiki</a>, allowing users to contribute documentation without allowing random changes from anyone.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="extensions">Extensions<a href="https://geysermc.org/blog/looking-back-at-2022#extensions" class="hash-link" aria-label="Direct link to Extensions" title="Direct link to Extensions">​</a></h2>
<p>After two years of theory and concepts, Geyser extensions are now possible, allowing for improved interaction with Bedrock clients to take advantage of what the Bedrock platform has to offer. These work very similar to plugins and allow for developers to write code specifically for Bedrock and Geyser features using the Geyser API. In 2023, we hope to see more API additions that allow for servers, plugins and mods to shine in creativity.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="geyser-fabric-joins-the-main-repository">Geyser-Fabric Joins the Main Repository<a href="https://geysermc.org/blog/looking-back-at-2022#geyser-fabric-joins-the-main-repository" class="hash-link" aria-label="Direct link to Geyser-Fabric Joins the Main Repository" title="Direct link to Geyser-Fabric Joins the Main Repository">​</a></h2>
<p>Geyser-Fabric is now a part of the main Geyser repository, instead of being relegated to a separate repository. This will ensure that the Fabric mod always gets the latest changes to Geyser, and isn’t prone to losing out on updates.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="secure-profiles-and-geyser">Secure Profiles and Geyser<a href="https://geysermc.org/blog/looking-back-at-2022#secure-profiles-and-geyser" class="hash-link" aria-label="Direct link to Secure Profiles and Geyser" title="Direct link to Secure Profiles and Geyser">​</a></h2>
<p>The 1.19 Java updates added new changes that allowed player chat to be verified and reported to Mojang. Bedrock as it stands is essentially incompatible with these changes; before 1.19.3, requiring that all players chat securely (enabling <code>enforce-secure-profile</code> in <code>server.properties</code>) would prevent Bedrock from joining. Thankfully, in 1.19.3, that same setting now allows Bedrock players to join, just without the ability to chat.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="almost-100-day-one-updates">Almost 100% Day-One Updates<a href="https://geysermc.org/blog/looking-back-at-2022#almost-100-day-one-updates" class="hash-link" aria-label="Direct link to Almost 100% Day-One Updates" title="Direct link to Almost 100% Day-One Updates">​</a></h2>
<p>I’m very proud of all our developers and contributors that are able to get updates ready before each Minecraft release. Two years ago for 1.16, we were unable to have an update ready before the release date. Now, we are in a place to be consistently prepared for supporting auto-updating Bedrock clients by having a Geyser version released by the day of. The almost exception this year was the Bedrock 1.19.21 update released in August - while it was supposed to be a patch update, it surprised the entire Bedrock community (even featured servers) by being incompatible with the prior 1.19.20 version without any notice from Mojang. There was no notable difference, and we were able to push an update in about an hour after we discovered the incompatibility.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="upcoming-geyser-and-floodgate-merge">Upcoming: Geyser and Floodgate Merge<a href="https://geysermc.org/blog/looking-back-at-2022#upcoming-geyser-and-floodgate-merge" class="hash-link" aria-label="Direct link to Upcoming: Geyser and Floodgate Merge" title="Direct link to Upcoming: Geyser and Floodgate Merge">​</a></h2>
<p>As we look to 2023, one of my goals as a project lead on Geyser is ensuring the setup and update process is as smooth and secure as possible. Having two plugins for users to worry about isn’t fun, and many support requests we get have no idea that they need Floodgate for Bedrock players to join without needing a Java account. While Floodgate has to stick around for backend servers and Geyser Standalone, we want to package Floodgate functionality into Geyser for improved efficiency, to fix some <a href="https://github.com/GeyserMC/Floodgate/issues/178" target="_blank" rel="noopener noreferrer">annoying bugs</a> where having duplicate classes causes API errors, and to simplify how many plugins you need to install to get Geyser running.</p>
<p>Overall, I’m really happy and very grateful to see Geyser where it is today. We have 20,000 running Geyser instances, with 10,000 players combined on all of them. We have an amazing community, and the support of many in the wider Minecraft community. 2023 promises more good changes - here’s to it!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[1.18 Release, MCProtocolLib, Refactors & More!]]></title>
            <link>https://geysermc.org/blog/1-18-release-and-more</link>
            <guid>https://geysermc.org/blog/1-18-release-and-more</guid>
            <pubDate>Tue, 28 Dec 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[In this post, we will be covering all the changes that led up to the 1.18 release.]]></description>
            <content:encoded><![CDATA[<p>Hi everyone 👋</p>
<p>Welcome to the new Geyser blog! We’ll be posting new content here periodically about project updates, future plans, project announcements and really just miscellaneous development-related content around the Geyser project(s). These will be linked in our #blog-feed channel on Discord, so if you want to be notified when we make new posts and such, feel free to either follow the channel in your own Discord server, or turn on notifications.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="introduction">Introduction:<a href="https://geysermc.org/blog/1-18-release-and-more#introduction" class="hash-link" aria-label="Direct link to Introduction:" title="Direct link to Introduction:">​</a></h2>
<p>In this post, we will be covering all the changes that led up to the 1.18 release. With 1.18 came a huge set of changes for Geyser which although may not be visible to the end user, were a massive feat internally. This resulted in not only multiple project refactors of Geyser along with surrounding projects (PacketLib, MCProtocolLib, etc.) but many additional optimizations and improvements to how the code operated and ran. For the latter half of 2021 especially, we’ve been putting in a lot more time to ensure Geyser runs more smoothly and to optimize poorly performing parts of the code, so much of these changes were a direct result of that initiative.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="writing-a-new-java-edition-protocol-library">Writing a New Java Edition Protocol Library:<a href="https://geysermc.org/blog/1-18-release-and-more#writing-a-new-java-edition-protocol-library" class="hash-link" aria-label="Direct link to Writing a New Java Edition Protocol Library:" title="Direct link to Writing a New Java Edition Protocol Library:">​</a></h2>
<p>To preface, we were not initially planning to do this big refactor all at once, but one thing led to another and here we are. Our initial plans were actually quite a bit different, with us initially planning to deprecate and remove MCProtocolLib from our codebase, <a href="https://github.com/GeyserMC/Protocol/tree/feature/java-3.0" target="_blank" rel="noopener noreferrer">and instead implement support for Java Edition</a> inside of <a href="https://github.com/CloudburstMC/Protocol" target="_blank" rel="noopener noreferrer">Protocol</a>, our Bedrock Edition protocol library. We actually got it to a point where you could join and properly send/receive packets quite well!</p>
<p><img decoding="async" loading="lazy" src="https://user-images.githubusercontent.com/29153871/144722769-88a6701f-4478-4608-96ae-a5c855b752b7.png" alt="Java Edition Lib" class="img_ev3q"></p>
<p>This was inline with our plans to continually improve performance and maintainability with Geyser, since using a library where much of the code is the same across both the Java &amp; Bedrock protocol libraries would reduce much of the additional work we need to do in. A good example of this is inside our <a href="https://github.com/GeyserMC/Geyser/blob/master/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java#L295-L357" target="_blank" rel="noopener noreferrer">ItemTranslator</a> class, where we translate NBT objects from that used inside of MCProtocolLib, to that used inside of our Bedrock protocol library. We were intending to have this done with 1.18 since the update itself was not too drastic, meaning we could spend much more time on Geyser itself, rather than trying to update to the protocol.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="taking-over-mcprotocollib">Taking over MCProtocolLib:<a href="https://geysermc.org/blog/1-18-release-and-more#taking-over-mcprotocollib" class="hash-link" aria-label="Direct link to Taking over MCProtocolLib:" title="Direct link to Taking over MCProtocolLib:">​</a></h2>
<p>However our plans completely changed when Steveice10, the maintainer of MCProtocolLib at the time, reached out <a href="https://github.com/GeyserMC/MCProtocolLib/issues/659" target="_blank" rel="noopener noreferrer">and asked if we wanted to take over the project</a>. At first we were a bit hesitant as we had already put in quite a bit of work to our new library, but as MCProtocolLib was already an integral part of Geyser from <a href="https://github.com/GeyserMC/Geyser/commit/17b99a80fe910ba7147aa4f3cd2669b5538422c7" target="_blank" rel="noopener noreferrer">the very beginning</a> and we had essentially been maintaining the library for the past year or so, we all came to the consensus that scrapping the library would be a poor idea, both for us as well as the wider community who was also using this library. We decided to take over it.</p>
<p>With us now being in full control of MCProtocolLib, that gave us much more freedom to update and improve the project that we previously were unable to do. Rather than go on with a new library altogether, we felt it would be better to gradually port over much of our work into MCProtocolLib. With the release of 1.18 still lingering, we decided to jump the gun and start on a massive refactor of packets, with us adopting Mojang-mapped packet names. This is something we were doing inside of Protocol for Java Edition and with more and more projects adopting these names and for the sake of unity across the board, we felt now was the best time to make this decision.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="improving-performance-in-mcprotocollib">Improving Performance in MCProtocolLib:<a href="https://geysermc.org/blog/1-18-release-and-more#improving-performance-in-mcprotocollib" class="hash-link" aria-label="Direct link to Improving Performance in MCProtocolLib:" title="Direct link to Improving Performance in MCProtocolLib:">​</a></h2>
<p>During the process of renaming packets to use Mojmap names, we found that most of the performance bottlenecks with MCProtocolLib &amp; Geyser did not particularly lie with object translation, since it's relatively cheap in the grand scheme of things, but just the ways in which the library operated itself.</p>
<p><img decoding="async" loading="lazy" src="https://user-images.githubusercontent.com/29153871/144722843-4bef937f-b393-487d-99fc-cc56a8eece58.PNG" alt="Slow Packets" class="img_ev3q"></p>
<p>What we identified is that inside of MinecraftProtocol, the main class inside of MCProtocolLib, that it was re-registering the Minecraft protocol individually for every player individually, any time the protocol state changed. To give a bit more background on this - the Minecraft protocol operates over four individual state. The first is the handshaking state, which is the state set when a client first makes a connection the Minecraft server. Once the handshake has completed, the next state is either the <code>login</code> or the <code>status</code> state. The status state is set when a client pings the server from the server list and never actually joins, while the login state is for when the client is logging into the server. Once the login is complete, the server then goes on to the <code>game</code> state, where you actually recieve packets that let you interact with the world.</p>
<p>Below is an example of what MCProtocolLib was doing previously, any time you switched from the <code>login</code> state to the <code>game</code> state:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">initGame</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">BiConsumer</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&lt;</span><span class="token generics class-name">Integer</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token generics"> </span><span class="token generics class-name">Class</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&lt;</span><span class="token generics operator">?</span><span class="token generics"> </span><span class="token generics keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token generics"> </span><span class="token generics class-name">Packet</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"> clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">BiConsumer</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&lt;</span><span class="token generics class-name">Integer</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token generics"> </span><span class="token generics class-name">Class</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&lt;</span><span class="token generics operator">?</span><span class="token generics"> </span><span class="token generics keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token generics"> </span><span class="token generics class-name">Packet</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"> serverboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x00</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerSpawnEntityPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x01</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerSpawnExpOrbPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x02</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerSpawnLivingEntityPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x03</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerSpawnPaintingPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x04</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerSpawnPlayerPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x05</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerAddVibrationSignalPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x06</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerEntityAnimationPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x07</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerStatisticsPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x08</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerPlayerActionAckPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x09</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerBlockBreakAnimPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x0A</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerUpdateTileEntityPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x0B</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerBlockValuePacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x0C</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerBlockChangePacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x0D</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerBossBarPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x0E</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerDifficultyPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x0F</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerChatPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x10</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerClearTitlesPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x11</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerTabCompletePacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x12</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerDeclareCommandsPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x13</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerCloseWindowPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x14</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerWindowItemsPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x15</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerWindowPropertyPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x16</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerSetSlotPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x17</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerSetCooldownPacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        clientboundPackets</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">accept</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0x18</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">ServerPluginMessagePacket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token comment" style="color:rgb(98, 114, 164)">// this continues for more than 100 more packets</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>With the above code, every game packet would be registered into a new map. This was a far less than ideal situation, given that hundreds of packets would be registered, and this was something called for every client. We opted to replace this with a <a href="https://github.com/GeyserMC/MCProtocolLib/blob/master/src/main/java/com/github/steveice10/mc/protocol/codec/MinecraftCodec.java" target="_blank" rel="noopener noreferrer">static registry</a> which instead holds these values just once. Any time the sub-protocol changes, it instead just pulls from this static codec instead, rather than populating a map every time.</p>
<p>We also identified other areas where code was running poorly - previously, every packet was constructed through reflection, which we realized could easily be replaced with a packet factory. Nowadays, the packet registration code is only constructed once, and the player's protocol state determines which map to pull packets from.</p>
<p>With all these changes consolidated into an individual codec, it also opens the door for multi-version compatibility - something we were initially planning to do with our Java Edition work in Protocol. Although not officially supported yet nor something we have fully committed to, these changes will allow that capability in the future, and implementing projects technically could implement the capability to do so if they please.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="refactoring-geyser">Refactoring Geyser:<a href="https://geysermc.org/blog/1-18-release-and-more#refactoring-geyser" class="hash-link" aria-label="Direct link to Refactoring Geyser:" title="Direct link to Refactoring Geyser:">​</a></h2>
<p>With the massive changes inside MCProtocolLib already lining up, we already foresaw the changes in Geyser being quite drastic. With plans for extensions and a more streamlined API being in the plans for over a year, we felt that now was the best time to start moving along with that. This initially started with a massive refactor of the packages inside of Geyser. Previously, everything involved with the work Geyser did with packet translation and whatnot lied in the <code>connector</code> module of the project. This name was slightly confusing for many as Geyser does much more than just "connecting you to a server." With that being said, we decided to rename the module to <code>core</code> and update the packaging for it from <code>org.geysermc.connector</code> to <code>org.geysermc.geyser</code>.</p>
<p>Along with the package name changes, we decided to start implementing a new API. At the time of writing, this is still something that is very much a work in progress, however this will make it much easier to write projects that interop with Geyser &amp; Floodgate in a much more streamlined fashion, and allow for extensions to have a solid base to build off of.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="improving-code-in-geyser">Improving Code in Geyser:<a href="https://geysermc.org/blog/1-18-release-and-more#improving-code-in-geyser" class="hash-link" aria-label="Direct link to Improving Code in Geyser:" title="Direct link to Improving Code in Geyser:">​</a></h2>
<p>As mentioned earlier in this post, one of our plans was to eventually move away from MCProtocolLib due to the additional translation we have to do between MCProtocolLib and Protocol objects. However, as we continued working on both the MCProtocolLib changes and the Geyser refactor, we identified that these translations were not the sources of most performance bottlenecks inside of Geyser itself. This led to us refactoring our entity system inside of Geyser, not solely for the sake of performance, but also for the sake of better usability and understanding.</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">updateBedrockMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityMetadata</span><span class="token plain"> entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">GeyserSession</span><span class="token plain"> session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token number">0</span><span class="token operator">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">==</span><span class="token plain"> </span><span class="token class-name">MetadataType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">BYTE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">byte</span><span class="token plain"> xd </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">byte</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">ON_FIRE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">xd </span><span class="token operator">&amp;</span><span class="token plain"> </span><span class="token number">0x01</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">==</span><span class="token plain"> </span><span class="token number">0x01</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token operator">!</span><span class="token plain">metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">FIRE_IMMUNE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Otherwise immune entities sometimes flicker onfire</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SNEAKING</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">xd </span><span class="token operator">&amp;</span><span class="token plain"> </span><span class="token number">0x02</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">==</span><span class="token plain"> </span><span class="token number">0x02</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SPRINTING</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">xd </span><span class="token operator">&amp;</span><span class="token plain"> </span><span class="token number">0x08</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">==</span><span class="token plain"> </span><span class="token number">0x08</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    </span><span class="token comment" style="color:rgb(98, 114, 164)">// Swimming is ignored here and instead we rely on the pose</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">GLIDING</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">xd </span><span class="token operator">&amp;</span><span class="token plain"> </span><span class="token number">0x80</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">==</span><span class="token plain"> </span><span class="token number">0x80</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    </span><span class="token function" style="color:rgb(80, 250, 123)">setInvisible</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">xd </span><span class="token operator">&amp;</span><span class="token plain"> </span><span class="token number">0x20</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">==</span><span class="token plain"> </span><span class="token number">0x20</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token number">1</span><span class="token operator">:</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Air/bubbles</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token function" style="color:rgb(80, 250, 123)">setAir</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token number">2</span><span class="token operator">:</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// custom name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">instanceof</span><span class="token plain"> </span><span class="token class-name">Component</span><span class="token plain"> message</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    </span><span class="token comment" style="color:rgb(98, 114, 164)">// Always translate even if it's a TextMessage since there could be translatable parameters</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">put</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">NAMETAG</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">MessageTranslator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">convertMessage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLocale</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token number">3</span><span class="token operator">:</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// is custom name visible</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token operator">!</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">is</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">PlayerEntity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                    metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">put</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">NAMETAG_ALWAYS_SHOW</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">byte</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">boolean</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">?</span><span class="token plain"> </span><span class="token number">1</span><span class="token plain"> </span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token number">4</span><span class="token operator">:</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// silent</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SILENT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">boolean</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token number">5</span><span class="token operator">:</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// no gravity</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">HAS_GRAVITY</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token operator">!</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">boolean</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token number">6</span><span class="token operator">:</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Pose change - typically used for bounding box and not animation</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token class-name">Pose</span><span class="token plain"> pose </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Pose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SLEEPING</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> pose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">equals</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Pose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SLEEPING</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token comment" style="color:rgb(98, 114, 164)">// Triggered when crawling</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                metadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SWIMMING</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> pose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">equals</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Pose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SWIMMING</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token function" style="color:rgb(80, 250, 123)">setDimensions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">pose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token number">7</span><span class="token operator">:</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Freezing ticks</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token comment" style="color:rgb(98, 114, 164)">// The value that Java edition gives us is in ticks, but Bedrock uses a float percentage of the strength 0.0 -&gt; 1.0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token comment" style="color:rgb(98, 114, 164)">// The Java client caps its freezing tick percentage at 140</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> freezingTicks </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">Math</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">min</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">140</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token function" style="color:rgb(80, 250, 123)">setFreezing</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">session</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> freezingTicks </span><span class="token operator">/</span><span class="token plain"> </span><span class="token number">140f</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Looking at the code above, our previous code for translating entity metadata was extremely scattered and utilized many magic “numbers” associated with entity translation. These types of switch statements were all over various entity classes, and were quite messy.</p>
<p>To explain the above code in more detail - the way Minecraft Java sends entity metadata over the protocol is that it associates an id for every entity metadata “type”. Looking at the above code, id 3 for example, is associated with whether an entity’s name is visible above their head. The problem with handling our code like this is that if Mojang decides to add a new entity metadata field at id 2 for example, everything above that will be incremented by 1, so 'custom name visible' would have an id of 4, rather than 3 in future updates. Along with the code being so scattered, it meant that we would need to increment ids inside of <em>every</em> entity class, which was far less than ideal.</p>
<p>What we opted to do to remedy this issue is to instead not use massive if or switch statements on the ids, but to register these values inside of a list, and add them based on the order they should be translated in.</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token class-name">EntityDefinition</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&lt;</span><span class="token generics class-name">Entity</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"> entityBase </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">EntityDefinition</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">builder</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">BaseEntityFactory</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&lt;</span><span class="token generics class-name">Entity</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token class-name">Entity</span><span class="token operator">::</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addTranslator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MetadataType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">BYTE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Entity</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">setFlags</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addTranslator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MetadataType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">INT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Entity</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">setAir</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Air/bubbles</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addTranslator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MetadataType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">OPTIONAL_CHAT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Entity</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">setDisplayName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addTranslator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MetadataType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">BOOLEAN</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Entity</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">setDisplayNameVisible</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addTranslator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MetadataType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">BOOLEAN</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">entity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-&gt;</span><span class="token plain"> entity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">EntityFlag</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SILENT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">BooleanEntityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> entityMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getPrimitiveValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addTranslator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MetadataType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">BOOLEAN</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Entity</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">setGravity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addTranslator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MetadataType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">POSE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Entity</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">setPose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">addTranslator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MetadataType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">INT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Entity</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">setFreezing</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">build</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>All that code shown earlier has been condensed into the following. Now, if Mojang is to add a new metadata field at id 2 for instance, we can simply just plug it in as the third value, and boom, everything else will automatically be incremented!</p>
<p>In regards to performance, previously all the entity data had been held in an EntityType enum, which was not the best for constructing more complex entity objects. This meant we had to use reflection for constructing entities which as mentioned earlier, was used inside of MCProtocolLib, and was slower than what we wanted. This too was replaced with an entity factory, and can be seen in the above code snippet.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="new-api-extensions-and-looking-onward">New API, Extensions, and Looking Onward:<a href="https://geysermc.org/blog/1-18-release-and-more#new-api-extensions-and-looking-onward" class="hash-link" aria-label="Direct link to New API, Extensions, and Looking Onward:" title="Direct link to New API, Extensions, and Looking Onward:">​</a></h2>
<p>As brought up multiple times throughout this post, we have been spending time working up a new API. We eventually want to bring in extensions to Geyser, which act as plugins on their own except they are loaded from Geyser itself. With more and more people and larger servers adopting Geyser, many more unique and niche usecases have popped up which don’t particularly fit inside of Geyser itself, but would still benefit users as a whole. As Geyser is capable of running on 6 platforms at this point in time (Spigot, Sponge, Standalone, Velocity, Fabric and BungeeCord, with Forge likely on the way), as a developer, creating a separate addon capable of running on all these platforms is far less than ideal. We’ve opted to get around this by creating a new extension system, allowing developers to create an extension one time for Geyser, and it being capable of running on any of these platforms.</p>
<p>This extension API has not been created yet however, and plans for the base API inside of Geyser are still being finalized. We also intend to start moving most of Floodgate into Geyser itself, so unless you are running Floodgate independently from Geyser (e.g. you use Geyser Standalone but run Floodgate on the proxy), in the near future you will only need to install Geyser, and Floodgate’s functions will all be handled automatically in Geyser.</p>
<p>With that coming up, we also want to design the base API to be agnostic in the sense that basic functions such as retrieving how many players are online can be done using the same API, whether the server has just Geyser installed or just Floodgate. But at the same time, we also want to make it easy to utilize a more-specific Floodgate and Geyser API.</p>
<p>Anyway, that about wraps up the first post! Thanks for reading and feel free to offer any feedback about the topics covered in our <a href="https://discord.gg/geysermc" target="_blank" rel="noopener noreferrer">Discord server</a>!</p>]]></content:encoded>
        </item>
    </channel>
</rss>