예제 #1
0
        public static void Run(SCPDiscord pl)
        {
            plugin = pl;
            while (!Config.ready || !Language.ready)
            {
                Thread.Sleep(1000);
            }

            while (!plugin.shutdown)
            {
                try
                {
                    if (IsConnected())
                    {
                        Update();
                    }
                    else
                    {
                        Connect();
                    }
                    Thread.Sleep(1000);
                }
                catch (Exception e)
                {
                    plugin.Error("Network error caught, if this happens a lot try using the 'scpd_rc' command." + e);
                }
            }
        }
예제 #2
0
        public override void OnEnable()
        {
            plugin = this;

            serverStartTime.Start();
            AddCommand("scpd_rc", new ReconnectCommand());
            AddCommand("scpd_reconnect", new ReconnectCommand());
            AddCommand("scpd_reload", new ReloadCommand());
            AddCommand("scpd_unsync", new UnsyncCommand());
            AddCommand("scpd_verbose", new VerboseCommand());
            AddCommand("scpd_debug", new DebugCommand());
            AddCommand("scpd_validate", new ValidateCommand());
            AddCommand("scpd_grs", new GrantReservedSlotCommand());
            AddCommand("scpd_rrs", new RemoveReservedSlotCommand());
            AddCommand("scpd_grantreservedslot", new GrantReservedSlotCommand());
            AddCommand("scpd_removereservedslot", new RemoveReservedSlotCommand());
            AddCommand("scpd_gvr", new GrantVanillaRankCommand());
            AddCommand("scpd_grantvanillarank", new GrantVanillaRankCommand());

            SetUpFileSystem();
            this.roleSync = new RoleSync(this);
            LoadConfig();
            if (this.Server.Port == Config.GetInt("bot.port"))
            {
                this.Error("ERROR: Server is running on the same port as the plugin, aborting...");
                this.Disable();
            }
            Language.Reload();

            new Thread(() => new StartNetworkSystem(plugin)).Start();

            GetMaxPlayers();
            Info("SCPDiscord " + this.Details.version + " enabled.");
        }
예제 #3
0
        public static void Run(SCPDiscord plugin)
        {
            topicUpdateTimer = Stopwatch.StartNew();
            topicUpdateTimer.Start();
            NetworkSystem.plugin = plugin;
            while (!Config.ready || !Language.ready)
            {
                Thread.Sleep(1000);
            }

            Thread messageThread = new Thread(new ThreadStart(() => new BotListener(plugin)));

            messageThread.Start();

            while (!plugin.shutdown)
            {
                try
                {
                    if (IsConnected())
                    {
                        Update(plugin);
                    }
                    else
                    {
                        Connect(Config.GetString("bot.ip"), Config.GetInt("bot.port"));
                    }
                    Thread.Sleep(1000);
                }
                catch (Exception e)
                {
                    plugin.Error("Network error caught, if this happens a lot try using the 'scpd_rc' command." + e);
                }
            }
        }
예제 #4
0
        public static void Run(SCPDiscord pl)
        {
            plugin           = pl;
            topicUpdateTimer = Stopwatch.StartNew();
            topicUpdateTimer.Start();
            while (!Config.ready || !Language.ready)
            {
                Thread.Sleep(1000);
            }

            // ReSharper disable once ObjectCreationAsStatement
            Thread messageThread = new Thread(() => new BotListener(plugin));

            messageThread.Start();

            while (!plugin.shutdown)
            {
                try
                {
                    if (IsConnected())
                    {
                        Update();
                    }
                    else
                    {
                        Connect();
                    }
                    Thread.Sleep(1000);
                }
                catch (Exception e)
                {
                    plugin.Error("Network error caught, if this happens a lot try using the 'scpd_rc' command." + e);
                }
            }
        }
예제 #5
0
        public override void OnEnable()
        {
            plugin = this;

            serverStartTime.Start();
            this.AddCommand("scpd_rc", new ReconnectCommand(this));
            this.AddCommand("scpd_reconnect", new ReconnectCommand(this));
            this.AddCommand("scpd_reload", new ReloadCommand(this));
            this.AddCommand("scpd_unsync", new UnsyncCommand(this));
            this.AddCommand("scpd_verbose", new VerboseCommand(this));
            this.AddCommand("scpd_debug", new DebugCommand(this));

            Task.Run(async() =>
            {
                await Task.Delay(4000);
                SetUpFileSystem();
                LoadConfig();
                roleSync = new RoleSync(this);

                Language.Reload();
                Thread connectionThread = new Thread(new ThreadStart(() => new StartNetworkSystem(plugin)));
                connectionThread.Start();
                this.Info("SCPDiscord " + this.Details.version + " enabled.");
            });
        }
예제 #6
0
        public override void OnEnable()
        {
            plugin = this;

            serverStartTime.Start();
            AddCommand("scpd_rc", new ReconnectCommand());
            AddCommand("scpd_reconnect", new ReconnectCommand());
            AddCommand("scpd_reload", new ReloadCommand());
            AddCommand("scpd_unsync", new UnsyncCommand());
            AddCommand("scpd_verbose", new VerboseCommand());
            AddCommand("scpd_debug", new DebugCommand());
            AddCommand("scpd_validate", new ValidateCommand());
            AddCommand("scpd_grs", new GrantReservedSlotCommand());
            AddCommand("scpd_rrs", new RemoveReservedSlotCommand());
            AddCommand("scpd_grantreservedslot", new ValidateCommand());
            AddCommand("scpd_removereservedslot", new RemoveReservedSlotCommand());
            AddCommand("scpd_gvr", new GrantVanillaRankCommand());
            AddCommand("scpd_grantvanillarank", new GrantVanillaRankCommand());

            SetUpFileSystem();
            this.roleSync = new RoleSync(this);
            LoadConfig();
            Language.Reload();

            // ReSharper disable once ObjectCreationAsStatement
            new Thread(() => new StartNetworkSystem(plugin)).Start();

            this.maxPlayers = GetConfigInt("max_players");
            Info("SCPDiscord " + this.Details.version + " enabled.");
        }
