public override void Validate(string value) { base.Validate(value); Rank rank; if (value.Length == 0) { rank = GetBlankValueSubstitute(); if (rank == null) { return; // ranks must not have loaded yet; can't validate } } else { rank = RankManager.ParseRank(value); if (rank == null) { throw new FormatException("Value cannot be parsed as a rank."); } } if (!CanBeLowest && rank == RankManager.LowestRank) { throw new FormatException("Value may not be the lowest rank."); } if (!CanBeHighest && rank == RankManager.HighestRank) { throw new FormatException("Value may not be the highest rank."); } }
static Rank LoadWorldRankRestriction(World world, string fieldType, XElement element) { if (world == null) { throw new ArgumentNullException("world"); } if (element == null) { throw new ArgumentNullException("element"); } XAttribute temp; if ((temp = element.Attribute(fieldType)) == null) { return(RankManager.LowestRank); } Rank rank; if ((rank = RankManager.ParseRank(temp.Value)) != null) { return(rank); } Logger.Log("Server.ParseWorldListXML: Could not parse the specified {0} rank for world \"{1}\": \"{2}\". No {0} limit was set.", LogType.Error, fieldType, world.Name, temp.Value); return(RankManager.LowestRank); }
internal static void ThrowPermissionMissing([NotNull] Player player, [CanBeNull] PlayerInfo target, [NotNull] string action, [NotNull] params Permission[] permissions) { if (player == null) { throw new ArgumentNullException("player"); } if (action == null) { throw new ArgumentNullException("action"); } if (permissions == null) { throw new ArgumentNullException("permissions"); } Rank minRank = RankManager.GetMinRankWithAllPermissions(permissions); string msg, colorMsg; if (minRank != null) { msg = String.Format("You need to be ranked {0}+ to {1}.", minRank.Name, action); colorMsg = String.Format("&SYou need to be ranked {0}&S+ to {1}.", minRank.ClassyName, action); } else { msg = String.Format("No one is allowed to {0} on this server.", action); colorMsg = String.Format("&SNo one is allowed to {0} on this server.", action); } throw new PlayerOpException(player, target, PlayerOpExceptionCode.PermissionMissing, msg, colorMsg); }
internal static void Commands(Player player, Command cmd) { string param = cmd.Next(); CommandDescriptor[] cd; if (param == null) { player.Message("List of available commands:"); cd = CommandManager.GetCommands(false); } else if (param.StartsWith("@")) { string rankName = param.Substring(1); Rank rank = RankManager.FindRank(rankName); if (rank == null) { player.Message("Unknown rank: {0}", rankName); return; } else { player.Message("List of commands available to {0}&S:", rank.GetClassyName()); cd = CommandManager.GetCommands(rank, true); } } else if (param.Equals("all", StringComparison.OrdinalIgnoreCase)) { player.Message("List of ALL commands:"); cd = CommandManager.GetCommands(); } else if (param.Equals("hidden", StringComparison.OrdinalIgnoreCase)) { player.Message("List of hidden commands:"); cd = CommandManager.GetCommands(true); } else if (Enum.GetNames(typeof(CommandCategory)).Contains(param, StringComparer.OrdinalIgnoreCase)) { CommandCategory category = (CommandCategory)Enum.Parse(typeof(CommandCategory), param, true); player.Message("List of {0} commands:", category); cd = CommandManager.GetCommands(category, false); } else if (Enum.GetNames(typeof(Permission)).Contains(param, StringComparer.OrdinalIgnoreCase)) { Permission permission = (Permission)Enum.Parse(typeof(Permission), param, true); player.Message("List of commands that need {0} permission:", permission); cd = CommandManager.GetCommands(permission, true); } else { cdCommands.PrintUsage(player); return; } string[] commandNames = cd.Select(desc => desc.Name).ToArray(); player.MessagePrefixed("&S ", "&S " + String.Join(", ", commandNames)); }
void HandleRankChatMessage([NotNull] string rawMessage) { if (rawMessage == null) { throw new ArgumentNullException("rawMessage"); } if (!Can(Permission.Chat)) { return; } if (Info.IsMuted) { MessageMuted(); return; } if (DetectChatSpam()) { return; } if (rawMessage.EndsWith("//")) { rawMessage = rawMessage.Substring(0, rawMessage.Length - 1); } Rank rank; if (rawMessage[2] == ' ') { rank = Info.Rank; } else { string rankName = rawMessage.Substring(2, rawMessage.IndexOf(' ') - 2); rank = RankManager.FindRank(rankName); if (rank == null) { MessageNoRank(rankName); return; } } string messageText = rawMessage.Substring(rawMessage.IndexOf(' ') + 1); Player[] spectators = Server.Players.NotRanked(Info.Rank) .Where(p => p.spectatedPlayer == this) .ToArray(); if (spectators.Length > 0) { spectators.Message("[Spectate]: &Fto rank {0}&F: {1}", rank.ClassyName, messageText); } Chat.SendRank(this, rank, messageText); }
static void MassRankHandler(Player player, CommandReader cmd) { string fromRankName = cmd.Next(); string toRankName = cmd.Next(); string reason = cmd.NextAll(); if (fromRankName == null || toRankName == null) { CdMassRank.PrintUsage(player); return; } Rank fromRank = RankManager.FindRank(fromRankName); if (fromRank == null) { player.MessageNoRank(fromRankName); return; } Rank toRank = RankManager.FindRank(toRankName); if (toRank == null) { player.MessageNoRank(toRankName); return; } if (fromRank == toRank) { player.Message("Ranks must be different"); return; } int playerCount; using (PlayerDB.GetReadLock()) { playerCount = PlayerDB.List.Count(t => t.Rank == fromRank); } string verb = (fromRank > toRank ? "demot" : "promot"); if (!cmd.IsConfirmed) { player.Confirm(cmd, "MassRank: {0}e {1} players?", verb.UppercaseFirst(), playerCount); return; } player.Message("MassRank: {0}ing {1} players...", verb, playerCount); int affected = PlayerDB.MassRankChange(player, fromRank, toRank, reason); player.Message("MassRank: done, {0} records affected.", affected); }
// Shows general information about a particular rank. internal static void RankInfo(Player player, Command cmd) { Rank rank; string rankName = cmd.Next(); if (rankName == null) { rank = player.Info.Rank; } else { rank = RankManager.FindRank(rankName); if (rank == null) { player.Message("No such rank: \"{0}\". See &H/ranks", rankName); return; } } if (rank != null) { List <Permission> permissions = new List <Permission>(); for (int i = 0; i < rank.Permissions.Length; i++) { if (rank.Permissions[i]) { permissions.Add((Permission)i); } } string[] sortedPermissionNames = permissions.Select(p => p.ToString()) .OrderBy(s => s, StringComparer.OrdinalIgnoreCase).ToArray(); player.Message("Players of rank {0}&S can do the following: {1}", rank.GetClassyName(), String.Join(", ", sortedPermissionNames)); if (rank.Can(Permission.Draw)) { if (rank.DrawLimit > 0) { player.Message("Draw command limit: {0} blocks.", rank.DrawLimit); } else { player.Message("Draw command limit: None (unlimited blocks)"); } } } }
public void NoAccessMessage(params Permission[] permissions) { Rank reqRank = RankManager.GetMinRankWithPermission(permissions); if (reqRank == null) { Message("This command is disabled on the server."); } else { Message("This command requires {0}+&S rank.", reqRank.GetClassyName()); } }
internal bool ParsePermissionLimits() { bool ok = true; for (int i = 0; i < PermissionLimits.Length; i++) { if (PermissionLimitStrings[i] == null) { continue; } SetLimit((Permission)i, RankManager.ParseRank(PermissionLimitStrings[i])); ok &= (GetLimit((Permission)i) != null); } return(ok); }
/// <summary> Checks if a zone name makes it a special zone, and if so, whether the player can manage the special zone. </summary> public static bool CanManage(string name, Player player, string action) { if (name == null) { return(false); } Rank rank = RankManager.GetMinRankWithAnyPermission(Permission.ManageSpecialZones); if (name.CaselessStarts(Command) || name.CaselessStarts(ConsoleCommand)) { if (player.Info.Rank == RankManager.HighestRank && player.Can(Permission.ManageSpecialZones)) { return(true); } if (rank != null) { player.Message("You must be {0}&S to {1} command zone.", RankManager.HighestRank.ClassyName, action); } else { player.Message("No rank has permission to {0} command zone.", action); } return(false); } else if (IsSpecialAffect(name) || IsSpecialMove(name)) { if (player.Can(Permission.ManageSpecialZones)) { return(true); } if (rank != null) { player.Message("You must be {0}&S to {1} special zone.", rank.ClassyName, action); } else { player.Message("No rank has permission to {0} special zone.", action); } return(false); } return(true); }
public SecurityController(XElement el) { if (el == null) { throw new ArgumentNullException("el"); } if (el.Element("minRank") != null) { minRank = RankManager.ParseRank(el.Element("minRank").Value); } else { minRank = null; } //maxRank = RankManager.ParseRank( root.Element( "maxRank" ).Value ); foreach (XElement player in el.Elements("included")) { if (!Player.IsValidName(player.Value)) { continue; } PlayerInfo info = PlayerDB.FindPlayerInfoExact(player.Value); if (info != null) { Include(info); } } foreach (XElement player in el.Elements("excluded")) { if (!Player.IsValidName(player.Value)) { continue; } PlayerInfo info = PlayerDB.FindPlayerInfoExact(player.Value); if (info != null) { Exclude(info); } } UpdatePlayerListCache(); }
/// <summary> Prints "This command requires ___+ rank" message. </summary> /// <param name="permissions"> List of permissions required for the command. </param> /// <exception cref="ArgumentNullException"> permissions is null. </exception> /// <exception cref="ArgumentException"> permissions array is empty. </exception> public void MessageNoAccess([NotNull] params Permission[] permissions) { if (permissions == null) { throw new ArgumentNullException("permissions"); } if (permissions.Length == 0) { throw new ArgumentException("At least one permission required.", "permissions"); } Rank reqRank = RankManager.GetMinRankWithAllPermissions(permissions); if (reqRank == null) { Message("None of the ranks have permissions for this command."); } else { Message("This command requires {0}+&S rank.", reqRank.ClassyName); } }
static void ZoneAddHandler(Player player, CommandReader cmd) { World playerWorld = player.World; if (playerWorld == null) { PlayerOpException.ThrowNoWorld(player); } string givenZoneName = cmd.Next(); if (givenZoneName == null) { CdZoneAdd.PrintUsage(player); return; } if (!player.Info.Rank.AllowSecurityCircumvention) { SecurityCheckResult buildCheck = playerWorld.BuildSecurity.CheckDetailed(player.Info); switch (buildCheck) { case SecurityCheckResult.BlackListed: player.Message("Cannot add zones to world {0}&S: You are barred from building here.", playerWorld.ClassyName); return; case SecurityCheckResult.RankTooLow: player.Message("Cannot add zones to world {0}&S: You are not allowed to build here.", playerWorld.ClassyName); return; } } Zone newZone = new Zone(); ZoneCollection zoneCollection = player.WorldMap.Zones; if (givenZoneName.StartsWith("+")) { // personal zone (/ZAdd +Name) givenZoneName = givenZoneName.Substring(1); // Find the target player PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, givenZoneName); if (info == null) { return; } // Make sure that the name is not taken already. // If a zone named after the player already exists, try adding a number after the name (e.g. "Notch2") newZone.Name = info.Name; for (int i = 2; zoneCollection.Contains(newZone.Name); i++) { newZone.Name = givenZoneName + i; } newZone.Controller.MinRank = info.Rank.NextRankUp ?? info.Rank; newZone.Controller.Include(info); player.Message("ZoneAdd: Creating a {0}+&S zone for player {1}&S. Click or &H/Mark&S 2 blocks.", newZone.Controller.MinRank.ClassyName, info.ClassyName); player.SelectionStart(2, ZoneAddCallback, newZone, CdZoneAdd.Permissions); } else { // Adding an ordinary, rank-restricted zone. if (!World.IsValidName(givenZoneName)) { player.Message("\"{0}\" is not a valid zone name", givenZoneName); return; } if (zoneCollection.Contains(givenZoneName)) { player.Message("A zone with this name already exists. Use &H/ZEdit&S to edit."); return; } newZone.Name = givenZoneName; string rankName = cmd.Next(); if (rankName == null) { player.Message("No rank was specified. See &H/Help zone"); return; } Rank minRank = RankManager.FindRank(rankName); if (minRank == null) { player.MessageNoRank(rankName); return; } string name; while ((name = cmd.Next()) != null) { if (name.Length < 1) { CdZoneAdd.PrintUsage(player); return; } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, name.Substring(1)); if (info == null) { return; } if (name.StartsWith("+")) { newZone.Controller.Include(info); } else if (name.StartsWith("-")) { newZone.Controller.Exclude(info); } } newZone.Controller.MinRank = minRank; player.SelectionStart(2, ZoneAddCallback, newZone, CdZoneAdd.Permissions); player.Message("ZoneAdd: Creating zone {0}&S. Click or &H/Mark&S 2 blocks.", newZone.ClassyName); } }
internal static void ZoneEdit(Player player, Command cmd) { bool changesWereMade = false; string zoneName = cmd.Next(); if (zoneName == null) { player.Message("No zone name specified. See &H/help zedit"); return; } Zone zone = player.World.Map.FindZone(zoneName); if (zone == null) { player.Message("No zone found with the name \"{0}\". See &H/zones", zoneName); return; } string name; while ((name = cmd.Next()) != null) { if (name.Length < 2) { continue; } if (name.StartsWith("+")) { PlayerInfo info; if (!PlayerDB.FindPlayerInfo(name.Substring(1), out info)) { player.Message("More than one player found matching \"{0}\"", name.Substring(1)); return; } if (info == null) { player.NoPlayerMessage(name.Substring(1)); return; } // prevent players from whitelisting themselves to bypass protection if (!player.Info.Rank.AllowSecurityCircumvention && player.Info == info) { if (!zone.Controller.Check(info)) { player.Message("You must be {0}+&S to add yourself to this zone's whitelist.", zone.Controller.MinRank.GetClassyName()); continue; } } switch (zone.Controller.Include(info)) { case PermissionOverride.Deny: player.Message("{0}&S is no longer excluded from zone {1}", info.GetClassyName(), zone.GetClassyName()); changesWereMade = true; break; case PermissionOverride.None: player.Message("{0}&S is now included in zone {1}", info.GetClassyName(), zone.GetClassyName()); changesWereMade = true; break; case PermissionOverride.Allow: player.Message("{0}&S is already included in zone {1}", info.GetClassyName(), zone.GetClassyName()); break; } } else if (name.StartsWith("-")) { PlayerInfo info; if (!PlayerDB.FindPlayerInfo(name.Substring(1), out info)) { player.Message("More than one player found matching \"{0}\"", name.Substring(1)); return; } if (info == null) { player.NoPlayerMessage(name.Substring(1)); return; } switch (zone.Controller.Exclude(info)) { case PermissionOverride.Deny: player.Message("{0}&S is already excluded from zone {1}", info.GetClassyName(), zone.GetClassyName()); break; case PermissionOverride.None: player.Message("{0}&S is now excluded from zone {1}", info.GetClassyName(), zone.GetClassyName()); changesWereMade = true; break; case PermissionOverride.Allow: player.Message("{0}&S is no longer included in zone {1}", info.GetClassyName(), zone.GetClassyName()); changesWereMade = true; break; } } else { Rank minRank = RankManager.ParseRank(name); if (minRank != null) { // prevent players from lowering rank so bypass protection if (!player.Info.Rank.AllowSecurityCircumvention && zone.Controller.MinRank > player.Info.Rank && minRank <= player.Info.Rank) { player.Message("You are not allowed to lower the zone's rank."); continue; } if (zone.Controller.MinRank != minRank) { zone.Controller.MinRank = minRank; player.Message("Permission for zone \"{0}\" changed to {1}+", zone.Name, minRank.GetClassyName()); changesWereMade = true; } } else { player.NoRankMessage(name); } } if (changesWereMade) { zone.Edit(player.Info); player.World.Map.ChangedSinceSave = true; } else { player.Message("No changes were made to the zone."); } } }
static void ZoneEditHandler(Player player, CommandReader cmd) { if (player.World == null) { PlayerOpException.ThrowNoWorld(player); } bool changesWereMade = false; string zoneName = cmd.Next(); if (zoneName == null) { player.Message("No zone name specified. See &H/Help ZEdit"); return; } Zone zone = player.WorldMap.Zones.Find(zoneName); if (zone == null) { player.MessageNoZone(zoneName); return; } string nextToken; while ((nextToken = cmd.Next()) != null) { // Clear whitelist if (nextToken.Equals("-*")) { PlayerInfo[] oldWhitelist = zone.Controller.ExceptionList.Included; if (oldWhitelist.Length > 0) { zone.Controller.ResetIncludedList(); player.Message("Whitelist of zone {0}&S cleared: {1}", zone.ClassyName, oldWhitelist.JoinToClassyString()); Logger.Log(LogType.UserActivity, "Player {0} cleared whitelist of zone {1} on world {2}: {3}", player.Name, zone.Name, player.World.Name, oldWhitelist.JoinToString(pi => pi.Name)); } else { player.Message("Whitelist of zone {0}&S is empty.", zone.ClassyName); } continue; } // Clear blacklist if (nextToken.Equals("+*")) { PlayerInfo[] oldBlacklist = zone.Controller.ExceptionList.Excluded; if (oldBlacklist.Length > 0) { zone.Controller.ResetExcludedList(); player.Message("Blacklist of zone {0}&S cleared: {1}", zone.ClassyName, oldBlacklist.JoinToClassyString()); Logger.Log(LogType.UserActivity, "Player {0} cleared blacklist of zone {1} on world {2}: {3}", player.Name, zone.Name, player.World.Name, oldBlacklist.JoinToString(pi => pi.Name)); } else { player.Message("Blacklist of zone {0}&S is empty.", zone.ClassyName); } continue; } if (nextToken.StartsWith("+")) { PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, nextToken.Substring(1)); if (info == null) { return; } // prevent players from whitelisting themselves to bypass protection if (!player.Info.Rank.AllowSecurityCircumvention && player.Info == info) { switch (zone.Controller.CheckDetailed(info)) { case SecurityCheckResult.BlackListed: player.Message("You are not allowed to remove yourself from the blacklist of zone {0}", zone.ClassyName); continue; case SecurityCheckResult.RankTooLow: player.Message("You must be {0}+&S to add yourself to the whitelist of zone {1}", zone.Controller.MinRank.ClassyName, zone.ClassyName); continue; } } switch (zone.Controller.Include(info)) { case PermissionOverride.Deny: player.Message("{0}&S is no longer excluded from zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; case PermissionOverride.None: player.Message("{0}&S is now included in zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; case PermissionOverride.Allow: player.Message("{0}&S is already included in zone {1}", info.ClassyName, zone.ClassyName); break; } } else if (nextToken.StartsWith("-")) { PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, nextToken.Substring(1)); if (info == null) { return; } switch (zone.Controller.Exclude(info)) { case PermissionOverride.Deny: player.Message("{0}&S is already excluded from zone {1}", info.ClassyName, zone.ClassyName); break; case PermissionOverride.None: player.Message("{0}&S is now excluded from zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; case PermissionOverride.Allow: player.Message("{0}&S is no longer included in zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; } } else { Rank minRank = RankManager.FindRank(nextToken); if (minRank != null) { // prevent players from lowering rank so bypass protection if (!player.Info.Rank.AllowSecurityCircumvention && zone.Controller.MinRank > player.Info.Rank && minRank <= player.Info.Rank) { player.Message("You are not allowed to lower the zone's rank."); continue; } if (zone.Controller.MinRank != minRank) { zone.Controller.MinRank = minRank; player.Message("Permission for zone \"{0}\" changed to {1}+", zone.Name, minRank.ClassyName); changesWereMade = true; } } else { player.MessageNoRank(nextToken); } } if (changesWereMade) { zone.Edit(player.Info); } else { player.Message("No changes were made to the zone."); } } }
static XElement DefineDefaultRanks() { XElement permissions = new XElement("Ranks"); XElement owner = new XElement("Rank"); owner.Add(new XAttribute("id", RankManager.GenerateID())); owner.Add(new XAttribute("name", "owner")); owner.Add(new XAttribute("rank", 100)); owner.Add(new XAttribute("color", "red")); owner.Add(new XAttribute("prefix", "+")); owner.Add(new XAttribute("drawLimit", 0)); owner.Add(new XAttribute("antiGriefBlocks", 0)); owner.Add(new XAttribute("antiGriefSeconds", 0)); owner.Add(new XAttribute("idleKickAfter", 0)); owner.Add(new XAttribute("reserveSlot", true)); owner.Add(new XAttribute("allowSecurityCircumvention", true)); owner.Add(new XElement(Permission.Chat.ToString())); owner.Add(new XElement(Permission.Build.ToString())); owner.Add(new XElement(Permission.Delete.ToString())); owner.Add(new XElement(Permission.UseSpeedHack.ToString())); owner.Add(new XElement(Permission.UseColorCodes.ToString())); owner.Add(new XElement(Permission.PlaceGrass.ToString())); owner.Add(new XElement(Permission.PlaceWater.ToString())); owner.Add(new XElement(Permission.PlaceLava.ToString())); owner.Add(new XElement(Permission.PlaceAdmincrete.ToString())); owner.Add(new XElement(Permission.DeleteAdmincrete.ToString())); owner.Add(new XElement(Permission.Say.ToString())); owner.Add(new XElement(Permission.ReadStaffChat.ToString())); XElement temp = new XElement(Permission.Kick.ToString()); temp.Add(new XAttribute("max", "owner")); owner.Add(temp); temp = new XElement(Permission.Ban.ToString()); temp.Add(new XAttribute("max", "owner")); owner.Add(temp); owner.Add(new XElement(Permission.BanIP.ToString())); owner.Add(new XElement(Permission.BanAll.ToString())); temp = new XElement(Permission.Promote.ToString()); temp.Add(new XAttribute("max", "owner")); owner.Add(temp); temp = new XElement(Permission.Demote.ToString()); temp.Add(new XAttribute("max", "owner")); owner.Add(temp); owner.Add(new XElement(Permission.Hide.ToString())); owner.Add(new XElement(Permission.ViewOthersInfo.ToString())); owner.Add(new XElement(Permission.ViewPlayerIPs.ToString())); owner.Add(new XElement(Permission.EditPlayerDB.ToString())); owner.Add(new XElement(Permission.Teleport.ToString())); owner.Add(new XElement(Permission.Bring.ToString())); owner.Add(new XElement(Permission.BringAll.ToString())); owner.Add(new XElement(Permission.Patrol.ToString())); //owner.Add( new XElement( Permission.Spectate.ToString() ) ); owner.Add(new XElement(Permission.Freeze.ToString())); owner.Add(new XElement(Permission.Mute.ToString())); owner.Add(new XElement(Permission.SetSpawn.ToString())); owner.Add(new XElement(Permission.Lock.ToString())); owner.Add(new XElement(Permission.ManageZones.ToString())); owner.Add(new XElement(Permission.ManageWorlds.ToString())); owner.Add(new XElement(Permission.Import.ToString())); owner.Add(new XElement(Permission.Draw.ToString())); owner.Add(new XElement(Permission.CopyAndPaste.ToString())); owner.Add(new XElement(Permission.ReloadConfig.ToString())); owner.Add(new XElement(Permission.ShutdownServer.ToString())); permissions.Add(owner); try { RankManager.AddRank(new Rank(owner)); } catch (RankDefinitionException ex) { Logger.Log(ex.Message, LogType.Error); } XElement op = new XElement("Rank"); op.Add(new XAttribute("id", RankManager.GenerateID())); op.Add(new XAttribute("name", "op")); op.Add(new XAttribute("rank", 80)); op.Add(new XAttribute("color", "aqua")); op.Add(new XAttribute("prefix", "-")); op.Add(new XAttribute("drawLimit", 0)); op.Add(new XAttribute("antiGriefBlocks", 0)); op.Add(new XAttribute("antiGriefSeconds", 0)); op.Add(new XAttribute("idleKickAfter", 0)); op.Add(new XElement(Permission.Chat.ToString())); op.Add(new XElement(Permission.Build.ToString())); op.Add(new XElement(Permission.Delete.ToString())); op.Add(new XElement(Permission.UseSpeedHack.ToString())); op.Add(new XElement(Permission.UseColorCodes.ToString())); op.Add(new XElement(Permission.PlaceGrass.ToString())); op.Add(new XElement(Permission.PlaceWater.ToString())); op.Add(new XElement(Permission.PlaceLava.ToString())); op.Add(new XElement(Permission.PlaceAdmincrete.ToString())); op.Add(new XElement(Permission.DeleteAdmincrete.ToString())); op.Add(new XElement(Permission.Say.ToString())); op.Add(new XElement(Permission.ReadStaffChat.ToString())); temp = new XElement(Permission.Kick.ToString()); temp.Add(new XAttribute("max", "op")); op.Add(temp); temp = new XElement(Permission.Ban.ToString()); temp.Add(new XAttribute("max", "regular")); op.Add(temp); op.Add(new XElement(Permission.BanIP.ToString())); temp = new XElement(Permission.Promote.ToString()); temp.Add(new XAttribute("max", "regular")); op.Add(temp); temp = new XElement(Permission.Demote.ToString()); temp.Add(new XAttribute("max", "regular")); op.Add(temp); op.Add(new XElement(Permission.Hide.ToString())); op.Add(new XElement(Permission.ViewOthersInfo.ToString())); op.Add(new XElement(Permission.ViewPlayerIPs.ToString())); op.Add(new XElement(Permission.Teleport.ToString())); op.Add(new XElement(Permission.Bring.ToString())); op.Add(new XElement(Permission.Patrol.ToString())); //op.Add( new XElement( Permission.Spectate.ToString() ) ); op.Add(new XElement(Permission.Freeze.ToString())); op.Add(new XElement(Permission.Mute.ToString())); op.Add(new XElement(Permission.SetSpawn.ToString())); op.Add(new XElement(Permission.ManageZones.ToString())); op.Add(new XElement(Permission.Lock.ToString())); op.Add(new XElement(Permission.Draw.ToString())); op.Add(new XElement(Permission.CopyAndPaste.ToString())); permissions.Add(op); try { RankManager.AddRank(new Rank(op)); } catch (RankDefinitionException ex) { Logger.Log(ex.Message, LogType.Error); } XElement regular = new XElement("Rank"); regular.Add(new XAttribute("id", RankManager.GenerateID())); regular.Add(new XAttribute("name", "regular")); regular.Add(new XAttribute("rank", 30)); regular.Add(new XAttribute("color", "white")); regular.Add(new XAttribute("prefix", "")); regular.Add(new XAttribute("drawLimit", 4096)); regular.Add(new XAttribute("antiGriefBlocks", 47)); regular.Add(new XAttribute("antiGriefSeconds", 6)); regular.Add(new XAttribute("idleKickAfter", 20)); regular.Add(new XElement(Permission.Chat.ToString())); regular.Add(new XElement(Permission.Build.ToString())); regular.Add(new XElement(Permission.Delete.ToString())); regular.Add(new XElement(Permission.UseSpeedHack.ToString())); regular.Add(new XElement(Permission.PlaceGrass.ToString())); regular.Add(new XElement(Permission.PlaceWater.ToString())); regular.Add(new XElement(Permission.PlaceLava.ToString())); regular.Add(new XElement(Permission.PlaceAdmincrete.ToString())); regular.Add(new XElement(Permission.DeleteAdmincrete.ToString())); temp = new XElement(Permission.Kick.ToString()); temp.Add(new XAttribute("max", "regular")); regular.Add(temp); regular.Add(new XElement(Permission.ViewOthersInfo.ToString())); regular.Add(new XElement(Permission.Teleport.ToString())); regular.Add(new XElement(Permission.Draw.ToString())); permissions.Add(regular); try { RankManager.AddRank(new Rank(regular)); } catch (RankDefinitionException ex) { Logger.Log(ex.Message, LogType.Error); } XElement guest = new XElement("Rank"); guest.Add(new XAttribute("id", RankManager.GenerateID())); guest.Add(new XAttribute("name", "guest")); guest.Add(new XAttribute("rank", 0)); guest.Add(new XAttribute("color", "silver")); guest.Add(new XAttribute("prefix", "")); guest.Add(new XAttribute("drawLimit", 512)); guest.Add(new XAttribute("antiGriefBlocks", 37)); guest.Add(new XAttribute("antiGriefSeconds", 5)); guest.Add(new XAttribute("idleKickAfter", 20)); guest.Add(new XElement(Permission.Chat.ToString())); guest.Add(new XElement(Permission.Build.ToString())); guest.Add(new XElement(Permission.Delete.ToString())); guest.Add(new XElement(Permission.UseSpeedHack.ToString())); permissions.Add(guest); try { RankManager.AddRank(new Rank(guest)); } catch (RankDefinitionException ex) { Logger.Log(ex.Message, LogType.Error); } return(permissions); }
internal static void ZoneAdd(Player player, Command cmd) { string zoneName = cmd.Next(); if (zoneName == null) { cdZoneAdd.PrintUsage(player); return; } Zone zone = new Zone(); if (zoneName.StartsWith("+")) { PlayerInfo info; if (!PlayerDB.FindPlayerInfo(zoneName.Substring(1), out info)) { player.Message("More than one player found matching \"{0}\"", zoneName.Substring(1)); return; } if (info == null) { player.NoPlayerMessage(zoneName.Substring(1)); return; } zone.Name = info.Name; zone.Controller.MinRank = info.Rank.NextRankUp ?? info.Rank; zone.Controller.Include(info); player.Message("Zone: Creating a {0}+&S zone for player {1}&S. Place a block or type /mark to use your location.", zone.Controller.MinRank.GetClassyName(), info.GetClassyName()); player.SetCallback(2, ZoneAddCallback, zone, cdZoneAdd.Permissions); } else { if (!World.IsValidName(zoneName)) { player.Message("\"{0}\" is not a valid zone name", zoneName); return; } if (player.World.Map.FindZone(zoneName) != null) { player.Message("A zone with this name already exists. Use &H/zedit&S to edit."); return; } zone.Name = zoneName; string rankName = cmd.Next(); if (rankName == null) { player.Message("No rank was specified. See &H/help zone"); return; } Rank minRank = RankManager.ParseRank(rankName); if (minRank != null) { string name; while ((name = cmd.Next()) != null) { if (name.Length == 0) { continue; } PlayerInfo info; if (!PlayerDB.FindPlayerInfo(name.Substring(1), out info)) { player.Message("More than one player found matching \"{0}\"", name.Substring(1)); return; } if (info == null) { player.NoPlayerMessage(name.Substring(1)); return; } if (name.StartsWith("+")) { zone.Controller.Include(info); } else if (name.StartsWith("-")) { zone.Controller.Exclude(info); } } zone.Controller.MinRank = minRank; player.SetCallback(2, ZoneAddCallback, zone, cdZoneAdd.Permissions); player.Message("Zone: Place a block or type /mark to use your location."); } else { player.NoRankMessage(rankName); } } }
static void SetInfoHandler(Player player, CommandReader cmd) { string targetName = cmd.Next(); string propertyName = cmd.Next(); string valName = cmd.NextAll(); if (targetName == null || propertyName == null) { CdSetInfo.PrintUsage(player); return; } PlayerInfo info = PlayerDB.FindByPartialNameOrPrintMatches(player, targetName); if (info == null) { return; } switch (propertyName.ToLower()) { case "banreason": if (valName.Length == 0) { valName = null; } if (SetPlayerInfoField(player, "BanReason", info, info.BanReason, valName)) { info.BanReason = valName; } break; case "displayedname": string oldDisplayedName = info.DisplayedName; if (valName.Length == 0) { valName = null; } if (valName == info.DisplayedName) { if (valName == null) { player.Message("SetInfo: DisplayedName for {0} is not set.", info.Name); } else { player.Message("SetInfo: DisplayedName for {0} is already set to \"{1}&S\"", info.Name, valName); } break; } info.DisplayedName = valName; if (oldDisplayedName == null) { player.Message("SetInfo: DisplayedName for {0} set to \"{1}&S\"", info.Name, valName); } else if (valName == null) { player.Message("SetInfo: DisplayedName for {0} was reset (was \"{1}&S\")", info.Name, oldDisplayedName); } else { player.Message("SetInfo: DisplayedName for {0} changed from \"{1}&S\" to \"{2}&S\"", info.Name, oldDisplayedName, valName); } break; case "kickreason": if (valName.Length == 0) { valName = null; } if (SetPlayerInfoField(player, "KickReason", info, info.LastKickReason, valName)) { info.LastKickReason = valName; } break; case "name": if (valName.Equals(info.Name, StringComparison.OrdinalIgnoreCase)) { player.Message("SetInfo: You may change capitalization of player's real name. " + "If you'd like to make other changes to the way player's name is displayed, " + "use &H/SetInfo <Name> DisplayedName <NewName>"); break; } string oldName = info.Name; if (oldName != valName) { info.Name = valName; player.Message("Name capitalization changed from \"{0}\" to \"{1}\"", oldName, valName); } else { player.Message("Name capitalization is already \"{0}\"", oldName); } break; case "previousrank": Rank newPreviousRank; if (valName.Length > 0) { newPreviousRank = RankManager.FindRank(valName); if (newPreviousRank == null) { player.MessageNoRank(valName); break; } } else { newPreviousRank = null; } Rank oldPreviousRank = info.PreviousRank; if (newPreviousRank == oldPreviousRank) { if (newPreviousRank == null) { player.Message("SetInfo: PreviousRank for {0}&S is not set.", info.ClassyName); } else { player.Message("SetInfo: PreviousRank for {0}&S is already set to {1}", info.ClassyName, newPreviousRank.ClassyName); } break; } info.PreviousRank = newPreviousRank; if (oldPreviousRank == null) { player.Message("SetInfo: PreviousRank for {0}&S set to {1}&", info.ClassyName, newPreviousRank.ClassyName); } else if (newPreviousRank == null) { player.Message("SetInfo: PreviousRank for {0}&S was reset (was {1}&S)", info.ClassyName, oldPreviousRank.ClassyName); } else { player.Message("SetInfo: PreviousRank for {0}&S changed from {1}&S to {2}", info.ClassyName, oldPreviousRank.ClassyName, newPreviousRank.ClassyName); } break; case "rankchangetype": RankChangeType oldType = info.RankChangeType; try { info.RankChangeType = (RankChangeType)Enum.Parse(typeof(RankChangeType), valName, true); } catch (ArgumentException) { player.Message("SetInfo: Could not parse RankChangeType. Allowed values: {0}", String.Join(", ", Enum.GetNames(typeof(RankChangeType)))); break; } player.Message("SetInfo: RankChangeType for {0}&S changed from {1} to {2}", info.ClassyName, oldType, info.RankChangeType); break; case "rankreason": if (valName.Length == 0) { valName = null; } if (SetPlayerInfoField(player, "RankReason", info, info.RankChangeReason, valName)) { info.RankChangeReason = valName; } break; case "timeskicked": int oldTimesKicked = info.TimesKicked; if (ValidateInt(valName, 0, 9999)) { info.TimesKicked = Int32.Parse(valName); player.Message("SetInfo: TimesKicked for {0}&S changed from {1} to {2}", info.ClassyName, oldTimesKicked, info.TimesKicked); } else { player.Message("SetInfo: TimesKicked value out of range (Acceptable value range: 0-9999)"); } break; case "totaltime": TimeSpan newTotalTime; TimeSpan oldTotalTime = info.TotalTime; if (valName.TryParseMiniTimespan(out newTotalTime)) { if (newTotalTime > DateTimeUtil.MaxTimeSpan) { player.MessageMaxTimeSpan(); break; } info.TotalTime = newTotalTime; player.Message("SetInfo: TotalTime for {0}&S changed from {1} ({2}) to {3} ({4})", info.ClassyName, oldTotalTime.ToMiniString(), oldTotalTime.ToCompactString(), info.TotalTime.ToMiniString(), info.TotalTime.ToCompactString()); } else { player.Message("SetInfo: Could not parse value given for TotalTime."); } break; case "unbanreason": if (valName.Length == 0) { valName = null; } if (SetPlayerInfoField(player, "UnbanReason", info, info.UnbanReason, valName)) { info.UnbanReason = valName; } break; default: player.Message("Only the following properties are editable: " + "TimesKicked, PreviousRank, TotalTime, RankChangeType, " + "BanReason, UnbanReason, RankReason, KickReason, DisplayedName"); return; } }
/// <summary> Resets the list of ranks to defaults (guest/regular/op/owner). /// Warning: This method is not thread-safe. </summary> public static void ResetRanks() { RankManager.Reset(); DefineDefaultRanks(); RankManager.ParsePermissionLimits(); }
internal static void RealmBuild(Player player, Command cmd, string worldName, string name, string NameIfRankIsName) { // Print information about the current realm if (worldName == null) { if (player.World == null) { player.Message("When calling /wbuild from console, you must specify a realm name."); } else { player.Message(player.World.BuildSecurity.GetDescription(player.World, "realm", "modified")); } return; } // Find a realm by name World realm = WorldManager.FindWorldOrPrintMatches(player, worldName); if (realm == null) { return; } if (name == null) { player.Message(realm.BuildSecurity.GetDescription(realm, "realm", "modified")); return; } bool changesWereMade = false; do { if (name.Length < 2) { continue; } // Whitelisting individuals if (name.StartsWith("+")) { PlayerInfo info; if (!PlayerDB.FindPlayerInfo(name.Substring(1), out info)) { player.Message("More than one player found matching \"{0}\"", name.Substring(1)); continue; } else if (info == null) { player.MessageNoPlayer(name.Substring(1)); continue; } if (realm.BuildSecurity.CheckDetailed(info) == SecurityCheckResult.Allowed) { player.Message("{0}&S is already allowed to build in {1}&S (by rank)", info.ClassyName, realm.ClassyName); continue; } Player target = info.PlayerObject; if (target == player) { target = null; // to avoid duplicate messages } switch (realm.BuildSecurity.Include(info)) { case PermissionOverride.Deny: if (realm.BuildSecurity.Check(info)) { player.Message("{0}&S is no longer barred from building in {1}", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("You can now build in realm {0}&S (removed from blacklist by {1}&S).", realm.ClassyName, player.ClassyName); } } else { player.Message("{0}&S was removed from the build blacklist of {1}&S. " + "Player is still NOT allowed to build (by rank).", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("You were removed from the build blacklist of realm {0}&S by {1}&S. " + "You are still NOT allowed to build (by rank).", player.ClassyName, realm.ClassyName); } } Logger.Log(LogType.UserActivity, "{0} removed {1} from the build blacklist of {2}", player.Name, info.Name, realm.Name); changesWereMade = true; break; case PermissionOverride.None: player.Message("{0}&S is now allowed to build in {1}", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("You can now build in realm {0}&S (whitelisted by {1}&S).", realm.ClassyName, player.ClassyName); } Logger.Log(LogType.UserActivity, "{0} added {1} to the build whitelist on realm {2}", player.Name, info.Name, realm.Name); break; case PermissionOverride.Allow: player.Message("{0}&S is already on the build whitelist of {1}", info.ClassyName, realm.ClassyName); break; } // Blacklisting individuals } else if (name.StartsWith("-")) { PlayerInfo info; if (!PlayerDB.FindPlayerInfo(name.Substring(1), out info)) { player.Message("More than one player found matching \"{0}\"", name.Substring(1)); continue; } else if (info == null) { player.MessageNoPlayer(name.Substring(1)); continue; } if (realm.BuildSecurity.CheckDetailed(info) == SecurityCheckResult.RankTooHigh || realm.BuildSecurity.CheckDetailed(info) == SecurityCheckResult.RankTooLow) { player.Message("{0}&S is already barred from building in {1}&S (by rank)", info.ClassyName, realm.ClassyName); continue; } Player target = info.PlayerObject; if (target == player) { target = null; // to avoid duplicate messages } switch (realm.BuildSecurity.Exclude(info)) { case PermissionOverride.Deny: player.Message("{0}&S is already on build blacklist of {1}", info.ClassyName, realm.ClassyName); break; case PermissionOverride.None: player.Message("{0}&S is now barred from building in {1}", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("&WYou were barred by {0}&W from building in realm {1}", player.ClassyName, realm.ClassyName); } Logger.Log(LogType.UserActivity, "{0} added {1} to the build blacklist on realm {2}", player.Name, info.Name, realm.Name); changesWereMade = true; break; case PermissionOverride.Allow: if (realm.BuildSecurity.Check(info)) { player.Message("{0}&S is no longer on the build whitelist of {1}&S. " + "Player is still allowed to build (by rank).", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("You were removed from the build whitelist of realm {0}&S by {1}&S. " + "You are still allowed to build (by rank).", player.ClassyName, realm.ClassyName); } } else { player.Message("{0}&S is no longer allowed to build in {1}", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("&WYou can no longer build in realm {0}&W (removed from whitelist by {1}&W).", realm.ClassyName, player.ClassyName); } } Logger.Log(LogType.UserActivity, "{0} removed {1} from the build whitelist on realm {2}", player.Name, info.Name, realm.Name); changesWereMade = true; break; } // Setting minimum rank } else { Rank rank = RankManager.FindRank(name); if (rank == null) { player.MessageNoRank(name); } else if (!player.Info.Rank.AllowSecurityCircumvention && realm.BuildSecurity.MinRank > rank && realm.BuildSecurity.MinRank > player.Info.Rank) { player.Message("&WYou must be ranked {0}&W+ to lower build restrictions for realm {1}", realm.BuildSecurity.MinRank.ClassyName, realm.ClassyName); } else { // list players who are redundantly blacklisted var exceptionList = realm.BuildSecurity.ExceptionList; PlayerInfo[] noLongerExcluded = exceptionList.Excluded.Where(excludedPlayer => excludedPlayer.Rank < rank).ToArray(); if (noLongerExcluded.Length > 0) { player.Message("Following players no longer need to be blacklisted on realm {0}&S: {1}", realm.ClassyName, noLongerExcluded.JoinToClassyString()); } // list players who are redundantly whitelisted PlayerInfo[] noLongerIncluded = exceptionList.Included.Where(includedPlayer => includedPlayer.Rank >= rank).ToArray(); if (noLongerIncluded.Length > 0) { player.Message("Following players no longer need to be whitelisted on realm {0}&S: {1}", realm.ClassyName, noLongerIncluded.JoinToClassyString()); } // apply changes realm.BuildSecurity.MinRank = rank; changesWereMade = true; if (realm.BuildSecurity.MinRank == RankManager.LowestRank) { Server.Message("{0}&S allowed anyone to build on realm {1}", player.ClassyName, realm.ClassyName); } else { Server.Message("{0}&S allowed only {1}+&S to build in realm {2}", player.ClassyName, realm.BuildSecurity.MinRank.ClassyName, realm.ClassyName); } Logger.Log(LogType.UserActivity, "{0} set build rank for realm {1} to {2}+", player.Name, realm.Name, realm.BuildSecurity.MinRank.Name); } } } while ((name = cmd.Next()) != null); if (changesWereMade) { WorldManager.SaveWorldList(); } }
public static void RealmLoad(Player player, Command cmd, string fileName, string worldName, string buildRankName, string accessRankName) { if (worldName == null && player.World == null) { player.Message("When using /realm from console, you must specify the realm name."); return; } if (fileName == null) { // No params given at all return; } string fullFileName = WorldManager.FindMapFile(player, fileName); if (fullFileName == null) { return; } // Loading map into current realm if (worldName == null) { if (!cmd.IsConfirmed) { player.Confirm(cmd, "About to replace THIS REALM with \"{0}\".", fileName); return; } Map map; try { map = MapUtility.Load(fullFileName); } catch (Exception ex) { player.MessageNow("Could not load specified file: {0}: {1}", ex.GetType().Name, ex.Message); return; } World realm = player.World; // Loading to current realm realm.MapChangedBy = player.Name; realm.ChangeMap(map); realm.Players.Message(player, "{0}&S loaded a new map for this realm.", player.ClassyName); player.MessageNow("New map loaded for the realm {0}", realm.ClassyName); Logger.Log(LogType.UserActivity, "{0} loaded new map for realm \"{1}\" from {2}", player.Name, realm.Name, fileName); realm.IsHidden = false; realm.IsRealm = true; WorldManager.SaveWorldList(); } else { // Loading to some other (or new) realm if (!World.IsValidName(worldName)) { player.MessageInvalidWorldName(worldName); return; } Rank buildRank = RankManager.DefaultBuildRank; Rank accessRank = null; if (buildRankName != null) { buildRank = RankManager.FindRank(buildRankName); if (buildRank == null) { player.MessageNoRank(buildRankName); return; } if (accessRankName != null) { accessRank = RankManager.FindRank(accessRankName); if (accessRank == null) { player.MessageNoRank(accessRankName); return; } } } // Retype realm name, if needed if (worldName == "-") { if (player.LastUsedWorldName != null) { worldName = player.LastUsedWorldName; } else { player.Message("Cannot repeat realm name: you haven't used any names yet."); return; } } lock (WorldManager.SyncRoot) { World realm = WorldManager.FindWorldExact(worldName); if (realm != null) { player.LastUsedWorldName = realm.Name; // Replacing existing realm's map if (!cmd.IsConfirmed) { player.Confirm(cmd, "About to replace realm map for {0}&S with \"{1}\".", realm.ClassyName, fileName); return; } Map map; try { map = MapUtility.Load(fullFileName); realm.IsHidden = false; realm.IsRealm = true; WorldManager.SaveWorldList(); } catch (Exception ex) { player.MessageNow("Could not load specified file: {0}: {1}", ex.GetType().Name, ex.Message); return; } try { realm.MapChangedBy = player.Name; realm.ChangeMap(map); realm.IsHidden = false; realm.IsRealm = true; WorldManager.SaveWorldList(); } catch (WorldOpException ex) { Logger.Log(LogType.Error, "Could not complete RealmLoad operation: {0}", ex.Message); player.Message("&WRealmLoad: {0}", ex.Message); return; } realm.Players.Message(player, "{0}&S loaded a new map for the realm {1}", player.ClassyName, realm.ClassyName); player.MessageNow("New map for the realm {0}&S has been loaded.", realm.ClassyName); Logger.Log(LogType.UserActivity, "{0} loaded new map for realm \"{1}\" from {2}", player.Name, realm.Name, fullFileName); } else { // Adding a new realm string targetFullFileName = Path.Combine(Paths.MapPath, worldName + ".fcm"); if (!cmd.IsConfirmed && File.Exists(targetFullFileName) && // target file already exists !Paths.Compare(targetFullFileName, fullFileName)) { // and is different from sourceFile player.Confirm(cmd, "A map named \"{0}\" already exists, and will be overwritten with \"{1}\".", Path.GetFileName(targetFullFileName), Path.GetFileName(fullFileName)); return; } Map map; try { map = MapUtility.Load(fullFileName); //realm.IsHidden = false; //realm.IsRealm = true; //WorldManager.SaveWorldList(); } catch (Exception ex) { player.MessageNow("Could not load \"{0}\": {1}: {2}", fileName, ex.GetType().Name, ex.Message); return; } World newWorld; try { newWorld = WorldManager.AddWorld(player, worldName, map, false); } catch (WorldOpException ex) { player.Message("RealmLoad: {0}", ex.Message); return; } player.LastUsedWorldName = worldName; newWorld.BuildSecurity.MinRank = buildRank; if (accessRank == null) { newWorld.AccessSecurity.ResetMinRank(); } else { newWorld.AccessSecurity.MinRank = accessRank; } newWorld.BlockDB.AutoToggleIfNeeded(); if (BlockDB.IsEnabledGlobally && newWorld.BlockDB.IsEnabled) { player.Message("BlockDB is now auto-enabled on realm {0}", newWorld.ClassyName); } newWorld.LoadedBy = player.Name; newWorld.LoadedOn = DateTime.UtcNow; Server.Message("{0}&S created a new realm named {1}", player.ClassyName, newWorld.ClassyName); Logger.Log(LogType.UserActivity, "{0} created a new realm named \"{1}\" (loaded from \"{2}\")", player.Name, worldName, fileName); newWorld.IsHidden = false; newWorld.IsRealm = true; WorldManager.SaveWorldList(); player.MessageNow("Access permission is {0}+&S, and build permission is {1}+", newWorld.AccessSecurity.MinRank.ClassyName, newWorld.BuildSecurity.MinRank.ClassyName); } } } Server.RequestGC(); }
static void Load(bool reloading, bool loadRankList) { JsonObject root; bool fromFile; // load file if (File.Exists(Paths.ConfigFileName)) { try { string raw = File.ReadAllText(Paths.ConfigFileName); root = new JsonObject(raw); fromFile = true; } catch (SerializationException ex) { string errorMsg = "Config.Load: Config file is not properly formatted: " + ex.Message; throw new MisconfigurationException(errorMsg, ex); } } else { Logger.Log(LogType.Warning, "Config.Load: Config file not found; using defaults."); root = new JsonObject(); fromFile = false; } // detect version number int version; if (root.TryGetInt("ConfigVersion", out version)) { if (version < LowestSupportedVersion) { Logger.Log(LogType.Warning, "Config.Load: Your config file is too old to be loaded properly. " + "Some settings will be lost or replaced with defaults. " + "Please run ConfigGUI/ConfigCLI to make sure that everything is in order."); } else if (version != CurrentVersion) { Logger.Log(LogType.Warning, "Config.Load: Your config.xml was made for a different version of fCraft. " + "Some obsolete settings might be ignored, and some recently-added settings will be set to defaults. " + "It is recommended that you run ConfigGUI/ConfigCLI to make sure that everything is in order."); } } else if (fromFile) { Logger.Log(LogType.Warning, "Config.Load: Version number missing from config file. It might be corrupted. " + "Please run ConfigGUI/ConfigCLI to make sure that everything is in order."); } // read rank definitions if (loadRankList) { RankManager.Reset(); // TODO: LoadRankList( config, fromFile ); } // load log options ResetLogOptions(); if (root.HasArray("ConsoleOptions")) { ReadLogOptions(root, "ConsoleOptions", Logger.ConsoleOptions); } else if (fromFile) { Logger.Log(LogType.Warning, "Config.Load: Using default console options."); } if (root.HasArray("LogFileOptions")) { ReadLogOptions(root, "LogFileOptions", Logger.LogFileOptions); } else if (fromFile) { Logger.Log(LogType.Warning, "Config.Load: Using default log file options."); } // load normal config keys JsonObject settings; if (root.TryGetObject("Settings", out settings)) { foreach (var kvp in settings) { ReadSetting(kvp.Key, kvp.Value); } } // apply rank-related settings if (!reloading) { RankManager.DefaultRank = Rank.Parse(ConfigKey.DefaultRank.GetString()); RankManager.DefaultBuildRank = Rank.Parse(ConfigKey.DefaultBuildRank.GetString()); RankManager.PatrolledRank = Rank.Parse(ConfigKey.PatrolledRank.GetString()); RankManager.BlockDBAutoEnableRank = Rank.Parse(ConfigKey.BlockDBAutoEnableRank.GetString()); } // read PlayerDB settings JsonObject playerDBSettings; if (!reloading && root.TryGetObject("PlayerDB", out playerDBSettings)) { ReadPlayerDBSettings(playerDBSettings); } // key relation validation if (ConfigKey.MaxPlayersPerWorld.GetInt() > ConfigKey.MaxPlayers.GetInt()) { Logger.Log(LogType.Warning, "Value of MaxPlayersPerWorld ({0}) was lowered to match MaxPlayers ({1}).", ConfigKey.MaxPlayersPerWorld.GetInt(), ConfigKey.MaxPlayers.GetInt()); ConfigKey.MaxPlayersPerWorld.TrySetValue(ConfigKey.MaxPlayers.GetInt()); } // raise Config.Reloaded, if applicable if (reloading) { RaiseReloadedEvent(); } }
static void ImportRanks(Player player, CommandReader cmd) { string serverName = cmd.Next(); string fileName = cmd.Next(); string rankName = cmd.Next(); bool silent = (cmd.Next() != null); // Make sure all parameters are specified if (serverName == null || fileName == null || rankName == null) { CdImport.PrintUsage(player); return; } // Check if file exists if (!File.Exists(fileName)) { player.Message("File not found: {0}", fileName); return; } Rank targetRank = RankManager.FindRank(rankName); if (targetRank == null) { player.MessageNoRank(rankName); return; } string[] names; switch (serverName.ToLower()) { case "mcsharp": case "mczall": case "mclawl": try { names = File.ReadAllLines(fileName); } catch (Exception ex) { Logger.Log(LogType.Error, "Could not open \"{0}\" to import ranks: {1}", fileName, ex); return; } break; default: player.Message("fCraft does not support importing from {0}", serverName); return; } if (!cmd.IsConfirmed) { player.Confirm(cmd, "Import {0} player ranks from \"{1}\"?", names.Length, Path.GetFileName(fileName)); return; } string reason = "(Import from " + serverName + ")"; foreach (string name in names) { PlayerInfo info = PlayerDB.FindExact(name) ?? PlayerDB.AddUnrecognizedPlayer(name, RankChangeType.Promoted); try { info.ChangeRank(player, targetRank, reason, !silent, true, false); } catch (PlayerOpException ex) { player.Message(ex.MessageColored); } } PlayerDB.Save(); }
// Parses message incoming from the player public void ParseMessage(string rawMessage, bool fromConsole) { if (rawMessage == null) { throw new ArgumentNullException("rawMessage"); } if (partialMessage != null) { rawMessage = partialMessage + rawMessage; partialMessage = null; } switch (CommandManager.GetMessageType(rawMessage)) { case MessageType.Chat: { if (!Can(Permission.Chat)) { return; } if (Info.IsMuted) { MutedMessage(); return; } if (DetectChatSpam()) { return; } if (World != null && !World.FireSentMessageEvent(this, ref rawMessage) || !Server.FireSentMessageEvent(this, ref rawMessage)) { return; } Info.LinesWritten++; Logger.Log("{0}: {1}", LogType.GlobalChat, Name, rawMessage); // Escaped slash removed AFTER logging, to avoid confusion with real commands if (rawMessage.StartsWith("//")) { rawMessage = rawMessage.Substring(1); } if (rawMessage.EndsWith("//")) { rawMessage = rawMessage.Substring(0, rawMessage.Length - 1); } if (Can(Permission.UseColorCodes) && rawMessage.Contains("%")) { rawMessage = Color.ReplacePercentCodes(rawMessage); } Server.SendToAllExceptIgnored(this, "{0}{1}: {2}", Console, GetClassyName(), Color.White, rawMessage); } break; case MessageType.Command: { if (rawMessage.EndsWith("//")) { rawMessage = rawMessage.Substring(0, rawMessage.Length - 1); } Logger.Log("{0}: {1}", LogType.UserCommand, Name, rawMessage); Command cmd = new Command(rawMessage); LastCommand = cmd; CommandManager.ParseCommand(this, cmd, fromConsole); } break; case MessageType.RepeatCommand: { if (LastCommand == null) { Message("No command to repeat."); } else { LastCommand.Rewind(); Logger.Log("{0}: repeat {1}", LogType.UserCommand, Name, LastCommand.Message); Message("Repeat: {0}", LastCommand.Message); CommandManager.ParseCommand(this, LastCommand, fromConsole); } } break; case MessageType.PrivateChat: { if (!Can(Permission.Chat)) { return; } if (Info.IsMuted) { MutedMessage(); return; } if (DetectChatSpam()) { return; } if (rawMessage.EndsWith("//")) { rawMessage = rawMessage.Substring(0, rawMessage.Length - 1); } string otherPlayerName, messageText; if (rawMessage[1] == ' ') { otherPlayerName = rawMessage.Substring(2, rawMessage.IndexOf(' ', 2) - 2); messageText = rawMessage.Substring(rawMessage.IndexOf(' ', 2) + 1); } else { otherPlayerName = rawMessage.Substring(1, rawMessage.IndexOf(' ') - 1); messageText = rawMessage.Substring(rawMessage.IndexOf(' ') + 1); } if (messageText.Contains("%") && Can(Permission.UseColorCodes)) { messageText = Color.ReplacePercentCodes(messageText); } // first, find ALL players (visible and hidden) Player[] allPlayers = Server.FindPlayers(otherPlayerName); // if there is more than 1 target player, exclude hidden players if (allPlayers.Length > 1) { allPlayers = Server.FindPlayers(this, otherPlayerName); } if (allPlayers.Length == 1) { Player target = allPlayers[0]; if (target.IsIgnoring(Info)) { if (CanSee(target)) { MessageNow("&WCannot PM {0}&W: you are ignored.", target.GetClassyName()); } } else { Logger.Log("{0} to {1}: {2}", LogType.PrivateChat, Name, target.Name, messageText); target.Message("{0}from {1}: {2}", Color.PM, Name, messageText); if (CanSee(target)) { Message("{0}to {1}: {2}", Color.PM, target.Name, messageText); } else { NoPlayerMessage(otherPlayerName); } } } else if (allPlayers.Length == 0) { NoPlayerMessage(otherPlayerName); } else { ManyMatchesMessage("player", allPlayers); } } break; case MessageType.RankChat: { if (!Can(Permission.Chat)) { return; } if (Info.IsMuted) { MutedMessage(); return; } if (DetectChatSpam()) { return; } if (rawMessage.EndsWith("//")) { rawMessage = rawMessage.Substring(0, rawMessage.Length - 1); } string rankName = rawMessage.Substring(2, rawMessage.IndexOf(' ') - 2); Rank rank = RankManager.FindRank(rankName); if (rank != null) { Logger.Log("{0} to rank {1}: {2}", LogType.RankChat, Name, rank.Name, rawMessage); string messageText = rawMessage.Substring(rawMessage.IndexOf(' ') + 1); if (messageText.Contains("%") && Can(Permission.UseColorCodes)) { messageText = Color.ReplacePercentCodes(messageText); } string formattedMessage = String.Format("{0}({1}{2}){3}{4}: {5}", rank.Color, (ConfigKey.RankPrefixesInChat.GetBool() ? rank.Prefix : ""), rank.Name, Color.PM, Name, messageText); Server.SendToRank(this, formattedMessage, rank); if (Info.Rank != rank) { Message(formattedMessage); } } else { Message("No rank found matching \"{0}\"", rankName); } } break; case MessageType.Confirmation: { if (CommandToConfirm != null) { if (DateTime.UtcNow.Subtract(CommandToConfirmDate).TotalSeconds < ConfirmationTimeout) { CommandToConfirm.IsConfirmed = true; CommandManager.ParseCommand(this, CommandToConfirm, fromConsole); CommandToConfirm = null; } else { MessageNow("Confirmation timed out. Enter the command again."); } } else { MessageNow("There is no command to confirm."); } } break; case MessageType.PartialMessage: partialMessage = rawMessage.Substring(0, rawMessage.Length - 1); MessageNow("Partial: &F{0}", partialMessage); break; case MessageType.Invalid: { Message("Unknown command."); } break; } }
public Rank([NotNull] XElement el) : this() { if (el == null) { throw new ArgumentNullException("el"); } // Name XAttribute attr = el.Attribute("name"); if (attr == null) { throw new RankDefinitionException(null, "Rank definition with no name was ignored."); } else if (!IsValidRankName(attr.Value.Trim())) { throw new RankDefinitionException(Name, "Invalid name specified for rank \"{0}\". " + "Rank names can only contain letters, digits, and underscores. " + "Rank definition was ignored.", Name); } else { // duplicate Name check is done in RankManager.AddRank() Name = attr.Value.Trim(); } // ID attr = el.Attribute("id"); if (attr == null) { ID = RankManager.GenerateID(); Logger.Log(LogType.Warning, "Rank({0}): No ID specified; issued a new unique ID: {1}", Name, ID); } else if (!IsValidID(attr.Value.Trim())) { ID = RankManager.GenerateID(); Logger.Log(LogType.Warning, "Rank({0}): Invalid ID specified (must be alphanumeric, and exactly 16 characters long); issued a new unique ID: {1}", Name, ID); } else { ID = attr.Value.Trim(); // duplicate ID check is done in RankManager.AddRank() } FullName = Name + "#" + ID; // Color (optional) if ((attr = el.Attribute("color")) != null) { string color = fCraft.Color.Parse(attr.Value); if (color == null) { Logger.Log(LogType.Warning, "Rank({0}): Could not parse rank color. Assuming default (none).", Name); Color = fCraft.Color.White; } else { Color = color; } } else { Color = fCraft.Color.White; } // Prefix (optional) if ((attr = el.Attribute("prefix")) != null) { if (IsValidPrefix(attr.Value)) { Prefix = attr.Value; } else { Logger.Log(LogType.Warning, "Rank({0}): Invalid prefix format. Expecting 1 character.", Name); } } // AntiGrief block limit (assuming unlimited if not given) int value; XAttribute agBlocks = el.Attribute("antiGriefBlocks"); XAttribute agSeconds = el.Attribute("antiGriefSeconds"); if (agBlocks != null && agSeconds != null) { if (Int32.TryParse(agBlocks.Value, out value)) { if (value >= 0 && value < 1000) { AntiGriefBlocks = value; } else { Logger.Log(LogType.Warning, "Rank({0}): Value for antiGriefBlocks is not within valid range (0-1000). Assuming default ({1}).", Name, AntiGriefBlocks); } } else { Logger.Log(LogType.Warning, "Rank({0}): Could not parse the value for antiGriefBlocks. Assuming default ({1}).", Name, AntiGriefBlocks); } if (Int32.TryParse(agSeconds.Value, out value)) { if (value >= 0 && value < 100) { AntiGriefSeconds = value; } else { Logger.Log(LogType.Warning, "Rank({0}): Value for antiGriefSeconds is not within valid range (0-100). Assuming default ({1}).", Name, AntiGriefSeconds); } } else { Logger.Log(LogType.Warning, "Rank({0}): Could not parse the value for antiGriefSeconds. Assuming default ({1}).", Name, AntiGriefSeconds); } } // Draw command limit, in number-of-blocks (assuming unlimited if not given) if ((attr = el.Attribute("drawLimit")) != null) { if (Int32.TryParse(attr.Value, out value)) { if (value >= 0 && value < 100000000) { DrawLimit = value; } else { Logger.Log(LogType.Warning, "Rank({0}): Value for drawLimit is not within valid range (0-100000000). Assuming default ({1}).", Name, DrawLimit); } } else { Logger.Log(LogType.Warning, "Rank({0}): Could not parse the value for drawLimit. Assuming default ({1}).", Name, DrawLimit); } } // Idle kick timer, in minutes. (assuming 'never' if not given) if ((attr = el.Attribute("idleKickAfter")) != null) { if (!Int32.TryParse(attr.Value, out IdleKickTimer)) { Logger.Log(LogType.Warning, "Rank({0}): Could not parse the value for idleKickAfter. Assuming 0 (never).", Name); IdleKickTimer = 0; } } else { IdleKickTimer = 0; } // Reserved slot. (assuming 'no' if not given) if ((attr = el.Attribute("reserveSlot")) != null) { if (!Boolean.TryParse(attr.Value, out HasReservedSlot)) { Logger.Log(LogType.Warning, "Rank({0}): Could not parse value for reserveSlot. Assuming \"false\".", Name); HasReservedSlot = false; } } else { HasReservedSlot = false; } // Security circumvention. (assuming 'no' if not given) if ((attr = el.Attribute("allowSecurityCircumvention")) != null) { if (!Boolean.TryParse(attr.Value, out AllowSecurityCircumvention)) { Logger.Log(LogType.Warning, "Rank({0}): Could not parse the value for allowSecurityCircumvention. Assuming \"false\".", Name); AllowSecurityCircumvention = false; } } else { AllowSecurityCircumvention = false; } // Copy slots (assuming default 2 if not given) if ((attr = el.Attribute("copySlots")) != null) { if (Int32.TryParse(attr.Value, out value)) { if (value > 0 && value < 256) { CopySlots = value; } else { Logger.Log(LogType.Warning, "Rank({0}): Value for copySlots is not within valid range (1-255). Assuming default ({1}).", Name, CopySlots); } } else { Logger.Log(LogType.Warning, "Rank({0}): Could not parse the value for copySlots. Assuming default ({1}).", Name, CopySlots); } } // Fill limit (assuming default 32 if not given) if ((attr = el.Attribute("fillLimit")) != null) { if (Int32.TryParse(attr.Value, out value)) { if (value < 1) { Logger.Log(LogType.Warning, "Rank({0}): Value for fillLimit may not be negative. Assuming default ({1}).", Name, FillLimit); } else if (value > 2048) { FillLimit = 2048; } else { FillLimit = value; } } else { Logger.Log(LogType.Warning, "Rank({0}): Could not parse the value for fillLimit. Assuming default ({1}).", Name, FillLimit); } } // Permissions for (int i = 0; i < Enum.GetValues(typeof(Permission)).Length; i++) { string permission = ((Permission)i).ToString(); XElement temp; if ((temp = el.Element(permission)) != null) { Permissions[i] = true; if ((attr = temp.Attribute("max")) != null) { permissionLimitStrings[i] = attr.Value; } } } // check consistency of ban permissions if (!Can(Permission.Ban) && (Can(Permission.BanAll) || Can(Permission.BanIP))) { Logger.Log(LogType.Warning, "Rank({0}): Rank is allowed to BanIP and/or BanAll but not allowed to Ban. " + "Assuming that all ban permissions were meant to be off.", Name); Permissions[(int)Permission.BanIP] = false; Permissions[(int)Permission.BanAll] = false; } // check consistency of patrol permissions if (!Can(Permission.Teleport) && Can(Permission.Patrol)) { Logger.Log(LogType.Warning, "Rank({0}): Rank is allowed to Patrol but not allowed to Teleport. " + "Assuming that Patrol permission was meant to be off.", Name); Permissions[(int)Permission.Patrol] = false; } // check consistency of draw permissions if (!Can(Permission.Draw) && Can(Permission.DrawAdvanced)) { Logger.Log(LogType.Warning, "Rank({0}): Rank is allowed to DrawAdvanced but not allowed to Draw. " + "Assuming that DrawAdvanced permission was meant to be off.", Name); Permissions[(int)Permission.DrawAdvanced] = false; } // check consistency of Undo permissions if (!Can(Permission.UndoOthersActions) && Can(Permission.UndoAll)) { Logger.Log(LogType.Warning, "Rank({0}): Rank is allowed to UndoAll but not allowed to UndoOthersActions. " + "Assuming that UndoAll permission was meant to be off.", Name); Permissions[(int)Permission.UndoAll] = false; } }
static void LoadRankList(XElement el, int version, bool fromFile) { if (el == null) { throw new ArgumentNullException("el"); } XElement legacyRankMappingTag = el.Element("LegacyRankMapping"); if (legacyRankMappingTag != null) { foreach (XElement rankPair in legacyRankMappingTag.Elements("LegacyRankPair")) { XAttribute fromRankID = rankPair.Attribute("from"); XAttribute toRankID = rankPair.Attribute("to"); if (fromRankID == null || String.IsNullOrEmpty(fromRankID.Value) || toRankID == null || String.IsNullOrEmpty(toRankID.Value)) { Logger.Log("Config.Load: Could not parse a LegacyRankMapping entry: {0}", LogType.Error, rankPair.ToString()); } else { RankManager.LegacyRankMapping.Add(fromRankID.Value, toRankID.Value); } } } XElement rankList = el.Element("Ranks") ?? el.Element("Classes"); if (rankList != null) { XElement[] rankDefinitionList = rankList.Elements("Rank").ToArray(); if (rankDefinitionList.Length == 0) { rankDefinitionList = rankList.Elements("PlayerClass").ToArray(); // LEGACY } foreach (XElement rankDefinition in rankDefinitionList) { try { RankManager.AddRank(new Rank(rankDefinition)); } catch (RankDefinitionException ex) { Logger.Log(ex.Message, LogType.Error); } } if (RankManager.RanksByName.Count == 0) { Logger.Log("Config.Load: No ranks were defined, or none were defined correctly. Using default ranks (guest, regular, op, and owner).", LogType.Warning); rankList.Remove(); el.Add(DefineDefaultRanks()); } else if (version < ConfigVersion) // start LEGACY code { if (version < 103) // speedhack permission { if (!RankManager.RanksByID.Values.Any(rank => rank.Can(Permission.UseSpeedHack))) { foreach (Rank rank in RankManager.RanksByID.Values) { rank.Permissions[(int)Permission.UseSpeedHack] = true; } Logger.Log("Config.Load: All ranks were granted UseSpeedHack permission (default). " + "Use ConfigTool to update config. If you are editing config.xml manually, " + "set version=\"{0}\" to prevent permissions from resetting in the future.", LogType.Warning, ConfigVersion); } } if (version < 111) { RankManager.SortRanksByLegacyNumericRank(); } } // end LEGACY code } else { if (fromFile) { Logger.Log("Config.Load: using default player ranks.", LogType.Warning); } el.Add(DefineDefaultRanks()); } // parse rank-limit permissions RankManager.ParsePermissionLimits(); }
internal static void RealmAccess(Player player, Command cmd, string worldName, string name) { // Print information about the current realm if (worldName == null) { if (player.World == null) { player.Message("Error."); } else { player.Message(player.World.AccessSecurity.GetDescription(player.World, "realm", "accessed")); } return; } // Find a realm by name World realm = WorldManager.FindWorldOrPrintMatches(player, worldName); if (realm == null) { return; } if (name == null) { player.Message(realm.AccessSecurity.GetDescription(realm, "realm", "accessed")); return; } if (realm == WorldManager.MainWorld) { player.Message("The main realm cannot have access restrictions."); return; } bool changesWereMade = false; do { if (name.Length < 2) { continue; } // Whitelisting individuals if (name.StartsWith("+")) { PlayerInfo info; if (!PlayerDB.FindPlayerInfo(name.Substring(1), out info)) { player.Message("More than one player found matching \"{0}\"", name.Substring(1)); continue; } else if (info == null) { player.MessageNoPlayer(name.Substring(1)); continue; } // prevent players from whitelisting themselves to bypass protection if (realm.AccessSecurity.CheckDetailed(info) == SecurityCheckResult.Allowed) { player.Message("{0}&S is already allowed to access {1}&S (by rank)", info.ClassyName, realm.ClassyName); continue; } Player target = info.PlayerObject; if (target == player) { target = null; // to avoid duplicate messages } switch (realm.AccessSecurity.Include(info)) { case PermissionOverride.Deny: if (realm.AccessSecurity.Check(info)) { player.Message("{0}&S is unbanned from Realm {1}", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("You are now unbanned from Realm {0}&S (removed from blacklist by {1}&S).", realm.ClassyName, player.ClassyName); } } else { player.Message("{0}&S was unbanned from Realm {1}&S. " + "Player is still NOT allowed to join (by rank).", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("You were Unbanned from Realm {0}&S by {1}&S. " + "You are still NOT allowed to join (by rank).", player.ClassyName, realm.ClassyName); } } Logger.Log(LogType.UserActivity, "{0} removed {1} from the access blacklist of {2}", player.Name, info.Name, realm.Name); changesWereMade = true; break; case PermissionOverride.None: player.Message("{0}&S is now allowed to access {1}", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("You can now access realm {0}&S (whitelisted by {1}&S).", realm.ClassyName, player.ClassyName); } Logger.Log(LogType.UserActivity, "{0} added {1} to the access whitelist on realm {2}", player.Name, info.Name, realm.Name); changesWereMade = true; break; case PermissionOverride.Allow: player.Message("{0}&S is already on the access whitelist of {1}", info.ClassyName, realm.ClassyName); break; } // Blacklisting individuals } else if (name.StartsWith("-")) { PlayerInfo info; if (!PlayerDB.FindPlayerInfo(name.Substring(1), out info)) { player.Message("More than one player found matching \"{0}\"", name.Substring(1)); continue; } else if (info == null) { player.MessageNoPlayer(name.Substring(1)); continue; } if (realm.AccessSecurity.CheckDetailed(info) == SecurityCheckResult.RankTooHigh || realm.AccessSecurity.CheckDetailed(info) == SecurityCheckResult.RankTooLow) { player.Message("{0}&S is already barred from accessing {1}&S (by rank)", info.ClassyName, realm.ClassyName); continue; } Player target = info.PlayerObject; if (target == player) { target = null; // to avoid duplicate messages } switch (realm.AccessSecurity.Exclude(info)) { case PermissionOverride.Deny: player.Message("{0}&S is already banned from Realm {1}", info.ClassyName, realm.ClassyName); break; case PermissionOverride.None: player.Message("{0}&S is now banned from accessing {1}", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("&WYou were banned by {0}&W from accessing realm {1}", player.ClassyName, realm.ClassyName); } Logger.Log(LogType.UserActivity, "{0} added {1} to the access blacklist on realm {2}", player.Name, info.Name, realm.Name); changesWereMade = true; break; case PermissionOverride.Allow: if (realm.AccessSecurity.Check(info)) { player.Message("{0}&S is no longer on the access whitelist of {1}&S. " + "Player is still allowed to join (by rank).", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("You were banned from Realm {0}&S by {1}&S. " + "You are still allowed to join (by rank).", player.ClassyName, realm.ClassyName); } } else { player.Message("{0}&S is no longer allowed to access {1}", info.ClassyName, realm.ClassyName); if (target != null) { target.Message("&WYou were banned from Realm {0}&W (Banned by {1}&W).", realm.ClassyName, player.ClassyName); } } Logger.Log(LogType.UserActivity, "{0} removed {1} from the access whitelist on realm {2}", player.Name, info.Name, realm.Name); changesWereMade = true; break; } // Setting minimum rank } else { Rank rank = RankManager.FindRank(name); if (rank == null) { player.MessageNoRank(name); } else { // list players who are redundantly blacklisted var exceptionList = realm.AccessSecurity.ExceptionList; PlayerInfo[] noLongerExcluded = exceptionList.Excluded.Where(excludedPlayer => excludedPlayer.Rank < rank).ToArray(); if (noLongerExcluded.Length > 0) { player.Message("Following players no longer need to be blacklisted to be barred from {0}&S: {1}", realm.ClassyName, noLongerExcluded.JoinToClassyString()); } // list players who are redundantly whitelisted PlayerInfo[] noLongerIncluded = exceptionList.Included.Where(includedPlayer => includedPlayer.Rank >= rank).ToArray(); if (noLongerIncluded.Length > 0) { player.Message("Following players no longer need to be whitelisted to access {0}&S: {1}", realm.ClassyName, noLongerIncluded.JoinToClassyString()); } // apply changes realm.AccessSecurity.MinRank = rank; changesWereMade = true; if (realm.AccessSecurity.MinRank == RankManager.LowestRank) { Server.Message("{0}&S made the realm {1}&S accessible to everyone.", player.ClassyName, realm.ClassyName); } else { Server.Message("{0}&S made the realm {1}&S accessible only by {2}+", player.ClassyName, realm.ClassyName, realm.AccessSecurity.MinRank.ClassyName); } Logger.Log(LogType.UserActivity, "{0} set access rank for realm {1} to {2}+", player.Name, realm.Name, realm.AccessSecurity.MinRank.Name); } } } while ((name = cmd.Next()) != null); if (changesWereMade) { var playersWhoCantStay = realm.Players.Where(p => !p.CanJoin(realm)); foreach (Player p in playersWhoCantStay) { p.Message("&WYou are no longer allowed to join realm {0}", realm.ClassyName); p.JoinWorld(WorldManager.MainWorld, WorldChangeReason.PermissionChanged); } WorldManager.SaveWorldList(); } }
internal static void ApplyConfig() { Logger.SplittingType = (LogSplittingType)Enum.Parse(typeof(LogSplittingType), Settings[ConfigKey.LogMode], true); Logger.MarkLogStart(); Player.RelayAllUpdates = GetBool(ConfigKey.RelayAllBlockUpdates); if (GetBool(ConfigKey.NoPartialPositionUpdates)) { Session.FullPositionUpdateInterval = 0; } else { Session.FullPositionUpdateInterval = Session.FullPositionUpdateIntervalDefault; } // chat colors Color.Sys = Color.Parse(Settings[ConfigKey.SystemMessageColor]); Color.Say = Color.Parse(Settings[ConfigKey.SayColor]); Color.Help = Color.Parse(Settings[ConfigKey.HelpColor]); Color.Announcement = Color.Parse(Settings[ConfigKey.AnnouncementColor]); Color.PM = Color.Parse(Settings[ConfigKey.PrivateMessageColor]); Color.IRC = Color.Parse(Settings[ConfigKey.IRCMessageColor]); Color.Me = Color.Parse(Settings[ConfigKey.MeColor]); Color.Warning = Color.Parse(Settings[ConfigKey.WarningColor]); // default class if (!ConfigKey.DefaultRank.IsBlank()) { if (RankManager.ParseRank(Settings[ConfigKey.DefaultRank]) != null) { RankManager.DefaultRank = RankManager.ParseRank(Settings[ConfigKey.DefaultRank]); } else { RankManager.DefaultRank = RankManager.LowestRank; Logger.Log("Config.ApplyConfig: Could not parse DefaultRank; assuming that the lowest rank ({0}) is the default.", LogType.Warning, RankManager.DefaultRank.Name); } } else { RankManager.DefaultRank = RankManager.LowestRank; } // antispam Player.SpamChatCount = GetInt(ConfigKey.AntispamMessageCount); Player.SpamChatTimer = GetInt(ConfigKey.AntispamInterval); Player.AutoMuteDuration = TimeSpan.FromSeconds(GetInt(ConfigKey.AntispamMuteDuration)); // scheduler settings Server.MaxUploadSpeed = GetInt(ConfigKey.UploadBandwidth); Server.PacketsPerSecond = GetInt(ConfigKey.BlockUpdateThrottling); Server.TicksPerSecond = 1000 / (float)GetInt(ConfigKey.TickInterval); // rank to patrol World.RankToPatrol = RankManager.ParseRank(ConfigKey.PatrolledRank.GetString()); // IRC delay IRC.SendDelay = GetInt(ConfigKey.IRCDelay); BuildingCommands.MaxUndoCount = GetInt(ConfigKey.MaxUndo); if (!Paths.IgnoreMapPathConfigKey && GetString(ConfigKey.MapPath).Length > 0) { if (Paths.TestDirectory("MapPath", GetString(ConfigKey.MapPath), true)) { Paths.MapPath = Path.GetFullPath(GetString(ConfigKey.MapPath)); Logger.Log("Maps are stored at: {0}", LogType.SystemActivity, Paths.MapPath); } } AutoRankManager.CheckAutoRankSetting(); }
static void ZoneEditHandler(Player player, Command cmd) { bool changesWereMade = false; string zoneName = cmd.Next(); if (zoneName == null) { player.Message("No zone name specified. See &H/Help ZEdit"); return; } Zone zone = player.WorldMap.Zones.Find(zoneName); if (zone == null) { player.MessageNoZone(zoneName); return; } string name; while ((name = cmd.Next()) != null) { if (name.StartsWith("+")) { if (name.Length == 1) { CdZoneEdit.PrintUsage(player); break; } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, name.Substring(1)); if (info == null) { return; } // prevent players from whitelisting themselves to bypass protection if (!player.Info.Rank.AllowSecurityCircumvention && player.Info == info) { if (!zone.Controller.Check(info)) { player.Message("You must be {0}+&S to add yourself to this zone's whitelist.", zone.Controller.MinRank.ClassyName); continue; } } switch (zone.Controller.Include(info)) { case PermissionOverride.Deny: player.Message("{0}&S is no longer excluded from zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; case PermissionOverride.None: player.Message("{0}&S is now included in zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; case PermissionOverride.Allow: player.Message("{0}&S is already included in zone {1}", info.ClassyName, zone.ClassyName); break; } } else if (name.StartsWith("-")) { if (name.Length == 1) { CdZoneEdit.PrintUsage(player); break; } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, name.Substring(1)); if (info == null) { return; } switch (zone.Controller.Exclude(info)) { case PermissionOverride.Deny: player.Message("{0}&S is already excluded from zone {1}", info.ClassyName, zone.ClassyName); break; case PermissionOverride.None: player.Message("{0}&S is now excluded from zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; case PermissionOverride.Allow: player.Message("{0}&S is no longer included in zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; } } else { Rank minRank = RankManager.FindRank(name); if (minRank != null) { // prevent players from lowering rank so bypass protection if (!player.Info.Rank.AllowSecurityCircumvention && zone.Controller.MinRank > player.Info.Rank && minRank <= player.Info.Rank) { player.Message("You are not allowed to lower the zone's rank."); continue; } if (zone.Controller.MinRank != minRank) { zone.Controller.MinRank = minRank; player.Message("Permission for zone \"{0}\" changed to {1}+", zone.Name, minRank.ClassyName); changesWereMade = true; } } else { player.MessageNoRank(name); } } if (changesWereMade) { zone.Edit(player.Info); } else { player.Message("No changes were made to the zone."); } } }
static void LoadRankList([NotNull] XContainer el, bool fromFile) { if (el == null) { throw new ArgumentNullException("el"); } XElement legacyRankMappingTag = el.Element("LegacyRankMapping"); if (legacyRankMappingTag != null) { foreach (XElement rankPair in legacyRankMappingTag.Elements("LegacyRankPair")) { XAttribute fromRankID = rankPair.Attribute("from"); XAttribute toRankID = rankPair.Attribute("to"); if (fromRankID == null || String.IsNullOrEmpty(fromRankID.Value) || toRankID == null || String.IsNullOrEmpty(toRankID.Value)) { Logger.Log(LogType.Error, "Config.Load: Could not parse a LegacyRankMapping entry: {0}", rankPair); } else { RankManager.LegacyRankMapping.Add(fromRankID.Value, toRankID.Value); } } } XElement rankList = el.Element("Ranks"); if (rankList != null) { XElement[] rankDefinitionList = rankList.Elements("Rank").ToArray(); foreach (XElement rankDefinition in rankDefinitionList) { try { RankManager.AddRank(new Rank(rankDefinition)); } catch (RankDefinitionException ex) { Logger.Log(LogType.Error, ex.Message); } } if (RankManager.RanksByName.Count == 0) { Logger.Log(LogType.Warning, "Config.Load: No ranks were defined, or none were defined correctly. " + "Using default ranks (guest, builder, op, and owner)."); rankList.Remove(); el.Add(DefineDefaultRanks()); } } else { if (fromFile) { Logger.Log(LogType.Warning, "Config.Load: using default player ranks."); } el.Add(DefineDefaultRanks()); } // parse rank-limit permissions RankManager.ParsePermissionLimits(); }