ParseRank() public static method

Parses serialized rank. Accepts either the "name" or "name#ID" format. Uses legacy rank mapping table for unrecognized ranks. Does not autocomple.
public static ParseRank ( string name ) : Rank
name string Full rank name
return Rank
        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.");
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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();
        }
Example #5
0
        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.");
                }
            }
        }
Example #6
0
        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);
                }
            }
        }
Example #7
0
        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();
        }
Example #8
0
        internal static PlayerInfo LoadOldFormat(string[] fields, bool convertDatesToUtc)
        {
            PlayerInfo info = new PlayerInfo {
                Name = fields[0]
            };

            if (fields[1].Length == 0 || !IPAddress.TryParse(fields[1], out info.LastIP))      // LEGACY
            {
                info.LastIP = IPAddress.None;
            }

            info.Rank = RankManager.ParseRank(fields[2]) ?? RankManager.DefaultRank;
            DateTimeUtil.TryParseLocalDate(fields[3], out info.RankChangeDate);
            info.RankChangedBy = fields[4];
            if (info.RankChangedBy == "-")
            {
                info.RankChangedBy = "";
            }

            info.Banned = (fields[5] == "b");

            // ban information
            if (DateTimeUtil.TryParseLocalDate(fields[6], out info.BanDate))
            {
                info.BannedBy  = fields[7];
                info.BanReason = UnescapeOldFormat(fields[10]);
                if (info.BanReason == "-")
                {
                    info.BanReason = "";
                }
            }

            // unban information
            if (DateTimeUtil.TryParseLocalDate(fields[8], out info.UnbanDate))
            {
                info.UnbannedBy  = fields[9];
                info.UnbanReason = UnescapeOldFormat(fields[11]);
                if (info.UnbanReason == "-")
                {
                    info.UnbanReason = "";
                }
            }

            // failed logins
            if (fields[12].Length > 1)
            {
                DateTimeUtil.TryParseLocalDate(fields[12], out info.LastFailedLoginDate);
            }
            if (fields[13].Length > 1 || !IPAddress.TryParse(fields[13], out info.LastFailedLoginIP))      // LEGACY
            {
                info.LastFailedLoginIP = IPAddress.None;
            }
            if (fields[14].Length > 0)
            {
                info.FailedLoginCount = Int32.Parse(fields[14]);
            }

            // login/logout times
            DateTimeUtil.TryParseLocalDate(fields[15], out info.FirstLoginDate);
            DateTimeUtil.TryParseLocalDate(fields[16], out info.LastLoginDate);
            TimeSpan.TryParse(fields[17], out info.TotalTime);

            // stats
            if (fields[18].Length > 0)
            {
                Int32.TryParse(fields[18], out info.BlocksBuilt);
            }
            if (fields[19].Length > 0)
            {
                Int32.TryParse(fields[19], out info.BlocksDeleted);
            }
            Int32.TryParse(fields[20], out info.TimesVisited);
            if (fields[20].Length > 0)
            {
                Int32.TryParse(fields[21], out info.LinesWritten);
            }
            // fields 22-23 are no longer in use

            if (fields.Length > MinFieldCount)
            {
                if (fields[24].Length > 0)
                {
                    info.PreviousRank = RankManager.ParseRank(fields[24]);
                }
                if (fields[25].Length > 0)
                {
                    info.RankChangeReason = UnescapeOldFormat(fields[25]);
                }
                Int32.TryParse(fields[26], out info.TimesKicked);
                Int32.TryParse(fields[27], out info.TimesKickedOthers);
                Int32.TryParse(fields[28], out info.TimesBannedOthers);
                if (fields.Length > 29)
                {
                    info.ID = Int32.Parse(fields[29]);
                    if (info.ID < 256)
                    {
                        info.ID = PlayerDB.GetNextID();
                    }
                    int rankChangeTypeCode;
                    if (Int32.TryParse(fields[30], out rankChangeTypeCode))
                    {
                        info.RankChangeType = (RankChangeType)rankChangeTypeCode;
                        if (!Enum.IsDefined(typeof(RankChangeType), rankChangeTypeCode))
                        {
                            info.GuessRankChangeType();
                        }
                    }
                    else
                    {
                        info.GuessRankChangeType();
                    }
                    DateTimeUtil.TryParseLocalDate(fields[31], out info.LastKickDate);
                    if (!DateTimeUtil.TryParseLocalDate(fields[32], out info.LastSeen) || info.LastSeen < info.LastLoginDate)
                    {
                        info.LastSeen = info.LastLoginDate;
                    }
                    Int64.TryParse(fields[33], out info.BlocksDrawn);

                    info.LastKickBy     = fields[34];
                    info.LastKickReason = UnescapeOldFormat(fields[35]);
                }
                else
                {
                    info.ID = PlayerDB.GetNextID();
                    info.GuessRankChangeType();
                    info.LastSeen = info.LastLoginDate;
                }

                if (fields.Length > 36)
                {
                    DateTimeUtil.TryParseLocalDate(fields[36], out info.BannedUntil);
                    info.IsFrozen = (fields[37] == "f");
                    info.FrozenBy = UnescapeOldFormat(fields[38]);
                    DateTimeUtil.TryParseLocalDate(fields[39], out info.FrozenOn);
                    DateTimeUtil.TryParseLocalDate(fields[40], out info.MutedUntil);
                    info.MutedBy  = UnescapeOldFormat(fields[41]);
                    info.Password = UnescapeOldFormat(fields[42]);
                    // fields[43] is "online", and is ignored
                }

                if (fields.Length > 44)
                {
                    if (fields[44].Length != 0)
                    {
                        info.BandwidthUseMode = (BandwidthUseMode)Int32.Parse(fields[44]);
                    }
                }
            }

            if (info.LastSeen < info.FirstLoginDate)
            {
                info.LastSeen = info.FirstLoginDate;
            }
            if (info.LastLoginDate < info.FirstLoginDate)
            {
                info.LastLoginDate = info.FirstLoginDate;
            }

            if (convertDatesToUtc)
            {
                if (info.RankChangeDate != DateTime.MinValue)
                {
                    info.RankChangeDate = info.RankChangeDate.ToUniversalTime();
                }
                if (info.BanDate != DateTime.MinValue)
                {
                    info.BanDate = info.BanDate.ToUniversalTime();
                }
                if (info.UnbanDate != DateTime.MinValue)
                {
                    info.UnbanDate = info.UnbanDate.ToUniversalTime();
                }
                if (info.LastFailedLoginDate != DateTime.MinValue)
                {
                    info.LastFailedLoginDate = info.LastFailedLoginDate.ToUniversalTime();
                }
                if (info.FirstLoginDate != DateTime.MinValue)
                {
                    info.FirstLoginDate = info.FirstLoginDate.ToUniversalTime();
                }
                if (info.LastLoginDate != DateTime.MinValue)
                {
                    info.LastLoginDate = info.LastLoginDate.ToUniversalTime();
                }
                if (info.LastKickDate != DateTime.MinValue)
                {
                    info.LastKickDate = info.LastKickDate.ToUniversalTime();
                }
                if (info.LastSeen != DateTime.MinValue)
                {
                    info.LastSeen = info.LastSeen.ToUniversalTime();
                }
                if (info.BannedUntil != DateTime.MinValue)
                {
                    info.BannedUntil = info.BannedUntil.ToUniversalTime();
                }
                if (info.FrozenOn != DateTime.MinValue)
                {
                    info.FrozenOn = info.FrozenOn.ToUniversalTime();
                }
                if (info.MutedUntil != DateTime.MinValue)
                {
                    info.MutedUntil = info.MutedUntil.ToUniversalTime();
                }
            }

            return(info);
        }