예제 #7
0
파일: Config.cs 프로젝트: SandeQ/SCPDiscord
        public static void ValidateConfig(SCPDiscord plugin)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("||||||||||||| SCPDiscord config validator ||||||||||||||\n");
            sb.Append("------------ Config strings ------------\n");
            foreach (KeyValuePair <string, string> node in configStrings)
            {
                sb.Append(node.Key + ": " + node.Value + "\n");
            }

            sb.Append("------------ Config ints ------------\n");
            foreach (KeyValuePair <string, bool> node in configBools)
            {
                sb.Append(node.Key + ": " + node.Value + "\n");
            }

            sb.Append("------------ Config bools ------------\n");
            foreach (KeyValuePair <string, bool> node in configBools)
            {
                sb.Append(node.Key + ": " + node.Value + "\n");
            }

            sb.Append("------------ Config arrays ------------\n");
            foreach (KeyValuePair <string, string[]> node in configArrays)
            {
                sb.Append(node.Key + ": [ " + string.Join(", ", node.Value) + " ]\n");
                if (node.Key.StartsWith("channels."))
                {
                    foreach (string s in node.Value)
                    {
                        if (!GetDict("aliases").ContainsKey(s))
                        {
                            sb.Append("WARNING: Channel alias '" + s + "' does not exist!\n");
                        }
                    }
                }
            }

            sb.Append("------------ Config dictionaries ------------\n");
            foreach (KeyValuePair <string, Dictionary <string, string> > node in configDicts)
            {
                sb.Append(node.Key + ":\n");
                foreach (KeyValuePair <string, string> subNode in node.Value)
                {
                    if (!Regex.IsMatch(subNode.Value, @"^\d+$"))
                    {
                        sb.Append("WARNING: Invalid channel ID: " + subNode.Value + "!\n");
                    }
                    sb.Append("    " + subNode.Key + ": " + subNode.Value + "\n");
                }
            }
            sb.Append("|||||||||||||||||||||||||||||||||||||||||||||||||||||||");
            plugin.Info(sb.ToString());
        }
예제 #8
0
        public override void OnEnabled()
        {
            base.OnEnabled();

            if (!Config.IsEnabled)
            {
                return;
            }

            instance = this;
            ev       = new EventHandlers();

            Exiled.Events.Handlers.Server.WaitingForPlayers         += ev.OnWaitingForPlayers;
            Exiled.Events.Handlers.Server.SendingRemoteAdminCommand += ev.OnRACommand;
            Exiled.Events.Handlers.Server.SendingConsoleCommand     += ev.OnConsoleCommand;
            Exiled.Events.Handlers.Server.RoundStarted    += ev.OnRoundStart;
            Exiled.Events.Handlers.Server.RoundEnded      += ev.OnRoundEnd;
            Exiled.Events.Handlers.Server.RestartingRound += ev.OnRoundRestart;
            Exiled.Events.Handlers.Server.RespawningTeam  += ev.OnTeamRespawn;

            Exiled.Events.Handlers.Map.Decontaminating += ev.OnDecontamination;

            Exiled.Events.Handlers.Player.Joined                  += ev.OnPlayerJoin;
            Exiled.Events.Handlers.Player.ChangingRole            += ev.OnSetClass;
            Exiled.Events.Handlers.Player.DroppingItem            += ev.OnDropItem;
            Exiled.Events.Handlers.Player.PickingUpItem           += ev.OnPickupItem;
            Exiled.Events.Handlers.Player.Left                    += ev.OnPlayerLeave;
            Exiled.Events.Handlers.Player.Hurting                 += ev.OnPlayerHurt;
            Exiled.Events.Handlers.Player.Died                    += ev.OnPlayerDeath;
            Exiled.Events.Handlers.Player.PreAuthenticating       += ev.OnPreAuth;
            Exiled.Events.Handlers.Player.ThrowingGrenade         += ev.OnGrenadeThrown;
            Exiled.Events.Handlers.Player.ChangingGroup           += ev.OnSetGroup;
            Exiled.Events.Handlers.Player.EnteringPocketDimension += ev.OnPocketDimensionEnter;
            Exiled.Events.Handlers.Player.EscapingPocketDimension += ev.OnPocketDimensionEscape;

            Exiled.Events.Handlers.Scp914.ChangingKnobSetting += ev.OnScp914ChangeKnob;
            Exiled.Events.Handlers.Scp914.Activating          += ev.OnScp914Activation;

            Exiled.Events.Handlers.Scp079.InteractingTesla += ev.OnScp079TriggerTesla;

            Exiled.Events.Handlers.Scp106.Containing += ev.OnScp106Contain;
        }
예제 #9
0
        private static void Update(SCPDiscord plugin)
        {
            if (topicUpdateTimer.ElapsedMilliseconds >= 10000)
            {
                topicUpdateTimer.Reset();
                topicUpdateTimer.Start();
                float tps = TickCounter.Reset() / 10.0f;

                // Update player count
                if (Config.GetBool("settings.playercount"))
                {
                    string activity = "botactivity" + (plugin.pluginManager.Server.NumPlayers - 1) + " / " + plugin.GetConfigString("max_players");
                    QueueMessage(activity);
                }

                // Update channel topic
                foreach (string channel in Config.GetArray("channels.topic"))
                {
                    if (Config.GetDict("aliases").ContainsKey(channel))
                    {
                        RefreshChannelTopic(plugin, Config.GetDict("aliases")[channel], tps);
                    }
                }
            }

            // Send all messages
            for (int i = 0; i < messageQueue.Count; i++)
            {
                if (SendMessage(messageQueue[i]))
                {
                    messageQueue.RemoveAt(i);
                    i--;
                }
            }

            if (messageQueue.Count != 0 && Config.GetBool("settings.verbose"))
            {
                plugin.Warn("Warn could not send all messages.");
            }
        }
