Files
GeyserWebsite/_site/geyser/extensions/index.html
T
2023-11-07 19:40:55 -06:00

561 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="utf-8">
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GeyserMC Wiki: Geyser Extensions</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/darcula.css">
<meta name="author" content="GeyserMC">
<meta name="description" content="This is the wiki for all of GeyserMC's projects.">
<meta name="theme-color" content="#2b3035">
<meta property="og:type" content="website">
<meta property="og:url" content="http://localhost:4000">
<meta property="og:title" content="GeyserMC Wiki: Geyser Extensions">
<meta property="og:description" content="This is the wiki for all of GeyserMC's projects.">
<meta property="og:image" content="/android-chrome-192x192.png">
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="192x192" href="/android-chrome-192x192.png">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#248f00">
</head>
<body>
<header>
<nav class="navbar navbar-expand-lg bg-body-tertiary fixed-top">
<div class="container-fluid">
<a class="navbar-brand" href="/"><img src="/android-chrome-512x512.png" alt="geyser logo" height="32"> GeyserMC Wiki</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarLinks" aria-controls="navbarLinks" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarLinks">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="https://geysermc.org/"><i class="bi bi-house pe-1"></i> Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://geysermc.org/download"><i class="bi bi-download pe-1"></i> Download</a>
</li>
</ul>
<form class="d-flex" role="search" action="/search/">
<div class="input-group">
<button class="btn btn-outline-secondary" type="submit" id="button-search"><i class="bi bi-search"></i></button>
<input type="text" name="q" class="form-control" placeholder="Search the site..." aria-label="Search the site..." aria-describedby="button-search">
</div>
</form>
</div>
</div>
</nav>
</header>
<div id="page-content" class="container-fluid">
<div class="row">
<div class="col-12 col-md-3 col-xl-2">
<div class="sticky-top">
<div class="sidebar py-2 text-break">
<nav class="navbar navbar-expand-md">
<div class="container-fluid">
<div class="d-block d-md-none">Wiki Navigation</div>
<button class="navbar-toggler mb-2" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarNav" aria-controls="sidebarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse flex-column align-items-start" id="sidebarNav">
<div class="nav-item dropdown">
<a class="nav-link dropdown-toggle fw-bold show" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="false" aria-expanded="false">Geyser Documentation</a>
<ul class="pe-3 pt-0 dropdown-menu position-relative border-0 list-disc show">
<li class="ms-4">
<a href="/geyser/setup/">Setting up Geyser</a>
<ul>
<li>
<a href="/geyser/supported-hosting-providers/">Supported Hosting Providers</a>
</li>
<li>
<a href="/geyser/using-geyser-with-consoles/">Using Geyser with Consoles</a>
</li>
<li>
<a href="/geyser/playit-gg/">Using playit.gg with Geyser</a>
</li>
<li>
<a href="/geyser/creating-a-startup-script/">Creating a Startup Script</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/geyser/common-issues/">Common Issues</a>
<ul>
<li>
<a href="/geyser/fixing-unable-to-connect-to-world/">Fixing 'Unable to Connect to World'</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/geyser/understanding-the-config/">Configuring Geyser</a>
<ul>
<li>
<a href="/geyser/commands/">Commands</a>
</li>
<li>
<a href="/geyser/geyser-command-line-arguments-and-system-properties/">Geyser Command Line Arguments and System Properties</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/geyser/faq/">FAQ</a>
<ul>
<li>
<a href="/geyser/anticheat-compatibility/">Anticheat Compatibility</a>
</li>
<li>
<a href="/geyser/current-limitations/">Current Limitations</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/geyser/custom-items/">Custom items with Geyser</a>
<ul>
<li>
<a href="/geyser/custom-items/#json-mappings">JSON mappings</a>
</li>
<li>
<a href="/geyser/custom-items/#geyser-extensions">Geyser extensions</a>
</li>
<li>
<a href="/geyser/custom-items/#resource-pack">Resource pack</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/geyser/custom-blocks/">Custom blocks with Geyser</a>
<ul>
<li>
<a href="/geyser/custom-blocks/#enabling-custom-blocks">Enabling custom blocks</a>
</li>
<li>
<a href="/geyser/custom-blocks/#json-mappings">JSON mappings</a>
</li>
<li>
<a href="/geyser/custom-blocks/#geyser-extensions">Geyser extensions</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/geyser/custom-skulls/">Custom skulls with Geyser</a>
<ul>
<li>
<a href="/geyser/custom-skulls/#enabling-custom-skulls">Enabling custom skulls</a>
</li>
<li>
<a href="/geyser/custom-skulls/#custom-skullsyml">custom-skulls.yml</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/geyser/api/">Geyser API</a>
<ul>
<li>
<a href="/geyser/getting-started-with-the-api/">Getting Started</a>
</li>
<li>
<a href="/geyser/api/#short-overview-of-the-geyser-api">Overview</a>
</li>
<li>
<a href="/geyser/events/">Events</a>
</li>
<li>
<a href="/geyser/forms/">Forms and Cumulus</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/geyser/extensions/">Geyser Extensions</a>
<ul>
<li>
<a href="/geyser/extensions/#creating-the-main-class">Main class</a>
</li>
<li>
<a href="/geyser/extensions/#creating-commands-with-geyser-extensions">Creating Commands</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/geyser/global-api/">Global API</a>
</li>
</ul>
</div>
<div class="nav-item dropdown">
<a class="nav-link dropdown-toggle fw-bold" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="false" aria-expanded="false">Floodgate Documentation</a>
<ul class="pe-3 pt-0 dropdown-menu position-relative border-0 list-disc">
<li class="ms-4">
<a href="/floodgate/setup/">Setup</a>
</li>
<li class="ms-4">
<a href="/floodgate/issues/">Issues</a>
</li>
<li class="ms-4">
<a href="/floodgate/faq/">FAQ</a>
</li>
<li class="ms-4">
<a href="/floodgate/features/">Features</a>
<ul>
<li>
<a href="/floodgate/features/#whitelist-command">Whitelist command</a>
</li>
<li>
<a href="/floodgate/commands/">Commands</a>
</li>
<li>
<a href="/floodgate/features/#what-is-skin-uploading">Skin Uploading</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/floodgate/api/">Floodgate API</a>
<ul>
<li>
<a href="/floodgate/player/">FloodgatePlayer</a>
</li>
<li>
<a href="/geyser/forms/">Forms and Cumulus</a>
</li>
</ul>
</li>
<li class="ms-4">
<a href="/floodgate/linking/">Linking</a>
<ul>
<li>
<a href="/floodgate/linking/#what-is-global-linking">Global Linking</a>
</li>
<li>
<a href="/floodgate/linking/#local-linking">Local Linking</a>
</li>
</ul>
</li>
</ul>
</div>
<div class="nav-item dropdown">
<a class="nav-link dropdown-toggle fw-bold" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="false" aria-expanded="false">Other</a>
<ul class="pe-3 pt-0 dropdown-menu position-relative border-0 list-disc">
<li class="ms-4">
<a href="/other/geyseroptionalpack/">GeyserOptionalPack</a>
</li>
<li class="ms-4">
<a href="/other/hurricane/">Hurricane</a>
</li>
<li class="ms-4">
<a href="/other/geyserconnect/">GeyserConnect</a>
</li>
<li class="ms-4">
<a href="/other/community-geyser-projects/">Community Geyser Projects</a>
</li>
<li class="ms-4">
<a href="/other/test-server/">Test Server</a>
</li>
<li class="ms-4">
<a href="/other/developer-guide/">Developer Guide</a>
</li>
<li class="ms-4">
<a href="/other/discord-bot-usage/">Geyser Discord Bot Usage</a>
</li>
</ul>
</div>
</div>
</div>
</nav>
</div>
</div>
</div>
<main class="col-12 col-md-9 col-xl-8" role="main">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="http://localhost:4000/geyser/">Geyser</a></li>
<li class="breadcrumb-item active" aria-current="page">Geyser Extensions</li>
</ol>
</nav>
<h2 id="geyser-extensions">Geyser Extensions</h2>
<p>Geyser Extensions are the equivalent of “plugins”, but specifically for the Geyser platform. This brings the advantage of them being platform-agnostic, meaning that you won’t have to worry about supporting all platforms individually. Additionally, they will be, by design, only applied for Bedrock players joining via Geyser.</p>
<h3 id="what-can-geyser-extensions-do">What can Geyser Extensions do?</h3>
<p>Extensions can fully utilize the Geyser API to add additional functionality to Geyser. See <a href="/geyser/api/">Geyser API docs</a> for info on what is currently possible. To name a few examples:</p>
<ul>
<li>Register custom items and blocks</li>
<li>Hide commands from being suggested</li>
<li>Change the MOTD</li>
<li>Register your own commands</li>
<li>Listen to events, e.g. the emote event.</li>
</ul>
<p>The underlying Geyser API is steadily expanding, creating more and more opportunities.</p>
<h3 id="which-geyser-extensions-exist">Which Geyser Extensions exist?</h3>
<p>At the moment, extensions are still a new system, so there is only a small list of known extensions for Geyser. However, new extensions are always being created!
There is an <a href="https://github.com/GeyserMC/GeyserExtensionList">official list</a> of available extensions you can check out. If you have an extension you’d like to see on this list, feel free to open a PR!</p>
<h3 id="installing-extensions">Installing Extensions</h3>
<p>To install an extension, simply put the extension .jar file into Geyser’s ‘extensions’ folder. Then, restart Geyser (or the server Geyser runs on).</p>
<h3 id="creating-geyser-extensions">Creating Geyser Extensions</h3>
<p>The easiest way to create an extension would be utilizing <a href="https://github.com/GeyserMC/GeyserExampleExtension/">this official template</a>. Simply create a new repository from the template, customize the ‘extension.yml’ &amp; ‘settings.gradle’ files, and get started making the extension.</p>
<p>Geyser recognizes extensions when they have a file called ‘extension.yml’ in the jars ‘resources’ folder.</p>
<p>extension.yml:</p>
<div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">id</span><span class="pi">:</span> <span class="s">exampleid</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">ExampleExtension</span>
<span class="na">main</span><span class="pi">:</span> <span class="s">org.geyser.extension.exampleid.ExampleExtension</span>
<span class="na">api</span><span class="pi">:</span> <span class="s">1.0.0</span>
<span class="na">version</span><span class="pi">:</span> <span class="s">1.0.0</span>
<span class="na">authors</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">ExampleAuthor</span><span class="pi">]</span>
</code></pre></div></div>
<p>Explanations for the individual fields:</p>
<ul>
<li>id: The id of the extension. Every extension needs to have their unique id - all lowercase letters. If you e.g. register a command for your extension, it will have the id as a prefix: e.g. ‘/exampleid command’.</li>
<li>name: The name of the extension.</li>
<li>main: The main class of your extension.</li>
<li>api: The Base API version your extension targets.</li>
<li>authors: The author(s) of the extension. To add more than one entry, separate entries with a comma.</li>
</ul>
<h3 id="creating-the-main-class">Creating the main class</h3>
<p>The main class, the entrypoint for the extension, needs to <a href="https://github.com/GeyserMC/GeyserExampleExtension/blob/master/src/main/java/org/geyser/extension/exampleid/ExampleExtension.java#L12">implement the ‘Extension’ interface provided by Geyser</a>.
That way, Geyser recognizes the extension, and gives you access to important methods - such as ‘logger()’, to get your extensions logger. <br />
To see all the methods provided by that interface, see <a href="https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/extension/Extension.java">here</a>.</p>
<p>Unlike plugins, extensions do not have a ‘onEnable’ or ‘onDisable’ method. Instead, most actions are done in events at different stages during Geyser’s lifecycle using events.
Some important ones are:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">GeyserPreInitializeEvent</code>: This event is fired when Geyser starts to initialize. If you e.g. need to register extension commands that are configured in your config,
you would need to load the config here to ensure that your config is ready before the GeyserDefineCommandsEvent is fired.</li>
<li><code class="language-plaintext highlighter-rouge">GeyserPostInitializeEvent</code>: It is called when Geyser has completed initializing. The bulk of your code should go here, as the GeyserAPI is fully available at this stage.</li>
<li><code class="language-plaintext highlighter-rouge">GeyserShutdownEvent</code>: Called when Geyser is shutting down. You can use this to e.g. save data, or clean up resources.</li>
</ul>
<p>See below for an example:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Subscribe</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">onPostInitialize</span><span class="o">(</span><span class="nc">GeyserPostInitializeEvent</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// example: show that your extension is loading.</span>
<span class="k">this</span><span class="o">.</span><span class="na">logger</span><span class="o">().</span><span class="na">info</span><span class="o">(</span><span class="s">"Loading example extension..."</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>If you wish to register custom items, global resource packs (or soon, custom blocks and entities), you will need to subscribe to the event using the @Subscribe annotation,
and register them in the event. You can find an example for custom items <a href="/geyser/custom-items/#geyser-extensions">here</a>. For other events, see <a href="/geyser/events">here</a> for documentation.</p>
<p>To build your extension, run the Gradle build task, and install the extension.</p>
<h3 id="creating-commands-with-geyser-extensions">Creating commands with Geyser Extensions</h3>
<p>To create a command, you would need to use the “Commands” package in the Geyser API. Brief rundown:</p>
<ul>
<li><a href="https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/command/Command.java">Command.java</a>
This interface represents a command in Geyser - to make one, you can use the CommandBuilder. You can register it with the
<a href="https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCommandsEvent.java">GeyserDefineCommandsEvent</a></li>
<li><a href="https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/command/CommandExecutor.java">CommandExecutor.java</a>
This interface represents a command execute handler in Geyser, and extends the CommandSource interface.</li>
<li><a href="https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/command/CommandSource.java">CommandSource.java</a>
This interface represents a command source in Geyser. It can be used to e.g. send messages to the source, check if the source has permission to execute a command, or get the locale.</li>
</ul>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Command</span> <span class="n">command</span> <span class="o">=</span> <span class="nc">Command</span><span class="o">.</span><span class="na">builder</span><span class="o">(</span><span class="k">this</span><span class="o">)</span> <span class="c1">// "this" is the extension's main class</span>
<span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="s">"ExampleCommand"</span><span class="o">)</span>
<span class="o">.</span><span class="na">bedrockOnly</span><span class="o">(</span><span class="kc">true</span><span class="o">)</span>
<span class="o">.</span><span class="na">source</span><span class="o">(</span><span class="nc">CommandSource</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="o">.</span><span class="na">aliases</span><span class="o">(</span><span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"example"</span><span class="o">,</span> <span class="s">"ex"</span><span class="o">))</span>
<span class="o">.</span><span class="na">description</span><span class="o">(</span><span class="s">"An example command"</span><span class="o">)</span>
<span class="o">.</span><span class="na">executableOnConsole</span><span class="o">(</span><span class="kc">false</span><span class="o">)</span>
<span class="o">.</span><span class="na">suggestedOpOnly</span><span class="o">(</span><span class="kc">false</span><span class="o">)</span>
<span class="o">.</span><span class="na">permission</span><span class="o">(</span><span class="s">"example.command"</span><span class="o">)</span>
<span class="o">.</span><span class="na">executor</span><span class="o">((</span><span class="n">source</span><span class="o">,</span> <span class="n">cmd</span><span class="o">,</span> <span class="n">args</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="o">{</span>
<span class="c1">// this is the command executor - this is where you would put your code to execute the command.</span>
<span class="c1">// source is the source that executed the command</span>
<span class="c1">// cmd is the command that was executed</span>
<span class="c1">// args are the arguments passed to the command</span>
<span class="n">source</span><span class="o">.</span><span class="na">sendMessage</span><span class="o">(</span><span class="s">"Hello World"</span><span class="o">);</span>
<span class="o">})</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>
<p>To register the command, you would need to subscribe to the GeyserDefineCommandsEvent, and register the command there:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Subscribe</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">onDefineCommands</span><span class="o">(</span><span class="nc">GeyserDefineCommandsEvent</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span>
<span class="n">event</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="n">command</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>If everything went right, you should be able to execute the command in-game by running “/extesionid [command]” - in our case, “/exampleid examplecommand”.
Here, it would send “Hello World” to the source that ran the command.
Since we also set aliases, you could also run “/exampleid example” or “/exampleid ex” for the same command.
To provide args, simple run “/exampleid examplecommand [args]” - replacing [args] with the arguments you want to pass to the command.</p>
<h3 id="listening-to-events">Listening to Events</h3>
<p>See <a href="/geyser/events">here</a> for documentation. You do not need to register the event listener, Geyser will do that for you.</p>
<hr />
<p>Facing troubles with extensions?</p>
<ul>
<li>Make sure you are using the latest version of Geyser - older versions might not have the latest API changes.</li>
<li>Add debug prints.</li>
<li>Ask in the #development channel in the <a href="https://discord.gg/geysermc">Geyser Discord server</a>.</li>
</ul>
</main>
<div class="col-2 d-none d-xl-block">
<div class="sticky-top">
<div class="sidebar py-2">
<a class="d-block text-decoration-none" href="https://github.com/GeyserMC/GeyserWiki/edit/master/_docs/geyser/extensions.md" target="_blank"><i class="bi bi-pencil"></i> Edit this page</a>
<a class="d-block text-decoration-none" href="https://github.com/GeyserMC/GeyserWiki/issues/new?labels=question&title=Question:&body=Question on: _docs/geyser/extensions.md" target="_blank"><i class="bi bi-github"></i> Create Wiki issue/bug report</a>
<a class="d-block text-decoration-none" href="/issues/new" target="_blank"><i class="bi bi-list-check"></i> Create Geyser issue/bug report</a>
<div id="page-nav" class="py-3 "></div>
</div>
</div>
</div>
</div>
</div>
<!-- <footer class="p-4 text-center bg-body-tertiary">
&copy; 2023 GeyserMC
</footer> -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
<script src="/js/page-nav.js"></script>
</body>
</html>