internal static PlayerInfo LoadFormat0(string[] fields, bool convertDatesToUtc) { PlayerInfo info = new PlayerInfo { Name = fields[0] }; if (fields[1].Length == 0 || !IPAddress.TryParse(fields[1], out info.LastIP)) { info.LastIP = IPAddress.None; } info.Rank = Rank.Parse(fields[2]) ?? RankManager.DefaultRank; DateTimeUtil.TryParseLocalDate(fields[3], out info.RankChangeDate); if (fields[4].Length > 0) { info.RankChangedBy = fields[4]; if (info.RankChangedBy == "-") { info.RankChangedBy = null; } } switch (fields[5]) { case "b": info.BanStatus = BanStatus.Banned; break; case "x": info.BanStatus = BanStatus.IPBanExempt; break; default: info.BanStatus = BanStatus.NotBanned; break; } // ban information if (DateTimeUtil.TryParseLocalDate(fields[6], out info.BanDate)) { if (fields[7].Length > 0) { info.BannedBy = fields[7]; } if (fields[10].Length > 0) { info.BanReason = UnescapeOldFormat(fields[10]); if (info.BanReason == "-") { info.BanReason = null; } } } // unban information if (DateTimeUtil.TryParseLocalDate(fields[8], out info.UnbanDate)) { if (fields[9].Length > 0) { info.UnbannedBy = fields[9]; } if (fields[11].Length > 0) { info.UnbanReason = UnescapeOldFormat(fields[11]); if (info.UnbanReason == "-") { info.UnbanReason = null; } } } // 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; } // skip 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.MessagesWritten); } // fields 22-23 are no longer in use if (fields.Length > MinFieldCount) { if (fields[24].Length > 0) { info.PreviousRank = Rank.Parse(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(); } byte rankChangeTypeCode; if (Byte.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); if (fields[34].Length > 0) { info.LastKickBy = UnescapeOldFormat(fields[34]); } if (fields[35].Length > 0) { 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"); if (fields[38].Length > 0) { info.FrozenBy = UnescapeOldFormat(fields[38]); } DateTimeUtil.TryParseLocalDate(fields[39], out info.FrozenOn); DateTimeUtil.TryParseLocalDate(fields[40], out info.MutedUntil); if (fields[41].Length > 0) { 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); }
public static int MassRankChange([NotNull] Player player, [NotNull] Rank from, [NotNull] Rank to, [NotNull] string reason) { if (player == null) { throw new ArgumentNullException("player"); } if (from == null) { throw new ArgumentNullException("from"); } if (to == null) { throw new ArgumentNullException("to"); } if (reason == null) { throw new ArgumentNullException("reason"); } CheckIfLoaded(); int affected = 0; string fullReason = reason + "~MassRank"; lock ( AddLocker ) { for (int i = 0; i < PlayerInfoList.Length; i++) { if (PlayerInfoList[i].Rank == from) { try { list[i].ChangeRank(player, to, fullReason, true, true, false); } catch (PlayerOpException ex) { player.Message(ex.MessageColored); } affected++; } } return(affected); } }
static void ZoneEditHandler(Player player, CommandReader cmd) { World playerWorld = player.World; if (playerWorld == 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, playerWorld.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, playerWorld.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), SearchOptions.IncludeSelf); 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), SearchOptions.IncludeSelf); 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.OnEdited(player.Info.Name); } else { player.Message("No changes were made to the zone."); } } }
private 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 if (name.ToLower().StartsWith("msg=")) { zone.Message = name.Substring(4) + " " + (cmd.NextAll() ?? ""); changesWereMade = true; player.Message("Zedit: Custom denied messaged changed to '" + zone.Message + "'"); 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."); } }
public static IEnumerable <Player> RankedAtLeast(this IEnumerable <Player> source, Rank minRank) { if (source == null) { throw new ArgumentNullException("source"); } if (minRank == null) { throw new ArgumentNullException("minRank"); } foreach (Player player in source) { if (player.Info.Rank >= minRank) { yield return(player); } } }
static void LoadWorldListEntry([NotNull] XElement el) { if (el == null) { throw new ArgumentNullException("el"); } XAttribute tempAttr; if ((tempAttr = el.Attribute("name")) == null) { Logger.Log(LogType.Error, "WorldManager: World tag with no name skipped."); return; } string worldName = tempAttr.Value; bool neverUnload = (el.Attribute("noUnload") != null); World world; try { world = AddWorld(null, worldName, null, neverUnload); } catch (WorldOpException ex) { Logger.Log(LogType.Error, "WorldManager: Error adding world \"{0}\": {1}", worldName, ex.Message); return; } if ((tempAttr = el.Attribute("hidden")) != null) { bool isHidden; if (Boolean.TryParse(tempAttr.Value, out isHidden)) { world.IsHidden = isHidden; } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"hidden\" attribute of world \"{0}\", assuming NOT hidden.", worldName); } } if (firstWorld == null) { firstWorld = world; } XElement tempEl = el.Element("Greeting"); if (tempEl != null && !String.IsNullOrEmpty(tempEl.Value)) { world.Greeting = tempEl.Value; } if ((tempEl = el.Element(AccessSecurityXmlTagName)) != null) { world.AccessSecurity = new SecurityController(tempEl, true); } else if ((tempEl = el.Element("accessSecurity")) != null) { world.AccessSecurity = new SecurityController(tempEl, true); } if ((tempEl = el.Element(BuildSecurityXmlTagName)) != null) { world.BuildSecurity = new SecurityController(tempEl, true); } else if ((tempEl = el.Element("buildSecurity")) != null) { world.BuildSecurity = new SecurityController(tempEl, true); } // load backup settings if ((tempAttr = el.Attribute("backup")) != null) { TimeSpan backupInterval; if (tempAttr.Value.ToTimeSpan(out backupInterval)) { if (backupInterval <= TimeSpan.Zero) { world.BackupEnabledState = YesNoAuto.No; } else { world.BackupInterval = backupInterval; } } else { world.BackupEnabledState = YesNoAuto.Auto; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"backup\" attribute of world \"{0}\", assuming default ({1}).", worldName, world.BackupInterval.ToMiniString()); } } else { world.BackupEnabledState = YesNoAuto.Auto; } // load BlockDB settings XElement blockEl = el.Element(BlockDB.XmlRootName); if (blockEl != null) { world.BlockDB.LoadSettings(blockEl); } // load environment settings XElement envEl = el.Element(EnvironmentXmlTagName); if (envEl != null) { if ((tempAttr = envEl.Attribute("cloud")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.CloudColor)) { world.CloudColor = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"cloud\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("fog")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.FogColor)) { world.FogColor = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"fog\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("sky")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.SkyColor)) { world.SkyColor = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"sky\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("level")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.EdgeLevel)) { world.EdgeLevel = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"level\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("edge")) != null) { Block block; if (Map.GetBlockByName(tempAttr.Value, false, out block)) { if (Map.GetEdgeTexture(block) == null) { world.EdgeBlock = Block.Water; Logger.Log(LogType.Warning, "WorldManager: Unacceptable blocktype given for \"edge\" attribute of Environment settings for world \"{0}\", assuming default (Water).", worldName); } else { world.EdgeBlock = block; } } else { world.EdgeBlock = Block.Water; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"edge\" attribute of Environment settings for world \"{0}\", assuming default (Water).", worldName); } } } // load loaded/map-changed information long timestamp; tempEl = el.Element("LoadedBy"); if (tempEl != null) { world.LoadedBy = tempEl.Value; } tempEl = el.Element("LoadedOn"); if (tempEl != null && Int64.TryParse(tempEl.Value, out timestamp)) { world.LoadedOn = timestamp.ToDateTime(); } tempEl = el.Element("MapChangedBy"); if (tempEl != null) { world.MapChangedBy = tempEl.Value; } tempEl = el.Element("MapChangedOn"); if (tempEl != null && Int64.TryParse(tempEl.Value, out timestamp)) { world.MapChangedOn = timestamp.ToDateTime(); } // load lock information if ((tempAttr = el.Attribute("locked")) != null) { bool isLocked; if (Boolean.TryParse(tempAttr.Value, out isLocked)) { world.IsLocked = isLocked; } tempEl = el.Element("LockedBy"); if (tempEl != null) { world.LockedBy = tempEl.Value; } tempEl = el.Element("LockedOn"); if (tempEl != null && Int64.TryParse(tempEl.Value, out timestamp)) { world.LockedOn = timestamp.ToDateTime(); } } else { tempEl = el.Element("UnlockedBy"); if (tempEl != null) { world.UnlockedBy = tempEl.Value; } tempEl = el.Element("UnlockedOn"); if (tempEl != null && Int64.TryParse(tempEl.Value, out timestamp)) { world.UnlockedOn = timestamp.ToDateTime(); } } foreach (XElement mainedRankEl in el.Elements(RankMainXmlTagName)) { Rank rank = Rank.Parse(mainedRankEl.Value); if (rank != null) { if (rank < world.AccessSecurity.MinRank) { world.AccessSecurity.MinRank = rank; Logger.Log(LogType.Warning, "WorldManager: Lowered access MinRank of world {0} to allow it to be the main world for that rank.", rank.Name); } rank.MainWorld = world; } } CheckMapFile(world); }
static bool RaiseRankChangingEvent([NotNull] PlayerInfo playerInfo, [NotNull] Player rankChanger, [NotNull] Rank newRank, [CanBeNull] string reason, RankChangeType rankChangeType, bool announce) { var h = RankChanging; if (h == null) { return(false); } var e = new PlayerInfoRankChangingEventArgs(playerInfo, rankChanger, newRank, reason, rankChangeType, announce); h(null, e); return(e.Cancel); }
static void LoadWorldListEntry([NotNull] XElement el, FileInfo[] allMapFiles) { if (el == null) { throw new ArgumentNullException("el"); } XAttribute tempAttr; if ((tempAttr = el.Attribute("name")) == null) { Logger.Log(LogType.Error, "WorldManager: World tag with no name skipped."); return; } string worldName = tempAttr.Value; bool neverUnload = (el.Attribute("noUnload") != null); World world; try { world = AddWorld(null, worldName, null, neverUnload); } catch (WorldOpException ex) { Logger.Log(LogType.Error, "WorldManager: Error adding world \"{0}\": {1}", worldName, ex.Message); return; } if ((tempAttr = el.Attribute("worldOnlyChat")) != null) { bool worldOnlyChat; if (Boolean.TryParse(tempAttr.Value, out worldOnlyChat)) { world.WorldOnlyChat = worldOnlyChat; } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"worldOnlyChat\" attribute of world \"{0}\", assuming NO world only chat.", worldName); } } if ((tempAttr = el.Attribute("realm")) != null) { if (tempAttr.Value == "yes") { world.IsRealm = true; } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"realm\" attribute of world \"{0}\", assuming NOT a realm.", worldName); } } if ((tempAttr = el.Attribute("hidden")) != null) { bool isHidden; if (Boolean.TryParse(tempAttr.Value, out isHidden)) { world.IsHidden = isHidden; } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"hidden\" attribute of world \"{0}\", assuming NOT hidden.", worldName); } } if ((tempAttr = el.Attribute("visitCount")) != null) { int vCount; if (Int32.TryParse(tempAttr.Value, out vCount)) { world.VisitCount = vCount; } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"VisitCount\" attribute of world \"{0}\", assuming NO Visits.", worldName); } } if (firstWorld == null) { firstWorld = world; } XElement tempEl; if ((tempEl = el.Element(AccessSecurityXmlTagName)) != null) { world.AccessSecurity = new SecurityController(tempEl, true); } else if ((tempEl = el.Element("accessSecurity")) != null) { world.AccessSecurity = new SecurityController(tempEl, true); } if ((tempEl = el.Element(BuildSecurityXmlTagName)) != null) { world.BuildSecurity = new SecurityController(tempEl, true); } else if ((tempEl = el.Element("buildSecurity")) != null) { world.BuildSecurity = new SecurityController(tempEl, true); } if ((tempAttr = el.Attribute("backup")) != null) { TimeSpan backupInterval; if (tempAttr.Value.ToTimeSpan(out backupInterval)) { world.BackupInterval = backupInterval; } else { world.BackupInterval = World.DefaultBackupInterval; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"backup\" attribute of world \"{0}\", assuming default ({1}).", worldName, world.BackupInterval.ToMiniString()); } } else { world.BackupInterval = World.DefaultBackupInterval; } if ((tempEl = el.Element("Locked")) != null) { bool locked; if (Boolean.TryParse(tempEl.Value, out locked)) { world.IsLocked = locked; } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"Locked\" attribute of world \"{0}\", assuming NOT locked.", worldName); } } if ((tempEl = el.Element("LockedBy")) != null) { world.LockedBy = tempEl.Value; } if ((tempEl = el.Element("LockedOn")) != null) { DateTime lockedOn = DateTime.UtcNow; if (DateTimeUtil.ToDateTime(tempEl.Value, ref lockedOn)) { world.LockedDate = lockedOn; } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"LockedOn\" attribute of world \"{0}\", assuming NO lock time.", worldName); } } if ((tempEl = el.Element("UnlockedBy")) != null) { world.UnlockedBy = tempEl.Value; } if ((tempEl = el.Element("UnlockedOn")) != null) { DateTime unlockedOn = DateTime.UtcNow; if (DateTimeUtil.ToDateTime(tempEl.Value, ref unlockedOn)) { world.UnlockedDate = unlockedOn; } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"UnlockedOn\" attribute of world \"{0}\", assuming NO unlock time.", worldName); } } XElement blockEl = el.Element(BlockDB.XmlRootName); if (blockEl != null) { world.BlockDB.LoadSettings(blockEl); } XElement envEl = el.Element(EnvironmentXmlTagName); if (envEl != null) { if ((tempAttr = envEl.Attribute("cloud")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.CloudColor)) { world.CloudColor = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"cloud\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("terrain")) != null) { world.Terrain = envEl.Attribute("terrain").Value; } if ((tempAttr = envEl.Attribute("fog")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.FogColor)) { world.FogColor = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"fog\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("sky")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.SkyColor)) { world.SkyColor = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"sky\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("level")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.EdgeLevel)) { world.EdgeLevel = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"level\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("edge")) != null) { Block block = Map.GetBlockByName(tempAttr.Value); if (block == Block.Undefined) { world.EdgeBlock = Block.Water; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"edge\" attribute of Environment settings for world \"{0}\", assuming default (Water).", worldName); } else { world.EdgeBlock = block; } } if ((tempAttr = envEl.Attribute("side")) != null) { Block block = Map.GetBlockByName(tempAttr.Value); if (block == Block.Undefined) { world.EdgeBlock = Block.Admincrete; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"side\" attribute of Environment settings for world \"{0}\", assuming default (Admincrete).", worldName); } else { world.SideBlock = block; } } if ((tempAttr = envEl.Attribute("cloudCC")) != null) { world.CloudColor = System.Drawing.ColorTranslator.FromHtml(tempAttr.Value).ToArgb(); } if ((tempAttr = envEl.Attribute("fogCC")) != null) { world.FogColor = System.Drawing.ColorTranslator.FromHtml(tempAttr.Value).ToArgb(); } if ((tempAttr = envEl.Attribute("skyCC")) != null) { world.SkyColor = System.Drawing.ColorTranslator.FromHtml(tempAttr.Value).ToArgb(); } if ((tempAttr = envEl.Attribute("levelCC")) != null) { world.EdgeLevel = Convert.ToInt16(tempAttr.Value); } if ((tempAttr = envEl.Attribute("edgeCC")) != null) { world.EdgeBlock = (Block)Byte.Parse(tempAttr.Value); } if ((tempAttr = envEl.Attribute("sideCC")) != null) { world.SideBlock = (Block)Byte.Parse(tempAttr.Value); } if ((tempAttr = envEl.Attribute("textureCC")) != null) { world.textureURL = tempAttr.Value; } if ((tempAttr = envEl.Attribute("hacks")) != null) { world.Hax = Convert.ToBoolean(tempAttr.Value); } } foreach (XElement mainedRankEl in el.Elements(RankMainXmlTagName)) { Rank rank = Rank.Parse(mainedRankEl.Value); if (rank != null) { if (rank < world.AccessSecurity.MinRank) { world.AccessSecurity.MinRank = rank; Logger.Log(LogType.Warning, "WorldManager: Lowered access MinRank of world {0} to allow it to be the main world for that rank.", rank.Name); } rank.MainWorld = world; } } CheckMapFile(world, allMapFiles); }
public static void RealmLoad(Player player, Command cmd, string fileName, string worldName) { 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; } string buildRankName = cmd.Next(); string accessRankName = cmd.Next(); 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 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(); }
public static int GetIndex(Rank rank) { return(rank == null) ? 0 :(rank.Index + 1); }
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; } }
static void ApplyKeyChange(ConfigKey key) { switch (key) { case ConfigKey.AnnouncementColor: Color.Announcement = Color.Parse(key.GetString()); break; case ConfigKey.AntispamInterval: Player.AntispamInterval = key.GetInt(); break; case ConfigKey.AntispamMessageCount: Player.AntispamMessageCount = key.GetInt(); break; case ConfigKey.DefaultBuildRank: RankManager.DefaultBuildRank = Rank.Parse(key.GetString()); break; case ConfigKey.DefaultRank: RankManager.DefaultRank = Rank.Parse(key.GetString()); break; case ConfigKey.BandwidthUseMode: Player[] playerListCache = Server.Players; if (playerListCache != null) { foreach (Player p in playerListCache) { if (p.BandwidthUseMode == BandwidthUseMode.Default) { // resets the use tweaks p.BandwidthUseMode = BandwidthUseMode.Default; } } } break; case ConfigKey.BlockDBAutoEnableRank: RankManager.BlockDBAutoEnableRank = Rank.Parse(key.GetString()); if (BlockDB.IsEnabledGlobally) { World[] worldListCache = WorldManager.Worlds; foreach (World world in worldListCache) { if (world.BlockDB.AutoToggleIfNeeded()) { if (world.BlockDB.IsEnabled) { Logger.Log(LogType.SystemActivity, "BlockDB is now auto-enabled on world {0}", world.Name); } else { Logger.Log(LogType.SystemActivity, "BlockDB is now auto-disabled on world {0}", world.Name); } } } } break; case ConfigKey.BlockUpdateThrottling: Server.BlockUpdateThrottling = key.GetInt(); break; case ConfigKey.BypassHttpsCertificateValidation: if (key.Enabled()) { ServicePointManager.ServerCertificateValidationCallback = delegate { return(true); }; } else { ServicePointManager.ServerCertificateValidationCallback = null; } break; case ConfigKey.ConsoleName: if (Player.Console != null) { Player.Console.Info.Name = key.GetString(); } break; case ConfigKey.DefaultBackupInterval: World.DefaultBackupInterval = new TimeSpan(TimeSpan.TicksPerMinute * key.GetInt()); break; case ConfigKey.HeartbeatUrl: Heartbeat.MinecraftNetUri = new Uri(key.GetString()); break; case ConfigKey.HelpColor: Color.Help = Color.Parse(key.GetString()); break; case ConfigKey.IRCDelay: IRC.SendDelay = TimeSpan.FromMilliseconds(key.GetInt()); break; case ConfigKey.IRCMessageColor: Color.IRC = Color.Parse(key.GetString()); break; case ConfigKey.LogMode: Logger.SplittingType = key.GetEnum <LogSplittingType>(); break; case ConfigKey.MapPath: if (!Paths.IgnoreMapPathConfigKey && GetString(ConfigKey.MapPath).Length > 0) { if (Paths.TestDirectory("MapPath", GetString(ConfigKey.MapPath), true)) { Paths.MapPath = Path.GetFullPath(GetString(ConfigKey.MapPath)); } } break; case ConfigKey.MaxUndo: BuildingCommands.MaxUndoCount = key.GetInt(); break; case ConfigKey.MeColor: Color.Me = Color.Parse(key.GetString()); break; case ConfigKey.NoPartialPositionUpdates: if (key.Enabled()) { Player.FullPositionUpdateInterval = 0; } else { Player.FullPositionUpdateInterval = Player.FullPositionUpdateIntervalDefault; } break; case ConfigKey.PatrolledRank: RankManager.PatrolledRank = Rank.Parse(key.GetString()); break; case ConfigKey.PrivateMessageColor: Color.PM = Color.Parse(key.GetString()); break; case ConfigKey.RelayAllBlockUpdates: Player.RelayAllUpdates = key.Enabled(); break; case ConfigKey.SayColor: Color.Say = Color.Parse(key.GetString()); break; case ConfigKey.SystemMessageColor: Color.Sys = Color.Parse(key.GetString()); break; case ConfigKey.TickInterval: Server.TicksPerSecond = 1000 / (float)key.GetInt(); break; case ConfigKey.UploadBandwidth: Server.MaxUploadSpeed = key.GetInt(); break; case ConfigKey.WarningColor: Color.Warning = Color.Parse(key.GetString()); break; } }
/// <summary> Loads configuration from file. </summary> /// <param name="skipRankList"> If true, skips over rank definitions. </param> /// <param name="raiseReloadedEvent"> Whether ConfigReloaded event should be raised. </param> public static void Load(bool skipRankList, bool raiseReloadedEvent) { bool fromFile = false; // try to load config file (XML) XDocument file; if (File.Exists(Paths.ConfigFileName)) { file = XDocument.Load(Paths.ConfigFileName); if (file.Root == null || file.Root.Name != ConfigXmlRootName) { Logger.Log(LogType.Warning, "Config.Load: Malformed or incompatible config file {0}. Loading defaults.", Paths.ConfigFileName); file = new XDocument(); file.Add(new XElement(ConfigXmlRootName)); } else { Logger.Log(LogType.Debug, "Config.Load: Config file {0} loaded successfully.", Paths.ConfigFileName); fromFile = true; } } else { // create a new one (with defaults) if no file exists file = new XDocument(); file.Add(new XElement(ConfigXmlRootName)); } XElement config = file.Root; if (config == null) { throw new Exception("Config.xml has no root. Never happens."); } int version = 0; if (fromFile) { XAttribute attr = config.Attribute("version"); if (attr != null && Int32.TryParse(attr.Value, out version)) { if (version < LowestSupportedVersion) { Logger.Log(LogType.Warning, "Config.Load: Your copy of config.xml is too old (v{0}) to be loaded properly. " + "Some settings will be lost or replaced with defaults. " + "Please run ConfigGUI to make sure that everything is in order.", version); } 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 to make sure that everything is in order. (v{0} -> v{1})", version, CurrentVersion); } } else { Logger.Log(LogType.Warning, "Config.Load: Unknown version of config.xml found. It might be corrupted. " + "Please run ConfigGUI to make sure that everything is in order."); } } // read rank definitions if (!skipRankList) { LoadRankList(config, fromFile); } ResetLogOptions(); // read log options for console XElement consoleOptions = config.Element("ConsoleOptions"); if (consoleOptions != null) { LoadLogOptions(consoleOptions, Logger.ConsoleOptions); } else if (fromFile) { Logger.Log(LogType.Warning, "Config.Load: using default console options."); } // read log options for log files XElement logFileOptions = config.Element("LogFileOptions"); if (logFileOptions != null) { LoadLogOptions(logFileOptions, Logger.LogFileOptions); } else if (fromFile) { Logger.Log(LogType.Warning, "Config.Load: using default log file options."); } // read the rest of the keys if (version < FirstVersionWithSectionTags) { foreach (XElement element in config.Elements()) { ParseKeyElementPreSettings(element); } } else if (version < FirstVersionWithSettingsTag) { foreach (XElement section in config.Elements("Section")) { foreach (XElement keyElement in section.Elements()) { ParseKeyElementPreSettings(keyElement); } } } else { XElement settings = config.Element("Settings"); if (settings != null) { foreach (XElement pair in settings.Elements("ConfigKey")) { ParseKeyElement(pair); } } else { Logger.Log(LogType.Warning, "Config.Load: No <Settings> tag present. Using default for everything."); } } if (!skipRankList) { 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()); } // key relation validation if (version < FirstVersionWithMaxPlayersKey) { ConfigKey.MaxPlayersPerWorld.TrySetValue(ConfigKey.MaxPlayers.GetInt()); } 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()); } if (raiseReloadedEvent) { RaiseReloadedEvent(); } }
public static void LoadWorldListEntry([NotNull] XElement el) { if (el == null) { throw new ArgumentNullException("el"); } XAttribute tempAttr; if ((tempAttr = el.Attribute("name")) == null) { Logger.Log(LogType.Error, "WorldManager: World tag with no name skipped."); return; } string worldName = tempAttr.Value; bool neverUnload = (el.Attribute("noUnload") != null); World world; try { world = AddWorld(null, worldName, null, neverUnload); } catch (WorldOpException ex) { Logger.Log(LogType.Error, "WorldManager: Error adding world \"{0}\": {1}", worldName, ex.Message); return; } if ((tempAttr = el.Attribute("hidden")) != null) { bool isHidden; if (Boolean.TryParse(tempAttr.Value, out isHidden)) { world.IsHidden = isHidden; } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"hidden\" attribute of world \"{0}\", assuming NOT hidden.", worldName); } } if ((tempAttr = el.Attribute("prophunt")) != null) { bool isPropHunt; if (Boolean.TryParse(tempAttr.Value, out isPropHunt)) { //PropHunt.PropHuntWorlds.Add(world); world.IsPropHunt = isPropHunt; PropHunt.PropHuntWorlds.Add(world); } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"prophunt\" attribute of world \"{0}\", assuming NOT useable for PropHunt.", worldName); } } if ((tempAttr = el.Attribute("visitCount")) != null) { int vCount; if (Int32.TryParse(tempAttr.Value, out vCount)) { world.VisitCount = vCount; } else { Logger.Log(LogType.Warning, "WorldManager: Could not parse \"VisitCount\" attribute of world \"{0}\", assuming NO Visits.", worldName); } } if (firstWorld == null) { firstWorld = world; } XElement tempEl = el.Element("Greeting"); if (tempEl != null && !String.IsNullOrEmpty(tempEl.Value)) { world.Greeting = tempEl.Value; } if ((tempEl = el.Element(AccessSecurityXmlTagName)) != null) { world.AccessSecurity = new SecurityController(tempEl, true); } else if ((tempEl = el.Element("accessSecurity")) != null) { world.AccessSecurity = new SecurityController(tempEl, true); } if ((tempEl = el.Element(BuildSecurityXmlTagName)) != null) { world.BuildSecurity = new SecurityController(tempEl, true); } else if ((tempEl = el.Element("buildSecurity")) != null) { world.BuildSecurity = new SecurityController(tempEl, true); } if ((tempAttr = el.Attribute("backup")) != null) { TimeSpan backupInterval; if (tempAttr.Value.ToTimeSpan(out backupInterval)) { world.BackupInterval = backupInterval; } else { world.BackupInterval = WorldManager.DefaultBackupInterval; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"backup\" attribute of world \"{0}\", assuming default ({1}).", worldName, world.BackupInterval.ToMiniString()); } } else { world.BackupInterval = WorldManager.DefaultBackupInterval; } XElement blockEl = el.Element(BlockDB.XmlRootName); if (blockEl != null) { world.BlockDB.LoadSettings(blockEl); } XElement PhyEl = el.Element(Physics.XmlRootName); if (PhyEl != null) { Physics.LoadSettings(PhyEl, world); } XElement PhyEl2 = el.Element(Physics.XmlRootName2); if (PhyEl2 != null) { Physics.LoadOtherSettings(PhyEl2, world); } XElement RealmEl = el.Element(world.RealmXMLRootName); if (RealmEl != null) { world.LoadRealmState(RealmEl); } XElement envEl = el.Element(EnvironmentXmlTagName); if (envEl != null) { if ((tempAttr = envEl.Attribute("cloud")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.CloudColor)) { world.CloudColor = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"cloud\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("terrain")) != null) { world.Terrain = envEl.Attribute("terrain").Value; } if ((tempAttr = envEl.Attribute("fog")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.FogColor)) { world.FogColor = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"fog\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("sky")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.SkyColor)) { world.SkyColor = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"sky\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("level")) != null) { if (!Int32.TryParse(tempAttr.Value, out world.EdgeLevel)) { world.EdgeLevel = -1; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"level\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName); } } if ((tempAttr = envEl.Attribute("edge")) != null) { Block block = Map.GetBlockByName(tempAttr.Value); if (block == Block.Undefined) { world.EdgeBlock = Block.Water; Logger.Log(LogType.Warning, "WorldManager: Could not parse \"edge\" attribute of Environment settings for world \"{0}\", assuming default (Water).", worldName); } else { if (Map.GetEdgeTexture(block) == null) { world.EdgeBlock = Block.Water; Logger.Log(LogType.Warning, "WorldManager: Unacceptable blocktype given for \"edge\" attribute of Environment settings for world \"{0}\", assuming default (Water).", worldName); } else { world.EdgeBlock = block; } } } } foreach (XElement mainedRankEl in el.Elements(RankMainXmlTagName)) { Rank rank = Rank.Parse(mainedRankEl.Value); if (rank != null) { if (rank < world.AccessSecurity.MinRank) { world.AccessSecurity.MinRank = rank; Logger.Log(LogType.Warning, "WorldManager: Lowered access MinRank of world {0} to allow it to be the main world for that rank.", rank.Name); } rank.MainWorld = world; } } CheckMapFile(world); }
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 LoadBinary() { lock ( SaveLoadLocker ) { if (File.Exists(Paths.PlayerDBFileName + ".bin")) { Stopwatch sw = Stopwatch.StartNew(); using (FileStream fs = OpenRead(Paths.PlayerDBFileName + ".bin")) { BinaryReader reader = new BinaryReader(fs); int version = reader.ReadInt32(); if (version > FormatVersion) { Logger.Log(LogType.Warning, "PlayerDB.LoadBinary: Attempting to load unsupported PlayerDB format ({0}). Errors may occur.", version); } else if (version < FormatVersion) { Logger.Log(LogType.Warning, "PlayerDB.LoadBinary: Converting PlayerDB to a newer format (version {0} to {1}).", version, FormatVersion); } maxID = reader.ReadInt32(); lock ( AddLocker ) { int rankCount = reader.ReadInt32(); rankMapping = new Dictionary <int, Rank>(rankCount); for (int i = 0; i < rankCount; i++) { byte rankIndex = reader.ReadByte(); string rankName = reader.ReadString(); Rank rank = Rank.Parse(rankName); if (rank == null) { Logger.Log(LogType.Error, "PlayerDB.LoadBinary: Could not parse rank: \"{0}\". Assigning rank {1} instead.", rankName, RankManager.DefaultRank); rank = RankManager.DefaultRank; } rankMapping.Add(rankIndex, rank); } int records = reader.ReadInt32(); int emptyRecords = 0; for (int i = 0; i < records; i++) { #if !DEBUG try { #endif PlayerInfo info; switch (version) { default: // Versions 2-5 differ in semantics only, not in actual serialization format. info = PlayerInfo.LoadBinaryFormat0(reader); break; } if (info.ID > maxID) { maxID = info.ID; Logger.Log(LogType.Warning, "PlayerDB.LoadBinary: Adjusting wrongly saved MaxID ({0} to {1})."); } // A record is considered "empty" if the player has never logged in. // Empty records may be created by /Import, /Ban, and /Rank commands on typos. // Deleting such records should have no negative impact on DB completeness. if ((info.LastIP.Equals(IPAddress.None) || info.LastIP.Equals(IPAddress.Any) || info.TimesVisited == 0) && !info.IsBanned && info.Rank == RankManager.DefaultRank) { Logger.Log(LogType.SystemActivity, "PlayerDB.LoadBinary: Skipping an empty record for player \"{0}\"", info.Name); emptyRecords++; continue; } // Check for duplicates. Unless PlayerDB.txt was altered externally, this does not happen. if (Trie.ContainsKey(info.Name)) { Logger.Log(LogType.Error, "PlayerDB.LoadBinary: Duplicate record for player \"{0}\" skipped.", info.Name); } else { Trie.Add(info.Name, info); list.Add(info); } #if !DEBUG } catch (Exception ex) { Logger.LogAndReportCrash("Error while parsing PlayerInfo record", "fCraft", ex, false); } #endif } if (emptyRecords > 0) { Logger.Log(LogType.Warning, "PlayerDB.LoadBinary: Skipped {0} empty records.", emptyRecords); } RunCompatibilityChecks(version); } } sw.Stop(); Logger.Log(LogType.Debug, "PlayerDB.LoadBinary: Done loading player DB ({0} records) in {1}ms. MaxID={2}", Trie.Count, sw.ElapsedMilliseconds, maxID); } else { Logger.Log(LogType.Warning, "PlayerDB.Load: No player DB file found."); } UpdateCache(); IsLoaded = true; } }
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 Zone([NotNull] string raw, [CanBeNull] World world) : this() { if (raw == null) { throw new ArgumentNullException("raw"); } 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 = Rank.Parse(header[7]); // if all else fails, fall back to lowest class if (buildRank == null) { if (world != null) { Controller.MinRank = world.BuildSecurity.MinRank; } else { Controller.ResetMinRank(); } Logger.Log(LogType.Error, "Zone: Error parsing zone definition: unknown rank \"{0}\". Permission reset to default ({1}).", header[7], Controller.MinRank.Name); } else { Controller.MinRank = buildRank; } if (PlayerDB.IsLoaded) { // Part 2: if (parts[1].Length > 0) { foreach (string playerName in parts[1].Split(' ')) { if (!Player.IsValidName(playerName)) { Logger.Log(LogType.Warning, "Invalid entry in zone \"{0}\" whitelist: {1}", Name, playerName); continue; } PlayerInfo info = PlayerDB.FindPlayerInfoExact(playerName); if (info == null) { Logger.Log(LogType.Warning, "Unrecognized player in zone \"{0}\" whitelist: {1}", Name, playerName); continue; // player name not found in the DB (discarded) } Controller.Include(info); } } // Part 3: excluded list if (parts[2].Length > 0) { foreach (string playerName in parts[2].Split(' ')) { if (!Player.IsValidName(playerName)) { Logger.Log(LogType.Warning, "Invalid entry in zone \"{0}\" blacklist: {1}", Name, playerName); continue; } PlayerInfo info = PlayerDB.FindPlayerInfoExact(playerName); if (info == null) { Logger.Log(LogType.Warning, "Unrecognized player in zone \"{0}\" whitelist: {1}", Name, playerName); continue; // player name not found in the DB (discarded) } Controller.Exclude(info); } } } else { rawWhitelist = parts[1]; rawBlacklist = parts[2]; } // Part 4: extended header if (parts.Length > 3) { string[] xheader = parts[3].Split(' '); if (xheader[0] == "-") { CreatedBy = null; CreatedDate = DateTime.MinValue; } else { CreatedBy = xheader[0]; CreatedDate = DateTime.Parse(xheader[1]); } if (xheader[2] == "-") { EditedBy = null; EditedDate = DateTime.MinValue; } else { EditedBy = xheader[2]; EditedDate = DateTime.Parse(xheader[3]); } } }
public bool Can(Permission permission) { return(Rank.Can(permission)); }
static void RaiseRankChangedEvent([NotNull] PlayerInfo playerInfo, [NotNull] Player rankChanger, [NotNull] Rank oldRank, [CanBeNull] string reason, RankChangeType rankChangeType, bool announce) { var h = RankChanged; if (h != null) { h(null, new PlayerInfoRankChangedEventArgs(playerInfo, rankChanger, oldRank, reason, rankChangeType, announce)); } }
public bool Can(Permission permission, Rank rank) { return(Rank.Can(permission, rank)); }
public static IEnumerable <Player> NotRanked(this IEnumerable <Player> source, Rank rank) { if (source == null) { throw new ArgumentNullException("source"); } if (rank == null) { throw new ArgumentNullException("rank"); } foreach (Player player in source) { if (player.Info.Rank != rank) { yield return(player); } } }
internal static PlayerInfo LoadFormat2(string[] fields) { if (fields.Length < 44) { throw new FormatException("PlayerInfo record did not contain all the expected information. " + "This record, or maybe the whole file, may be corrupted."); } PlayerInfo info = new PlayerInfo { Name = fields[0] }; if (fields[1].Length == 0 || !IPAddress.TryParse(fields[1], out info.LastIP)) { info.LastIP = IPAddress.None; } info.Rank = Rank.Parse(fields[2]) ?? RankManager.DefaultRank; DateTimeUtil.TryParseDateTime(fields[3], ref info.RankChangeDate); if (fields[4].Length > 0) { info.RankChangedBy = PlayerDB.Unescape(fields[4]); } switch (fields[5]) { case "b": info.BanStatus = BanStatus.Banned; break; case "x": info.BanStatus = BanStatus.IPBanExempt; break; default: info.BanStatus = BanStatus.NotBanned; break; } // ban information if (DateTimeUtil.TryParseDateTime(fields[6], ref info.BanDate)) { if (fields[7].Length > 0) { info.BannedBy = PlayerDB.Unescape(fields[7]); } if (fields[10].Length > 0) { info.BanReason = PlayerDB.Unescape(fields[10]); } } // unban information if (DateTimeUtil.TryParseDateTime(fields[8], ref info.UnbanDate)) { if (fields[9].Length > 0) { info.UnbannedBy = PlayerDB.Unescape(fields[9]); } if (fields[11].Length > 0) { info.UnbanReason = PlayerDB.Unescape(fields[11]); } } // failed logins DateTimeUtil.TryParseDateTime(fields[12], ref info.LastFailedLoginDate); if (fields[13].Length > 1 || !IPAddress.TryParse(fields[13], out info.LastFailedLoginIP)) { // LEGACY info.LastFailedLoginIP = IPAddress.None; } // skip 14 DateTimeUtil.TryParseDateTime(fields[15], ref info.FirstLoginDate); // login/logout times DateTimeUtil.TryParseDateTime(fields[16], ref info.LastLoginDate); DateTimeUtil.TryParseTimeSpan(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.MessagesWritten); } // fields 22-23 are no longer in use if (fields[24].Length > 0) { info.PreviousRank = Rank.Parse(fields[24]); } if (fields[25].Length > 0) { info.RankChangeReason = PlayerDB.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(); } byte rankChangeTypeCode; if (Byte.TryParse(fields[30], out rankChangeTypeCode)) { info.RankChangeType = (RankChangeType)rankChangeTypeCode; if (!Enum.IsDefined(typeof(RankChangeType), rankChangeTypeCode)) { info.GuessRankChangeType(); } } else { info.GuessRankChangeType(); } DateTimeUtil.TryParseDateTime(fields[31], ref info.LastKickDate); if (!DateTimeUtil.TryParseDateTime(fields[32], ref info.LastSeen) || info.LastSeen < info.LastLoginDate) { info.LastSeen = info.LastLoginDate; } Int64.TryParse(fields[33], out info.BlocksDrawn); if (fields[34].Length > 0) { info.LastKickBy = PlayerDB.Unescape(fields[34]); } if (fields[35].Length > 0) { info.LastKickReason = PlayerDB.Unescape(fields[35]); } DateTimeUtil.TryParseDateTime(fields[36], ref info.BannedUntil); info.IsFrozen = (fields[37] == "f"); if (fields[38].Length > 0) { info.FrozenBy = PlayerDB.Unescape(fields[38]); } DateTimeUtil.TryParseDateTime(fields[39], ref info.FrozenOn); DateTimeUtil.TryParseDateTime(fields[40], ref info.MutedUntil); if (fields[41].Length > 0) { info.MutedBy = PlayerDB.Unescape(fields[41]); } info.Password = PlayerDB.Unescape(fields[42]); // fields[43] is "online", and is ignored byte bandwidthUseModeCode; if (Byte.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 (fields.Length > 45) { if (fields[45].Length == 0) { info.IsHidden = false; } else { info.IsHidden = info.Rank.Can(Permission.Hide); } } if (fields.Length > 46) { DateTimeUtil.TryParseDateTime(fields[46], ref info.LastModified); } if (fields.Length > 47 && fields[47].Length > 0) { info.DisplayedName = PlayerDB.Unescape(fields[47]); } if (fields.Length > 48) { byte accountTypeCode; if (Byte.TryParse(fields[48], out accountTypeCode)) { info.AccountType = (AccountType)accountTypeCode; if (!Enum.IsDefined(typeof(AccountType), accountTypeCode)) { info.AccountType = AccountType.Unknown; } } } if (fields.Length > 49) { if (fields[49].Length > 0) { info.Email = PlayerDB.Unescape(fields[49]); } } // date consistency checks if (info.LastSeen < info.FirstLoginDate) { info.LastSeen = info.FirstLoginDate; } if (info.LastLoginDate < info.FirstLoginDate) { info.LastLoginDate = info.FirstLoginDate; } return(info); }
public SecurityController([NotNull] NbtCompound tag) { if (tag == null) { throw new ArgumentNullException("tag"); } var rankNameTag = tag.Get <NbtString>("MinRank"); if (rankNameTag == null) { throw new SerializationException("MinRank missing"); } minRankName = rankNameTag.Value; minRank = Rank.Parse(minRankName); if (minRank == null) { Logger.Log(LogType.Warning, "Unrecognized rank name: {0}", minRankName); } var whitelistTag = tag.Get <NbtList>("Whitelist"); if (whitelistTag == null) { throw new SerializationException("Whitelist missing"); } var blacklistTag = tag.Get <NbtList>("Blacklist"); if (blacklistTag == null) { throw new SerializationException("Whitelist missing"); } if (PlayerDB.IsLoaded) { foreach (NbtString whitelistNameTag in whitelistTag) { string playerName = whitelistNameTag.Value; PlayerInfo info = PlayerDB.FindPlayerInfoExact(playerName); if (info == null) { Logger.Log(LogType.Warning, "Unrecognized player name on a permission whitelist: {0}", playerName); } else { Include(info); } } foreach (NbtString blacklistNameTag in blacklistTag) { string playerName = blacklistNameTag.Value; PlayerInfo info = PlayerDB.FindPlayerInfoExact(playerName); if (info == null) { Logger.Log(LogType.Warning, "Unrecognized player name on a permission blacklist: {0}", playerName); } else { Exclude(info); } } } else { rawWhitelist = whitelistTag.Select(nameTag => nameTag.StringValue).ToArray(); rawBlacklist = blacklistTag.Select(nameTag => nameTag.StringValue).ToArray(); } }
internal static PlayerInfo LoadFormat1(string[] fields) { PlayerInfo info = new PlayerInfo { Name = fields[0] }; if (fields[1].Length == 0 || !IPAddress.TryParse(fields[1], out info.LastIP)) { info.LastIP = IPAddress.None; } info.Rank = Rank.Parse(fields[2]) ?? RankManager.DefaultRank; fields[3].ToDateTimeLegacy(ref info.RankChangeDate); if (fields[4].Length > 0) { info.RankChangedBy = fields[4]; } switch (fields[5]) { case "b": info.BanStatus = BanStatus.Banned; break; case "x": info.BanStatus = BanStatus.IPBanExempt; break; default: info.BanStatus = BanStatus.NotBanned; break; } // ban information if (fields[6].ToDateTimeLegacy(ref info.BanDate)) { if (fields[7].Length > 0) { info.BannedBy = PlayerDB.Unescape(fields[7]); } if (fields[10].Length > 0) { info.BanReason = PlayerDB.Unescape(fields[10]); } } // unban information if (fields[8].ToDateTimeLegacy(ref info.UnbanDate)) { if (fields[9].Length > 0) { info.UnbannedBy = PlayerDB.Unescape(fields[9]); } if (fields[11].Length > 0) { info.UnbanReason = PlayerDB.Unescape(fields[11]); } } // failed logins fields[12].ToDateTimeLegacy(ref info.LastFailedLoginDate); if (fields[13].Length > 1 || !IPAddress.TryParse(fields[13], out info.LastFailedLoginIP)) // LEGACY { info.LastFailedLoginIP = IPAddress.None; } // skip 14 fields[15].ToDateTimeLegacy(ref info.FirstLoginDate); // login/logout times fields[16].ToDateTimeLegacy(ref info.LastLoginDate); fields[17].ToTimeSpanLegacy(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.MessagesWritten); } // fields 22-23 are no longer in use if (fields[24].Length > 0) { info.PreviousRank = Rank.Parse(fields[24]); } if (fields[25].Length > 0) { info.RankChangeReason = PlayerDB.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(); } byte rankChangeTypeCode; if (Byte.TryParse(fields[30], out rankChangeTypeCode)) { info.RankChangeType = (RankChangeType)rankChangeTypeCode; if (!Enum.IsDefined(typeof(RankChangeType), rankChangeTypeCode)) { info.GuessRankChangeType(); } } else { info.GuessRankChangeType(); } fields[31].ToDateTimeLegacy(ref info.LastKickDate); if (!fields[32].ToDateTimeLegacy(ref info.LastSeen) || info.LastSeen < info.LastLoginDate) { info.LastSeen = info.LastLoginDate; } Int64.TryParse(fields[33], out info.BlocksDrawn); if (fields[34].Length > 0) { info.LastKickBy = PlayerDB.Unescape(fields[34]); } if (fields[34].Length > 0) { info.LastKickReason = PlayerDB.Unescape(fields[35]); } fields[36].ToDateTimeLegacy(ref info.BannedUntil); info.IsFrozen = (fields[37] == "f"); if (fields[38].Length > 0) { info.FrozenBy = PlayerDB.Unescape(fields[38]); } fields[39].ToDateTimeLegacy(ref info.FrozenOn); fields[40].ToDateTimeLegacy(ref info.MutedUntil); if (fields[41].Length > 0) { info.MutedBy = PlayerDB.Unescape(fields[41]); } info.Password = PlayerDB.Unescape(fields[42]); // fields[43] is "online", and is ignored byte bandwidthUseModeCode; if (Byte.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 (fields.Length > 45) { if (fields[45].Length == 0) { info.IsHidden = false; } else { info.IsHidden = info.Rank.Can(Permission.Hide); } } // date consistency checks if (info.LastSeen < info.FirstLoginDate) { info.LastSeen = info.FirstLoginDate; } if (info.LastLoginDate < info.FirstLoginDate) { info.LastLoginDate = info.FirstLoginDate; } return(info); }
internal static void SwapPlayerInfo([NotNull] PlayerInfo p1, [NotNull] PlayerInfo p2) { if (p1 == null) { throw new ArgumentNullException("p1"); } if (p2 == null) { throw new ArgumentNullException("p2"); } lock ( AddLocker ) { lock ( SaveLoadLocker ) { if (p1.IsOnline || p2.IsOnline) { throw new Exception("Both players must be offline to swap info."); } Swap(ref p1.BanDate, ref p2.BanDate); Swap(ref p1.BandwidthUseMode, ref p2.BandwidthUseMode); Swap(ref p1.BanStatus, ref p2.BanStatus); Swap(ref p1.BannedBy, ref p2.BannedBy); Swap(ref p1.BannedUntil, ref p2.BannedUntil); Swap(ref p1.BanReason, ref p2.BanReason); Swap(ref p1.BlocksBuilt, ref p2.BlocksBuilt); Swap(ref p1.BlocksDeleted, ref p2.BlocksDeleted); Swap(ref p1.BlocksDrawn, ref p2.BlocksDrawn); Swap(ref p1.DisplayedName, ref p2.DisplayedName); Swap(ref p1.FirstLoginDate, ref p2.FirstLoginDate); Swap(ref p1.FrozenBy, ref p2.FrozenBy); Swap(ref p1.FrozenOn, ref p2.FrozenOn); Swap(ref p1.ID, ref p2.ID); Swap(ref p1.IsFrozen, ref p2.IsFrozen); //Swap( ref p1.IsHidden, ref p2.IsHidden ); Swap(ref p1.LastFailedLoginDate, ref p2.LastFailedLoginDate); Swap(ref p1.LastFailedLoginIP, ref p2.LastFailedLoginIP); //Swap( ref p1.LastIP, ref p2.LastIP ); Swap(ref p1.LastKickBy, ref p2.LastKickBy); Swap(ref p1.LastKickDate, ref p2.LastKickDate); Swap(ref p1.LastKickReason, ref p2.LastKickReason); //Swap( ref p1.LastLoginDate, ref p2.LastLoginDate ); //Swap( ref p1.LastSeen, ref p2.LastSeen ); //Swap( ref p1.LeaveReason, ref p2.LeaveReason ); Swap(ref p1.MessagesWritten, ref p2.MessagesWritten); Swap(ref p1.MutedBy, ref p2.MutedBy); Swap(ref p1.MutedUntil, ref p2.MutedUntil); //Swap( ref p1.Name, ref p2.Name ); //Swap( ref p1.Online, ref p2.Online ); Swap(ref p1.Password, ref p2.Password); //Swap( ref p1.PlayerObject, ref p2.PlayerObject ); Swap(ref p1.PreviousRank, ref p2.PreviousRank); Rank p1Rank = p1.Rank; p1.Rank = p2.Rank; p2.Rank = p1Rank; Swap(ref p1.RankChangeDate, ref p2.RankChangeDate); Swap(ref p1.RankChangedBy, ref p2.RankChangedBy); Swap(ref p1.RankChangeReason, ref p2.RankChangeReason); Swap(ref p1.RankChangeType, ref p2.RankChangeType); Swap(ref p1.TimesBannedOthers, ref p2.TimesBannedOthers); Swap(ref p1.TimesKicked, ref p2.TimesKicked); Swap(ref p1.TimesKickedOthers, ref p2.TimesKickedOthers); Swap(ref p1.TimesVisited, ref p2.TimesVisited); Swap(ref p1.TotalTime, ref p2.TotalTime); Swap(ref p1.UnbanDate, ref p2.UnbanDate); Swap(ref p1.UnbannedBy, ref p2.UnbannedBy); Swap(ref p1.UnbanReason, ref p2.UnbanReason); list.Sort(PlayerIDComparer.Instance); } } }
/// <summary> Adds a new rank to the list (bottom of hierarchy). Checks for duplicates. </summary> /// <param name="rank"> Rank to add to the list. </param> /// <exception cref="ArgumentNullException"> If rank is null. </exception> /// <exception cref="InvalidOperationException"> If PlayerDB is already loaded. </exception> /// <exception cref="RankDefinitionException"> If a rank with this name or ID is already defined. </exception> public static void AddRank([NotNull] Rank rank) { AddRank(rank, Ranks.Count); }
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, SearchOptions.IncludeSelf); 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), SearchOptions.IncludeSelf); 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 PlayerInfo AddSuperPlayer( ReservedPlayerID id, [NotNull] string name, [NotNull] Rank rank ) { if( name == null ) throw new ArgumentNullException( "name" ); CheckIfLoaded(); PlayerInfo newInfo = new PlayerInfo( (int)id, name, rank, RankChangeType.AutoPromoted, true ) { RaisePropertyChangedEvents = true }; return newInfo; }