/// <summary> /// The internal code to check if the player has a permission. /// </summary> /// <param name="path">The details of the node path.</param> /// <returns>Whether the permission is marked.</returns> public bool?HasPermission(params string[] path) { bool? b; FDSSection sect = Root; int end = path.Length - 1; for (int i = 0; i < end; i++) { sect = sect?.GetSection(path[i]); } b = sect?.GetBool(path[end]); if (b.HasValue) { return(b.Value); } sect = Root; for (int i = 0; i < end; i++) { b = sect?.GetBool("*"); if (b.HasValue) { return(b.Value); } sect = sect?.GetSection(path[i]); } if (InheritsFrom != null) { return(InheritsFrom.HasPermission(path)); } return(null); }
/// <summary> /// Gets a list of texts, in the default language. /// </summary> /// <param name="Files">The file system.</param> /// <param name="pathAndVars">The path and its vars.</param> /// <returns>The text list.</returns> public List <string> GetTextListDefault(FileHandler Files, params string[] pathAndVars) { if (pathAndVars.Length < 2) { return(GetTextListDefault(Files, "core", "common.languages.badinput")); } string category = pathAndVars[0].ToLowerFast(); string defPath = pathAndVars[1].ToLowerFast(); FDSSection langen = GetLangDoc(category, Files, DefaultLanguage, EnglishDocuments); List <string> str = null; if (langen != null) { str = langen.GetStringList(defPath); if (str != null) { return(HandleList(str, pathAndVars)); } } if (defPath == BADKEY) { return(new List <string>() { "((Invalid key!))" }); } return(GetTextListDefault(Files, "core", BADKEY)); }
/// <summary> /// Gets the topic section for a voting command. Also performs other basic prechecks. /// </summary> public static FDSSection GetVoteTopicSection(string[] cmds, IUserMessage message, out string topic) { topic = null; if (!IsUserAllowed(message)) { return(null); } if (DemocracyBot.VoteTopicsSection.IsEmpty()) { SendGenericNegativeMessageReply(message, "No Current Voting", "Nothing to vote on. Check back later!"); return(null); } if (DemocracyBot.VoteTopicsSection.Data.Count == 1) { topic = DemocracyBot.VoteTopicsSection.Data.Keys.First(); } else if (cmds.Length > 0) { topic = cmds[0].Replace("`", "").Replace(",", "").Replace(":", "").Trim(); } if (topic == null) { SendErrorMessageReply(message, "Must Specify Topic", "There are currently multiple topics being voted on. Please specify which. Use `!ballot` to see the list of current topics!"); return(null); } FDSSection topicSection = DemocracyBot.VoteTopicsSection.GetSectionLowered(topic); if (topicSection == null) { SendErrorMessageReply(message, "Invalid Topic, Or Must Specify", "There are currently multiple topics being voted on. Please specify which. Use `!ballot` to see the list of current topics!" + "\n\nIf you did specify a topic, you likely typed it in wrong. Remember, just use the short topic prefix, not the full name."); return(null); } return(topicSection); }
public void LoadConfig() { string folder = "saves/" + Name; TheServer.Files.CreateDirectory(folder); // TODO: Journaling read string fname = folder + "/world.fds"; if (TheServer.Files.Exists(fname)) { Config = new FDSSection(TheServer.Files.ReadText(fname)); } else { Config = new FDSSection(); } Config.Set("general.IMPORTANT_NOTE", "Edit this configuration at your own risk!"); Config.Set("general.name", Name); Config.Default("general.seed", Utilities.UtilRandom.Next(SeedMax) - SeedMax / 2); Config.Default("general.spawnpoint", new Location(0, 0, 50).ToString()); Config.Default("general.flat", "false"); CFGEdited = true; Seed = Config.GetInt("general.seed", DefaultSeed).Value; SpawnPoint = Location.FromString(Config.GetString("general.spawnpoint", DefaultSpawnPoint)); Flat = Config.GetString("general.flat", "false").ToString().ToLowerFast() == "true"; Random seedGen = new Random(Seed);// TODO: Own random method that doesn't depend on C# impl! Seed2 = (seedGen.Next(SeedMax) - SeedMax / 2); Seed3 = (seedGen.Next(SeedMax) - SeedMax / 2); Seed4 = (seedGen.Next(SeedMax) - SeedMax / 2); Seed5 = (seedGen.Next(SeedMax) - SeedMax / 2); }
/// <summary> /// Gets a text. /// </summary> /// <param name="Files">The file system.</param> /// <param name="pathAndVars">The path and its vars.</param> /// <returns>The text.</returns> public string GetText(FileEngine Files, params string[] pathAndVars) { if (pathAndVars.Length < 2) { return(GetText(Files, "core", "common.languages.badinput")); } string category = pathAndVars[0].ToLowerFast(); string defPath = pathAndVars[1].ToLowerFast(); FDSSection lang = GetLangDoc(category, Files); FDSSection langen = GetLangDoc(category, Files, DefaultLanguage, EnglishDocuments); string str = null; if (lang != null) { str = lang.GetString(defPath, null); if (str != null) { return(Handle(str, pathAndVars)); } } if (langen != null) { str = langen.GetString(defPath, null); if (str != null) { return(Handle(str, pathAndVars)); } } if (defPath == BADKEY) { return("((Invalid key!))"); } return(GetText(Files, "core", BADKEY)); }
/// <summary> /// User command to see the available voting topics. /// </summary> public void CMD_Ballot(string[] cmds, IUserMessage message) { if (!IsUserAllowed(message)) { return; } if (DemocracyBot.VoteTopicsSection.IsEmpty()) { SendGenericNegativeMessageReply(message, "No Current Voting", "Nothing to vote on. Check back later!"); return; } foreach (string topic in DemocracyBot.VoteTopicsSection.GetRootKeys()) { FDSSection topicSection = DemocracyBot.VoteTopicsSection.GetSection(topic); EmbedBuilder embed = new EmbedBuilder().WithTitle($"Topic **{topic}**: {topicSection.GetString("Topic")}"); FDSSection choicesSection = topicSection.GetSection("Choices"); foreach (string choice in choicesSection.GetRootKeys()) { embed.AddField($"Option **{choice}**:", choicesSection.GetString(choice)); } List <string> choices = topicSection.GetStringList($"user_results.{message.Author.Id}"); if (choices != null) { embed.AddField("You've already voted for:", $"`{string.Join(", ", choices)}`"); } SendReply(message, embed.Build()); } }
public void LoadFromSection(Server tserver, FDSSection sect) { try { Section = sect; FDSSection automation = sect.GetSection("automation") ?? new FDSSection(); Saves = automation.GetString("saves", tserver == null ? "true" : (tserver.Settings.WorldDefault.Saves ? "true" : "false")) == "true"; FDSSection limits = sect.GetSection("limits") ?? new FDSSection(); MaxHeight = limits.GetInt("max_height", tserver == null ? 5000 : tserver.Settings.WorldDefault.MaxHeight).Value; MinHeight = limits.GetInt("min_height", tserver == null ? -5000 : tserver.Settings.WorldDefault.MinHeight).Value; MaxDistance = limits.GetInt("max_distance", tserver == null ? 100000000 : tserver.Settings.WorldDefault.MaxDistance).Value; FDSSection players = sect.GetSection("players") ?? new FDSSection(); MaxRenderDistance = players.GetInt("max_render_distance", tserver == null ? 6 : tserver.Settings.WorldDefault.MaxRenderDistance).Value; MaxLODRenderDistance = players.GetInt("max_lod_render_distance", tserver == null ? 20 : tserver.Settings.WorldDefault.MaxLODRenderDistance).Value; FDSSection debug = sect.GetSection("debug") ?? new FDSSection(); TreesInDistance = debug.GetString("trees_in_distance", tserver == null ? "false" : (tserver.Settings.WorldDefault.TreesInDistance ? "true" : "false")) == "true"; FDSSection generator = sect.GetSection("generator") ?? new FDSSection(); GeneratorFlat = generator.GetBool("flat", false).Value; } catch (Exception ex) { Utilities.CheckException(ex); SysConsole.Output(ex); } }
/// <summary> /// Admin command to end an existing vote. /// </summary> public void CMD_EndVote(string[] cmds, IUserMessage message) { if (!DemocracyBot.IsAdmin(message.Author)) { return; } FDSSection topicSection = VotingCommands.GetVoteTopicSection(cmds, message, out string topicName); if (topicSection == null) { return; } topicName = topicName.ToLowerFast(); Console.WriteLine($"Trying to end vote for {topicName} at {StringConversionHelper.DateTimeToString(DateTimeOffset.UtcNow, true)}"); FDSSection choicesSection = topicSection.GetSection("Choices"); Bot.ConfigFile.Set("old_topics." + StringConversionHelper.DateTimeToString(DateTimeOffset.UtcNow, true).Replace(".", "_") + "_topic_" + topicName.Replace(".", "_"), topicSection); string realKey = DemocracyBot.VoteTopicsSection.Data.Keys.First(s => s.ToLowerFast() == topicName); DemocracyBot.VoteTopicsSection.Remove(realKey); RefreshTopicData(topicName, topicSection, true); FDSSection userResultsSection = topicSection.GetSection("user_results"); tallyVotes(topicSection, choicesSection, userResultsSection, message, topicName, true); }
/// <summary> /// Gets a language document for the specified parameters. /// </summary> /// <param name="id">The document ID.</param> /// <param name="Files">The file system.</param> /// <param name="lang">The language to enforce for this read, if any.</param> /// <param name="confs">The custom configuration set to use, if any.</param> /// <returns></returns> public FDSSection GetLangDoc(string id, FileEngine Files, string lang = null, Dictionary <string, FDSSection> confs = null) { if (lang == null) { lang = CurrentLanguage; } if (confs == null) { confs = LanguageDocuments; } string idlow = id.ToLowerFast(); if (LanguageDocuments.TryGetValue(idlow, out FDSSection doc)) { return(doc); } string path = "info/text/" + idlow + "_" + lang + ".fds"; if (Files.TryReadFileText(path, out string dat)) { try { doc = new FDSSection(dat); LanguageDocuments[idlow] = doc; return(doc); } catch (Exception ex) { CommonUtilities.CheckException(ex); SysConsole.Output("Reading language documents", ex); } } LanguageDocuments[idlow] = null; return(null); }
public FDSSection GetLangDoc(string id, FileHandler Files, string lang = null, Dictionary<string, FDSSection> confs = null) { if (lang == null) { lang = CurrentLanguage; } if (confs == null) { confs = LanguageDocuments; } string idlow = id.ToLowerFast(); FDSSection doc; if (LanguageDocuments.TryGetValue(idlow, out doc)) { return doc; } string path = "info/text/" + idlow + "_" + lang + ".fds"; if (Files.Exists(path)) { try { string dat = Files.ReadText(path); doc = new FDSSection(dat); LanguageDocuments[idlow] = doc; return doc; } catch (Exception ex) { Utilities.CheckException(ex); SysConsole.Output("Reading language documents", ex); } } LanguageDocuments[idlow] = null; return null; }
/// <summary> /// Gets the config file for a player. /// If the player is online, will return the online player's config data. /// Otherwise, will return a temporary copy from file. /// </summary> /// <param name="username">The username of the player.</param> /// <returns>The config data.</returns> public FDSSection GetPlayerConfig(string username) { if (username.Length == 0) { return(null); } lock (TickLock) { PlayerEntity pl = GetPlayerFor(username); if (pl != null) { return(pl.PlayerConfig); } FDSSection PlayerConfig = null; string nl = username.ToLower(); // TODO: Journaling read string fn = "server_player_saves/" + nl[0].ToString() + "/" + nl + ".plr"; if (Files.Exists(fn)) { string dat = Files.ReadText(fn); if (dat != null) { PlayerConfig = new FDSSection(dat); } } return(PlayerConfig); } }
public void Reload() { try { FDSSection serverSect = Section.GetSection("server") ?? new FDSSection(); Worlds = serverSect.GetStringList("worlds") ?? new List <string>() { "default" }; FPS = serverSect.GetInt("fps", 30).Value; Debug = serverSect.GetBool("debug", true).Value; WorldDefault.LoadFromSection(null, Section.GetSection("world_defaults") ?? new FDSSection()); FDSSection network = Section.GetSection("network") ?? new FDSSection(); Net_VerifyIP = network.GetString("verify_ip", "true") == "true"; Net_ChunksPerTick = network.GetInt("chunks_per_tick", 2).Value; Net_OnlineMode = network.GetString("online_mode", "true") == "true"; FDSSection text = Section.GetSection("text") ?? new FDSSection(); Text_TranslateURLs = text.GetString("translate_urls", "true") == "true"; Text_BlockURLs = text.GetString("block_urls", "false") == "true"; Text_BlockColors = text.GetString("block_colors", "false") == "true"; OnReloaded?.Invoke(); } catch (Exception ex) { Utilities.CheckException(ex); SysConsole.Output(ex); } }
/// <summary> /// Software entry point - starts the bot. /// </summary> static void Main(string[] args) { DiscordBotBaseHelper.StartBotHandler(args, new DiscordBotConfig() { CommandPrefix = "!", Initialize = (bot) => { InfoCommands infoCommands = new InfoCommands() { Bot = bot }; VotingCommands voteCommands = new VotingCommands() { Bot = bot }; CoreCommands coreCommands = new CoreCommands(IsAdmin) { Bot = bot }; AdminCommands adminCommands = new AdminCommands() { Bot = bot }; OwningGuildID = bot.ConfigFile.GetUlong("guild_id").Value; VoteTopicsSection = bot.ConfigFile.GetSection("vote_topics"); if (VoteTopicsSection == null) { VoteTopicsSection = new FDSSection(); bot.ConfigFile.Set("vote_topics", VoteTopicsSection); } Admins = new HashSet <ulong>(bot.ConfigFile.GetStringList("admins").Select(s => ulong.Parse(s))); // Info bot.RegisterCommand(infoCommands.CMD_Help, "help", "halp", "hlp", "hal", "hel", "h", "?", "use", "usage"); bot.RegisterCommand(infoCommands.CMD_Hello, "hello", "hi", "whoareyou", "what", "link", "info"); // Voting bot.RegisterCommand(voteCommands.CMD_Ballot, "ballot", "b"); bot.RegisterCommand(voteCommands.CMD_Vote, "vote", "v"); bot.RegisterCommand(voteCommands.CMD_ClearVote, "clearvote", "voteclear", "cv"); // Admin bot.RegisterCommand(coreCommands.CMD_Restart, "restart"); bot.RegisterCommand(adminCommands.CMD_CallVote, "callvote"); bot.RegisterCommand(adminCommands.CMD_EndVote, "endvote"); bot.RegisterCommand(adminCommands.CMD_VoteStatus, "votestatus"); bot.Client.Ready += () => { bot.Client.SetGameAsync("With the balance of power in this world.").Wait(); return(Task.CompletedTask); }; }, ShouldPayAttentionToMessage = (message) => { //return message.Channel is IPrivateChannel || IsAdmin(message.Author); return(true); } }); }
public static void Init() { Config = FDSUtility.ReadFile("config/config.fds"); ReloadWebhookToken = Config.GetString("reload-webhook-token"); if (Config.HasKey("alt-sources")) { MetaDocsLoader.SourcesToUse = Config.GetStringList("alt-sources").ToArray(); } ReloadMeta(); }
/// <summary>Loads the paste config.</summary> public static void LoadConfig() { FDSSection Config = FDSUtility.ReadFile("config/config.fds"); URL_BASE = Config.GetString("url-base"); MaxPasteRawLength = Config.GetInt("max-paste-size").Value; TrustXForwardedFor = Config.GetBool("trust-x-forwarded-for").Value; MaxPastesPerMinute = Config.GetInt("max-pastes-per-minute").Value; NewPasteWebhooks = (Config.GetStringList("webhooks.new-paste") ?? new List <string>()).ToArray(); Console.WriteLine($"Loaded at URL-base {URL_BASE} with max length {MaxPasteRawLength} with ratelimit {MaxPastesPerMinute} and x-forwarded-for set {TrustXForwardedFor}"); }
public void ConnectFlap(VehiclePartEntity flap, FDSSection flapDat) { JointBallSocket jbs = new JointBallSocket(this, flap, flap.GetPosition()); // TODO: necessity? TheRegion.AddJoint(jbs); JointNoCollide jnc = new JointNoCollide(this, flap); TheRegion.AddJoint(jnc); string mode = flapDat.GetString("mode"); VehicleFlap vf = new VehicleFlap() { MaxAngle = flapDat.GetDouble("max_angle", 10).Value, Speed = flapDat.GetDouble("corrective_speed", 2.25).Value }; if (mode == "roll/l") { JointHinge jh = new JointHinge(this, flap, new Location(1, 0, 0)); TheRegion.AddJoint(jh); JointVehicleMotor jvm = new JointVehicleMotor(this, flap, new Location(1, 0, 0), true); TheRegion.AddJoint(jvm); vf.JVM = jvm; Flaps_RollL.Add(vf); } else if (mode == "roll/r") { JointHinge jh = new JointHinge(this, flap, new Location(1, 0, 0)); TheRegion.AddJoint(jh); JointVehicleMotor jvm = new JointVehicleMotor(this, flap, new Location(1, 0, 0), true); TheRegion.AddJoint(jvm); vf.JVM = jvm; Flaps_RollR.Add(vf); } else if (mode == "yaw") { JointHinge jh = new JointHinge(this, flap, new Location(0, 0, 1)); TheRegion.AddJoint(jh); JointVehicleMotor jvm = new JointVehicleMotor(this, flap, new Location(0, 0, 1), true); TheRegion.AddJoint(jvm); vf.JVM = jvm; Flaps_Yaw.Add(vf); } else if (mode == "pitch") { JointHinge jh = new JointHinge(this, flap, new Location(1, 0, 0)); TheRegion.AddJoint(jh); JointVehicleMotor jvm = new JointVehicleMotor(this, flap, new Location(1, 0, 0), true); TheRegion.AddJoint(jvm); vf.JVM = jvm; Flaps_Pitch.Add(vf); } }
public static VehicleEntity CreateVehicleFor(Region tregion, string name) { if (!tregion.TheServer.Files.Exists("info/vehicles/" + name + ".fds")) { return(null); } string dat = tregion.TheServer.Files.ReadText("info/vehicles/" + name + ".fds"); FDSSection sect = new FDSSection(dat); FDSSection vehicleSect = sect.GetSection("vehicle"); string typer = vehicleSect.GetString("type"); if (string.IsNullOrWhiteSpace(typer)) { SysConsole.Output(OutputType.WARNING, "Invalid vehicle type!"); return(null); } if (typer == "plane") { string model = vehicleSect.GetString("model"); if (string.IsNullOrWhiteSpace(model)) { SysConsole.Output(OutputType.WARNING, "Invalid vehicle model!"); return(null); } PlaneEntity pe = new PlaneEntity(vehicleSect.GetString("name"), tregion, model) { SourceName = name, SourceFile = sect }; FDSSection forceSect = vehicleSect.GetSection("forces"); pe.FastStrength = forceSect.GetDouble("strong").Value; pe.RegularStrength = forceSect.GetDouble("weak").Value; pe.StrPitch = forceSect.GetDouble("pitch").Value; pe.StrRoll = forceSect.GetDouble("roll").Value; pe.StrYaw = forceSect.GetDouble("yaw").Value; pe.WheelStrength = forceSect.GetDouble("wheels").Value; pe.TurnStrength = forceSect.GetDouble("turn").Value; pe.ForwardHelper = vehicleSect.GetDouble("forwardness_helper").Value; pe.LiftHelper = vehicleSect.GetDouble("lift_helper").Value; pe.ViewBackMultiplier = vehicleSect.GetFloat("view_distance", 7).Value; pe.CenterOfMassOffset = Location.FromString(vehicleSect.GetString("center_of_mass", "0,0,0")); return(pe); } else { SysConsole.Output(OutputType.WARNING, "Invalid vehicle type: " + typer); return(null); } }
public static void TestReadInValid() { FDSSection test_section = new FDSSection(TEST_FILE); Assert.That(test_section.HasKey("my root section 1"), "Key exists!"); Assert.That(!test_section.HasKey("my root section"), "Key shouldn't exist!"); Assert.AreEqual(test_section.GetInt("my root section 1.my_sub_section.my numeric key"), 3, "Key == 3!"); Assert.AreEqual(test_section.GetDouble("my root section 1.my_sub_section.my decimal key"), 3.14159, "Key == 3.14159!"); Assert.AreEqual(test_section.GetString("my root section 1.my other section.my string key"), "alpha", "Key == alpha!"); Assert.AreEqual(StringConversionHelper.UTF8Encoding.GetString(test_section.GetData("my second root section.my binary key").Internal as byte[]), "Hello world, and all who inhabit it!", "Key string from binary check!"); List <string> list = test_section.GetStringList("my second root section.my list key"); Assert.AreEqual(list[0], "1", "Key->List yields 1!"); Assert.AreEqual(list[1], "two", "Key->List yields two!"); Assert.That(test_section.GetData("my root section 1").PrecedingComments[0].Trim() == "MyTestFile.fds", "Root comment!"); }
/// <summary> /// User command to clear their vote. /// </summary> public void CMD_ClearVote(string[] cmds, IUserMessage message) { FDSSection topicSection = GetVoteTopicSection(cmds, message, out string topicName); if (topicSection == null) { return; } List <string> choices = topicSection.GetStringList($"user_results.{message.Author.Id}"); if (choices == null) { SendGenericNegativeMessageReply(message, "Nothing To Clear", "You already do not have any vote cast to that voting topic."); return; } topicSection.Remove($"user_results.{message.Author.Id}"); DemocracyBot.Save(); SendGenericPositiveMessageReply(message, "Cleared", $"Your vote for topic `{topicName}` has been removed.\n\nFor your own reference, here is your original vote for that topic: `{string.Join(", ", choices)}`."); }
public void LoadFromSaves(FDSSection config) { string world = config.GetString("world", null); if (world != null) // TODO: && worldIsValidAndLoaded { // TODO: Set world! } if (!Enum.TryParse(config.GetString("gamemode", "SURVIVOR"), out Mode)) { SysConsole.Output(OutputType.WARNING, "Invalid gamemode for " + Name + ", reverting to SURVIVOR!"); Mode = GameMode.SURVIVOR; } base.SetMaxHealth(config.GetFloat("maxhealth", 100).Value); base.SetHealth(config.GetFloat("health", 100).Value); if (config.GetString("flying", "false").ToLowerFast() == "true") // TODO: ReadBoolean? { base.Fly(); //Network.SendPacket(new FlagEntityPacketOut(this, EntityFlag.FLYING, 1)); //Network.SendPacket(new FlagEntityPacketOut(this, EntityFlag.MASS, 0)); } else { base.Unfly(); } SetVelocity(Location.FromString(config.GetString("velocity", "0,0,0"))); SetPosition(Location.FromString(config.GetString("position", TheRegion.TheWorld.SpawnPoint.ToString()))); SecureMovement = config.GetString("secure_movement", "true").ToLowerFast() == "true"; // TODO: ReadBoolean? if (config.HasKey("permissions")) { Permissions = config.GetSection("permissions"); } if (Permissions == null) { Permissions = new FDSSection(); } EID = config.GetLong("eid").Value; IsFirstJoin = false; SpawnedTime = TheRegion.GlobalTickTime; }
public void CMD_VoteStatus(string[] cmds, IUserMessage message) { if (!DemocracyBot.IsAdmin(message.Author)) { return; } FDSSection topicSection = VotingCommands.GetVoteTopicSection(cmds, message, out string topicName); if (topicSection == null) { return; } topicName = topicName.ToLowerFast(); Console.WriteLine($"Trying get vote status for {topicName} at {StringConversionHelper.DateTimeToString(DateTimeOffset.UtcNow, true)}"); FDSSection choicesSection = topicSection.GetSection("Choices"); string realKey = DemocracyBot.VoteTopicsSection.Data.Keys.First(s => s.ToLowerFast() == topicName); RefreshTopicData(topicName, topicSection, false); FDSSection userResultsSection = topicSection.GetSection("user_results"); tallyVotes(topicSection, choicesSection, userResultsSection, message, topicName, false); }
/// <summary> /// Loads the world configuration onto this world object. /// Is called as part of the startup sequence for a world. /// </summary> public void LoadConfig() { string folder = "saves/" + Name; TheServer.Files.CreateDirectory(folder); // TODO: Journaling read string fname = folder + "/world.fds"; if (TheServer.Files.Exists(fname)) { Config = new FDSSection(TheServer.Files.ReadText(fname)); } else { Config = new FDSSection(); } Config.Set("general.IMPORTANT_NOTE", "Edit this configuration at your own risk!"); Config.Set("general.name", Name); Config.Default("general.seed", Utilities.UtilRandom.Next(SeedMax) - SeedMax / 2); Config.Default("general.spawnpoint", new Location(0, 0, 50).ToString()); Config.Default("general.time", 0); Config.Default("general.generator", "simple"); Config.Default("general.generator_scale", 1.0); Settings = new WorldSettings(); Settings.LoadFromSection(TheServer, Config); GlobalTickTime = Config.GetDouble("general.time", 0).Value; CFGEdited = true; Seed = Config.GetInt("general.seed", DefaultSeed).Value; SpawnPoint = Location.FromString(Config.GetString("general.spawnpoint", DefaultSpawnPoint)); Generator = Config.GetString("general.generator", "simple").ToLowerFast(); GeneratorScale = Config.GetDouble("general.generator_scale", 1.0).Value; MTRandom seedGen = new MTRandom(39, (ulong)Seed); Seed2 = (seedGen.Next(SeedMax) - SeedMax / 2); Seed3 = (seedGen.Next(SeedMax) - SeedMax / 2); Seed4 = (seedGen.Next(SeedMax) - SeedMax / 2); Seed5 = (seedGen.Next(SeedMax) - SeedMax / 2); SaveConfig(); }
/// <summary> /// Gets the permissions group for a name. /// </summary> /// <param name="name">The name.</param> /// <returns>The group.</returns> public PermissionsGroup GetGroup(string name) { name = FileHandler.CleanFileName(name); if (Groups.TryGetValue(name, out PermissionsGroup grp)) { return(grp); } try { if (TheServer.Files.Exists("groups/" + name + ".fds")) { string dat = TheServer.Files.ReadText("groups/" + name + ".fds"); FDSSection sect = new FDSSection(dat); grp = new PermissionsGroup() { Name = name, Root = sect }; FDSSection grpint = sect.GetSection("__group_internal__"); if (grpint != null) { string inherit = grpint.GetString("inherits"); if (inherit != null) { grp.InheritsFrom = GetGroup(inherit); } grp.Priority = grpint.GetDouble("priority", 0).Value; } Groups[name] = grp; return(grp); } } catch (Exception ex) { Utilities.CheckException(ex); SysConsole.Output("Handling permissions-group reading", ex); } return(null); }
/// <summary> /// Refreshes the topic data in the publicly visible counting post. /// </summary> public static void RefreshTopicData(string topicId, FDSSection topicSection, bool isClosed) { try { string topicTitle = topicSection.GetString("Topic"); ulong channelId = topicSection.GetUlong("channel_id").Value; ulong postId = topicSection.GetUlong("post_id").Value; Console.WriteLine($"Try refresh of {topicId} via channel {channelId} at post {postId}."); StringBuilder choicesText = new StringBuilder(100); FDSSection choicesSection = topicSection.GetSection("Choices"); foreach (string choice in choicesSection.GetRootKeys()) { choicesText.Append($"**{choice}**: `{choicesSection.GetString(choice)}`\n"); } Embed embed = GetGenericPositiveMessageEmbed($"Vote For Topic **{topicId}**: {topicTitle}", $"Choices:\n{choicesText}\nVotes cast thus far: {topicSection.GetSection("user_results").Data.Count}\n\n" + (isClosed ? "This vote is closed. Find the results below." : "DM this bot `!help` to cast your vote!")); IMessage message = (DiscordBotBaseHelper.CurrentBot.Client.GetChannel(channelId) as ITextChannel).GetMessageAsync(postId).Result; (message as IUserMessage).ModifyAsync(m => m.Embed = embed).Wait(); } catch (Exception ex) { Console.WriteLine($"Topic data refresh for {topicId} failed: {ex}"); } }
public void SaveToYAML(FDSSection config) { config.Set("gamemode", Mode.ToString()); config.Set("maxhealth", GetMaxHealth()); config.Set("health", GetHealth()); config.Set("flying", IsFlying ? "true": "false"); // TODO: Boolean safety config.Set("velocity", GetVelocity().ToString()); config.Set("position", GetPosition().ToString()); config.Set("secure_movement", SecureMovement ? "true" : "false"); // TODO: Boolean safety config.Set("world", TheRegion.TheWorld.Name); for (int i = 0; i < (int)NetUsageType.COUNT; i++) { string path = "stats.net_usage." + ((NetUsageType)i).ToString().ToLowerFast(); config.Set(path, config.GetLong(path, 0).Value + UsagesTotal[i]); } const string timePath = "stats.general.time_seconds"; config.Set(timePath, config.GetDouble(timePath, 0).Value + (TheRegion.GlobalTickTime - SpawnedTime)); config.Set("permissions", Permissions); config.Set("eid", EID); // TODO: Other stats! // TODO: CBody settings? Mass? ...? // TODO: Inventory! }
/// <summary> /// Initializes the bot object, connects, and runs the active loop. /// </summary> public void InitAndRun(string[] args) { Console.WriteLine("Preparing..."); BotMonitor = new ConnectionMonitor(this); if (File.Exists(CONFIG_FILE)) { lock (ConfigSaveLock) { ConfigFile = FDSUtility.ReadFile(CONFIG_FILE); } } PopulateFromConfig(); DefaultCommands(); Console.WriteLine("Loading Discord..."); DiscordSocketConfig config = new DiscordSocketConfig { MessageCacheSize = 256 }; //config.LogLevel = LogSeverity.Debug; Client = new DiscordSocketClient(config); /*Client.Log += (m) => * { * Console.WriteLine(m.Severity + ": " + m.Source + ": " + m.Exception + ": " + m.Message); * return Task.CompletedTask; * };*/ Client.Ready += () => { if (BotMonitor.ShouldStopAllLogic()) { return(Task.CompletedTask); } BotMonitor.ConnectedCurrently = true; Client.SetGameAsync("Type !help").Wait(); if (BotMonitor.ConnectedOnce) { return(Task.CompletedTask); } Console.WriteLine($"Args: {args.Length}"); if (args.Length > 0 && ulong.TryParse(args[0], out ulong argument1)) { ISocketMessageChannel channelToNotify = Client.GetChannel(argument1) as ISocketMessageChannel; Console.WriteLine($"Restarted as per request in channel: {channelToNotify.Name}"); channelToNotify.SendMessageAsync(embed: UserCommands.GetGenericPositiveMessageEmbed("Restarted", "Connected and ready!")).Wait(); } BotMonitor.ConnectedOnce = true; return(Task.CompletedTask); }; Client.MessageReceived += (message) => { if (BotMonitor.ShouldStopAllLogic()) { return(Task.CompletedTask); } if (message.Author.Id == Client.CurrentUser.Id) { return(Task.CompletedTask); } BotMonitor.LoopsSilent = 0; if (message.Author.IsBot || message.Author.IsWebhook) { return(Task.CompletedTask); } if (message.Channel.Name.StartsWith("@") || !(message.Channel is SocketGuildChannel sgc)) { Console.WriteLine($"Refused message from ({message.Author.Username}): (Invalid Channel: {message.Channel.Name}): {message.Content}"); return(Task.CompletedTask); } if (ValidChannels.Count != 0 && !ValidChannels.Contains(message.Channel.Id)) { Console.WriteLine($"Refused message from ({message.Author.Username}): (Non-whitelisted Channel: {message.Channel.Name}): {message.Content}"); return(Task.CompletedTask); } bool mentionedMe = message.MentionedUsers.Any((su) => su.Id == Client.CurrentUser.Id); Console.WriteLine($"Parsing message from ({message.Author.Username}), in channel: {message.Channel.Name}: {message.Content}"); if (mentionedMe || message.Content.StartsWith(Constants.COMMAND_PREFIX)) { try { Respond(message, mentionedMe); } catch (Exception ex) { if (ex is ThreadAbortException) { throw; } Console.WriteLine($"Error handling command: {ex.ToString()}"); } } return(Task.CompletedTask); }; Console.WriteLine("Logging in to Discord..."); Client.LoginAsync(TokenType.Bot, TOKEN).Wait(); Console.WriteLine("Connecting to Discord..."); Client.StartAsync().Wait(); Console.WriteLine("Running Discord!"); Console.WriteLine("Starting monitor..."); BotMonitor.StartMonitorLoop(); StoppedEvent.WaitOne(); }
/// <summary> /// Fills fields with data from the config file. /// </summary> public void PopulateFromConfig() { ValidChannels.Clear(); Constants.DOCS_URL_BASE = ConfigFile.GetString("url_base"); Constants.COMMAND_PREFIX = ConfigFile.GetString("command_prefix"); foreach (string channel in ConfigFile.GetStringList("valid_channels")) { ValidChannels.Add(ulong.Parse(channel.Trim())); } FDSSection infoSection = ConfigFile.GetSection("info_replies"); foreach (string key in infoSection.GetRootKeys()) { string infoValue = infoSection.GetRootData(key).AsString; string[] keysSplit = key.SplitFast(','); InformationalDataNames.Add(keysSplit[0]); foreach (string name in keysSplit) { InformationalData[name.Trim()] = infoValue; } } FDSSection projectDetailsSection = ConfigFile.GetSection("project_details"); foreach (string key in projectDetailsSection.GetRootKeys()) { FDSSection detailsSection = projectDetailsSection.GetSection(key); ProjectDetails detail = new ProjectDetails { Name = key, Icon = detailsSection.GetString("icon", ""), GitHub = detailsSection.GetString("github", ""), UpdateMessage = detailsSection.GetString("update", "") }; ProjectToDetails.Add(key.ToLowerFast(), detail); } FDSSection channelDetailsSection = ConfigFile.GetSection("channel_details"); foreach (string key in channelDetailsSection.GetRootKeys()) { FDSSection detailsSection = channelDetailsSection.GetSection(key); ChannelDetails detail = new ChannelDetails(); List <ProjectDetails> projects = new List <ProjectDetails>(); foreach (string projName in detailsSection.GetString("updates", "").Split(' ', StringSplitOptions.RemoveEmptyEntries)) { projects.Add(ProjectToDetails[projName]); } detail.Updates = projects.ToArray(); detail.Docs = detailsSection.GetBool("docs", false).Value; ChannelToDetails.Add(ulong.Parse(key), detail); } FDSSection rulesSection = ConfigFile.GetSection("rules"); foreach (string rule in rulesSection.GetRootKeys()) { Rules.Add(rule, rulesSection.GetString(rule)); } FDSSection buildNumbersSection = ConfigFile.GetSection("build_numbers"); foreach (string projectName in buildNumbersSection.GetRootKeys()) { FDSSection project = buildNumbersSection.GetSection(projectName); BuildNumberTracker.AddTracker(project.GetString("name"), project.GetString("regex"), project.GetString("jenkins_job")); } }
public void InitPlayer() { // TODO: Convert all these to item files! Items.GiveItem(new ItemStack("open_hand", TheServer, 1, "items/common/open_hand_ico", "Open Hand", "Grab things!", Color.White, "items/common/hand", true, 0)); Items.GiveItem(new ItemStack("fist", TheServer, 1, "items/common/fist_ico", "Fist", "Hit things!", Color.White, "items/common/fist", true, 0)); Items.GiveItem(new ItemStack("hook", TheServer, 1, "items/common/hook_ico", "Grappling Hook", "Grab distant things!", Color.White, "items/common/hook", true, 0)); Items.GiveItem(TheServer.Items.GetItem("admintools/manipulator", 1)); Items.GiveItem(new ItemStack("pickaxe", TheServer, 1, "render_model:self", "Generic Pickaxe", "Rapid stone mining!", Color.White, "items/tools/generic_pickaxe", false, 0)); Items.GiveItem(new ItemStack("flashlight", TheServer, 1, "items/common/flashlight_ico", "Flashlight", "Lights things up!", Color.White, "items/common/flashlight", false, 0)); Items.GiveItem(new ItemStack("flashantilight", TheServer, 1, "items/common/flashlight_ico", "Flashantilight", "Lights things down!", Color.White, "items/common/flashlight", false, 0)); Items.GiveItem(new ItemStack("sun_angler", TheServer, 1, "items/tools/sun_angler", "Sun Angler", "Moves the sun itself!", Color.White, "items/tools/sun_angler", false, 0)); Items.GiveItem(new ItemStack("breadcrumb", TheServer, 1, "items/common/breadcrumbs", "Bread Crumbs", "Finds the way back, even over the river and through the woods!", Color.White, "items/common/breadcrumbs", false, 0)); for (int i = 1; i < MaterialHelpers.ALL_MATS.Count; i++) { if (MaterialHelpers.IsValid((Material)i)) { Items.GiveItem(TheServer.Items.GetItem("blocks/" + ((Material)i).GetName().ToLowerFast(), 100)); } } Items.GiveItem(new ItemStack("pistol_gun", TheServer, 1, "render_model:self", "9mm Pistol", "It shoots bullets!", Color.White, "items/weapons/silenced_pistol", false, 0)); Items.GiveItem(new ItemStack("shotgun_gun", TheServer, 1, "items/weapons/shotgun_ico", "Shotgun", "It shoots many bullets!", Color.White, "items/weapons/shotgun", false, 0)); Items.GiveItem(new ItemStack("bow", TheServer, 1, "items/weapons/bow_ico", "Bow", "It shoots arrows!", Color.White, "items/weapons/bow", false, 0)); Items.GiveItem(new ItemStack("explodobow", TheServer, 1, "items/weapons/explodobow_ico", "ExplodoBow", "It shoots arrows that go boom!", Color.White, "items/weapons/explodo_bow", false, 0)); Items.GiveItem(new ItemStack("hatcannon", TheServer, 1, "items/weapons/hatcannon_ico", "Hat Cannon", "It shoots hats!", Color.White, "items/weapons/hat_cannon", false, 0)); Items.GiveItem(TheServer.Items.GetItem("weapons/rifles/m4")); Items.GiveItem(TheServer.Items.GetItem("weapons/rifles/minigun")); Items.GiveItem(new ItemStack("suctionray", TheServer, 1, "items/tools/suctionray_ico", "Suction Ray", "Sucks things towards you!", Color.White, "items/tools/suctionray", false, 0)); Items.GiveItem(new ItemStack("pushray", TheServer, 1, "items/tools/pushray_ico", "Push Ray", "Pushes things away from you!", Color.White, "items/tools/pushray", false, 0)); Items.GiveItem(new ItemStack("bullet", "9mm_ammo", TheServer, 100, "items/weapons/ammo/9mm_round_ico", "9mm Ammo", "Nine whole millimeters!", Color.White, "items/weapons/ammo/9mm_round", false, 0)); Items.GiveItem(new ItemStack("bullet", "shotgun_ammo", TheServer, 100, "items/weapons/ammo/shotgun_shell_ico", "Shotgun Ammo", "Always travels in packs!", Color.White, "items/weapons/ammo/shotgun_shell", false, 0)); Items.GiveItem(new ItemStack("bullet", "rifle_ammo", TheServer, 1000, "items/weapons/ammo/rifle_round_ico", "Assault Rifle Ammo", "Very rapid!", Color.White, "items/weapons/ammo/rifle_round", false, 0)); Items.GiveItem(new ItemStack("glowstick", TheServer, 10, "items/common/glowstick_ico", "Glowstick", "Pretty colors!", Color.Cyan, "items/common/glowstick", false, 0)); Items.GiveItem(TheServer.Items.GetItem("weapons/grenades/smoke", 10)); Items.GiveItem(TheServer.Items.GetItem("weapons/grenades/smokesignal", 10)); Items.GiveItem(TheServer.Items.GetItem("weapons/grenades/explosivegrenade", 10)); Items.GiveItem(new ItemStack("smokemachine", TheServer, 10, "items/common/smokemachine_ico", "Smoke Machine", "Do not inhale!", Color.White, "items/common/smokemachine", false, 0)); Items.GiveItem(TheServer.Items.GetItem("special/parachute", 1)); Items.GiveItem(TheServer.Items.GetItem("special/jetpack", 1)); Items.GiveItem(TheServer.Items.GetItem("useful/fuel", 100)); Items.GiveItem(TheServer.Items.GetItem("special/wings", 1)); CGroup = CollisionUtil.Player; string nl = Name.ToLower(); string fn = "server_player_saves/" + nl[0].ToString() + "/" + nl + ".plr"; if (TheServer.Files.Exists(fn)) { // TODO: Journaling read // TODO: Use ServerBase.GetPlayerConfig() ? string dat = TheServer.Files.ReadText(fn); if (dat != null) { PlayerConfig = new FDSSection(dat); LoadFromSaves(PlayerConfig); } } if (PlayerConfig == null) { PlayerConfig = new FDSSection(); SaveToYAML(PlayerConfig); } }
/// <summary> /// Admin command to start a new vote. /// </summary> public void CMD_CallVote(string[] cmds, IUserMessage message) { if (!DemocracyBot.IsAdmin(message.Author)) { return; } if (message.Channel is IPrivateChannel) { SendErrorMessageReply(message, "Wrong Location", "Votes cannot be called from a private message."); return; } if (cmds.Length < 4) { SendErrorMessageReply(message, "Invalid Input", "Input does not look like it can possibly be valid. Use `!help` for usage information."); return; } string topicId = cmds[0].Replace("`", "").Trim(); if (DemocracyBot.VoteTopicsSection.HasRootKeyLowered(topicId)) { SendErrorMessageReply(message, "Topic Already Present", "That voting topic ID already exists. Pick a new one!"); return; } StringBuilder topicTitle = new StringBuilder(100); topicTitle.Append(cmds[1].Replace("`", "")); int argId; for (argId = 2; argId < cmds.Length; argId++) { string arg = cmds[argId].Replace("`", ""); if (arg.Trim() == "|") { break; } topicTitle.Append(" ").Append(cmds[argId]); } List <string> choices = new List <string>(cmds.Length); StringBuilder currentChoice = new StringBuilder(100); for (argId++; argId < cmds.Length; argId++) { string arg = cmds[argId].Replace("`", ""); if (arg.Trim() == "|") { choices.Add(currentChoice.ToString().Trim()); currentChoice.Clear(); continue; } currentChoice.Append(" ").Append(cmds[argId]); } choices.Add(currentChoice.ToString().Trim()); for (int i = 0; i < choices.Count; i++) { if (string.IsNullOrWhiteSpace(choices[i])) { choices.RemoveAt(i--); } } if (choices.IsEmpty()) { SendErrorMessageReply(message, "Invalid Input", "No choices found."); return; } if (choices.Count == 1) { SendErrorMessageReply(message, "Insufficient Democracy", "Only 1 choice detected. Need at least 2."); return; } FDSSection newTopicSection = new FDSSection(); newTopicSection.SetRoot("Topic", topicTitle.ToString()); FDSSection choiceSection = new FDSSection(); for (int i = 0; i < choices.Count; i++) { choiceSection.Set((i + 1).ToString(), choices[i]); } IUserMessage sentMessage = message.Channel.SendMessageAsync(embed: GetGenericPositiveMessageEmbed("Vote In Progress", "New Vote... Data inbound, please wait!")).Result; newTopicSection.SetRoot("channel_id", sentMessage.Channel.Id); newTopicSection.SetRoot("post_id", sentMessage.Id); newTopicSection.SetRoot("Choices", choiceSection); newTopicSection.SetRoot("user_results", new FDSSection()); DemocracyBot.VoteTopicsSection.SetRoot(topicId, newTopicSection); DemocracyBot.Save(); RefreshTopicData(topicId, newTopicSection, false); }
private void tallyVotes(FDSSection topicSection, FDSSection choicesSection, FDSSection userResultsSection, IUserMessage message, string topicName, Boolean commitChanges) { if (userResultsSection == null || userResultsSection.GetRootKeys().IsEmpty()) { SendGenericNegativeMessageReply(message, $"Vote For Topic {topicName} Failed", "No votes were cast."); if (commitChanges) { DemocracyBot.Save(); } return; } List <List <string> > voteSets = new List <List <string> >(50); foreach (string userId in userResultsSection.GetRootKeys()) { List <string> choices = userResultsSection.GetStringList(userId); if (choices != null && !choices.IsEmpty() && !(choices.Count == 1 && choices[0] == "none")) { voteSets.Add(choices); } } if (voteSets.IsEmpty()) { SendGenericNegativeMessageReply(message, $"Vote For Topic {topicName} Failed", "No votes were cast."); if (commitChanges) { DemocracyBot.Save(); } return; } int usersWhoVotedTotal = voteSets.Count; int discards = 0; string gatherStats(string choice, string type, List <List <string> > placeVoteSets) { int numberHadFirst = 0; int positionTotal = 0; int numberHadAtAll = 0; foreach (string userId in userResultsSection.GetRootKeys()) { List <string> choices = userResultsSection.GetStringList(userId); if (choices != null && !choices.IsEmpty()) { int index = choices.IndexOf(choice); if (index != -1) { numberHadAtAll++; positionTotal += index + 1; if (index == 0) { numberHadFirst++; } } } } return($"Options that were discarded due to low support: {discards}\n" + $"Users whose votes were discarded due to supporting only unpopular options: {usersWhoVotedTotal - placeVoteSets.Count}\nUsers who listed the {type} first: {numberHadFirst}\n" + $"Users who listed the {type} at all: {numberHadAtAll}\nAverage ranking of the {type}: {positionTotal / (float)numberHadAtAll:0.0}"); } Tuple <string, string> firstTuple = getRankWinner(voteSets.ConvertAll(new Converter <List <string>, List <string> >(x => x.ConvertAll(new Converter <string, string>(y => y.ToString()))))); Tuple <string, string> secondTuple = getRankWinner(voteSets.ConvertAll(new Converter <List <string>, List <string> >(x => x.ConvertAll(new Converter <string, string>(y => y.ToString()))))); Tuple <string, string> thirdTuple = getRankWinner(voteSets.ConvertAll(new Converter <List <string>, List <string> >(x => x.ConvertAll(new Converter <string, string>(y => y.ToString()))))); Tuple <string, string> fourthTuple = getRankWinner(voteSets.ConvertAll(new Converter <List <string>, List <string> >(x => x.ConvertAll(new Converter <string, string>(y => y.ToString()))))); Tuple <string, string> fifthTuple = getRankWinner(voteSets.ConvertAll(new Converter <List <string>, List <string> >(x => x.ConvertAll(new Converter <string, string>(y => y.ToString()))))); Tuple <string, string> sixthTuple = getRankWinner(voteSets.ConvertAll(new Converter <List <string>, List <string> >(x => x.ConvertAll(new Converter <string, string>(y => y.ToString()))))); Tuple <string, string> getRankWinner(List <List <string> > placeVoteSets) { string topRank = ""; string topRankStats = ""; bool haveWinner = false; Dictionary <string, int> votesTracker = new Dictionary <string, int>(128); Dictionary <string, int> totalVotesTracker = new Dictionary <string, int>(); discards = 0; foreach (List <string> voteSet in placeVoteSets) { foreach (string singleVote in voteSet) { if (!totalVotesTracker.TryGetValue(singleVote, out int singleVoteCount)) { singleVoteCount = 0; } totalVotesTracker[singleVote] = singleVoteCount + 1; } } while (true) { votesTracker.Clear(); foreach (List <string> voteSet in placeVoteSets) { string vote = voteSet[0]; //Only checking highest vote right now if (!votesTracker.TryGetValue(vote, out int count)) { count = 0; } votesTracker[vote] = count + 1; } if (votesTracker.Count == 0) { Console.WriteLine("Something went funky in vote counting... tracker is empty without a clear winner!"); break; } string best = placeVoteSets[0][0]; List <string> worstList = new List <string>();// placeVoteSets[0][0]; int bestCount = 0, worstCount = int.MaxValue; foreach (KeyValuePair <string, int> voteResult in votesTracker) { if (voteResult.Value > bestCount) { best = voteResult.Key; bestCount = voteResult.Value; } if (voteResult.Value < worstCount) { worstList = new List <string>() { voteResult.Key }; worstCount = voteResult.Value; } else if (voteResult.Value == worstCount) { worstList.Add(voteResult.Key); } } if (bestCount * 2 > placeVoteSets.Count) { if (!haveWinner) { topRank = best; topRankStats = gatherStats(topRank, "winner", placeVoteSets); haveWinner = true; for (int i = 0; i < voteSets.Count; i++) { if (voteSets[i].Contains(topRank)) { voteSets[i].Remove(topRank); if (voteSets[i].IsEmpty()) { voteSets.RemoveAt(i--); } } } break; } } string worst = totalVotesTracker.Where(x => worstList.Contains(x.Key)).Aggregate((l, r) => l.Value < r.Value ? l : r).Key; for (int i = 0; i < placeVoteSets.Count; i++) { for (int j = 0; j < placeVoteSets[i].Count; j++) { if (placeVoteSets[i][j] == worst) { placeVoteSets[i].RemoveAt(j); } } } for (int i = 0; i < placeVoteSets.Count; i++) { if (placeVoteSets[i].IsEmpty()) { placeVoteSets.RemoveAt(i); i--; } } if (!haveWinner) { discards++; } } return(new Tuple <string, string>(topRank, topRankStats)); } SendGenericPositiveMessageReply(message, $"Vote Results For **{topicName}: {topicSection.GetString("Topic")}**", $"**__Winner__**: **{firstTuple.Item1}**: `{choicesSection.GetString(firstTuple.Item1)}`" + $"\n\n**Stats:**\nUsers who voted, in total: {usersWhoVotedTotal}\n{firstTuple.Item2}\n\n" + $"**__Runner Up__**: **{secondTuple.Item1}**: `{choicesSection.GetString(secondTuple.Item1)}`\n**Stats For Runner Up**:\n{secondTuple.Item2}\n\n" + $"**__Thrid Place__**: **{thirdTuple.Item1}**: `{choicesSection.GetString(thirdTuple.Item1)}`\n**Stats For Third Place**:\n{thirdTuple.Item2}\n\n" + $"**__Fourth Place__**: **{fourthTuple.Item1}**: `{choicesSection.GetString(fourthTuple.Item1)}`\n**Stats For Fourth Place**:\n{fourthTuple.Item2}\n\n" + $"**__Fifth Place__**: **{fifthTuple.Item1}**: `{choicesSection.GetString(fifthTuple.Item1)}`\n**Stats For Fifth Place**:\n{fifthTuple.Item2}\n\n" + $"**__Sixth Place__**: **{sixthTuple.Item1}**: `{choicesSection.GetString(sixthTuple.Item1)}`\n**Stats For Sixth Place**:\n{sixthTuple.Item2}" ); if (commitChanges) { DemocracyBot.Save(); } }
/// <summary> /// Fills fields with data from the config file. /// </summary> public void PopulateFromConfig(FDSSection configFile) { ValidChannels.Clear(); InformationalData.Clear(); InformationalDataNames.Clear(); ChannelToDetails.Clear(); ProjectToDetails.Clear(); Rules.Clear(); AcceptableServerVersions.Clear(); BuildNumberTracker.Clear(); DenizenMetaBotConstants.DOCS_URL_BASE = configFile.GetString("url_base"); DenizenMetaBotConstants.COMMAND_PREFIX = configFile.GetString("command_prefix"); DiscordBotBaseHelper.CurrentBot.ClientConfig.CommandPrefix = DenizenMetaBotConstants.COMMAND_PREFIX; if (configFile.HasKey("valid_channels")) { foreach (string channel in configFile.GetStringList("valid_channels")) { ValidChannels.Add(ulong.Parse(channel.Trim())); } } if (configFile.HasKey("info_replies")) { FDSSection infoSection = configFile.GetSection("info_replies"); foreach (string key in infoSection.GetRootKeys()) { string infoValue = infoSection.GetRootData(key).AsString; string[] keysSplit = key.SplitFast(','); InformationalDataNames.Add(keysSplit[0]); foreach (string name in keysSplit) { InformationalData[name.Trim()] = infoValue; } } } if (configFile.HasKey("project_details")) { FDSSection projectDetailsSection = configFile.GetSection("project_details"); foreach (string key in projectDetailsSection.GetRootKeys()) { FDSSection detailsSection = projectDetailsSection.GetSection(key); ProjectDetails detail = new ProjectDetails { Name = key, Icon = detailsSection.GetString("icon", ""), GitHub = detailsSection.GetString("github", ""), UpdateMessage = detailsSection.GetString("update", "") }; ProjectToDetails.Add(key.ToLowerFast(), detail); } } if (configFile.HasKey("channel_details")) { FDSSection channelDetailsSection = configFile.GetSection("channel_details"); foreach (string key in channelDetailsSection.GetRootKeys()) { FDSSection detailsSection = channelDetailsSection.GetSection(key); ChannelDetails detail = new ChannelDetails(); List <ProjectDetails> projects = new List <ProjectDetails>(); foreach (string projName in detailsSection.GetString("updates", "").Split(' ', StringSplitOptions.RemoveEmptyEntries)) { projects.Add(ProjectToDetails[projName]); } detail.Updates = projects.ToArray(); detail.Docs = detailsSection.GetBool("docs", false).Value; ChannelToDetails.Add(ulong.Parse(key), detail); } } if (configFile.HasKey("rules")) { FDSSection rulesSection = configFile.GetSection("rules"); foreach (string rule in rulesSection.GetRootKeys()) { Rules.Add(rule, rulesSection.GetString(rule)); } } if (configFile.HasKey("build_numbers")) { FDSSection buildNumbersSection = configFile.GetSection("build_numbers"); foreach (string projectName in buildNumbersSection.GetRootKeys()) { FDSSection project = buildNumbersSection.GetSection(projectName); BuildNumberTracker.AddTracker(project.GetString("name"), project.GetString("regex"), project.GetString("jenkins_job")); } } if (configFile.HasKey("acceptable_server_versions")) { AcceptableServerVersions = configFile.GetStringList("acceptable_server_versions"); foreach (string version in AcceptableServerVersions) { double versionNumber = double.Parse(version); if (LowestServerVersion <= 0.01 || versionNumber < LowestServerVersion) { LowestServerVersion = versionNumber; } if (versionNumber > HighestServerVersion) { HighestServerVersion = versionNumber; } BuildNumberTracker.AddPaperTracker(version); } } BuildNumberTracker.LoadSpigotData(); if (File.Exists(DiscordBot.CONFIG_FOLDER + "quotes.txt")) { Quotes = File.ReadAllText(DiscordBot.CONFIG_FOLDER + "quotes.txt").Replace("\r", "").Replace('`', '\'').Split("\n\n", StringSplitOptions.RemoveEmptyEntries); QuotesLower = Quotes.Select(s => s.ToLowerFast()).ToArray(); } }
public ServerSettings(Server tserver, FDSSection sect) { TheServer = tserver; Section = sect; Reload(); }
public FDSSection GetPlayerConfig(string username) { if (username.Length == 0) { return null; } lock (TickLock) { PlayerEntity pl = GetPlayerFor(username); if (pl != null) { return pl.PlayerConfig; } FDSSection PlayerConfig = null; string nl = username.ToLower(); // TODO: Journaling read string fn = "server_player_saves/" + nl[0].ToString() + "/" + nl + ".plr"; if (Files.Exists(fn)) { string dat = Files.ReadText(fn); if (dat != null) { PlayerConfig = new FDSSection(dat); } } return PlayerConfig; } }
/// <summary> /// Start up and run the server. /// </summary> public void StartUp(Action loaded = null) { CurThread = Thread.CurrentThread; SysConsole.Written += OnConsoleWritten; SysConsole.Output(OutputType.INIT, "Launching as new server, this is " + (this == Central ? "" : "NOT ") + "the Central server."); SysConsole.Output(OutputType.INIT, "Loading console input handler..."); ConsoleHandler.Init(); ConsoleHandler.OnCommandInput += CommandInputHandle; SysConsole.Output(OutputType.INIT, "Loading command engine..."); Commands = new ServerCommands(); Commands.Init(new ServerOutputter(this), this); SysConsole.Output(OutputType.INIT, "Loading CVar engine..."); CVars = new ServerCVar(); CVars.Init(this, Commands.Output); SysConsole.Output(OutputType.INIT, "Loading default settings..."); Config = new FDSSection(Files.ReadText("server_config.fds")); if (Files.Exists("serverdefaultsettings.cfg")) { string contents = Files.ReadText("serverdefaultsettings.cfg"); Commands.ExecuteCommands(contents); } if (Files.Exists("server_eid.txt")) { cID = long.Parse(Files.ReadText("server_eid.txt") ?? "1"); } SysConsole.Output(OutputType.INIT, "Loading player command engine..."); PCEngine = new PlayerCommandEngine(); SysConsole.Output(OutputType.INIT, "Loading item registry..."); ItemInfos = new ItemInfoRegistry(); Items = new ItemRegistry(this); Recipes = new RecipeRegistry() { TheServer = this }; SysConsole.Output(OutputType.INIT, "Loading model handler..."); Models = new ModelEngine(this); SysConsole.Output(OutputType.INIT, "Loading animation handler..."); Animations = new AnimationEngine(); SysConsole.Output(OutputType.INIT, "Preparing networking..."); Networking = new NetworkBase(this); Networking.Init(); SysConsole.Output(OutputType.INIT, "Loading plugins..."); Plugins = new PluginManager(this); Plugins.Init(); SysConsole.Output(OutputType.INIT, "Loading scripts..."); AutorunScripts(); SysConsole.Output(OutputType.INIT, "Building initial world(s)..."); foreach (string str in Config.GetStringList("server.worlds") ?? new List<string>()) { LoadWorld(str.ToLowerFast()); } SysConsole.Output(OutputType.INIT, "Preparing block image system..."); BlockImages = new BlockImageManager(); BlockImages.Init(this); if (loaded != null) { loaded.Invoke(); } SysConsole.Output(OutputType.INIT, "Ticking..."); // Tick double TARGETFPS = 30d; Stopwatch Counter = new Stopwatch(); Stopwatch DeltaCounter = new Stopwatch(); DeltaCounter.Start(); double TotalDelta = 0; double CurrentDelta = 0d; double TargetDelta = 0d; int targettime = 0; try { while (true) { // Update the tick time usage counter Counter.Reset(); Counter.Start(); // Update the tick delta counter DeltaCounter.Stop(); // Delta time = Elapsed ticks * (ticks/second) CurrentDelta = ((double)DeltaCounter.ElapsedTicks) / ((double)Stopwatch.Frequency); // Begin the delta counter to find out how much time is /really/ slept+ticked for DeltaCounter.Reset(); DeltaCounter.Start(); // How much time should pass between each tick ideally TARGETFPS = CVars.g_fps.ValueD; if (TARGETFPS < 1 || TARGETFPS > 600) { CVars.g_fps.Set("30"); TARGETFPS = 30; } TargetDelta = (1d / TARGETFPS); // How much delta has been built up TotalDelta += CurrentDelta; while (TotalDelta > TargetDelta * 3) { // Lagging - cheat to catch up! TargetDelta *= 2; } // As long as there's more delta built up than delta wanted, tick while (TotalDelta > TargetDelta) { if (NeedShutdown) { CurThread = Thread.CurrentThread; ShutDown(shutdownCallback); return; } lock (TickLock) { Tick(TargetDelta); } TotalDelta -= TargetDelta; } // The tick is done, stop measuring it Counter.Stop(); // Only sleep for target milliseconds/tick minus how long the tick took... this is imprecise but that's okay targettime = (int)((1000d / TARGETFPS) - Counter.ElapsedMilliseconds); // Only sleep at all if we're not lagging if (targettime > 0) { // Try to sleep for the target time - very imprecise, thus we deal with precision inside the tick code Thread.Sleep(targettime); } } } catch (ThreadAbortException) { return; } }