예제 #10
0
        /// ///////////////////////////////////////////////

        /// Channel topic refreshing //////////////////////
        private static void RefreshChannelTopic(SCPDiscord plugin, string channelID, float tps)
        {
            Dictionary <string, string> variables = new Dictionary <string, string>();

            try
            {
                Server server = plugin.pluginManager.Server;
                Dictionary <string, string> serverVariables;
                if (server != null)
                {
                    serverVariables = new Dictionary <string, string>
                    {
                        { "players", (server.NumPlayers - 1) + "" },
                        { "maxplayers", plugin.GetConfigString("max_players") },
                        { "ip", server.IpAddress },
                        { "port", server.Port + "" },
                        { "isvisible", server.Visible + "" },
                        { "isverified", server.Verified + "" },
                        { "uptime", (plugin.serverStartTime.ElapsedMilliseconds / 1000 / 60) + "" },
                        { "tps", tps.ToString("0.00") }
                    };
                }
                else
                {
                    serverVariables = new Dictionary <string, string>
                    {
                        { "players", "0" },
                        { "maxplayers", "0" },
                        { "ip", "---.---.---.---" },
                        { "port", "----" },
                        { "isvisible", "False" },
                        { "isverified", "False" },
                        { "uptime", "0" },
                        { "tps", tps.ToString("0.00") }
                    };
                }

                Dictionary <string, string> mapVariables;
                if (server != null && server.Map != null)
                {
                    mapVariables = new Dictionary <string, string>
                    {
                        //{ "warheaddetonated",   server.Map.WarheadDetonated + ""    },
                        { "decontaminated", server.Map.LCZDecontaminated + "" }
                    };
                }
                else
                {
                    mapVariables = new Dictionary <string, string>
                    {
                        //{ "warheaddetonated",   "False" },
                        { "decontaminated", "False" }
                    };
                }

                Dictionary <string, string> roundVariables;
                if (server != null && server.Round != null)
                {
                    roundVariables = new Dictionary <string, string>
                    {
                        { "roundduration", (server.Round.Duration / 60) + "" },
                        { "dclassalive", server.Round.Stats.ClassDAlive + "" },
                        { "dclassdead", server.Round.Stats.ClassDDead + "" },
                        { "dclassescaped", server.Round.Stats.ClassDEscaped + "" },
                        { "dclassstart", server.Round.Stats.ClassDStart + "" },
                        { "mtfalive", server.Round.Stats.NTFAlive + "" },
                        { "scientistsalive", server.Round.Stats.ScientistsAlive + "" },
                        { "scientistsdead", server.Round.Stats.ScientistsDead + "" },
                        { "scientistsescaped", server.Round.Stats.ScientistsEscaped + "" },
                        { "scientistsstart", server.Round.Stats.ScientistsStart + "" },
                        { "scpalive", server.Round.Stats.SCPAlive + "" },
                        { "scpdead", server.Round.Stats.SCPDead + "" },
                        { "scpkills", server.Round.Stats.SCPKills + "" },
                        { "scpstart", server.Round.Stats.SCPStart + "" },
                        { "warheaddetonated", server.Round.Stats.WarheadDetonated + "" },
                        { "zombies", server.Round.Stats.Zombies + "" }
                    };
                }
                else
                {
                    roundVariables = new Dictionary <string, string>
                    {
                        { "roundduration", "0" },
                        { "dclassalive", "0" },
                        { "dclassdead", "0" },
                        { "dclassescaped", "0" },
                        { "dclassstart", "0" },
                        { "mtfalive", "0" },
                        { "scientistsalive", "0" },
                        { "scientistsdead", "0" },
                        { "scientistsescaped", "0" },
                        { "scientistsstart", "0" },
                        { "scpalive", "0" },
                        { "scpdead", "0" },
                        { "scpkills", "0" },
                        { "scpstart", "0" },
                        { "warheaddetonated", "0" },
                        { "zombies", "0" }
                    };
                }

                foreach (var entry in serverVariables)
                {
                    variables.Add(entry.Key, entry.Value);
                }

                foreach (var entry in mapVariables)
                {
                    variables.Add(entry.Key, entry.Value);
                }

                foreach (var entry in roundVariables)
                {
                    variables.Add(entry.Key, entry.Value);
                }


                var topic = Language.GetString("topic.message");

                topic = topic.Replace("\n", "");

                // Variable insertion
                foreach (KeyValuePair <string, string> variable in variables)
                {
                    topic = topic.Replace("<var:" + variable.Key + ">", variable.Value);
                }

                // Regex replacements
                Dictionary <string, string> regex = Language.GetRegexDictionary("topic.regex");

                // Run the regex replacements
                foreach (KeyValuePair <string, string> entry in regex)
                {
                    topic = topic.Replace(entry.Key, entry.Value);
                }

                // Try to send the message to the bot
                try
                {
                    QueueMessage("channeltopic" + channelID + topic);

                    if (Config.GetBool("settings.debug"))
                    {
                        plugin.Info("Sent channel topic '" + topic + "' to bot.");
                    }
                }
                catch (InvalidOperationException e)
                {
                    if (Config.GetBool("settings.verbose"))
                    {
                        plugin.Error("Error sending channel topic '" + topic + "' to bot.");
                        plugin.Error(e.ToString());
                    }
                }
                catch (ArgumentNullException e)
                {
                    if (Config.GetBool("settings.verbose"))
                    {
                        plugin.Error("Error sending channel topic '" + topic + "' to bot.");
                        plugin.Error(e.ToString());
                    }
                }
            }
            catch (Exception e)
            {
                if (Config.GetBool("settings.verbose"))
                {
                    plugin.Error(e.ToString());
                }
            }
        }
예제 #11
0
 public ReloadCommand(SCPDiscord plugin)
 {
     this.plugin = plugin;
 }
