diff --git a/Components/MineSharp.Protocol/ClientSettings.cs b/Components/MineSharp.Protocol/ClientSettings.cs new file mode 100644 index 00000000..504aa298 --- /dev/null +++ b/Components/MineSharp.Protocol/ClientSettings.cs @@ -0,0 +1,98 @@ +using MineSharp.Core.Common; + +namespace MineSharp.Protocol; + +/// +/// Describes client settings +/// +public record ClientSettings +{ + /// + /// Default client settings + /// + public static readonly ClientSettings Default = new ClientSettings( + "en_GB", + 24, + ChatMode.Enabled, + true, + 0x7F, + PlayerHand.MainHand, + false, + true); + + /// + /// Locale (e.g. 'en_GB') + /// + public string Locale { get; } + + /// + /// The client's view distance + /// + public byte ViewDistance { get; } + + /// + /// What the client want's to see in chat (currently ignored) + /// + public ChatMode ChatMode { get; } // TODO: #31 + + /// + /// Whether the client allows colored chat (currently ignored) + /// + public bool ColoredChat { get; } // TODO: #31 + + /// + /// Bitmask of skin parts displayed by the client (not used) + /// + public byte DisplayedSkinParts { get; } + + /// + /// The clients main hand + /// + public PlayerHand MainHand { get; } + + /// + /// Whether to filter chat messages (currently ignored) + /// + public bool EnableTextFiltering { get; } // TODO: #31 + + /// + /// Whether you want to show up in a server's online players list + /// + public bool AllowServerListings { get; } + + /// + /// Constructor + /// + public ClientSettings(string locale, byte viewDistance, ChatMode chatMode, bool coloredChat, byte displayedSkinParts, PlayerHand mainHand, bool enableTextFiltering, bool allowServerListings) + { + Locale = locale; + ViewDistance = viewDistance; + ChatMode = chatMode; + ColoredChat = coloredChat; + DisplayedSkinParts = displayedSkinParts; + MainHand = mainHand; + EnableTextFiltering = enableTextFiltering; + AllowServerListings = allowServerListings; + } +} + +/// +/// Specifies the chat mode +/// +public enum ChatMode +{ + /// + /// Show all chat messages + /// + Enabled = 0, + + /// + /// Only command messages + /// + CommandsOnly = 1, + + /// + /// No player messages nor command messages + /// + Hidden = 2 +} diff --git a/Components/MineSharp.Protocol/MinecraftClient.cs b/Components/MineSharp.Protocol/MinecraftClient.cs index 20eb8dc9..16bad91d 100644 --- a/Components/MineSharp.Protocol/MinecraftClient.cs +++ b/Components/MineSharp.Protocol/MinecraftClient.cs @@ -98,22 +98,22 @@ public sealed class MinecraftClient : IDisposable /// public readonly ushort Port; + /// + /// The clients settings + /// + public readonly ClientSettings Settings; + /// /// Create a new MinecraftClient /// - /// The data used by the client - /// The session object - /// Hostname or ip of the server - /// Port of the server - /// Optional: instance of MinecraftApi - /// Optional: TcpClient factory public MinecraftClient( MinecraftData data, Session session, string hostnameOrIp, ushort port = 25565, MinecraftApi? api = null, - ITcpClientFactory? tcpFactory = null) + ITcpClientFactory? tcpFactory = null, + ClientSettings? settings = null) { this.Data = data; this._packetQueue = new ConcurrentQueue(); @@ -126,7 +126,7 @@ public MinecraftClient( this._useAnonymousNbt = this.Data.Version.Protocol >= ProtocolVersion.V_1_20_2; this._tcpTcpFactory = tcpFactory; this.ip = IPHelper.ResolveHostname(hostnameOrIp, ref port); - + if (session.OnlineSession) api ??= new MinecraftApi(); @@ -135,6 +135,7 @@ public MinecraftClient( this.Port = port; this.Hostname = hostnameOrIp; this.gameState = GameState.Handshaking; + this.Settings = settings ?? ClientSettings.Default; } /// @@ -278,15 +279,17 @@ internal void UpdateGameState(GameState next) this._gameJoinedTsc.TrySetResult(); if (next == GameState.Configuration) + { this.SendPacket(new ClientInformationPacket( - "en_pt", - 24, - 0, - true, - 0x7F, - 1, - false, - true)); // TODO: Add a settings object #31 + this.Settings.Locale, + this.Settings.ViewDistance, + (int)this.Settings.ChatMode, + this.Settings.ColoredChat, + this.Settings.DisplayedSkinParts, + (int)this.Settings.MainHand, + this.Settings.EnableTextFiltering, + this.Settings.AllowServerListings)); + } } internal void EnableEncryption(byte[] key) diff --git a/MineSharp.Bot/BotBuilder.cs b/MineSharp.Bot/BotBuilder.cs index 84428b1b..f90d52aa 100644 --- a/MineSharp.Bot/BotBuilder.cs +++ b/MineSharp.Bot/BotBuilder.cs @@ -45,6 +45,8 @@ public class BotBuilder // proxy private ProxyFactory? proxyProvider = null; + private ClientSettings? settings = null; + private bool autoConnect; /// @@ -113,6 +115,15 @@ public BotBuilder WithPlugin() where T : Plugin return this; } + /// + /// Set the client settings + /// + public BotBuilder WithSettings(ClientSettings settings) + { + this.settings = settings; + return this; + } + /// /// Do not load the default plugins /// @@ -229,6 +240,8 @@ public async Task CreateAsync() else throw new ArgumentNullException(nameof(this.session), "No session provided. Set either Session(), OfflineSession() or OnlineSession()"); + + this.settings ??= ClientSettings.Default; var client = new MinecraftClient( data, @@ -236,7 +249,8 @@ public async Task CreateAsync() this.hostname, this.port, api, - this.proxyProvider); + this.proxyProvider, + this.settings); var bot = new MineSharpBot(client);