From 95a493d25dba9f832f177b887fcadb8c0190adf2 Mon Sep 17 00:00:00 2001 From: bravelycowering Date: Wed, 24 Dec 2025 23:50:39 -0500 Subject: [PATCH 1/2] added setblockmessage and placemessageblock --- ccs.cs | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 149 insertions(+), 9 deletions(-) diff --git a/ccs.cs b/ccs.cs index 1179242..6401332 100644 --- a/ccs.cs +++ b/ccs.cs @@ -18,6 +18,7 @@ using MCGalaxy.Events.PlayerDBEvents; using MCGalaxy.Commands; using MCGalaxy.Network; +using MCGalaxy.Blocks.Extended; using BlockID = System.UInt16; using ExtraLevelProps; using NA2; @@ -1948,25 +1949,20 @@ CommandData GetCommandData() { data.MBCoords = this.cmdData.MBCoords; return data; } - public void DoCmd(Command cmd, string args) { + public bool CheckCommandPerms(Command cmd) { CommandData data = GetCommandData(); if (!perms.canRunMessageBlockRestricted && cmd.MessageBlockRestricted) { Error("\"{0}\" cannot be used in message blocks.", cmd.name); p.Message("Therefore, it cannot be ran in a script."); - return; + return false; } CommandPerms commandPerms = CommandPerms.Find(cmd.name); if (!commandPerms.UsableBy(data.Rank)) { Error("This script can only run commands with a permission of {0} or lower.", data.Rank); p.Message("Therefore, \"{0}\" cannot be ran.", cmd.name); - return; - } - try { - cmd.Use(p, args, data); - } catch (Exception ex) { - //Logger.LogError(ex); - Error("An error occured when running command {0} with args \"{1}\": &S{2}", cmd.name, args, ex.Message); + return false; } + return true; } public void DoCmdNoPermChecks(Command cmd, string args) { try { @@ -1976,6 +1972,11 @@ public void DoCmdNoPermChecks(Command cmd, string args) { Error("An error occured when running command {0} with args \"{1}\": &S{2}", cmd.name, args, ex.Message); } } + public void DoCmd(Command cmd, string args) { + if (CheckCommandPerms(cmd)) { + DoCmdNoPermChecks(cmd, args); + } + } public void DoNewThreadRunScript(ScriptRunner scriptRunner, string startLabel) { Thread thread = new Thread( () => { @@ -3995,6 +3996,33 @@ public static BlockID ClientBlockID(BlockID serverBlockID) { } } + public class SetBlockMessage : ScriptAction { + public override Cat cat { get { return Cat.Packages; } } + public override string[] documentation { get { return new string[] { + "[package] [block coordinates]", + " Sets the value of [package] to the message of the message block at the given [block coordinates] (or nothing if no message exists)", + }; } } + + public override string name { get { return "setblockmessage"; } } + + public override void Behavior(ScriptRunner run) { + string[] bits = run.args.SplitSpaces(4); + if (bits.Length < 4) { + run.Error("You need to specify a package and x y z coordinates of the block to retrieve the ID of."); + return; + } + string packageName = bits[0]; + string[] stringCoords = new string[] { bits[1], bits[2], bits[3] }; + + Vec3S32 coords = new Vec3S32(); + if (!CommandParser.GetCoords(run.p, stringCoords, 0, ref coords)) { run.ErrorAbove(); } + string message = MessageBlock.Get(run.startingLevel.name, (ushort)coords.X, (ushort)coords.Y, (ushort)coords.Z); + if (message == null) + message = ""; + run.SetString(packageName, message); + } + } + public class DefineHotkey : ScriptAction { public override Cat cat { get { return Cat.Player; } } public override string[] documentation { get { return new string[] { @@ -4114,6 +4142,118 @@ public override void Behavior(ScriptRunner run) { } } + public class PlaceMessageBlock : ScriptAction { + public override Cat cat { get { return Cat.World; } } + public override string[] documentation { get { return new string[] { + "[block] [block coordinates] ", + " Used to place message blocks in the map.", + " Just like placeblock, these are permanently placed just like editing the map for real, so caution should be taken when using this Action.", + " If no message is provided, this places a normal block and removes the message at the coordinates specified", + }; } } + + public override string name { get { return "placemessageblock"; } } + + // copied basically 1:1 from MCGalaxy/Blocks/Extended/MessageBlock.cs + // because MCGalaxy doesnt expose MessageBlock.GetParts as public + static string[] sep = new string[] { " |/" }; + static List empty = new List(); + static List GetMessageBlockParts(string message, out string text) { + if (message.IndexOf('|') == -1) return ParseSingle(message, out text); + + string[] parts = message.Split(sep, StringSplitOptions.RemoveEmptyEntries); + List cmds = ParseSingle(parts[0], out text); + if (parts.Length == 1) return cmds; + + if (text != null) cmds = new List(); + for (int i = 1; i < parts.Length; i++) + cmds.Add(parts[i]); + return cmds; + } + + static List ParseSingle(string message, out string text) { + bool isCommand = false; + if (message[0] == '/') { + if (!message.StartsWith("//")) { + isCommand = true; + } + message = message.Substring(1); + } + + if (isCommand) { + text = null; return new List(){ message }; + } else { + text = message; return empty; + } + } + + public override void Behavior(ScriptRunner run) { + string[] bits = run.args.SplitSpaces(5); + Vec3S32 coords = new Vec3S32(); + if (bits.Length < 4) { run.Error("Not enough arguments for placemessageblock"); return; } + if (!CommandParser.GetCoords(run.p, bits, 1, ref coords)) { run.ErrorAbove(); return; } + + BlockID block = 0; + switch (bits[0]) { + case "white": + block = Block.MB_White; + break; + case "black": + block = Block.MB_Black; + break; + case "air": + block = Block.MB_Air; + break; + case "water": + block = Block.MB_Water; + break; + case "lava": + block = Block.MB_Lava; + break; + default: + if (!CommandParser.GetBlock(run.p, bits[0], out block)) { return; } + break; + } + + if (!MCGalaxy.Group.GuestRank.CanPlace[block]) { + string blockName = Block.GetName(run.p, block); + run.Error("Rank {0} &Sis not allowed to use block \"{1}\". Therefore, script cannot place it.", + MCGalaxy.Group.GuestRank.ColoredName, blockName); + return; + } + BlockID deleted = run.startingLevel.GetBlock((ushort)coords.X, (ushort)coords.Y, (ushort)coords.Z); + if (!MCGalaxy.Group.GuestRank.CanDelete[deleted]) { + string blockName = Block.GetName(run.p, deleted); + run.Error("Rank {0} &Sis not allowed to delete block \"{1}\". Therefore, script cannot replace it.", + MCGalaxy.Group.GuestRank.ColoredName, blockName); + return; + } + + coords = run.startingLevel.ClampPos(coords); + + if (bits.Length == 5) { + // verify message block contents + string message = bits[4]; + string text; + List cmdstrs = GetMessageBlockParts(message, out text); + + foreach (string cmdstr in cmdstrs) { + string[] parts = cmdstr.SplitSpaces(2); + string cmdName = parts[0], cmdArgs = ""; + Command.Search(ref cmdName, ref cmdArgs); + + Command cmd = Command.Find(cmdName); + if (!run.CheckCommandPerms(cmd)) { return; } + } + MessageBlock.Set(run.startingLevel.name, (ushort)coords.X, (ushort)coords.Y, (ushort)coords.Z, message); + } else { + MessageBlock.Delete(run.startingLevel.name, (ushort)coords.X, (ushort)coords.Y, (ushort)coords.Z); + } + + run.startingLevel.SetBlock((ushort)coords.X, (ushort)coords.Y, (ushort)coords.Z, block); + run.startingLevel.BroadcastChange((ushort)coords.X, (ushort)coords.Y, (ushort)coords.Z, block); + } + } + public class ChangeModel : ScriptAction { public override Cat cat { get { return Cat.Player; } } public override string[] documentation { get { return new string[] { From 4e010412b24d882eb7638edbf8eebb457b184579 Mon Sep 17 00:00:00 2001 From: bravelycowering Date: Thu, 25 Dec 2025 00:10:41 -0500 Subject: [PATCH 2/2] Added a period to the documentation --- ccs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ccs.cs b/ccs.cs index 6401332..0e9f3d1 100644 --- a/ccs.cs +++ b/ccs.cs @@ -4148,7 +4148,7 @@ public class PlaceMessageBlock : ScriptAction { "[block] [block coordinates] ", " Used to place message blocks in the map.", " Just like placeblock, these are permanently placed just like editing the map for real, so caution should be taken when using this Action.", - " If no message is provided, this places a normal block and removes the message at the coordinates specified", + " If no message is provided, this places a normal block and removes the message at the coordinates specified.", }; } } public override string name { get { return "placemessageblock"; } }