예제 #12
0
        public BotListener(SCPDiscord plugin)
        {
            this.plugin = plugin;
            while (true)
            {
                try
                {
                    //Listen for connections
                    if (NetworkSystem.IsConnected())
                    {
                        MessageWrapper data;
                        try
                        {
                            data = MessageWrapper.Parser.ParseDelimitedFrom(NetworkSystem.networkStream);
                        }
                        catch (Exception e)
                        {
                            if (e is IOException)
                            {
                                plugin.Error("Connection to bot lost.");
                            }

                            else
                            {
                                plugin.Error("Couldnt parse incoming packet!\n" + e.ToString());
                            }

                            return;
                        }

                        plugin.Debug("Incoming packet: " + Google.Protobuf.JsonFormatter.Default.Format(data));

                        switch (data.MessageCase)
                        {
                        case MessageWrapper.MessageOneofCase.SyncRoleCommand:
                            plugin.SendStringByID(data.SyncRoleCommand.ChannelID, plugin.roleSync.AddPlayer(data.SyncRoleCommand.SteamID.ToString(), data.SyncRoleCommand.DiscordID));
                            break;

                        case MessageWrapper.MessageOneofCase.UnsyncRoleCommand:
                            plugin.SendStringByID(data.UnsyncRoleCommand.ChannelID, plugin.roleSync.RemovePlayer(data.UnsyncRoleCommand.DiscordID));
                            break;

                        case MessageWrapper.MessageOneofCase.ConsoleCommand:
                            string[] words    = data.ConsoleCommand.Command.Split(' ');
                            string   response = plugin.ConsoleCommand(plugin.PluginManager.Server, words[0], words.Skip(1).ToArray());
                            Dictionary <string, string> variables = new Dictionary <string, string>
                            {
                                { "feedback", response }
                            };
                            plugin.SendMessageByID(data.ConsoleCommand.ChannelID, "botresponses.consolecommandfeedback", variables);
                            break;

                        case MessageWrapper.MessageOneofCase.RoleResponse:
                            plugin.roleSync.ReceiveQueryResponse(data.RoleResponse.SteamID, data.RoleResponse.RoleIDs.ToList());
                            break;

                        case MessageWrapper.MessageOneofCase.BanCommand:
                            BanCommand(data.BanCommand.ChannelID, data.BanCommand.SteamID.ToString(), data.BanCommand.Duration, data.BanCommand.Reason, data.BanCommand.AdminTag);
                            break;

                        case MessageWrapper.MessageOneofCase.UnbanCommand:
                            UnbanCommand(data.UnbanCommand.ChannelID, data.UnbanCommand.SteamIDOrIP);
                            break;

                        case MessageWrapper.MessageOneofCase.KickCommand:
                            KickCommand(data.KickCommand.ChannelID, data.KickCommand.SteamID.ToString(), data.KickCommand.Reason, data.KickCommand.AdminTag);
                            break;

                        case MessageWrapper.MessageOneofCase.KickallCommand:
                            KickallCommand(data.KickallCommand.ChannelID, data.KickallCommand.Reason, data.KickallCommand.AdminTag);
                            break;

                        case MessageWrapper.MessageOneofCase.ListCommand:
                            var reply = "```md\n# Players online (" + (plugin.Server.NumPlayers - 1) + "):\n";
                            foreach (Player player in plugin.Server.GetPlayers())
                            {
                                reply += player.Name.PadRight(35) + "<" + player.UserID + ">" + "\n";
                            }
                            reply += "```";
                            plugin.SendStringByID(data.ListCommand.ChannelID, reply);
                            break;

                        case MessageWrapper.MessageOneofCase.BotActivity:
                        case MessageWrapper.MessageOneofCase.ChatMessage:
                        case MessageWrapper.MessageOneofCase.RoleQuery:
                            plugin.Warn("Recieved packet meant for bot: " + Google.Protobuf.JsonFormatter.Default.Format(data));
                            break;

                        default:
                            plugin.Warn("Unknown packet received: " + Google.Protobuf.JsonFormatter.Default.Format(data));
                            break;
                        }
                    }
                    Thread.Sleep(1000);
                }
                catch (Exception ex)
                {
                    plugin.Error("BotListener Error: " + ex);
                }
            }
        }
예제 #13
0
        public static void ValidateConfig(SCPDiscord plugin)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("\n||||||||||||| SCPDiscord config validator ||||||||||||||\n");
            sb.Append("------------ Config strings ------------\n");
            foreach (KeyValuePair <string, string> node in configStrings)
            {
                sb.Append(node.Key + ": " + node.Value + "\n");
            }

            sb.Append("------------ Config ints ------------\n");
            foreach (KeyValuePair <string, int> node in configInts)
            {
                sb.Append(node.Key + ": " + node.Value + "\n");
            }

            sb.Append("------------ Config bools ------------\n");
            foreach (KeyValuePair <string, bool> node in configBools)
            {
                sb.Append(node.Key + ": " + node.Value + "\n");
            }

            sb.Append("------------ Config arrays ------------\n");
            foreach (KeyValuePair <string, string[]> node in configArrays)
            {
                sb.Append(node.Key + ": [ " + string.Join(", ", node.Value) + " ]\n");
                if (node.Key.StartsWith("channels."))
                {
                    foreach (string s in node.Value)
                    {
                        if (!GetDict("aliases").ContainsKey(s))
                        {
                            sb.Append("WARNING: Channel alias '" + s + "' does not exist!\n");
                        }
                    }
                }
            }

            sb.Append("------------ Config dictionaries ------------\n");
            foreach (KeyValuePair <string, Dictionary <string, ulong> > node in configDicts)
            {
                sb.Append(node.Key + ":\n");
                foreach (KeyValuePair <string, ulong> subNode in node.Value)
                {
                    sb.Append("    " + subNode.Key + ": " + subNode.Value + "\n");
                }
            }

            sb.Append("------------ Rolesync system ------------\n");
            foreach (KeyValuePair <ulong, string[]> node in plugin.roleSync.roleDictionary)
            {
                sb.Append(node.Key + ":\n");
                foreach (string command in node.Value)
                {
                    sb.Append("    " + command + "\n");
                }
            }

            sb.Append("|||||||||||| End of config validation ||||||||||||");
            plugin.Info(sb.ToString());
        }
예제 #14
0
 public ReconnectCommand(SCPDiscord plugin)
 {
     this.plugin = plugin;
 }
