From b3ae2052d1cdf8747a65a450c53e364c4b9f1d8c Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 4 Aug 2016 11:42:58 +1000 Subject: [PATCH] Start work on separate brush factory code (So we can validate arguments at the time the player first does /z, instead of by the time they have placed their second block. --- Commands/building/CmdBrush.cs | 6 +- Commands/building/CmdReplaceBrush.cs | 2 +- Commands/building/CmdTree.cs | 2 +- Commands/building/DrawCmd.cs | 2 +- Drawing/BrushFactories/BrushFactory.cs | 73 ++++++++++++++++++++ Drawing/Brushes/Brush.cs | 36 ++-------- MCGalaxy_.csproj | 2 + Network/NetUtils.cs | 92 +++++++++++++------------- 8 files changed, 132 insertions(+), 83 deletions(-) create mode 100644 Drawing/BrushFactories/BrushFactory.cs diff --git a/Commands/building/CmdBrush.cs b/Commands/building/CmdBrush.cs index 15aeb1ca5..6e98a281f 100644 --- a/Commands/building/CmdBrush.cs +++ b/Commands/building/CmdBrush.cs @@ -51,7 +51,7 @@ namespace MCGalaxy.Commands.Building { } internal static string FindBrush(string message) { - foreach (var brush in Brush.Brushes) { + foreach (var brush in BrushFactory.Brushes) { if (brush.Key.CaselessEq(message)) return brush.Key; } @@ -59,7 +59,7 @@ namespace MCGalaxy.Commands.Building { } internal static string AvailableBrushes { - get { return Brush.Brushes.Keys.Join(); } + get { return BrushFactory.Brushes.Keys.Join(); } } public override void Help(Player p) { @@ -80,7 +80,7 @@ namespace MCGalaxy.Commands.Building { Player.Message(p, "No brush found with name \"{0}\".", message); Player.Message(p, "%HAvailable brushes: %S" + AvailableBrushes); } else { - Player.MessageLines(p, Brush.BrushesHelp[brush]); + Player.MessageLines(p, BrushFactory.BrushesHelp[brush]); } } } diff --git a/Commands/building/CmdReplaceBrush.cs b/Commands/building/CmdReplaceBrush.cs index 18272c709..6ac1b5e0c 100644 --- a/Commands/building/CmdReplaceBrush.cs +++ b/Commands/building/CmdReplaceBrush.cs @@ -57,7 +57,7 @@ namespace MCGalaxy.Commands.Building { string brushMessage = parts.Length > 2 ? parts[2].ToLower() : ""; BrushArgs args = new BrushArgs(p, brushMessage, type, extType); - Brush brush = Brush.Brushes[brushName](args); + Brush brush = BrushFactory.Brushes[brushName](args); if (brush == null) return false; DrawOp drawOp = null; diff --git a/Commands/building/CmdTree.cs b/Commands/building/CmdTree.cs index 6e5a13f5b..0623e816e 100644 --- a/Commands/building/CmdTree.cs +++ b/Commands/building/CmdTree.cs @@ -79,7 +79,7 @@ namespace MCGalaxy.Commands.Building { string brushArgs = parts.Length >= 2 ? parts[1].ToLower() : ""; BrushArgs args = new BrushArgs(p, brushArgs, block, extBlock); - return Brush.Brushes[brushName](args); + return BrushFactory.Brushes[brushName](args); } struct DrawArgs { public int mode; public string brushMsg; } diff --git a/Commands/building/DrawCmd.cs b/Commands/building/DrawCmd.cs index be130a786..b112c0b2f 100644 --- a/Commands/building/DrawCmd.cs +++ b/Commands/building/DrawCmd.cs @@ -83,7 +83,7 @@ namespace MCGalaxy.Commands.Building { if (end >= 0) brushMsg = dArgs.message.Substring(0, end); if (brushMsg == "") brushMsg = p.DefaultBrushArgs; - if (constructor == null) constructor = Brush.Brushes[p.BrushName]; + if (constructor == null) constructor = BrushFactory.Brushes[p.BrushName]; BrushArgs args = new BrushArgs(p, brushMsg, dArgs.block, dArgs.extBlock); return constructor(args); } diff --git a/Drawing/BrushFactories/BrushFactory.cs b/Drawing/BrushFactories/BrushFactory.cs new file mode 100644 index 000000000..0891945ed --- /dev/null +++ b/Drawing/BrushFactories/BrushFactory.cs @@ -0,0 +1,73 @@ +/* + Copyright 2015 MCGalaxy + + Dual-licensed under the Educational Community License, Version 2.0 and + the GNU General Public License, Version 3 (the "Licenses"); you may + not use this file except in compliance with the Licenses. You may + obtain a copy of the Licenses at + + http://www.opensource.org/licenses/ecl2.php + http://www.gnu.org/licenses/gpl-3.0.html + + Unless required by applicable law or agreed to in writing, + software distributed under the Licenses are distributed on an "AS IS" + BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the Licenses for the specific language governing + permissions and limitations under the Licenses. + */ +using System; +using System.Collections.Generic; +using MCGalaxy.Commands; +using MCGalaxy.Drawing.Ops; + +namespace MCGalaxy.Drawing.Brushes { + public abstract class BrushFactory { + + /// Human friendly name of this brush. + public abstract string Name { get; } + + /// Description of the brush, in addition to its syntax. + public abstract string[] Help { get; } + + /// Creates a brush from the given arguments, + /// returning null if invalid arguments are specified. + public abstract Brush Process(BrushArgs args); + + public static Dictionary> Brushes + = new Dictionary> { + { "normal", SolidBrush.Process }, { "paste", PasteBrush.Process }, + { "checkered", CheckeredBrush.Process }, { "rainbow", RainbowBrush.Process }, + { "bwrainbow", BWRainbowBrush.Process }, { "striped", StripedBrush.Process }, + { "replace", ReplaceBrush.Process }, { "replacenot", ReplaceNotBrush.Process }, + { "random", RandomBrush.Process }, { "cloudy", CloudyBrush.Process }, + }; + + public static Dictionary BrushesHelp = new Dictionary { + { "normal", SolidBrush.HelpString }, { "paste", PasteBrush.HelpString }, + { "checkered", CheckeredBrush.HelpString }, { "rainbow", RainbowBrush.HelpString }, + { "bwrainbow", BWRainbowBrush.HelpString }, { "striped", StripedBrush.HelpString }, + { "replace", ReplaceBrush.HelpString }, { "replacenot", ReplaceNotBrush.HelpString }, + { "random", RandomBrush.HelpString }, { "cloudy", CloudyBrush.HelpString }, + }; + } + + public struct BrushArgs { + /// Player that is providing arguments for this brush. + public Player Player; + + /// Raw message provided for arguments to the brush, including spaces. + public string Message; + + /// Raw block the player is currently holding. + /// If the player is holding a custom block, + /// this value is Block.custom_block and ExtBlock is the actual block. + public byte Block; + + /// Custom block the player is currently holding. + public byte ExtBlock; + + public BrushArgs(Player p, string message, byte block, byte extBlock) { + Player = p; Message = message; Block = block; ExtBlock = extBlock; + } + } +} diff --git a/Drawing/Brushes/Brush.cs b/Drawing/Brushes/Brush.cs index 3488f80f9..6a0f28a69 100644 --- a/Drawing/Brushes/Brush.cs +++ b/Drawing/Brushes/Brush.cs @@ -16,12 +16,9 @@ permissions and limitations under the Licenses. */ using System; -using System.Collections.Generic; -using MCGalaxy.Commands; using MCGalaxy.Drawing.Ops; namespace MCGalaxy.Drawing.Brushes { - public abstract class Brush { /// Human friendly name of this brush. @@ -33,35 +30,12 @@ namespace MCGalaxy.Drawing.Brushes { /// Performs calcuations (if necessary) for the given drawop. public virtual void Configure(DrawOp op, Player p) { } + /// Returns the next block that should be placed in the world, + /// based on the draw operation's current state. public abstract byte NextBlock(DrawOp op); - + + /// Returns the next custom block that should be placed in the world, + /// based on the draw operation's current state. public abstract byte NextExtBlock(DrawOp op); - - public static Dictionary> Brushes - = new Dictionary> { - { "normal", SolidBrush.Process }, { "paste", PasteBrush.Process }, - { "checkered", CheckeredBrush.Process }, { "rainbow", RainbowBrush.Process }, - { "bwrainbow", BWRainbowBrush.Process }, { "striped", StripedBrush.Process }, - { "replace", ReplaceBrush.Process }, { "replacenot", ReplaceNotBrush.Process }, - { "random", RandomBrush.Process }, { "cloudy", CloudyBrush.Process }, - }; - - public static Dictionary BrushesHelp = new Dictionary { - { "normal", SolidBrush.HelpString }, { "paste", PasteBrush.HelpString }, - { "checkered", CheckeredBrush.HelpString }, { "rainbow", RainbowBrush.HelpString }, - { "bwrainbow", BWRainbowBrush.HelpString }, { "striped", StripedBrush.HelpString }, - { "replace", ReplaceBrush.HelpString }, { "replacenot", ReplaceNotBrush.HelpString }, - { "random", RandomBrush.HelpString }, { "cloudy", CloudyBrush.HelpString }, - }; - } - - public struct BrushArgs { - public Player Player; - public string Message; - public byte Block, ExtBlock; // currently holding - - public BrushArgs(Player p, string message, byte block, byte extBlock) { - Player = p; Message = message; Block = block; ExtBlock = extBlock; - } } } diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj index 8b6acc2cd..f1ddcbafa 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -423,6 +423,7 @@ + @@ -691,6 +692,7 @@ + diff --git a/Network/NetUtils.cs b/Network/NetUtils.cs index 56f762729..c9fe3c4fb 100644 --- a/Network/NetUtils.cs +++ b/Network/NetUtils.cs @@ -18,61 +18,61 @@ using System; namespace MCGalaxy { - + /// Utility methods for reading/writing big endian integers, and fixed length strings. public static class NetUtils { - - public static void Write(string str, byte[] array, int offset, bool hasCP437) { - if (hasCP437) WriteCP437(str, array, offset); - else WriteAscii(str, array, offset); + + public static short ReadI16(byte[] array, int offset) { + return (short)(array[offset] << 8 | array[offset + 1]); } - - public static void WriteAscii(string str, byte[] array, int offset) { - for (int i = 0; i < 64; i++) - array[offset + i] = (byte)' '; - - for (int i = 0; i < Math.Min(str.Length, 64); i++) { - char raw = str[i]; - array[offset + i] = raw >= '\u0080' ? (byte)'?' : (byte)raw; - } - } - - public static void WriteCP437(string str, byte[] array, int offset) { - for (int i = 0; i < 64; i++) - array[offset + i] = (byte)' '; - - for (int i = 0; i < Math.Min(str.Length, 64); i++) { - array[offset + i] = (byte)str[i]; - } - } - - public static short ReadI16(byte[] array, int offset) { - return (short)(array[offset] << 8 | array[offset + 1]); - } public static ushort ReadU16(byte[] array, int offset) { - return (ushort)(array[offset] << 8 | array[offset + 1]); - } + return (ushort)(array[offset] << 8 | array[offset + 1]); + } public static int ReadI32(byte[] array, int offset) { - return array[offset] << 24 | array[offset + 1] << 16 - | array[offset + 2] << 8 | array[offset + 3]; - } + return array[offset] << 24 | array[offset + 1] << 16 + | array[offset + 2] << 8 | array[offset + 3]; + } public static void WriteI16(short value, byte[] array, int index) { - array[index++] = (byte)(value >> 8); - array[index++] = (byte)(value); - } + array[index++] = (byte)(value >> 8); + array[index++] = (byte)(value); + } public static void WriteU16(ushort value, byte[] array, int index) { - array[index++] = (byte)(value >> 8); - array[index++] = (byte)(value); - } - - public static void WriteI32(int value, byte[] array, int index) { - array[index++] = (byte)(value >> 24); - array[index++] = (byte)(value >> 16); - array[index++] = (byte)(value >> 8); - array[index++] = (byte)(value); - } + array[index++] = (byte)(value >> 8); + array[index++] = (byte)(value); + } + + public static void WriteI32(int value, byte[] array, int index) { + array[index++] = (byte)(value >> 24); + array[index++] = (byte)(value >> 16); + array[index++] = (byte)(value >> 8); + array[index++] = (byte)(value); + } + + + public static void Write(string str, byte[] array, int offset, bool hasCP437) { + if (hasCP437) WriteCP437(str, array, offset); + else WriteAscii(str, array, offset); + } + + public static void WriteAscii(string str, byte[] array, int offset) { + int count = Math.Min(str.Length, 64); + for (int i = 0; i < count; i++) { + char raw = str[i]; + array[offset + i] = raw >= '\u0080' ? (byte)'?' : (byte)raw; + } + for (int i = count; i < 64; i++) + array[offset + i] = (byte)' '; + } + + public static void WriteCP437(string str, byte[] array, int offset) { + int count = Math.Min(str.Length, 64); + for (int i = 0; i < count; i++) + array[offset + i] = (byte)str[i]; + for (int i = count; i < 64; i++) + array[offset + i] = (byte)' '; + } } }