Greeter
Join/quit messages and a server list MOTD
Source: src/scripting/managed/samples/Greeter/ · version 1.1.0. The code below is read from the repository at build time.
What it shows
Section titled “What it shows”- event subscriptions
- commands
- Brigadier command trees (v1)
- config (v1)
Events used: PlayerJoinEvent, PlayerQuitEvent, ServerListPingEvent
Build and run
Section titled “Build and run”dotnet build src/scripting/managed/samples/Greeter -c Release# the output lands in build/bin/dotnet/samples/Greeter/ when built through CMake (MC_BUILD_SCRIPTING);# copy the dll into your plugins folder and start the server with --pluginsSource
Section titled “Source”Greeter.cs
Section titled “Greeter.cs”using System.Text.Json.Serialization;
namespace Greeter;
/// <summary>The settings of the Greeter plugin. The defaults below are written to <c>plugins/greeter/config.json</c> the first time the plugin runs; edit the file and/// run <c>/greeter reload</c> to apply changes. Colours use legacy <c>&</c> codes.</summary>public sealed class GreeterConfig{ /// <summary>The line everybody sees when a player joins ({player} is the name).</summary> public string JoinMessage { get; set; } = "&8[&a+&8] &e{player}";
/// <summary>The line everybody sees when a player leaves.</summary> public string QuitMessage { get; set; } = "&8[&c-&8] &7{player}";
/// <summary>A private message sent to the joining player; empty to disable.</summary> public string Welcome { get; set; } = "&6Welcome to the server, &e{player}&6! Have fun.";
/// <summary>The server list description (two lines separated by \n); empty keeps the server's own.</summary> public string Motd { get; set; } = "&a&lA C# powered server\n&7plugins are the whole ecosystem";}
[JsonSerializable(typeof(GreeterConfig))]internal sealed partial class GreeterJson : JsonSerializerContext;
/// <summary>Sample: greets players on join with a coloured broadcast and a private message, says goodbye on quit and/// customises the server list entry. Everything is configurable in <c>config.json</c> (typed <see cref="Config{T}"/>, defaults written on first run, live reload).</summary>[PluginInfo("Greeter", Version = "1.1.0", Author = "Ramjet", Description = "Join/quit messages and a server list MOTD")]public sealed class GreeterPlugin : Plugin{ private Config<GreeterConfig> _config = null!;
protected override void OnEnable() { _config = Config.Load(GreeterJson.Default.GreeterConfig); _config.Watch = true; // edits of config.json are picked up without a command
Commands.Register(Command.Literal("greeter") .Then(Command.Literal("reload").Permission("greeter.reload").Executes(ctx => { bool ok = _config.Reload(); ctx.Reply(ok ? "Greeter configuration reloaded" : "config.json is invalid, see the server log (the previous values stay active)"); return ok ? 1 : 0; })));
Events.On((ref PlayerJoinEvent e) => { string name = e.Username.ToString(); var config = _config.Value; // the message everybody sees (replaces "<name> joined the game") if (config.JoinMessage.Length == 0) e.SetJoinMessage(Component.Empty); else e.SetJoinMessage(Component.Legacy(config.JoinMessage.Replace("{player}", name))); // a private welcome, sent right away if (config.Welcome.Length > 0) e.Player.SendMessage(Component.Legacy(config.Welcome.Replace("{player}", name))); });
Events.On((ref PlayerQuitEvent e) => { var config = _config.Value; e.SetQuitMessage(config.QuitMessage.Length == 0 ? Component.Empty : Component.Legacy(config.QuitMessage.Replace("{player}", e.Username.ToString()))); });
Events.On((ref ServerListPingEvent e) => { if (_config.Value.Motd.Length > 0) e.SetMotd(Component.Legacy(_config.Value.Motd.Replace("\\n", "\n"))); Log.Debug($"ping from {e.Address.ToString()}"); }); }}Greeter.csproj
Section titled “Greeter.csproj”<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <McApiProject>$(MSBuildThisFileDirectory)..\..\Mc.Scripting.Api\Mc.Scripting.Api.csproj</McApiProject> </PropertyGroup> <Import Project="..\..\Mc.Scripting.Plugin.props" /> <PropertyGroup Condition="'$(McOutDir)' != ''"> <OutputPath>$(McOutDir)samples/Greeter/</OutputPath> </PropertyGroup> <ItemGroup> <None Include="plugin.json" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup></Project>plugin.json
Section titled “plugin.json”{ "id": "greeter", "name": "Greeter", "version": "1.1.0", "api": "1.0", "authors": ["Ramjet"], "description": "Join/quit messages and a server list MOTD", "permissions": [ { "node": "greeter.reload", "default": "op:3", "description": "Reload the Greeter configuration" } ]}