예제 #15
0
파일: Config.cs 프로젝트: SandeQ/SCPDiscord
        internal static void Reload(SCPDiscord plugin)
        {
            ready = false;
            plugin.SetUpFileSystem();

            // Reads file contents into FileStream
            FileStream stream = File.OpenRead(FileManager.GetAppFolder() + "SCPDiscord/" + plugin.GetConfigString("scpdiscord_config"));

            // Converts the FileStream into a YAML Dictionary object
            IDeserializer deserializer = new DeserializerBuilder().Build();
            object        yamlObject   = deserializer.Deserialize(new StreamReader(stream));

            // Converts the YAML Dictionary into JSON String
            ISerializer serializer = new SerializerBuilder()
                                     .JsonCompatible()
                                     .Build();
            string jsonString = serializer.Serialize(yamlObject);

            JObject json = JObject.Parse(jsonString);

            // Reads the configvalidation node first as it is used for reading the others
            try
            {
                configBools["settings.configvalidation"] = json.SelectToken("settings.configvalidation").Value <bool>();
            }
            catch (ArgumentNullException)
            {
                if (GetBool("settings.configvalidation"))
                {
                    plugin.Warn("Config bool 'settings.configvalidation' not found, using default value: true");
                }
            }

            // Read config strings
            foreach (KeyValuePair <string, string> node in configStrings.ToList())
            {
                try
                {
                    configStrings[node.Key] = json.SelectToken(node.Key).Value <string>();
                }
                catch (ArgumentNullException)
                {
                    if (GetBool("settings.configvalidation"))
                    {
                        plugin.Warn("Config string '" + node.Key + "' not found, using default value: \"" + node.Value + "\"");
                    }
                }
            }

            // Read config ints
            foreach (KeyValuePair <string, int> node in configInts.ToList())
            {
                try
                {
                    configInts[node.Key] = json.SelectToken(node.Key).Value <int>();
                }
                catch (ArgumentNullException)
                {
                    if (GetBool("settings.configvalidation"))
                    {
                        plugin.Warn("Config int '" + node.Key + "' not found, using default value: \"" + node.Value + "\"");
                    }
                }
            }

            // Read config bools
            foreach (KeyValuePair <string, bool> node in configBools.ToList().Where(kvm => !(kvm.Key == "settings.configvalidation")))
            {
                try
                {
                    configBools[node.Key] = json.SelectToken(node.Key).Value <bool>();
                }
                catch (ArgumentNullException)
                {
                    if (GetBool("settings.configvalidation"))
                    {
                        plugin.Warn("Config bool '" + node.Key + "' not found, using default value: " + node.Value);
                    }
                }
            }

            // Read config arrays
            foreach (KeyValuePair <string, string[]> node in configArrays.ToList())
            {
                try
                {
                    configArrays[node.Key] = json.SelectToken(node.Key).Value <JArray>().Values <string>().ToArray();
                }
                catch (ArgumentNullException)
                {
                    if (GetBool("settings.configvalidation"))
                    {
                        plugin.Warn("Config array '" + node.Key + "' not found, using default value: []");
                    }
                }
            }

            // Read config dictionaries
            foreach (KeyValuePair <string, Dictionary <string, string> > node in configDicts.ToList())
            {
                try
                {
                    configDicts[node.Key] = json.SelectToken(node.Key).Value <JArray>().ToDictionary(k => ((JObject)k).Properties().First().Name, v => v.Values().First().Value <string>());
                }
                catch (ArgumentNullException)
                {
                    if (GetBool("settings.configvalidation"))
                    {
                        plugin.Warn("Config dictionary '" + node.Key + "' not found, using default value: []");
                    }
                }
            }

            if (GetBool("settings.configvalidation"))
            {
                ValidateConfig(plugin);
            }

            ready = true;
        }
예제 #16
0
        public static void Reload()
        {
            ready         = false;
            plugin        = SCPDiscord.plugin;
            languagesPath = FileManager.GetAppFolder(true, !plugin.GetConfigBool("scpdiscord_languages_global")) + "SCPDiscord/Languages/";

            // Save default language files
            SaveDefaultLanguages();

            // Read primary language file
            plugin.Info("Loading primary language file...");
            try
            {
                LoadLanguageFile(Config.GetString("settings.language"), false);
            }
            catch (Exception e)
            {
                switch (e)
                {
                case DirectoryNotFoundException _:
                    plugin.Error("Language directory not found.");
                    break;

                case UnauthorizedAccessException _:
                    plugin.Error("Primary language file access denied.");
                    break;

                case FileNotFoundException _:
                    plugin.Error("'" + languagesPath + Config.GetString("settings.language") + ".yml' was not found.");
                    break;

                case JsonReaderException _:
                case YamlException _:
                    plugin.Error("'" + languagesPath + Config.GetString("settings.language") + ".yml' formatting error.");
                    break;
                }
                plugin.Error("Error reading primary language file '" + languagesPath + Config.GetString("settings.language") + ".yml'. Attempting to initialize backup system...");
                plugin.Debug(e.ToString());
            }

            // Read backup language file if not the same as the primary
            if (Config.GetString("settings.language") != "english")
            {
                plugin.Info("Loading backup language file...");
                try
                {
                    LoadLanguageFile("english", true);
                }
                catch (Exception e)
                {
                    switch (e)
                    {
                    case DirectoryNotFoundException _:
                        plugin.Error("Language directory not found.");
                        break;

                    case UnauthorizedAccessException _:
                        plugin.Error("Backup language file access denied.");
                        break;

                    case FileNotFoundException _:
                        plugin.Error("'" + languagesPath + Config.GetString("settings.language") + ".yml' was not found.");
                        break;

                    case JsonReaderException _:
                    case YamlException _:
                        plugin.Error("'" + languagesPath + Config.GetString("settings.language") + ".yml' formatting error.");
                        break;
                    }
                    plugin.Error("Error reading backup language file '" + languagesPath + "english.yml'.");
                    plugin.Debug(e.ToString());
                }
            }
            if (primary == null && backup == null)
            {
                plugin.Error("NO LANGUAGE FILE LOADED! DEACTIVATING SCPDISCORD.");
                plugin.Disable();
            }

            if (Config.GetBool("settings.verbose"))
            {
                ValidateLanguageStrings();
            }

            ready = true;
        }