Example #9
0
        internal static PlayerInfo Load(string[] fields)
        {
            PlayerInfo info = new PlayerInfo {
                Name = fields[0]
            };

            if (fields[1].Length == 0 || !IPAddress.TryParse(fields[1], out info.LastIP))      // LEGACY
            {
                info.LastIP = IPAddress.None;
            }

            info.Rank = RankManager.ParseRank(fields[2]) ?? RankManager.DefaultRank;
            fields[3].ToDateTime(ref info.RankChangeDate);
            info.RankChangedBy = fields[4];

            info.Banned = (fields[5] == "b");

            // ban information
            if (fields[6].ToDateTime(ref info.BanDate))
            {
                info.BannedBy  = Unescape(fields[7]);
                info.BanReason = Unescape(fields[10]);
            }

            // unban information
            if (fields[8].ToDateTime(ref info.UnbanDate))
            {
                info.UnbannedBy  = Unescape(fields[9]);
                info.UnbanReason = Unescape(fields[11]);
            }

            // failed logins
            fields[12].ToDateTime(ref info.LastFailedLoginDate);

            if (fields[13].Length > 1 || !IPAddress.TryParse(fields[13], out info.LastFailedLoginIP))      // LEGACY
            {
                info.LastFailedLoginIP = IPAddress.None;
            }
            if (fields[14].Length > 0)
            {
                info.FailedLoginCount = Int32.Parse(fields[14]);
            }
            fields[15].ToDateTime(ref info.FirstLoginDate);

            // login/logout times
            fields[16].ToDateTime(ref info.LastLoginDate);
            fields[17].ToTimeSpan(ref info.TotalTime);

            // stats
            if (fields[18].Length > 0)
            {
                Int32.TryParse(fields[18], out info.BlocksBuilt);
            }
            if (fields[19].Length > 0)
            {
                Int32.TryParse(fields[19], out info.BlocksDeleted);
            }
            Int32.TryParse(fields[20], out info.TimesVisited);
            if (fields[20].Length > 0)
            {
                Int32.TryParse(fields[21], out info.LinesWritten);
            }
            // fields 22-23 are no longer in use

            if (fields[24].Length > 0)
            {
                info.PreviousRank = RankManager.ParseRank(fields[24]);
            }
            if (fields[25].Length > 0)
            {
                info.RankChangeReason = Unescape(fields[25]);
            }
            Int32.TryParse(fields[26], out info.TimesKicked);
            Int32.TryParse(fields[27], out info.TimesKickedOthers);
            Int32.TryParse(fields[28], out info.TimesBannedOthers);

            info.ID = Int32.Parse(fields[29]);
            if (info.ID < 256)
            {
                info.ID = PlayerDB.GetNextID();
            }

            int rankChangeTypeCode;

            if (Int32.TryParse(fields[30], out rankChangeTypeCode))
            {
                info.RankChangeType = (RankChangeType)rankChangeTypeCode;
                if (!Enum.IsDefined(typeof(RankChangeType), rankChangeTypeCode))
                {
                    info.GuessRankChangeType();
                }
            }
            else
            {
                info.GuessRankChangeType();
            }

            fields[31].ToDateTime(ref info.LastKickDate);
            if (!fields[32].ToDateTime(ref info.LastSeen) || info.LastSeen < info.LastLoginDate)
            {
                info.LastSeen = info.LastLoginDate;
            }
            Int64.TryParse(fields[33], out info.BlocksDrawn);

            info.LastKickBy     = Unescape(fields[34]);
            info.LastKickReason = Unescape(fields[35]);

            fields[36].ToDateTime(ref info.BannedUntil);
            info.IsFrozen = (fields[37] == "f");
            info.FrozenBy = Unescape(fields[38]);
            fields[39].ToDateTime(ref info.FrozenOn);
            fields[40].ToDateTime(ref info.MutedUntil);
            info.MutedBy  = Unescape(fields[41]);
            info.Password = Unescape(fields[42]);
            // fields[43] is "online", and is ignored

            int bandwidthUseModeCode;

            if (Int32.TryParse(fields[44], out bandwidthUseModeCode))
            {
                info.BandwidthUseMode = (BandwidthUseMode)bandwidthUseModeCode;
                if (!Enum.IsDefined(typeof(BandwidthUseMode), bandwidthUseModeCode))
                {
                    info.BandwidthUseMode = BandwidthUseMode.Default;
                }
            }
            else
            {
                info.BandwidthUseMode = BandwidthUseMode.Default;
            }

            if (info.LastSeen < info.FirstLoginDate)
            {
                info.LastSeen = info.FirstLoginDate;
            }
            if (info.LastLoginDate < info.FirstLoginDate)
            {
                info.LastLoginDate = info.FirstLoginDate;
            }

            return(info);
        }
