From 6a266c68c33db5e18460af22cc2e08d1ce8dd41a Mon Sep 17 00:00:00 2001 From: Milutinke Date: Wed, 28 Sep 2022 21:39:13 +0200 Subject: [PATCH 1/3] Leave bed command. --- MinecraftClient/Commands/Leavebed.cs | 17 +++++++++++++++++ MinecraftClient/Resources/lang/en.ini | 4 ++++ 2 files changed, 21 insertions(+) create mode 100644 MinecraftClient/Commands/Leavebed.cs diff --git a/MinecraftClient/Commands/Leavebed.cs b/MinecraftClient/Commands/Leavebed.cs new file mode 100644 index 00000000..1ded6aed --- /dev/null +++ b/MinecraftClient/Commands/Leavebed.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Commands +{ + public class leaveBedCommand : Command + { + public override string CmdName { get { return "leavebed"; } } + public override string CmdUsage { get { return "leavebed"; } } + public override string CmdDesc { get { return "cmd.leavebed.desc"; } } + + public override string Run(McClient handler, string command, Dictionary localVars) + { + handler.SendEntityAction(Protocol.EntityActionType.LeaveBed); + return Translations.TryGet("cmd.leavebed.leaving"); + } + } +} \ No newline at end of file diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini index 4b80c088..ceb42086 100644 --- a/MinecraftClient/Resources/lang/en.ini +++ b/MinecraftClient/Resources/lang/en.ini @@ -343,6 +343,10 @@ cmd.inventory.help.unknown=Unknown action. cmd.inventory.found_items=Found items cmd.inventory.no_found_items=Could not find the specified item in any of avaliable Inventories! +# Leave bed +cmd.leavebed.desc=Used to leave a bed. +cmd.leavebed.leaving=Leaving a bed. + # List cmd.list.desc=get the player list. cmd.list.players=PlayerList: {0} From cd3adfa14cdb168994ddad7ec1591bfdcc360bd8 Mon Sep 17 00:00:00 2001 From: Milutinke Date: Wed, 28 Sep 2022 22:43:14 +0200 Subject: [PATCH 2/3] Changed the bed command to be able to sleep. Added relative coordinates to /dig command. --- MinecraftClient/ChatBots/Map.cs | 2 +- MinecraftClient/Commands/Dig.cs | 8 ++- MinecraftClient/Commands/Leavebed.cs | 57 ++++++++++++++++--- MinecraftClient/Mapping/MaterialExtensions.cs | 32 +++++++++++ MinecraftClient/Resources/lang/en.ini | 8 ++- 5 files changed, 94 insertions(+), 13 deletions(-) diff --git a/MinecraftClient/ChatBots/Map.cs b/MinecraftClient/ChatBots/Map.cs index 0969daba..a6793e1f 100644 --- a/MinecraftClient/ChatBots/Map.cs +++ b/MinecraftClient/ChatBots/Map.cs @@ -33,7 +33,7 @@ namespace MinecraftClient.ChatBots deleteAllOnExit = Settings.Map_Delete_All_On_Unload; notifyOnFirstUpdate = Settings.Map_Notify_On_First_Update; - RegisterChatBotCommand("maps", "bot.map.cmd.desc", "maps > | maps >", OnMapCommand); + RegisterChatBotCommand("maps", "bot.map.cmd.desc", "maps list|render or maps l|r ", OnMapCommand); } public override void OnUnload() diff --git a/MinecraftClient/Commands/Dig.cs b/MinecraftClient/Commands/Dig.cs index fc5214fb..9a303561 100644 --- a/MinecraftClient/Commands/Dig.cs +++ b/MinecraftClient/Commands/Dig.cs @@ -24,9 +24,11 @@ namespace MinecraftClient.Commands { try { - int x = int.Parse(args[0]); - int y = int.Parse(args[1]); - int z = int.Parse(args[2]); + Location current = handler.GetCurrentLocation(); + double x = args[0].StartsWith('~') ? current.X + (args[0].Length > 1 ? double.Parse(args[0][1..]) : 0) : double.Parse(args[0]); + double y = args[1].StartsWith('~') ? current.Y + (args[1].Length > 1 ? double.Parse(args[1][1..]) : 0) : double.Parse(args[1]); + double z = args[2].StartsWith('~') ? current.Z + (args[2].Length > 1 ? double.Parse(args[2][1..]) : 0) : double.Parse(args[2]); + Location blockToBreak = new Location(x, y, z); if (blockToBreak.DistanceSquared(handler.GetCurrentLocation().EyesLocation()) > 25) return Translations.Get("cmd.dig.too_far"); diff --git a/MinecraftClient/Commands/Leavebed.cs b/MinecraftClient/Commands/Leavebed.cs index 1ded6aed..cfc0c4ce 100644 --- a/MinecraftClient/Commands/Leavebed.cs +++ b/MinecraftClient/Commands/Leavebed.cs @@ -1,17 +1,60 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using MinecraftClient.Mapping; +using PInvoke; namespace MinecraftClient.Commands { - public class leaveBedCommand : Command + public class BedCommand : Command { - public override string CmdName { get { return "leavebed"; } } - public override string CmdUsage { get { return "leavebed"; } } - public override string CmdDesc { get { return "cmd.leavebed.desc"; } } + public override string CmdName { get { return "bed"; } } + public override string CmdUsage { get { return "bed leave|sleep "; } } + public override string CmdDesc { get { return "cmd.bed.desc"; } } public override string Run(McClient handler, string command, Dictionary localVars) { - handler.SendEntityAction(Protocol.EntityActionType.LeaveBed); - return Translations.TryGet("cmd.leavebed.leaving"); + string[] args = getArgs(command); + + if (args.Length >= 1) + { + string subcommand = args[0].ToLower().Trim(); + + if (subcommand.Equals("leave") || subcommand.Equals("l")) + { + handler.SendEntityAction(Protocol.EntityActionType.LeaveBed); + return Translations.TryGet("cmd.bed.leaving"); + } + + if (subcommand.Equals("sleep") || subcommand.Equals("s")) + { + if (args.Length >= 3) + { + Location current = handler.GetCurrentLocation(); + double x = args[1].StartsWith('~') ? current.X + (args[1].Length > 1 ? double.Parse(args[1][1..]) : 0) : double.Parse(args[1]); + double y = args[2].StartsWith('~') ? current.Y + (args[2].Length > 1 ? double.Parse(args[2][1..]) : 0) : double.Parse(args[2]); + double z = args[3].StartsWith('~') ? current.Z + (args[3].Length > 1 ? double.Parse(args[3][1..]) : 0) : double.Parse(args[3]); + + Location block = new Location(x, y, z).ToFloor(), blockCenter = block.ToCenter(); + + if (!handler.GetWorld().GetBlock(block).Type.IsBed()) + return Translations.TryGet("cmd.bed.not_a_bed", blockCenter.X, blockCenter.Y, blockCenter.Z); + + bool res = handler.PlaceBlock(block, Direction.Down); + + return Translations.TryGet( + "cmd.bed.trying_to_use", + blockCenter.X, + blockCenter.Y, + blockCenter.Z, + Translations.TryGet(res ? "cmd.bed.in" : "cmd.bed.not_in") + ); + } + } + } + + return CmdUsage; } } } \ No newline at end of file diff --git a/MinecraftClient/Mapping/MaterialExtensions.cs b/MinecraftClient/Mapping/MaterialExtensions.cs index fafa4894..f1b9129a 100644 --- a/MinecraftClient/Mapping/MaterialExtensions.cs +++ b/MinecraftClient/Mapping/MaterialExtensions.cs @@ -752,6 +752,7 @@ namespace MinecraftClient.Mapping return false; } } + /// /// Check if the provided material is a liquid a player can swim into /// @@ -768,5 +769,36 @@ namespace MinecraftClient.Mapping return false; } } + + /// + /// Check if the provided material is a bed + /// + /// Material to test + /// True if the material is a bed + public static bool IsBed(this Material m) + { + switch (m) + { + case Material.BlackBed: + case Material.BlueBed: + case Material.BrownBed: + case Material.CyanBed: + case Material.GrayBed: + case Material.GreenBed: + case Material.LightBlueBed: + case Material.LightGrayBed: + case Material.LimeBed: + case Material.MagentaBed: + case Material.OrangeBed: + case Material.PinkBed: + case Material.PurpleBed: + case Material.RedBed: + case Material.WhiteBed: + case Material.YellowBed: + return true; + default: + return false; + } + } } } diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini index ceb42086..bbcfaddf 100644 --- a/MinecraftClient/Resources/lang/en.ini +++ b/MinecraftClient/Resources/lang/en.ini @@ -344,8 +344,12 @@ cmd.inventory.found_items=Found items cmd.inventory.no_found_items=Could not find the specified item in any of avaliable Inventories! # Leave bed -cmd.leavebed.desc=Used to leave a bed. -cmd.leavebed.leaving=Leaving a bed. +cmd.bed.desc=Used to sleep in or leave a bed. +cmd.bed.leaving=Sending a command to leave a bed to the server. +cmd.bed.trying_to_use=Trying to sleep in a bed on location (X: {0:0.0}, Y: {1:0.0}, Z: {2:0.0}). Result: {3} +cmd.bed.in=Succesfully laid in bed! +cmd.bed.not_in=Could not lay in bed. Are you trying to sleep in a bed? (PS: You must use the head block coordinates of the bed) +cmd.bed.not_a_bed=The block on (X: {0:0.0}, Y: {1:0.0}, Z: {2:0.0}) is not a bed! # List cmd.list.desc=get the player list. From a52da095b4f8e4b190c2bc0565c413a52d851b31 Mon Sep 17 00:00:00 2001 From: Milutinke Date: Thu, 29 Sep 2022 19:28:34 +0200 Subject: [PATCH 3/3] Added an option to find a bed and sleep in it. --- MinecraftClient/Commands/Leavebed.cs | 96 ++++++++++++++++++++++++++- MinecraftClient/Resources/lang/en.ini | 6 ++ 2 files changed, 99 insertions(+), 3 deletions(-) diff --git a/MinecraftClient/Commands/Leavebed.cs b/MinecraftClient/Commands/Leavebed.cs index cfc0c4ce..89f6c7a7 100644 --- a/MinecraftClient/Commands/Leavebed.cs +++ b/MinecraftClient/Commands/Leavebed.cs @@ -1,16 +1,15 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; +using System.Threading.Tasks; using MinecraftClient.Mapping; -using PInvoke; namespace MinecraftClient.Commands { public class BedCommand : Command { public override string CmdName { get { return "bed"; } } - public override string CmdUsage { get { return "bed leave|sleep "; } } + public override string CmdUsage { get { return "bed leave|sleep |sleep "; } } public override string CmdDesc { get { return "cmd.bed.desc"; } } public override string Run(McClient handler, string command, Dictionary localVars) @@ -29,6 +28,97 @@ namespace MinecraftClient.Commands if (subcommand.Equals("sleep") || subcommand.Equals("s")) { + if (args.Length == 2) + { + if (!int.TryParse(args[1], out int radius)) + return CmdUsage; + + handler.GetLogger().Info(Translations.TryGet("cmd.bed.searching", radius)); + + Location current = handler.GetCurrentLocation(); + Location bedLocation = current; + + Material[] bedMaterialList = new Material[]{ + Material.BlackBed, + Material.BlueBed, + Material.BrownBed, + Material.CyanBed, + Material.GrayBed, + Material.GreenBed, + Material.LightBlueBed, + Material.LightGrayBed, + Material.LimeBed, + Material.MagentaBed, + Material.OrangeBed, + Material.PinkBed, + Material.PurpleBed, + Material.RedBed, + Material.WhiteBed, + Material.YellowBed + }; + + bool found = false; + foreach (Material material in bedMaterialList) + { + List beds = handler.GetWorld().FindBlock(current, material, radius); + + if (beds.Count > 0) + { + found = true; + bedLocation = beds.First(); + break; + } + } + + if (!found) + return Translations.TryGet("cmd.bed.bed_not_found"); + + handler.Log.Info(Translations.TryGet("cmd.bed.found_a_bed_at", bedLocation.X, bedLocation.Y, bedLocation.Z)); + + if (!Movement.CheckChunkLoading(handler.GetWorld(), current, bedLocation)) + return Translations.Get("cmd.move.chunk_not_loaded", bedLocation.X, bedLocation.Y, bedLocation.Z); + + if (handler.MoveTo(bedLocation)) + { + Task.Factory.StartNew(() => + { + bool atTheLocation = false; + DateTime timeout = DateTime.Now.AddSeconds(60); + + while (DateTime.Now < timeout) + { + if (handler.GetCurrentLocation() == bedLocation || handler.GetCurrentLocation().Distance(bedLocation) <= 2.0) + { + atTheLocation = true; + break; + } + } + + if (!atTheLocation) + { + handler.Log.Info(Translations.TryGet("cmd.bed.failed_to_reach_in_time", bedLocation.X, bedLocation.Y, bedLocation.Z)); + return; + } + + handler.Log.Info(Translations.TryGet("cmd.bed.moving", bedLocation.X, bedLocation.Y, bedLocation.Z)); + + bool res = handler.PlaceBlock(bedLocation, Direction.Down); + + handler.Log.Info(Translations.TryGet( + "cmd.bed.trying_to_use", + bedLocation.X, + bedLocation.Y, + bedLocation.Z, + Translations.TryGet(res ? "cmd.bed.in" : "cmd.bed.not_in") + )); + }); + + return ""; + } + + return Translations.Get("cmd.bed.cant_reach_safely"); + } + if (args.Length >= 3) { Location current = handler.GetCurrentLocation(); diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini index bbcfaddf..92f0b614 100644 --- a/MinecraftClient/Resources/lang/en.ini +++ b/MinecraftClient/Resources/lang/en.ini @@ -350,6 +350,12 @@ cmd.bed.trying_to_use=Trying to sleep in a bed on location (X: {0:0.0}, Y: {1:0. cmd.bed.in=Succesfully laid in bed! cmd.bed.not_in=Could not lay in bed. Are you trying to sleep in a bed? (PS: You must use the head block coordinates of the bed) cmd.bed.not_a_bed=The block on (X: {0:0.0}, Y: {1:0.0}, Z: {2:0.0}) is not a bed! +cmd.bed.searching=Searching for a bed in radius of {0}... +cmd.bed.bed_not_found=Could not find a bed! +cmd.bed.found_a_bed_at=Found a bet at (X: {0:0.0}, Y: {1:0.0}, Z: {2:0.0}). +cmd.bed.cant_reach_safely=Can not reach the bed safely! +cmd.bed.moving=Moving to (X: {0:0.0}, Y: {1:0.0}, Z: {2:0.0}) where the bed is located. +cmd.bed.failed_to_reach_in_time=Failed to reach the bed position (X: {0:0.0}, Y: {1:0.0}, Z: {2:0.0}) in time (30 seconds). Giving up! # List cmd.list.desc=get the player list.