예제 #17
0
 public UnsyncCommand(SCPDiscord plugin)
 {
     this.plugin = plugin;
 }
        public BotListener(SCPDiscord plugin)
        {
            this.plugin = plugin;
            while (!plugin.shutdown)
            {
                //Listen for connections
                if (NetworkSystem.IsConnected())
                {
                    try
                    {
                        //Discord messages can be up to 2000 chars long, UTF8 chars can be up to 4 bytes long.
                        byte[] data       = new byte[1000];
                        int    dataLength = NetworkSystem.Receive(data);

                        string incomingData = Encoding.UTF8.GetString(data, 0, dataLength);

                        List <string> messages = new List <string>(incomingData.Split('\n'));

                        //If several messages come in at the same time, process all of them
                        while (messages.Count > 0)
                        {
                            if (messages[0].Length == 0)
                            {
                                messages.RemoveAt(0);
                                continue;
                            }

                            plugin.Debug("Incoming command from discord: " + messages[0]);

                            string[] words = messages[0].Split(' ');
                            if (words[0] == "command")
                            {
                                string   channel    = words[1];
                                string   discordTag = words[2].Replace('_', ' ');
                                string   command    = words[3];
                                string[] arguments  = new string[0];
                                if (words.Length >= 5)
                                {
                                    arguments = words.Skip(4).ToArray();
                                }

                                string response;
                                Dictionary <string, string> variables;

                                switch (command)
                                {
                                case "ban":
                                    //Check if the command has enough arguments
                                    if (arguments.Length >= 2)
                                    {
                                        BanCommand(channel, arguments[0], arguments[1], MergeString(arguments.Skip(2).ToArray()), discordTag);
                                    }
                                    else
                                    {
                                        variables = new Dictionary <string, string>
                                        {
                                            { "command", messages[0] }
                                        };
                                        plugin.SendMessageByID(channel, "botresponses.missingarguments", variables);
                                    }
                                    break;

                                case "kick":
                                    //Check if the command has enough arguments
                                    if (arguments.Length >= 1)
                                    {
                                        KickCommand(channel, arguments[0], MergeString(arguments.Skip(1).ToArray()), discordTag);
                                    }
                                    else
                                    {
                                        variables = new Dictionary <string, string>
                                        {
                                            { "command", messages[0] }
                                        };
                                        plugin.SendMessageByID(channel, "botresponses.missingarguments", variables);
                                    }
                                    break;

                                case "kickall":
                                    KickallCommand(channel, MergeString(arguments), discordTag);
                                    break;

                                case "unban":
                                    //Check if the command has enough arguments
                                    if (arguments.Length >= 1)
                                    {
                                        UnbanCommand(channel, arguments[0]);
                                    }
                                    else
                                    {
                                        variables = new Dictionary <string, string>
                                        {
                                            { "command", messages[0] }
                                        };
                                        plugin.SendMessageByID(channel, "botresponses.missingarguments", variables);
                                    }
                                    break;

                                case "list":
                                    var message = "```md\n# Players online (" + (plugin.Server.NumPlayers - 1) + "):\n";
                                    foreach (Player player in plugin.Server.GetPlayers())
                                    {
                                        message += player.Name.PadRight(35) + "<" + player.UserId + ">" + "\n";
                                    }
                                    message += "```";
                                    NetworkSystem.QueueMessage(channel + message);
                                    break;

                                case "exit":
                                    plugin.SendMessageByID(channel, "botresponses.exit");
                                    break;

                                case "help":
                                    plugin.SendMessageByID(channel, "botresponses.help");
                                    break;

                                case "hidetag":
                                case "showtag":
                                    if (plugin.PluginManager.GetEnabledPlugin("karlofduty.toggletag") != null)
                                    {
                                        if (arguments.Length > 0)
                                        {
                                            command  = "console_" + command;
                                            response = plugin.ConsoleCommand(plugin.PluginManager.Server, command, arguments);

                                            variables = new Dictionary <string, string>
                                            {
                                                { "feedback", response }
                                            };
                                            plugin.SendMessageByID(channel, "botresponses.consolecommandfeedback", variables);
                                        }
                                        else
                                        {
                                            variables = new Dictionary <string, string>
                                            {
                                                { "command", command }
                                            };
                                            plugin.SendMessageByID(channel, "botresponses.missingarguments", variables);
                                        }
                                    }
                                    else
                                    {
                                        plugin.SendMessageByID(channel, "botresponses.toggletag.notinstalled");
                                    }
                                    break;

                                case "vs_enable":
                                case "vs_disable":
                                case "vs_whitelist":
                                case "vs_reload":
                                    if (plugin.PluginManager.GetEnabledPlugin("karlofduty.vpnshield") != null)
                                    {
                                        response = plugin.ConsoleCommand(plugin.PluginManager.Server, command, arguments);

                                        variables = new Dictionary <string, string>
                                        {
                                            { "feedback", response }
                                        };
                                        plugin.SendMessageByID(channel, "botresponses.consolecommandfeedback", variables);
                                    }
                                    else
                                    {
                                        plugin.SendMessageByID(channel, "botresponses.vpnshield.notinstalled");
                                    }
                                    break;

                                case "scperms_reload":
                                case "scperms_giverank":
                                case "scperms_removerank":
                                case "scperms_verbose":
                                case "scperms_debug":
                                case "scpermissions_reload":
                                case "scpermissions_giverank":
                                case "scpermissions_removerank":
                                case "scpermissions_verbose":
                                case "scpermissions_debug":
                                    if (plugin.PluginManager.GetEnabledPlugin("karlofduty.scpermissions") != null)
                                    {
                                        response = plugin.ConsoleCommand(plugin.PluginManager.Server, command, arguments);

                                        variables = new Dictionary <string, string>
                                        {
                                            { "feedback", response }
                                        };
                                        plugin.SendMessageByID(channel, "botresponses.consolecommandfeedback", variables);
                                    }
                                    else
                                    {
                                        plugin.SendMessageByID(channel, "botresponses.scpermissions.notinstalled");
                                    }
                                    break;

                                case "syncrole":
                                    NetworkSystem.QueueMessage(channel + plugin.roleSync.AddPlayer(arguments[0], arguments[1]));
                                    break;

                                case "unsyncrole":
                                    NetworkSystem.QueueMessage(channel + plugin.roleSync.RemovePlayer(arguments[0]));
                                    break;

                                default:
                                    response  = plugin.ConsoleCommand(plugin.PluginManager.Server, command, arguments);
                                    variables = new Dictionary <string, string>
                                    {
                                        { "feedback", response }
                                    };
                                    plugin.SendMessageByID(channel, "botresponses.consolecommandfeedback", variables);
                                    break;
                                }
                            }
                            else if (words[0] == "roleresponse")
                            {
                                plugin.roleSync.ReceiveQueryResponse(words[1] + "@steam", MergeString(words.Skip(2).ToArray()));
                            }
                            plugin.Verbose("From discord: " + messages[0]);

                            messages.RemoveAt(0);
                        }
                    }
                    catch (Exception ex)
                    {
                        plugin.Error("BotListener Error: " + ex);
                    }
                }
                Thread.Sleep(1000);
            }
        }
