diff --git a/MCGalaxy/Bots/BotsFile.cs b/MCGalaxy/Bots/BotsFile.cs index 2e61172c8..032c60ae1 100644 --- a/MCGalaxy/Bots/BotsFile.cs +++ b/MCGalaxy/Bots/BotsFile.cs @@ -127,6 +127,7 @@ namespace MCGalaxy.Bots { [ConfigString] public string Color; [ConfigString] public string ClickedOnText; [ConfigString] public string DeathMessage; + [ConfigString] public string Owner; [ConfigString] public string AI; [ConfigBool] public bool Kill; @@ -147,6 +148,7 @@ namespace MCGalaxy.Bots { [ConfigFloat] public float ScaleZ; public void FromBot(PlayerBot bot) { + Owner = bot.Owner; Name = bot.name; Level = bot.level.name; Skin = bot.SkinName; AI = bot.AIName; Model = bot.Model; Color = bot.color; @@ -168,6 +170,7 @@ namespace MCGalaxy.Bots { rot.RotX = BodyX; rot.RotZ = BodyZ; bot.Rot = rot; + bot.Owner = Owner; bot.SkinName = Skin; bot.Model = Model; bot.color = Color; bot.AIName = AI; bot.hunt = Hunt; bot.kill = Kill; bot.DisplayName = DisplayName; diff --git a/MCGalaxy/Bots/PlayerBot.cs b/MCGalaxy/Bots/PlayerBot.cs index 853c26ae5..3b4c5ecab 100644 --- a/MCGalaxy/Bots/PlayerBot.cs +++ b/MCGalaxy/Bots/PlayerBot.cs @@ -21,6 +21,7 @@ using System.IO; using MCGalaxy.Bots; using MCGalaxy.Maths; using MCGalaxy.Network; +using MCGalaxy.Commands; namespace MCGalaxy { @@ -32,6 +33,7 @@ namespace MCGalaxy { public string name, DisplayName; public string ClickedOnText; public string DeathMessage; + public string Owner; public string ColoredName { get { return color + DisplayName; } } public byte id; @@ -59,6 +61,22 @@ namespace MCGalaxy { public override byte EntityID { get { return id; } } public override Level Level { get { return level; } } + public bool EditableBy(Player p, string attemptedAction = "modify") { + if (CanEditAny(p)) { return true; } + if (Owner == p.name) { return true; } + + p.Message("%WYou are not allowed to {0} bots that you did not create.", attemptedAction); + return false; + } + + public static bool CanEditAny(Player p) { + if (LevelInfo.IsRealmOwner(p.name, p.level.name)) { return true; } + ItemPerms perms = CommandExtraPerms.Find("Bot", 1); + perms = perms == null ? new ItemPerms(LevelPermission.Operator, null, null) : perms; + if (perms.UsableBy(p.Rank)) { return true; } + return false; + } + public static void Add(PlayerBot bot, bool save = true) { // Lock to ensure that no two bots can end up with the same playerid lock (bot.level.Bots.locker) { diff --git a/MCGalaxy/Commands/Bots/CmdBot.cs b/MCGalaxy/Commands/Bots/CmdBot.cs index 1d30b83e0..98b1026c3 100644 --- a/MCGalaxy/Commands/Bots/CmdBot.cs +++ b/MCGalaxy/Commands/Bots/CmdBot.cs @@ -28,6 +28,9 @@ namespace MCGalaxy.Commands.Bots { public override CommandAlias[] Aliases { get { return new[] { new CommandAlias("BotAdd", "add"), new CommandAlias("BotRemove", "remove") }; } } + public override CommandPerm[] ExtraPerms { + get { return new[] { new CommandPerm(LevelPermission.Operator, "can modify bots that do not belong to them") }; } + } public override void Use(Player p, string message, CommandData data) { if (message.Length == 0) { Help(p); return; } @@ -57,6 +60,7 @@ namespace MCGalaxy.Commands.Bots { void AddBot(Player p, string botName) { PlayerBot bot = new PlayerBot(botName, p.level); + bot.Owner = p.name; TryAddBot(p, bot); } @@ -86,12 +90,17 @@ namespace MCGalaxy.Commands.Bots { void RemoveBot(Player p, string botName) { if (botName.CaselessEq("all")) { - PlayerBot.RemoveLoadedBots(p.level, false); - BotsFile.Save(p.level); + if (PlayerBot.CanEditAny(p)) { + PlayerBot.RemoveLoadedBots(p.level, false); + BotsFile.Save(p.level); + } else { + p.Message("%WYou cannot remove all bots unless you are the owner of this map."); + } + } else { PlayerBot bot = Matcher.FindBots(p, botName); if (bot == null) return; - + if (!bot.EditableBy(p, "remove")) { return; } PlayerBot.Remove(bot); p.Message("Removed bot {0}", bot.ColoredName); } @@ -100,7 +109,7 @@ namespace MCGalaxy.Commands.Bots { void SetBotText(Player p, string botName, string text) { PlayerBot bot = Matcher.FindBots(p, botName); if (bot == null) return; - + if (!bot.EditableBy(p, "set the text of")) { return; } if (text == null) { p.Message("Removed text shown when bot {0} %Sclicked on", bot.ColoredName); bot.ClickedOnText = null; @@ -115,7 +124,7 @@ namespace MCGalaxy.Commands.Bots { void SetDeathMessage(Player p, string botName, string text) { PlayerBot bot = Matcher.FindBots(p, botName); if (bot == null) return; - + if (!bot.EditableBy(p, "set the death message of")) { return; } if (text == null) { p.Message("Reset shown when bot {0} %Skills someone", bot.ColoredName); bot.DeathMessage = null; @@ -133,6 +142,7 @@ namespace MCGalaxy.Commands.Bots { PlayerBot bot = Matcher.FindBots(p, botName); if (bot == null) return; + if (!bot.EditableBy(p, "rename")) { return; } if (BotExists(p.level, newName, bot)) { p.Message("A bot with the new name already exists."); return; } @@ -159,7 +169,7 @@ namespace MCGalaxy.Commands.Bots { BotProperties props = new BotProperties(); props.FromBot(bot); props.ApplyTo(clone); - + clone.Owner = p.name; clone.SetModel(clone.Model, p.level); BotsFile.LoadAi(props, clone); // Preserve custom name tag diff --git a/MCGalaxy/Commands/Bots/CmdBotSet.cs b/MCGalaxy/Commands/Bots/CmdBotSet.cs index d8245cd06..df5156ed9 100644 --- a/MCGalaxy/Commands/Bots/CmdBotSet.cs +++ b/MCGalaxy/Commands/Bots/CmdBotSet.cs @@ -36,7 +36,7 @@ namespace MCGalaxy.Commands.Bots { PlayerBot bot = Matcher.FindBots(p, args[0]); if (bot == null) return; if (!LevelInfo.Check(p, data.Rank, p.level, "change AI of bots in this level")) return; - + if (!bot.EditableBy(p, "change the AI of")) { return; } if (args.Length == 1) { bot.Instructions.Clear(); bot.kill = false; diff --git a/MCGalaxy/Commands/Bots/CmdBotSummon.cs b/MCGalaxy/Commands/Bots/CmdBotSummon.cs index 1e696b1cf..ae65c213a 100644 --- a/MCGalaxy/Commands/Bots/CmdBotSummon.cs +++ b/MCGalaxy/Commands/Bots/CmdBotSummon.cs @@ -33,6 +33,7 @@ namespace MCGalaxy.Commands.Bots { string[] args = message.SplitSpaces(2); PlayerBot bot = Matcher.FindBots(p, args[0]); if (bot == null) return; + if (!bot.EditableBy(p, "summon")) { return; } Position pos; byte yaw, pitch; if (args.Length == 1) { diff --git a/MCGalaxy/Commands/Bots/CmdBots.cs b/MCGalaxy/Commands/Bots/CmdBots.cs index 98fb2b362..78523f0e2 100644 --- a/MCGalaxy/Commands/Bots/CmdBots.cs +++ b/MCGalaxy/Commands/Bots/CmdBots.cs @@ -47,7 +47,7 @@ namespace MCGalaxy.Commands.Bots { static string FormatBot(PlayerBot bot) { string desc = bot.DisplayName; - if (bot.DisplayName != bot.name) desc += "%S(" + bot.name + ")"; + if (bot.DisplayName != bot.name) desc += "%S(&1" + bot.name + "%S)"; if (!String.IsNullOrEmpty(bot.AIName)) { desc += "[" + bot.AIName + "]"; diff --git a/MCGalaxy/Commands/EntityPropertyCmd.cs b/MCGalaxy/Commands/EntityPropertyCmd.cs index ed8dab8c3..993398cbf 100644 --- a/MCGalaxy/Commands/EntityPropertyCmd.cs +++ b/MCGalaxy/Commands/EntityPropertyCmd.cs @@ -35,6 +35,7 @@ namespace MCGalaxy.Commands { if (!CheckExtraPerm(p, data, 2)) return; if (!LevelInfo.Check(p, data.Rank, p.level, "change the " + type + " of that bot")) return; + if (!bot.EditableBy(p, "change the " + type + " of")) { return; } SetBotData(p, bot, args.Length > 2 ? args[2] : ""); } else { if (p != who && !CheckExtraPerm(p, data, 1)) return; diff --git a/MCGalaxy/Commands/Information/CmdWhoNick.cs b/MCGalaxy/Commands/Information/CmdWhoNick.cs index b2a90c15b..a00beb519 100644 --- a/MCGalaxy/Commands/Information/CmdWhoNick.cs +++ b/MCGalaxy/Commands/Information/CmdWhoNick.cs @@ -27,12 +27,20 @@ namespace MCGalaxy.Commands.Info { public override void Use(Player p, string message, CommandData data) { if (message.Length == 0) { Help(p); return; } + string[] args = message.SplitSpaces(2); + if (args.Length > 1 && args[0].CaselessEq("bot")) { + ForBot(p, args[1]); + return; + } + ForPlayer(p, message); + } + + static void ForPlayer(Player p, string message) { Player nick = FindNick(p, message); if (nick == null) return; p.Message("This player's real username is " + nick.name); } - static Player FindNick(Player p, string nick) { nick = Colors.Strip(nick); Player[] players = PlayerInfo.Online.Items; @@ -41,9 +49,25 @@ namespace MCGalaxy.Commands.Info { pl => Colors.Strip(pl.DisplayName), "online player nicks"); } + static void ForBot(Player p, string message) { + PlayerBot nick = FindBotNick(p, message); + + if (nick == null) return; + p.Message("This bot's real name is {0}, its nickname is {1}%S and its owner is {2}.", nick.name, nick.DisplayName, nick.Owner); + } + static PlayerBot FindBotNick(Player p, string nick) { + nick = Colors.Strip(nick); + PlayerBot[] bots = p.level.Bots.Items; + int matches; + return Matcher.Find(p, nick, out matches, bots, pl => true, + pl => Colors.Strip(pl.DisplayName), "bot nicknames"); + } + public override void Help(Player p) { p.Message("%T/WhoNick [nickname]"); p.Message("%HDisplays the player's real username"); + p.Message("%T/WhoNick bot [nickname]"); + p.Message("%HDisplays the bots's real name"); } } }