Example #10
0
        public Zone(string raw, World world)
        {
            string[] parts = raw.Split(',');

            string[] header = parts[0].Split(' ');
            Name   = header[0];
            Bounds = new BoundingBox(Int32.Parse(header[1]), Int32.Parse(header[2]), Int32.Parse(header[3]),
                                     Int32.Parse(header[4]), Int32.Parse(header[5]), Int32.Parse(header[6]));

            Rank buildRank = RankManager.ParseRank(header[7]);

            // if all else fails, fall back to lowest class
            if (buildRank == null)
            {
                if (world != null)
                {
                    Controller.MinRank = world.BuildSecurity.MinRank;
                }
                else
                {
                    Controller.MinRank = null;
                }
                Logger.Log("Zone: Error parsing zone definition: unknown rank \"{0}\". Permission reset to default ({1}).", LogType.Error,
                           header[7], Controller.MinRank.Name);
            }
            else
            {
                Controller.MinRank = buildRank;
            }


            // Part 2:
            foreach (string player in parts[1].Split(' '))
            {
                if (!Player.IsValidName(player))
                {
                    continue;
                }
                PlayerInfo info = PlayerDB.FindPlayerInfoExact(player);
                if (info == null)
                {
                    continue;                // player name not found in the DB (discarded)
                }
                Controller.Include(info);
            }

            // Part 3: excluded list
            foreach (string player in parts[2].Split(' '))
            {
                if (!Player.IsValidName(player))
                {
                    continue;
                }
                PlayerInfo info = PlayerDB.FindPlayerInfoExact(player);
                if (info == null)
                {
                    continue;                // player name not found in the DB (discarded)
                }
                Controller.Exclude(info);
            }

            Controller.UpdatePlayerListCache();

            // Part 4: extended header
            if (parts.Length > 3)
            {
                string[] xheader = parts[3].Split(' ');
                CreatedBy = PlayerDB.FindPlayerInfoExact(xheader[0]);
                if (CreatedBy != null)
                {
                    CreatedDate = DateTime.Parse(xheader[1]);
                }
                EditedBy = PlayerDB.FindPlayerInfoExact(xheader[2]);
                if (EditedBy != null)
                {
                    EditedDate = DateTime.Parse(xheader[3]);
                }
            }
        }