예제 #19
0
 public VerboseCommand(SCPDiscord plugin)
 {
     this.plugin = plugin;
 }
예제 #20
0
        public static void HandleCommand(JObject o)
        {
            try
            {
                string type = (string)o["type"];
                if (type == "IDENT")
                {
                    if ((string)o["data"] == "PASS")
                    {
                        Log.Debug($"Server {ServerConsole.Port} passed identification.");
                    }
                    else if ((string)o["data"] == "FAIL")
                    {
                        Log.Warn($"Server {ServerConsole.Port} failed identification.");
                    }
                }
                else if (type == "UPDATE")
                {
                    EventHandlers.tcp.SendData(new Update());
                }
                else if (type == "ROLESYNC")
                {
                    Log.Warn(o);

                    string userid = (string)o["userid"];

                    if (o["group"] == null)
                    {
                        Log.Debug($"No role sync found for {userid}");
                        SCPDiscord.VerifyReservedSlot(userid);
                        return;
                    }

                    string group = (string)o["group"];

                    UserGroup userGroup = ServerStatic.PermissionsHandler.GetGroup(group);
                    if (userGroup == null)
                    {
                        Log.Error($"Attempted to assign invalid user group {group} to {userid}");
                        return;
                    }

                    Player player = Player.Get(userid);
                    if (player == null)
                    {
                        Log.Error($"Error assigning user group to {userid}, player not found.");
                        return;
                    }

                    if (SCPDiscord.setRoleGroups.Contains(group))
                    {
                        Log.Debug($"Assigning role: {userGroup} to {userid}.");
                        player.Group = userGroup;
                    }

                    string tag = (string)o["tag"];
                    if (SCPDiscord.setTagGroups.Contains(group) && tag != null)
                    {
                        Log.Debug($"Changing tag of {userid} to {tag}.");
                        player.RankName = tag;
                    }

                    if (SCPDiscord.reservedSlotGroups.Contains(group))
                    {
                        // grant reserved slot
                        Log.Debug("Player has necessary rank for reserved slot, checking...");
                        List <string> lines = File.ReadAllLines(SCPDiscord.reservedSlots).ToList();
                        if (!lines.Contains(userid))
                        {
                            Log.Debug("Reserved slot not found, adding player...");
                            lines.Add(userid);
                            File.WriteAllLines(SCPDiscord.reservedSlots, lines);
                            // This only reloads the slots on the current server, change this to reload on every server?
                            // Might not work
                            ReservedSlot.Reload();
                        }
                    }
                    else
                    {
                        SCPDiscord.VerifyReservedSlot(userid);
                    }
                }
                else if (type == "COMMAND")
                {
                    GameCore.Console.singleton.TypeCommand((string)o["command"]);
                }
                else if (type == "BAN")
                {
                    bool   isuid = false;
                    string uid   = (string)o["user"];
                    if (!uid.Contains("@steam") && !uid.Contains("@discord"))
                    {
                        if (!uid.Contains("."))
                        {
                            isuid = true;
                            uid  += "@steam";
                        }
                    }
                    else
                    {
                        isuid = true;
                    }
                    Player player = Player.Get(uid);
                    int    min    = (int)o["min"];
                    string reason = (string)o["reason"];

                    Ban ban = new Ban
                    {
                        player   = null,
                        duration = min,
                        success  = true,
                        offline  = false
                    };

                    if (player != null)
                    {
                        PlayerManager.localPlayer.GetComponent <BanPlayer>().BanUser(player.GameObject, min, reason, "Server");

                        ban.player = new User
                        {
                            name   = player.Nickname,
                            userid = player.UserId
                        };
                    }
                    else
                    {
                        if (isuid)
                        {
                            ban.offline = true;

                            ban.player = new User
                            {
                                name   = "Offline Player",
                                userid = uid
                            };

                            if (SCPDiscord.instance.Config.SteamApiKey != string.Empty)
                            {
                                string data = null;
                                try
                                {
                                    data = webclient.DownloadString($"https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key={SCPDiscord.instance.Config.SteamApiKey}&format=json&steamids={uid.Replace("@steam", "")}");
                                }
                                catch
                                {
                                    Log.Debug("Failed to get profile data from SteamAPI.");
                                }
                                JObject o2 = JObject.Parse(data);

                                if (o2 != null)
                                {
                                    ban.player.name = (string)o2["response"]["players"][0]["personaname"];
                                }
                            }

                            BanHandler.IssueBan(new BanDetails()
                            {
                                OriginalName = ban.player.name,
                                Id           = uid,
                                IssuanceTime = TimeBehaviour.CurrentTimestamp(),
                                Expires      = DateTime.UtcNow.AddMinutes((double)min).Ticks,
                                Reason       = reason,
                                Issuer       = "Server"
                            }, BanHandler.BanType.UserId);
                        }
                        else if (uid.Contains("."))
                        {
                            ban.offline = true;

                            BanHandler.IssueBan(new BanDetails()
                            {
                                OriginalName = "IP Address",
                                Id           = uid,
                                IssuanceTime = TimeBehaviour.CurrentTimestamp(),
                                Expires      = DateTime.UtcNow.AddMinutes((double)min).Ticks,
                                Reason       = reason,
                                Issuer       = "Server"
                            }, BanHandler.BanType.IP);
                        }
                        else
                        {
                            ban.success = false;
                        }
                    }
                    EventHandlers.tcp.SendData(ban);
                }
                else if (type == "KICK")
                {
                    string uid = (string)o["user"];
                    if (!uid.Contains("@steam") && !uid.Contains("@discord"))
                    {
                        uid += "@steam";
                    }
                    Player player = Player.Get(uid);

                    Kick kick = new Kick
                    {
                        player = null
                    };

                    if (player != null)
                    {
                        kick.player = new User
                        {
                            name   = player.Nickname,
                            userid = player.UserId
                        };

                        ServerConsole.Disconnect(player.GameObject, (string)o["reason"]);
                    }
                    EventHandlers.tcp.SendData(kick);
                }
                else if (type == "UNBAN")
                {
                    Unban unban = new Unban();

                    List <string> ipBans     = File.ReadAllLines(SCPDiscord.ipBans).ToList();
                    List <string> userIDBans = File.ReadAllLines(SCPDiscord.useridBans).ToList();

                    string id = (string)o["user"];
                    if (!id.Contains("."))
                    {
                        if (!id.Contains("@steam") && !id.Contains("@discord"))
                        {
                            id += "@steam";
                        }
                    }
                    List <string> matchingIPBans      = ipBans.FindAll(s => s.Contains(id));
                    List <string> matchingSteamIDBans = userIDBans.FindAll(s => s.Contains(id));

                    if (matchingIPBans.Count == 0 && matchingSteamIDBans.Count == 0)
                    {
                        unban.success = false;
                        EventHandlers.tcp.SendData(unban);
                        return;
                    }

                    ipBans.RemoveAll(s => s.Contains(id));
                    userIDBans.RemoveAll(s => s.Contains(id));

                    foreach (var row in matchingIPBans)
                    {
                        userIDBans.RemoveAll(s => s.Contains(row.Split(';').Last()));
                    }
                    foreach (var row in matchingSteamIDBans)
                    {
                        ipBans.RemoveAll(s => s.Contains(row.Split(';').Last()));
                    }

                    File.WriteAllLines(SCPDiscord.ipBans, ipBans);
                    File.WriteAllLines(SCPDiscord.useridBans, userIDBans);

                    EventHandlers.tcp.SendData(unban);
                }
            }
            catch (Exception x)
            {
                Log.Error("SCPDiscord handle command error: " + x.Message);
            }
        }
