diff --git a/MCGalaxy/Commands/World/CmdMap.cs b/MCGalaxy/Commands/World/CmdMap.cs index d043588ac..60add7ff6 100644 --- a/MCGalaxy/Commands/World/CmdMap.cs +++ b/MCGalaxy/Commands/World/CmdMap.cs @@ -62,10 +62,8 @@ namespace MCGalaxy.Commands.World { } static bool IsMapOption(string[] args) { - string opt = args[0].ToLower(); - const string opts = "theme|finite|ai|edge|grass|ps|physicspeed|overload|motd|death|killer|fall|drown|unload" - + "|realmowner|chat|load|loadongoto|leaf|leafdecay|flow|randomflow|tree|growtrees|buildable|deletable"; - if (!opts.Contains(opt)) return false; + string opt = LevelOptions.Map(args[0].ToLower()); + if (!LevelOptions.Options.ContainsKey(opt)) return false; // In rare case someone uses /map motd motd My MOTD if (opt == "motd" && (args.Length == 1 || !args[1].CaselessStarts("motd "))) return true; diff --git a/MCGalaxy/Levels/LevelOptions.cs b/MCGalaxy/Levels/LevelOptions.cs new file mode 100644 index 000000000..b4096487a --- /dev/null +++ b/MCGalaxy/Levels/LevelOptions.cs @@ -0,0 +1,135 @@ +/* + Copyright 2015 MCGalaxy team + + 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; + +namespace MCGalaxy { + + public static class LevelOptions { + + public delegate void OptionSetter(Player p, Level lvl, string value); + + public static Dictionary Options = + new Dictionary() { + { "theme", SetTheme }, + { "motd", SetMotd }, + { "realmowner", SetRealmOwner }, + { "physicsspeed", (p, l, value) => SetPhysicsSpeed(p, l, value, "Physics speed") }, + { "overload", (p, l, value) => SetPhysicsOverload(p, l, value, "Physics overload") }, + { "fall", (p, l, value) => SetInt(p, l, ref l.fall, value, "Fall distance") }, + { "drown", (p, l, value) => SetInt(p, l, ref l.drown, value, "Drown time (in tenths of a second)") }, + { "finite", (p, l, value) => Set(p, l, ref l.finite, "Finite mode") }, + { "ai", (p, l, value) => Set(p, l, ref l.ai, "Animal AI") }, + { "edge", (p, l, value) => Set(p, l, ref l.edgeWater, "Edge water") }, + { "grass", (p, l, value) => Set(p, l, ref l.GrassGrow, "Growing grass") }, + { "death", (p, l, value) => Set(p, l, ref l.Death, "Survival death") }, + { "killer", (p, l, value) => Set(p, l, ref l.Killer, "Killer blocks") }, + { "unload", (p, l, value) => Set(p, l, ref l.unload, "Auto unload") }, + { "loadongoto", (p, l, value) => Set(p, l, ref l.loadOnGoto, "Load on goto") }, + { "leafdecay", (p, l, value) => Set(p, l, ref l.leafDecay, "Leaf decay") }, + { "randomflow", (p, l, value) => Set(p, l, ref l.randomFlow, "Random flow") }, + { "growtrees", (p, l, value) => Set(p, l, ref l.growTrees, "Tree growing") }, + { "chat", (p, l, value) => Set(p, l, ref l.worldChat, "Roleplay (level only) chat: ", true) }, + { "buildable", (p, l, value) => SetPerms(p, l, ref l.Buildable, "Buildable") }, + { "deletable", (p, l, value) => SetPerms(p, l, ref l.Deletable, "Deletable") }, + }; + + + public static string Map(string opt) { + if (opt == "ps") return "physicsspeed"; + if (opt == "load") return "loadongoto"; + if (opt == "leaf") return "leafdecay"; + if (opt == "flow") return "randomflow"; + if (opt == "tree") return "growtrees"; + return opt; + } + + static string GetBool(bool value) { return value ? "&aON" : "&cOFF"; } + + static void SetPhysicsSpeed(Player p, Level lvl, string value, string name) { + SetInt(p, lvl, ref lvl.speedPhysics, value, name, PhysicsSpeedValidator); + } + + static bool PhysicsSpeedValidator(Player p, int raw) { + if (raw < 10) { Player.Message(p, "Physics speed cannot be below 10 milliseconds."); return false; } + return true; + } + + static void SetPhysicsOverload(Player p, Level lvl, string value, string name) { + SetInt(p, lvl, ref lvl.overload, value, name, PhysicsOverloadValidator); + } + + static bool PhysicsOverloadValidator(Player p, int raw) { + if (raw < 500) { + Player.Message(p, "Physics overload cannot go below 500 (default is 1500)"); return false; + } + if (p != null && p.Rank < LevelPermission.Admin && raw > 2500) { + Player.Message(p, "Only SuperOPs may set physics overload higher than 2500"); return false; + } + return true; + } + + + static void SetTheme(Player p, Level lvl, string value) { + lvl.theme = value; + lvl.ChatLevel("Map theme: &b" + lvl.theme); + } + + static void SetMotd(Player p, Level lvl, string value) { + lvl.motd = value == "" ? "ignore" : value; + lvl.ChatLevel("Map's MOTD was changed to: &b" + lvl.motd); + + Player[] players = PlayerInfo.Online.Items; + foreach (Player pl in players) { + if (pl.level != lvl || !pl.HasCpeExt(CpeExt.HackControl)) continue; + pl.Send(Hacks.MakeHackControl(pl)); + } + } + + static void SetRealmOwner(Player p, Level lvl, string value) { + lvl.RealmOwner = value; + if (value == "") Player.Message(p, "Removed realm owner for this level."); + else Player.Message(p, "Set realm owner/owners of this level to {0}.", value); + } + + static void SetPerms(Player p, Level lvl, ref bool target, string name) { + Set(p, lvl, ref target, name); + lvl.UpdateBlockPermissions(); + } + + static void Set(Player p, Level lvl, ref bool target, string name, bool not = false) { + target = !target; + bool display = not ? !target : target; + lvl.ChatLevel(name + ": " + GetBool(display)); + + if (p == null || p.level != lvl) + Player.Message(p, name + ": " + GetBool(display)); + } + + static void SetInt(Player p, Level lvl, ref int target, string value, string name, + Func validator = null) { + if (value == "") { Player.Message(p, "You must provide an integer."); return; } + int raw; + if (!int.TryParse(value, out raw)) { Player.Message(p, "\"{0}\" is not a valid integer.", value); return; } + + if (validator != null && !validator(p, raw)) return; + target = raw; + lvl.ChatLevel(name + ": &b" + target); + } + } +} diff --git a/MCGalaxy/MCGalaxy_.csproj b/MCGalaxy/MCGalaxy_.csproj index 11543711f..8df0f7684 100644 --- a/MCGalaxy/MCGalaxy_.csproj +++ b/MCGalaxy/MCGalaxy_.csproj @@ -516,6 +516,7 @@ +