void HandleMessage([NotNull] string message) { if (message == null) { throw new ArgumentNullException("message"); } IRCMessage msg = MessageParser(message, ActualBotNick); #if DEBUG_IRC Logger.Log(LogType.IRC, "[{0}]: {1}", msg.Type, msg.RawMessage); #endif switch (msg.Type) { case IRCMessageType.Login: if (ConfigKey.IRCRegisteredNick.Enabled()) { Send(IRCCommands.Privmsg(ConfigKey.IRCNickServ.GetString(), ConfigKey.IRCNickServMessage.GetString())); } foreach (string channel in channelNames) { Send(IRCCommands.Join(channel)); } IsReady = true; AssignBotForInputParsing(); // bot should be ready to receive input after joining return; case IRCMessageType.Ping: // ping-pong Send(IRCCommands.Pong(msg.RawMessageArray[1].Substring(1))); return; case IRCMessageType.ChannelAction: case IRCMessageType.ChannelMessage: // channel chat if (!ResponsibleForInputParsing) { return; } if (!IsBotNick(msg.Nick)) { string processedMessage = msg.Message; if (msg.Type == IRCMessageType.ChannelAction) { if (processedMessage.StartsWith("\u0001ACTION")) { processedMessage = processedMessage.Substring(8); } else { return; } } processedMessage = NonPrintableChars.Replace(processedMessage, ""); processedMessage = Color.EscapeAmpersands(processedMessage).Trim(); if (processedMessage.Length > 0) { if (ConfigKey.IRCBotForwardFromIRC.Enabled()) { if (msg.Type == IRCMessageType.ChannelAction) { Server.Message("&i(IRC) * {0} {1}", msg.Nick, processedMessage); } else { Server.Message("&i(IRC) {0}{1}: {2}", msg.Nick, Color.White, processedMessage); } } else if (msg.Message.StartsWith("#")) { Server.Message("&i(IRC) {0}{1}: {2}", msg.Nick, Color.White, processedMessage.Substring(1)); } } } return; case IRCMessageType.Join: if (!ResponsibleForInputParsing) { return; } if (ConfigKey.IRCBotAnnounceIRCJoins.Enabled()) { Server.Message("&i(IRC) {0} joined {1}", msg.Nick, msg.Channel); } return; case IRCMessageType.Kick: string kicked = msg.RawMessageArray[3]; if (kicked == ActualBotNick) { Logger.Log(LogType.IRC, "Bot was kicked from {0} by {1} ({2}), rejoining.", msg.Channel, msg.Nick, msg.Message); Thread.Sleep(ReconnectDelay); Send(IRCCommands.Join(msg.Channel)); } else { if (!ResponsibleForInputParsing) { return; } Server.Message("&i(IRC) {0} kicked {1} from {2} ({3})", msg.Nick, kicked, msg.Channel, msg.Message); } return; case IRCMessageType.Part: case IRCMessageType.Quit: if (!ResponsibleForInputParsing) { return; } if (ConfigKey.IRCBotAnnounceIRCJoins.Enabled()) { Server.Message("&i(IRC) {0} left {1}", msg.Nick, msg.Channel); } return; case IRCMessageType.NickChange: if (!ResponsibleForInputParsing) { return; } Server.Message("&i(IRC) {0} is now known as {1}", msg.Nick, msg.Message); return; case IRCMessageType.ErrorMessage: case IRCMessageType.Error: bool die = false; switch (msg.ReplyCode) { case IRCReplyCode.ErrorNicknameInUse: case IRCReplyCode.ErrorNicknameCollision: Logger.Log(LogType.IRC, "Error: Nickname \"{0}\" is already in use. Trying \"{0}_\"", ActualBotNick); ActualBotNick += "_"; Send(IRCCommands.Nick(ActualBotNick)); break; case IRCReplyCode.ErrorBannedFromChannel: case IRCReplyCode.ErrorNoSuchChannel: Logger.Log(LogType.IRC, "Error: {0} ({1})", msg.ReplyCode, msg.Channel); die = true; break; case IRCReplyCode.ErrorBadChannelKey: Logger.Log(LogType.IRC, "Error: Channel password required for {0}. fCraft does not currently support passworded channels.", msg.Channel); die = true; break; default: Logger.Log(LogType.IRC, "Error ({0}): {1}", msg.ReplyCode, msg.RawMessage); break; } if (die) { Logger.Log(LogType.IRC, "Error: Disconnecting."); reconnect = false; DisconnectThread(); } return; case IRCMessageType.QueryAction: // TODO: PMs Logger.Log(LogType.IRC, "Query: {0}", msg.RawMessage); break; case IRCMessageType.Kill: Logger.Log(LogType.IRC, "Bot was killed from {0} by {1} ({2}), reconnecting.", hostName, msg.Nick, msg.Message); reconnect = true; isConnected = false; return; } }
/// <summary> Sends a global(white) chat. </summary> /// <param name="player"> Player writing the message. </param> /// <param name="rawMessage"> Message text. </param> /// <returns> True if message was sent, false if it was cancelled by an event callback. </returns> public static bool SendGlobal([NotNull] Player player, [NotNull] string rawMessage) { if (player == null) { throw new ArgumentNullException("player"); } if (rawMessage == null) { throw new ArgumentNullException("rawMessage"); } string OriginalMessage = rawMessage; rawMessage = rawMessage.Replace("$name", player.ClassyName + "&f"); rawMessage = rawMessage.Replace("$kicks", player.Info.TimesKickedOthers.ToString()); rawMessage = rawMessage.Replace("$bans", player.Info.TimesBannedOthers.ToString()); rawMessage = rawMessage.Replace("$awesome", "It is my professional opinion, that " + ConfigKey.ServerName.GetString() + " is the best server on Minecraft"); rawMessage = rawMessage.Replace("$server", ConfigKey.ServerName.GetString()); rawMessage = rawMessage.Replace("$motd", ConfigKey.MOTD.GetString()); rawMessage = rawMessage.Replace("$date", DateTime.UtcNow.ToShortDateString()); rawMessage = rawMessage.Replace("$time", DateTime.Now.ToString()); rawMessage = rawMessage.Replace("$money", player.Info.Money.ToString()); rawMessage = rawMessage.Replace("$ass", "You, my good sir, are an &cAss&f"); rawMessage = rawMessage.Replace("$mad", "U &cmad&f, bro?"); rawMessage = rawMessage.Replace("$welcome", "Welcome to " + ConfigKey.ServerName.GetString()); rawMessage = rawMessage.Replace("$clap", "A round of applause might be appropriate, *claps*"); rawMessage = rawMessage.Replace("$website", ConfigKey.WebsiteURL.GetString()); rawMessage = rawMessage.Replace("$ws", ConfigKey.WebsiteURL.GetString()); if (ConfigKey.IRCBotEnabled.Enabled()) { rawMessage = rawMessage.Replace("$irc", ConfigKey.IRCBotChannels.GetString()); } else { rawMessage = rawMessage.Replace("$irc", "No IRC"); } if (player.Can(Permission.UseColorCodes)) { rawMessage = rawMessage.Replace("$lime", "&a"); //alternate color codes for ease if you can't remember the codes rawMessage = rawMessage.Replace("$aqua", "&b"); rawMessage = rawMessage.Replace("$cyan", "&b"); rawMessage = rawMessage.Replace("$red", "&c"); rawMessage = rawMessage.Replace("$magenta", "&d"); rawMessage = rawMessage.Replace("$pink", "&d"); rawMessage = rawMessage.Replace("$yellow", "&e"); rawMessage = rawMessage.Replace("$white", "&f"); rawMessage = rawMessage.Replace("$navy", "&1"); rawMessage = rawMessage.Replace("$darkblue", "&1"); rawMessage = rawMessage.Replace("$green", "&2"); rawMessage = rawMessage.Replace("$teal", "&3"); rawMessage = rawMessage.Replace("$maroon", "&4"); rawMessage = rawMessage.Replace("$purple", "&5"); rawMessage = rawMessage.Replace("$olive", "&6"); rawMessage = rawMessage.Replace("$gold", "&6"); rawMessage = rawMessage.Replace("$silver", "&7"); rawMessage = rawMessage.Replace("$grey", "&8"); rawMessage = rawMessage.Replace("$gray", "&8"); rawMessage = rawMessage.Replace("$blue", "&9"); rawMessage = rawMessage.Replace("$black", "&0"); } if (!player.Can(Permission.ChatWithCaps)) { int caps = 0; for (int i = 0; i < rawMessage.Length; i++) { if (Char.IsUpper(rawMessage[i])) { caps++; if (caps > ConfigKey.MaxCaps.GetInt()) { rawMessage = rawMessage.ToLower(); player.Message("Your message was changed to lowercase as it exceeded the maximum amount of capital letters."); } } } } if (!player.Can(Permission.Swear)) { if (!File.Exists(Paths.SwearWordsFileName)) { StringBuilder sb = new StringBuilder(); sb.AppendLine("#This txt file should be filled with bad words that you want to be filtered out"); sb.AppendLine("#I have included some examples, excuse my language :P"); sb.AppendLine("f**k"); sb.AppendLine("f*****g"); sb.AppendLine("f****d"); sb.AppendLine("dick"); sb.AppendLine("bitch"); sb.AppendLine("shit"); sb.AppendLine("s******g"); sb.AppendLine("s******d"); sb.AppendLine("c**t"); sb.AppendLine("nigger"); sb.AppendLine("wanker"); sb.AppendLine("wank"); sb.AppendLine("wanking"); sb.AppendLine("piss"); File.WriteAllText(Paths.SwearWordsFileName, sb.ToString()); } string CensoredText = Color.ReplacePercentCodes(ConfigKey.SwearName.GetString()) + Color.White; if (ConfigKey.SwearName.GetString() == null) { CensoredText = "&CBlock&F"; } const string PatternTemplate = @"\b({0})(s?)\b"; const RegexOptions Options = RegexOptions.IgnoreCase; if (Swears.Count == 0) { Swears.AddRange(File.ReadAllLines(Paths.SwearWordsFileName). Where(line => line.StartsWith("#") == false || line.Trim().Equals(String.Empty))); } if (badWordMatchers == null) { badWordMatchers = Swears. Select(x => new Regex(string.Format(PatternTemplate, x), Options)); } string output = badWordMatchers. Aggregate(rawMessage, (current, matcher) => matcher.Replace(current, CensoredText)); rawMessage = output; } /*if(player.World != null) * { * if(player.World.GameOn) * { * if(Games.MineChallenge.mode == Games.MineChallenge.GameMode.math1) * { * if(rawMessage == Games.MineChallenge.answer.ToString() && !Games.MineChallenge.completed.Contains(player)) * { * Games.MineChallenge.completed.Add(player); * player.Message("&8Correct!"); * if(player.World.blueTeam.Contains(player)) player.World.blueScore++; * else player.World.redScore++; * } * else * { * player.Message("&8Incorrect"); * } * return false; * } * * if(Games.MineChallenge.mode == Games.MineChallenge.GameMode.math2) * { * if(rawMessage == Games.MineChallenge.answer.ToString() && !Games.MineChallenge.completed.Contains(player)) * { * Games.MineChallenge.completed.Add(player); * player.Message("&8Correct!"); * if(player.World.blueTeam.Contains(player)) player.World.blueScore++; * else player.World.redScore++; * } * else * { * player.Message("&8Incorrect"); * } * return false; * } * } * }*/ var recepientList = Server.Players.NotIgnoring(player); //if(player.World.WorldOnlyChat) recepientList = player.World.Players.NotIgnoring(player); string formattedMessage = String.Format("{0}&F: {1}", player.ClassyName, rawMessage); var e = new ChatSendingEventArgs(player, rawMessage, formattedMessage, ChatMessageType.Global, recepientList); if (!SendInternal(e)) { return(false); } Logger.Log(LogType.GlobalChat, "{0}: {1}", player.Name, OriginalMessage); return(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(); } }
// runs in its own thread, started from Connect() void IoThread() { string outputLine = ""; lastMessageSent = DateTime.UtcNow; do { try { reconnect = false; Logger.Log(LogType.IRC, "Connecting to {0}:{1} as {2}", hostName, port, ActualBotNick); Connect(); // register Send(IRCCommands.User(ActualBotNick, 8, ConfigKey.ServerName.GetString())); Send(IRCCommands.Nick(ActualBotNick)); while (isConnected && !reconnect) { Thread.Sleep(10); if (localQueue.Length > 0 && DateTime.UtcNow.Subtract(lastMessageSent).TotalMilliseconds >= SendDelay && localQueue.Dequeue(ref outputLine)) { writer.Write(outputLine + "\r\n"); lastMessageSent = DateTime.UtcNow; writer.Flush(); } if (OutputQueue.Length > 0 && DateTime.UtcNow.Subtract(lastMessageSent).TotalMilliseconds >= SendDelay && OutputQueue.Dequeue(ref outputLine)) { writer.Write(outputLine + "\r\n"); lastMessageSent = DateTime.UtcNow; writer.Flush(); } if (client.Client.Available > 0) { string line = reader.ReadLine(); if (line == null) { break; } HandleMessage(line); } } } catch (SocketException) { Logger.Log(LogType.Warning, "IRC: Disconnected. Will retry in {0} seconds.", ReconnectDelay / 1000); reconnect = true; } catch (IOException) { Logger.Log(LogType.Warning, "IRC: Disconnected. Will retry in {0} seconds.", ReconnectDelay / 1000); reconnect = true; #if !DEBUG } catch (Exception ex) { Logger.Log(LogType.Error, "IRC: {0}", ex); reconnect = true; #endif } if (reconnect) { Thread.Sleep(ReconnectDelay); } } while(reconnect); }
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(); }
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 bool LoadWorldList() { World newMainWorld = null; Worlds = new World[0]; if (File.Exists(Paths.WorldListFileName)) { try { XDocument doc = XDocument.Load(Paths.WorldListFileName); XElement root = doc.Root; if (root != null) { foreach (XElement el in root.Elements("World")) { #if !DEBUG try { #endif LoadWorldListEntry(el); #if !DEBUG } catch (Exception ex) { Logger.LogAndReportCrash("An error occured while trying to parse one of the entries on the world list", "fCraft", ex, false); } #endif } XAttribute temp; if ((temp = root.Attribute("main")) != null) { World suggestedMainWorld = FindWorldExact(temp.Value); if (suggestedMainWorld != null) { newMainWorld = suggestedMainWorld; } else if (firstWorld != null) { // if specified main world does not exist, use first-defined world Logger.Log(LogType.Warning, "The specified main world \"{0}\" does not exist. " + "\"{1}\" was designated main instead. You can use /WMain to change it.", temp.Value, firstWorld.Name); newMainWorld = firstWorld; } // if firstWorld was also null, LoadWorldList() should try creating a new mainWorld } else if (firstWorld != null) { newMainWorld = firstWorld; } } } catch (Exception ex) { Logger.LogAndReportCrash("Error occured while trying to load the world list.", "fCraft", ex, true); return(false); } if (newMainWorld == null) { Logger.Log(LogType.Error, "Server.Start: Could not load any of the specified worlds, or no worlds were specified. " + "Creating default \"main\" world."); newMainWorld = AddWorld(null, "main", MapGenerator.GenerateFlatgrass(128, 128, 64), true); } } else { Logger.Log(LogType.SystemActivity, "Server.Start: No world list found. Creating default \"main\" world."); newMainWorld = AddWorld(null, "main", MapGenerator.GenerateFlatgrass(128, 128, 64), true); } // if there is no default world still, die. if (newMainWorld == null) { throw new Exception("Could not create any worlds."); } else if (newMainWorld.AccessSecurity.HasRestrictions) { Logger.Log(LogType.Warning, "Server.LoadWorldList: Main world cannot have any access restrictions. " + "Access permission for \"{0}\" has been reset.", newMainWorld.Name); newMainWorld.AccessSecurity.Reset(); } MainWorld = newMainWorld; return(true); }
public static void RealmCreate(Player player, Command cmd, string themeName, string templateName) { MapGenTemplate template; MapGenTheme theme; int wx, wy, height = 128; if (!(cmd.NextInt(out wx) && cmd.NextInt(out wy) && cmd.NextInt(out height))) { if (player.World != null) { wx = 128; wy = 128; height = 128; } else { player.Message("When used from console, /gen requires map dimensions."); return; } cmd.Rewind(); cmd.Next(); cmd.Next(); } if (!Map.IsValidDimension(wx)) { player.Message("Cannot make map with width {0}: dimensions must be multiples of 16.", wx); return; } else if (!Map.IsValidDimension(wy)) { player.Message("Cannot make map with length {0}: dimensions must be multiples of 16.", wy); return; } else if (!Map.IsValidDimension(height)) { player.Message("Cannot make map with height {0}: dimensions must be multiples of 16.", height); return; } string fileName = player.Name; if (player.Name.Contains('.')) { fileName = player.Name.Replace(".", "-"); //support for email names } string fullFileName = null; if (fileName == null) { if (player.World == null) { player.Message("When used from console, /gen requires FileName."); return; } if (!cmd.IsConfirmed) { player.Confirm(cmd, "Replace this realm's map with a generated one?"); return; } } else { fileName = fileName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); if (!fileName.EndsWith(".fcm", StringComparison.OrdinalIgnoreCase)) { fileName += ".fcm"; } fullFileName = Path.Combine(Paths.MapPath, fileName); if (!Paths.IsValidPath(fullFileName)) { player.Message("Invalid filename."); return; } if (!Paths.Contains(Paths.MapPath, fullFileName)) { player.MessageUnsafePath(); return; } string dirName = fullFileName.Substring(0, fullFileName.LastIndexOf(Path.DirectorySeparatorChar)); if (!Directory.Exists(dirName)) { Directory.CreateDirectory(dirName); } if (!cmd.IsConfirmed && File.Exists(fullFileName)) { player.Confirm(cmd, "The mapfile \"{0}\" already exists. Overwrite?", fileName); return; } } bool noTrees; if (themeName.Equals("grass", StringComparison.OrdinalIgnoreCase)) { theme = MapGenTheme.Forest; noTrees = true; } else { try { theme = (MapGenTheme)Enum.Parse(typeof(MapGenTheme), themeName, true); noTrees = (theme != MapGenTheme.Forest); } catch (Exception) { player.MessageNow("Unrecognized theme \"{0}\". Available themes are: Grass, {1}", themeName, String.Join(", ", Enum.GetNames(typeof(MapGenTheme)))); return; } } try { template = (MapGenTemplate)Enum.Parse(typeof(MapGenTemplate), templateName, true); } catch (Exception) { player.Message("Unrecognized template \"{0}\". Available templates are: {1}", templateName, String.Join(", ", Enum.GetNames(typeof(MapGenTemplate)))); return; } if (!Enum.IsDefined(typeof(MapGenTheme), theme) || !Enum.IsDefined(typeof(MapGenTemplate), template)) { return; } MapGeneratorArgs args = MapGenerator.MakeTemplate(template); args.MapWidth = wx; args.MapLength = wy; args.MapHeight = height; args.MaxHeight = (int)(args.MaxHeight / 80d * height); args.MaxDepth = (int)(args.MaxDepth / 80d * height); args.Theme = theme; args.AddTrees = !noTrees; Map map; try { if (theme == MapGenTheme.Forest && noTrees) { player.MessageNow("Generating Grass {0}...", template); } else { player.MessageNow("Generating {0} {1}...", theme, template); } if (theme == MapGenTheme.Forest && noTrees && template == MapGenTemplate.Flat) { map = MapGenerator.GenerateFlatgrass(args.MapWidth, args.MapLength, args.MapHeight); } else { MapGenerator generator = new MapGenerator(args); map = generator.Generate(); } } catch (Exception ex) { Logger.Log(LogType.Error, "MapGenerator: Generation failed: {0}", ex); player.MessageNow("&WAn error occured while generating the map."); return; } if (fileName != null) { if (map.Save(fullFileName)) { player.MessageNow("Generation done. Saved to {0}", fileName); } else { player.Message("&WAn error occured while saving generated map to {0}", fileName); } } else { player.MessageNow("Generation done. Changing map..."); player.World.ChangeMap(map); } }
// Makes sure that the map file exists, is properly named, and is loadable. static void CheckMapFile([NotNull] World world) { if (world == null) { throw new ArgumentNullException("world"); } // Check the world's map file string fullMapFileName = world.MapFileName; string fileName = Path.GetFileName(fullMapFileName); if (Paths.FileExists(fullMapFileName, false)) { if (!Paths.FileExists(fullMapFileName, true)) { // Map file has wrong capitalization FileInfo[] matches = Paths.FindFiles(fullMapFileName); if (matches.Length == 1) { // Try to rename the map file to match world's capitalization // ReSharper disable AssignNullToNotNullAttribute Paths.ForceRename(matches[0].FullName, fileName); // ReSharper restore AssignNullToNotNullAttribute if (Paths.FileExists(fullMapFileName, true)) { Logger.Log(LogType.Warning, "WorldManager.CheckMapFile: Map file for world \"{0}\" was renamed from \"{1}\" to \"{2}\"", world.Name, matches[0].Name, fileName); } else { Logger.Log(LogType.Error, "WorldManager.CheckMapFile: Failed to rename map file of \"{0}\" from \"{1}\" to \"{2}\"", world.Name, matches[0].Name, fileName); return; } } else { Logger.Log(LogType.Warning, "WorldManager.CheckMapFile: More than one map file exists matching the world name \"{0}\". " + "Please check the map directory and use /WLoad to load the correct file.", world.Name); return; } } // Try loading the map header try { MapUtility.LoadHeader(world.MapFileName); } catch (Exception ex) { Logger.Log(LogType.Warning, "WorldManager.CheckMapFile: Could not load map file for world \"{0}\": {1}", world.Name, ex); } } else { Logger.Log(LogType.Warning, "WorldManager.CheckMapFile: Map file for world \"{0}\" was not found.", world.Name); } }
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; 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; } 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("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); }
public Map AcceptPlayer([NotNull] Player player, bool announce) { if (player == null) { throw new ArgumentNullException("player"); } lock ( SyncRoot ) { if (IsFull) { if (player.Info.Rank.ReservedSlot) { Player idlestPlayer = Players.Where(p => p.Info.Rank.IdleKickTimer != 0) .OrderBy(p => p.LastActiveTime) .FirstOrDefault(); if (idlestPlayer != null) { idlestPlayer.Kick(Player.Console, "Auto-kicked to make room (idle).", LeaveReason.IdleKick, false, false, false); Server.Players .CanSee(player) .Message("&SPlayer {0}&S was auto-kicked to make room for {1}", idlestPlayer.ClassyName, player.ClassyName); Server.Players .CantSee(player) .Message("{0}&S was kicked for being idle for {1} min", player.ClassyName, player.Info.Rank.IdleKickTimer); } else { return(null); } } else { return(null); } } if (playerIndex.ContainsKey(player.Name.ToLower())) { Logger.Log(LogType.Error, "This world already contains the player by name ({0}). " + "Some sort of state corruption must have occured.", player.Name); playerIndex.Remove(player.Name.ToLower()); } playerIndex.Add(player.Name.ToLower(), player); // load the map, if it's not yet loaded IsPendingMapUnload = false; Map = LoadMap(); if (ConfigKey.BackupOnJoin.Enabled() && (HasChangedSinceBackup || !ConfigKey.BackupOnlyWhenChanged.Enabled())) { string backupFileName = String.Format(JoinBackupFormat, Name, DateTime.Now, player.Name); // localized SaveBackup(Path.Combine(Paths.BackupPath, backupFileName)); } UpdatePlayerList(); if (announce && ConfigKey.ShowJoinedWorldMessages.Enabled()) { Server.Players.CanSee(player) .Message("&SPlayer {0}&S joined {1}", player.ClassyName, ClassyName); } Logger.Log(LogType.UserActivity, "Player {0} joined world {1}.", player.Name, Name); if (IsLocked) { player.Message("&WThis map is currently locked (read-only)."); } if (player.Info.IsHidden) { player.Message("&8Reminder: You are still hidden."); } return(Map); } }
/// <summary> Makes sure that the path format is valid, and optionally whether it is readable/writeable. </summary> /// <param name="fileLabel"> Name of the path that's being tested (e.g. "map path"). Used for logging. </param> /// <param name="filename"> Full or partial path of the file. </param> /// <param name="createIfDoesNotExist"> /// If target file is missing and this option is OFF, TestFile returns true. /// If target file is missing and this option is ON, TestFile tries to create /// a file and returns whether it succeeded. /// </param> /// <param name="neededAccess"> If file is present, type of access to test. </param> /// <returns> Whether target file passed all tests. </returns> public static bool TestFile([NotNull] string fileLabel, [NotNull] string filename, bool createIfDoesNotExist, FileAccess neededAccess) { if (fileLabel == null) { throw new ArgumentNullException("fileLabel"); } if (filename == null) { throw new ArgumentNullException("filename"); } try { new FileInfo(filename); if (File.Exists(filename)) { if ((neededAccess & FileAccess.Read) == FileAccess.Read) { using (File.OpenRead(filename)) { } } if ((neededAccess & FileAccess.Write) == FileAccess.Write) { using (File.OpenWrite(filename)) { } } } else if (createIfDoesNotExist) { using (File.Create(filename)) { } } return(true); } catch (Exception ex) { if (ex is ArgumentException || ex is NotSupportedException || ex is PathTooLongException) { Logger.Log(LogType.Error, "Paths.TestFile: Specified path for {0} is invalid or incorrectly formatted ({1}: {2}).", fileLabel, ex.GetType().Name, ex.Message); } else if (ex is SecurityException || ex is UnauthorizedAccessException) { Logger.Log(LogType.Error, "Paths.TestFile: Cannot create or write to {0}, please check permissions ({1}: {2}).", fileLabel, ex.GetType().Name, ex.Message); } else if (ex is DirectoryNotFoundException) { Logger.Log(LogType.Error, "Paths.TestFile: Drive/volume for {0} does not exist or is not mounted ({1}: {2}).", fileLabel, ex.GetType().Name, ex.Message); } else if (ex is IOException) { Logger.Log(LogType.Error, "Paths.TestFile: Specified file for {0} is not readable/writable ({1}: {2}).", fileLabel, ex.GetType().Name, ex.Message); } else { throw; } } return(false); }
/// <summary> Loads contents of PlayerDB. </summary> /// <exception cref="InvalidOperationException"> If PlayerDB is akready loaded. </exception> /// <exception cref="MisconfigurationException"> If an unknown PlayerDBProviderType is specified. </exception> /// <exception cref="TypeLoadException"> If MySqlPlayerDBProvider could not be found. </exception> public static void Load() { using( GetWriteLock() ) { if( IsLoaded ) throw new InvalidOperationException( "PlayerDB is already loaded." ); Stopwatch sw = Stopwatch.StartNew(); switch( ProviderType ) { case PlayerDBProviderType.Flatfile: provider = new FlatfilePlayerDBProvider(); break; case PlayerDBProviderType.MySql: Assembly mySqlAsm = Assembly.LoadFile( Path.Combine( Paths.WorkingPath, Paths.MySqlPlayerDBProviderModule ) ); provider = (IPlayerDBProvider)mySqlAsm.CreateInstance( MySqlPlayerDBProviderType ); if( provider == null ) { throw new TypeLoadException( "PlayerDB.Load: Could not find MySqlPlayerDBProvider." ); } break; default: throw new MisconfigurationException( "PlayerDB.Load: Unknown ProviderType: " + ProviderType ); } var playerList = provider.Load(); if( playerList != null ) { List.AddRange( playerList ); sw.Stop(); Logger.Log( LogType.Debug, "PlayerDB.Load: Done loading ({0} records read) in {1}ms", List.Count, sw.ElapsedMilliseconds ); } else { Logger.Log( LogType.Debug, "PlayerDB.Load: No records loaded." ); } Logger.Log( LogType.SystemActivity, "PlayerDB: Checking consistency of player records..." ); List.Sort( PlayerInfo.ComparerByID ); int unhid = 0, unfroze = 0, unmuted = 0; for( int i = 0; i < List.Count; i++ ) { if( List[i].IsBanned ) { if( List[i].IsHidden ) { unhid++; List[i].IsHidden = false; } if( List[i].IsFrozen ) { List[i].Unfreeze(); unfroze++; } if( List[i].IsMuted ) { List[i].Unmute(); unmuted++; } } List[i].RaisePropertyChangedEvents = true; } if( unhid != 0 || unfroze != 0 || unmuted != 0 ) { Logger.Log( LogType.SystemActivity, "PlayerDB: Unhid {0}, unfroze {1}, and unmuted {2} banned accounts.", unhid, unfroze, unmuted ); } IsLoaded = true; // Import everything from flatfile //provider.Import( new FlatfilePlayerDBProvider().Load() ); } }