예제 #21
0
 public PlayerEventListener(SCPDiscord plugin)
 {
     this.plugin = plugin;
 }
예제 #22
0
 public RoundEventListener(SCPDiscord plugin)
 {
     this.plugin = plugin;
 }
예제 #23
0
 public StartNetworkSystem(SCPDiscord plugin)
 {
     NetworkSystem.Run(plugin);
 }
예제 #24
0
 public EnvironmentEventListener(SCPDiscord plugin)
 {
     this.plugin = plugin;
 }
예제 #25
0
        public static void Reload()
        {
            ready  = false;
            plugin = SCPDiscord.plugin;

            // Save default language files
            SaveDefaultLanguages();

            // Read primary language file
            plugin.Info("Loading primary language file...");
            try
            {
                LoadLanguageFile(Config.GetString("settings.language"), false);
            }
            catch (Exception e)
            {
                if (e is DirectoryNotFoundException)
                {
                    plugin.Error("Language directory not found.");
                }
                else if (e is UnauthorizedAccessException)
                {
                    plugin.Error("Primary language file access denied.");
                }
                else if (e is FileNotFoundException)
                {
                    plugin.Error("'" + Config.GetString("settings.language") + ".yml' was not found.");
                }
                else if (e is JsonReaderException || e is YamlException)
                {
                    plugin.Error("'" + Config.GetString("settings.language") + ".yml' formatting error.");
                }
                plugin.Error("Error reading language file '" + Config.GetString("settings.language") + ".yml'. Attempting to initialize backup system...");
                plugin.Debug(e.ToString());
            }

            // Read backup language file if not the same as the primary
            if (Config.GetString("settings.language") != "english")
            {
                plugin.Info("Loading backup language file...");
                try
                {
                    LoadLanguageFile("english", true);
                }
                catch (Exception e)
                {
                    if (e is DirectoryNotFoundException)
                    {
                        plugin.Error("Language directory not found.");
                    }
                    else if (e is UnauthorizedAccessException)
                    {
                        plugin.Error("Backup language file access denied.");
                    }
                    else if (e is FileNotFoundException)
                    {
                        plugin.Error("'" + Config.GetString("settings.language") + ".yml' was not found.");
                    }
                    else if (e is JsonReaderException || e is YamlException)
                    {
                        plugin.Error("'" + Config.GetString("settings.language") + ".yml' formatting error.");
                    }
                    plugin.Error("Error reading backup language file 'english.yml'.");
                    plugin.Debug(e.ToString());
                }
            }
            if (primary == null && backup == null)
            {
                plugin.Error("NO LANGUAGE FILE LOADED! DEACTIVATING SCPDISCORD.");
                plugin.Disable();
            }

            ValidateLanguageStrings();

            ready = true;
        }
예제 #26
0
 public RoleSync(SCPDiscord plugin)
 {
     this.plugin = plugin;
     Reload();
     plugin.Info("RoleSync system loaded.");
 }
예제 #27
0
 public DebugCommand(SCPDiscord plugin)
 {
     this.plugin = plugin;
 }
예제 #28
0
 public TeamEventListener(SCPDiscord plugin)
 {
     this.plugin = plugin;
 }
예제 #29
0
 public AdminEventListener(SCPDiscord plugin)
 {
     this.plugin = plugin;
 }