├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── LICENSE ├── README.md ├── Unifiedban.Terminal.sln └── Unifiedban.Terminal ├── Bot ├── Command │ ├── AddBadWord.cs │ ├── AddNote.cs │ ├── AddSafeGroup.cs │ ├── AddToBlacklist.cs │ ├── AddTranslation.cs │ ├── AddWelcomeButton.cs │ ├── Alias.cs │ ├── Announce.cs │ ├── Ban.cs │ ├── Call.cs │ ├── Captcha.cs │ ├── CaptchaError.cs │ ├── Check.cs │ ├── Config.cs │ ├── Disable.cs │ ├── Echo.cs │ ├── Enable.cs │ ├── EndSupport.cs │ ├── Feedback.cs │ ├── Gate.cs │ ├── Get.cs │ ├── GetTranslation.cs │ ├── GetTrustFactor.cs │ ├── Help.cs │ ├── ICommand.cs │ ├── Id.cs │ ├── Invite.cs │ ├── InviteToPrivate.cs │ ├── Kick.cs │ ├── Leave.cs │ ├── Motd.cs │ ├── Mute.cs │ ├── Parser.cs │ ├── Pin.cs │ ├── ReloadConf.cs │ ├── ReloadTranslations.cs │ ├── RemoveBadWord.cs │ ├── RemoveFlood.cs │ ├── RemoveFromBlacklist.cs │ ├── RemoveNote.cs │ ├── RemoveSafeGroup.cs │ ├── RemoveWelcomeButton.cs │ ├── Report.cs │ ├── Rm.cs │ ├── Rules.cs │ ├── SetGate.cs │ ├── SetRules.cs │ ├── SetWelcome.cs │ ├── Start.cs │ ├── StartSupport.cs │ ├── Status.cs │ ├── TSSRenewLinks.cs │ ├── TestCommand.cs │ ├── Unban.cs │ ├── Unmute.cs │ └── WelcomeButtonsList.cs ├── CommandQueueManager.cs ├── Commands.cs ├── Functions.cs ├── Manager.cs └── MessageQueueManager.cs ├── CacheData.cs ├── CommandMessage.cs ├── Controls ├── FloodControl.cs ├── IControl.cs ├── Manager.cs ├── Notes.cs ├── SafeGroupControl.cs └── SpamNameControl.cs ├── Filters ├── BadWordFilter.cs ├── IFilter.cs ├── NonLatinFilter.cs ├── RTLNameFilter.cs ├── SafeGroupFilter.cs └── ScamFilter.cs ├── Jobs ├── ChatToolsJob.cs ├── ConfigToolsJob.cs ├── LogsJob.cs ├── UptimeJob.cs └── UserToolsJob.cs ├── MessageQueue.cs ├── Program.cs ├── TestArea.cs ├── Unifiedban.Terminal.csproj ├── UserPrivileges.cs ├── Utils ├── BotTools.cs ├── ChatTools.cs ├── ConfigTools.cs ├── ImageHash.cs ├── LogTools.cs ├── Parsers.cs └── UserTools.cs ├── appsettings.example.json └── log4net.config /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: ['unified-ban'] 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] - title" 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[Request] - title" 5 | labels: request 6 | assignees: mirkobrombin, francescomasala 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

unified/ban

4 |
5 | 6 | is the most complete solution for users and groups protection. It filters dangerous elements like SPAM, SCAM, flood and phishing. It allows to record a set of banned words, allows to deny to send links that refer to other groups and much more. 7 | 8 | ## Links 9 | Visit our [official website](https://unifiedban.solutions/)\ 10 | Follow our [📣 news channel](https://t.me/unifiedban_news) (it contains the changelog too)\ 11 | Join the [🆘 support group](https://t.me/unifiedban_group)\ 12 | Follow the live development on [Twitch](https://www.twitch.tv/prometheus_studio/)\ 13 | Support us on [Twitter](https://twitter.com/unifiedban/) 14 | 15 | ## Badges 16 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/103bc0b1fa6e4bc3b387274ad6827f54)](https://app.codacy.com/gh/unified-ban/Terminal?utm_source=github.com&utm_medium=referral&utm_content=unified-ban/Terminal&utm_campaign=Badge_Grade) 17 | [![License Badge](https://img.shields.io/badge/license-MPL--2.0-blue)](https://github.com/unified-ban/Terminal/blob/master/LICENSE) ![Development Version](https://img.shields.io/badge/DevVersion-beta.43-blue) ![Development Version](https://img.shields.io/badge/StableVersion-3.5.0-red) 18 | 19 | # Sponsor 20 | unified/ban is a project by [Mirko Brombin](https://mirko.pm/) and [Prometheus Studio](https://www.twitch.tv/prometheus_studio/).\ 21 | It is officially supported by [fabricators](https://fabricators.ltd) and [JetBrains](https://www.jetbrains.com/?from=unifiedban)\ 22 | 23 | -------------------------------------------------------------------------------- /Unifiedban.Terminal.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29230.47 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unifiedban.Terminal", "Unifiedban.Terminal\Unifiedban.Terminal.csproj", "{898077BC-2DE6-4476-94A2-77B3D7061287}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {898077BC-2DE6-4476-94A2-77B3D7061287}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {898077BC-2DE6-4476-94A2-77B3D7061287}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {898077BC-2DE6-4476-94A2-77B3D7061287}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {898077BC-2DE6-4476-94A2-77B3D7061287}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {3601356B-5EB8-4435-B5D4-2E04FED8286D} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/AddBadWord.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using Telegram.Bot; 7 | using Telegram.Bot.Types; 8 | 9 | namespace Unifiedban.Terminal.Bot.Command 10 | { 11 | public class AddBadWord : ICommand 12 | { 13 | public void Execute(Message message) 14 | { 15 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic) && 16 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 17 | { 18 | return; 19 | } 20 | 21 | string[] arguments = message.Text.Split(" "); 22 | 23 | if (arguments.Length < 3) 24 | { 25 | MessageQueueManager.EnqueueMessage( 26 | new Models.ChatMessage() 27 | { 28 | Timestamp = DateTime.UtcNow, 29 | Chat = message.Chat, 30 | Text = CacheData.GetTranslation("en", "addbadword_command_error_missingargument") 31 | }); 32 | return; 33 | } 34 | 35 | bool added = Filters.BadWordFilter.BanWord( 36 | CacheData.Groups[message.Chat.Id].GroupId, 37 | arguments[1].Trim(), 38 | message.Text 39 | .Substring(arguments[0].Length + arguments[1].Length + 1) 40 | .Trim()); 41 | 42 | if (!added) 43 | { 44 | MessageQueueManager.EnqueueMessage( 45 | new Models.ChatMessage() 46 | { 47 | Timestamp = DateTime.UtcNow, 48 | Chat = message.Chat, 49 | Text = CacheData.GetTranslation("en", "addbadword_command_error") 50 | }); 51 | return; 52 | } 53 | 54 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 55 | MessageQueueManager.EnqueueMessage( 56 | new Models.ChatMessage() 57 | { 58 | Timestamp = DateTime.UtcNow, 59 | Chat = message.Chat, 60 | Text = CacheData.GetTranslation("en", "addbadword_command_success") 61 | }); 62 | return; 63 | } 64 | 65 | public void Execute(CallbackQuery callbackQuery) { } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/AddNote.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using System.Text.RegularExpressions; 8 | using Telegram.Bot; 9 | using Telegram.Bot.Types; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class AddNote : ICommand 14 | { 15 | BusinessLogic.Group.NoteLogic noteLogic = new BusinessLogic.Group.NoteLogic(); 16 | 17 | public void Execute(Message message) 18 | { 19 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic) && 20 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 21 | { 22 | return; 23 | } 24 | 25 | if(message.ReplyToMessage != null) 26 | { 27 | if (!message.ReplyToMessage.Text.StartsWith("#")) 28 | { 29 | MessageQueueManager.EnqueueMessage( 30 | new Models.ChatMessage() 31 | { 32 | Timestamp = DateTime.UtcNow, 33 | Chat = message.Chat, 34 | ReplyToMessageId = message.MessageId, 35 | Text = CacheData.GetTranslation("en", "error_addnote_command_onreply") 36 | }); 37 | return; 38 | } 39 | 40 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.ReplyToMessage.MessageId); 41 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 42 | SaveNote(message.ReplyToMessage); 43 | return; 44 | } 45 | 46 | if (!message.Text.Remove(0, 9).StartsWith("#")) 47 | { 48 | MessageQueueManager.EnqueueMessage( 49 | new Models.ChatMessage() 50 | { 51 | Timestamp = DateTime.UtcNow, 52 | Chat = message.Chat, 53 | ReplyToMessageId = message.MessageId, 54 | Text = CacheData.GetTranslation("en", "error_addnote_command_starttag") 55 | }); 56 | return; 57 | } 58 | 59 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 60 | SaveNote(message); 61 | } 62 | 63 | public void Execute(CallbackQuery callbackQuery) { } 64 | 65 | private void SaveNote(Message message) 66 | { 67 | if (message.Text.StartsWith("/setnote") || 68 | message.Text.StartsWith("/addnote")) 69 | message.Text = message.Text.Remove(0, 9); 70 | 71 | Regex reg = new Regex("#[A-z0-9]+", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); 72 | MatchCollection matchedTags = reg.Matches(message.Text); 73 | if (matchedTags.Count == 0) 74 | { 75 | MessageQueueManager.EnqueueMessage( 76 | new Models.ChatMessage() 77 | { 78 | Timestamp = DateTime.UtcNow, 79 | Chat = message.Chat, 80 | Text = CacheData.GetTranslation("en", "addnote_command_error_starttag") 81 | }); 82 | return; 83 | } 84 | 85 | string tagCollection = ""; 86 | foreach(Match match in matchedTags) 87 | { 88 | tagCollection += match.Value; 89 | } 90 | 91 | message.Text += Environment.NewLine; 92 | message.Text += Environment.NewLine; 93 | message.Text += "The text of this note is set by the group administrator."; 94 | 95 | Models.Group.Note newNote = noteLogic.Add(CacheData.Groups.Values.Single(x => x.TelegramChatId == message.Chat.Id).GroupId, 96 | tagCollection, message.Text, -2); 97 | if(newNote == null) 98 | { 99 | MessageQueueManager.EnqueueMessage( 100 | new Models.ChatMessage() 101 | { 102 | Timestamp = DateTime.UtcNow, 103 | Chat = message.Chat, 104 | Text = CacheData.GetTranslation("en", "addnote_command_error_generic") 105 | }); 106 | return; 107 | } 108 | 109 | MessageQueueManager.EnqueueMessage( 110 | new Models.ChatMessage() 111 | { 112 | Timestamp = DateTime.UtcNow, 113 | Chat = message.Chat, 114 | Text = CacheData.GetTranslation("en", "addnote_command_success"), 115 | AutoDestroyTimeInSeconds = 5, 116 | PostSentAction = Models.ChatMessage.PostSentActions.Destroy 117 | }); 118 | 119 | MessageQueueManager.EnqueueMessage( 120 | new Models.ChatMessage() 121 | { 122 | Timestamp = DateTime.UtcNow, 123 | Chat = message.Chat, 124 | Text = newNote.Message 125 | }); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/AddSafeGroup.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using Telegram.Bot.Types; 7 | 8 | namespace Unifiedban.Terminal.Bot.Command 9 | { 10 | public class AddSafeGroup : ICommand 11 | { 12 | public void Execute(Message message) 13 | { 14 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic) && 15 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 16 | { 17 | MessageQueueManager.EnqueueMessage( 18 | new Models.ChatMessage() 19 | { 20 | Timestamp = DateTime.UtcNow, 21 | Chat = message.Chat, 22 | Text = CacheData.GetTranslation("en", "addsafe_command_error_notadmin") 23 | }); 24 | return; 25 | } 26 | 27 | string url = message.Text.Split(" ")[1].Trim(); 28 | 29 | if (url.StartsWith("@")) 30 | { 31 | url = "https://t.me/" + message.Text.Split(" ")[1].Remove(0, 1); 32 | } 33 | else if (url.StartsWith("t.me/")) 34 | { 35 | url = "https://" + url; 36 | } 37 | 38 | if (!Controls.Manager.IsTelegramLink(url)) 39 | { 40 | MessageQueueManager.EnqueueMessage( 41 | new Models.ChatMessage() 42 | { 43 | Timestamp = DateTime.UtcNow, 44 | Chat = message.Chat, 45 | Text = CacheData.GetTranslation("en", "addsafe_command_error_invalidgroupname") 46 | }); 47 | return; 48 | } 49 | 50 | BusinessLogic.Group.SafeGroupLogic safeGroupLogic = 51 | new BusinessLogic.Group.SafeGroupLogic(); 52 | Models.Group.SafeGroup safeGroup = safeGroupLogic.Add( 53 | CacheData.Groups[message.Chat.Id].GroupId, 54 | url, -2); 55 | if(safeGroup == null) 56 | { 57 | MessageQueueManager.EnqueueMessage( 58 | new Models.ChatMessage() 59 | { 60 | Timestamp = DateTime.UtcNow, 61 | Chat = message.Chat, 62 | Text = CacheData.GetTranslation("en", "addsafe_command_error_general") 63 | }); 64 | return; 65 | } 66 | 67 | string confirmationMessage = CacheData.GetTranslation("en", "addsafe_command_success"); 68 | MessageQueueManager.EnqueueMessage( 69 | new Models.ChatMessage() 70 | { 71 | Timestamp = DateTime.UtcNow, 72 | Chat = message.Chat, 73 | Text = confirmationMessage.Replace("{{groupname}}", 74 | message.Text.Split(" ")[1].Trim()) 75 | }); 76 | 77 | Filters.SafeGroupFilter.LoadCache(); 78 | } 79 | 80 | public void Execute(CallbackQuery callbackQuery) { } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/AddWelcomeButton.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using Telegram.Bot; 9 | using Telegram.Bot.Types; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class AddWelcomeButton : ICommand 14 | { 15 | public void Execute(Message message) 16 | { 17 | if (!Utils.BotTools.IsUserOperator(message.From.Id) && 18 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 19 | { 20 | MessageQueueManager.EnqueueMessage( 21 | new Models.ChatMessage() 22 | { 23 | Timestamp = DateTime.UtcNow, 24 | Chat = message.Chat, 25 | ReplyToMessageId = message.MessageId, 26 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 27 | }); 28 | return; 29 | } 30 | 31 | string[] arguments = message.Text.Split(" "); 32 | if (arguments.Length < 3) 33 | { 34 | MessageQueueManager.EnqueueMessage( 35 | new Models.ChatMessage() 36 | { 37 | Timestamp = DateTime.UtcNow, 38 | Chat = message.Chat, 39 | ReplyToMessageId = message.MessageId, 40 | Text = CacheData.GetTranslation("en", "awb_command_error_invalidsyntax") 41 | }); 42 | return; 43 | } 44 | 45 | string text = message.Text 46 | .Replace(arguments[0], "") 47 | .Replace(arguments[arguments.Length - 1], "") 48 | .Trim(); 49 | string url = arguments[arguments.Length - 1]; 50 | 51 | if (!Utils.BotTools.IsValidUrl(url)) 52 | { 53 | MessageQueueManager.EnqueueMessage( 54 | new Models.ChatMessage() 55 | { 56 | Timestamp = DateTime.UtcNow, 57 | Chat = message.Chat, 58 | ReplyToMessageId = message.MessageId, 59 | Text = CacheData.GetTranslation("en", "awb_command_error_invalidsyntax") 60 | }); 61 | return; 62 | } 63 | 64 | BusinessLogic.ButtonLogic buttonLogic = new BusinessLogic.ButtonLogic(); 65 | Models.Button newBtn = buttonLogic.Add(CacheData.Groups[message.Chat.Id].GroupId, 66 | text, url, Models.Button.Scopes.Welcome, -2); 67 | if (newBtn == null) 68 | { 69 | MessageQueueManager.EnqueueMessage( 70 | new Models.ChatMessage() 71 | { 72 | Timestamp = DateTime.UtcNow, 73 | Chat = message.Chat, 74 | ReplyToMessageId = message.MessageId, 75 | Text = CacheData.GetTranslation("en", "awb_command_error_general") 76 | }); 77 | return; 78 | } 79 | 80 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 81 | string successMsg = CacheData.GetTranslation("en", "awb_command_success"); 82 | MessageQueueManager.EnqueueMessage( 83 | new Models.ChatMessage() 84 | { 85 | Timestamp = DateTime.UtcNow, 86 | Chat = message.Chat, 87 | Text = successMsg.Replace("{{wbName}}", arguments[1]) 88 | }); 89 | } 90 | 91 | public void Execute(CallbackQuery callbackQuery) { } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Alias.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using Telegram.Bot.Types; 7 | using Unifiedban.Models; 8 | 9 | namespace Unifiedban.Terminal.Bot.Command 10 | { 11 | public class Alias : ICommand 12 | { 13 | public void Execute(Message message) 14 | { 15 | try 16 | { 17 | var link = CacheData.Groups[message.Chat.Id].InviteAlias != null ? 18 | CacheData.Configuration["GroupAliasLinkPrefix"] + CacheData.Groups[message.Chat.Id].InviteAlias : 19 | "No alias set for this group."; 20 | 21 | MessageQueueManager.EnqueueMessage( 22 | new ChatMessage() 23 | { 24 | Timestamp = DateTime.UtcNow, 25 | ReplyToMessageId = message.MessageId, 26 | Chat = message.Chat, 27 | Text = link 28 | }); 29 | } 30 | catch 31 | { 32 | MessageQueueManager.EnqueueMessage( 33 | new ChatMessage() 34 | { 35 | Timestamp = DateTime.UtcNow, 36 | Chat = message.Chat, 37 | Text = "Error getting alias link.", 38 | PostSentAction = ChatMessage.PostSentActions.Destroy, 39 | AutoDestroyTimeInSeconds = 10 40 | }); 41 | } 42 | } 43 | 44 | public void Execute(CallbackQuery callbackQuery) 45 | { 46 | return; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Announce.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using Telegram.Bot.Types; 10 | using Telegram.Bot.Types.Enums; 11 | using Unifiedban.Terminal.Utils; 12 | 13 | namespace Unifiedban.Terminal.Bot.Command 14 | { 15 | public class Announce : ICommand 16 | { 17 | public void Execute(Message message) 18 | { 19 | var sender = message.SenderChat?.Id ?? message.From?.Id ?? 0; 20 | var isOperator = BotTools.IsUserOperator(sender, Models.Operator.Levels.Basic); 21 | var isAdmin = ChatTools.IsUserAdmin(message.Chat.Id, sender); 22 | if (!isOperator && !isAdmin) 23 | { 24 | MessageQueueManager.EnqueueMessage( 25 | new Models.ChatMessage() 26 | { 27 | Timestamp = DateTime.UtcNow, 28 | Chat = message.Chat, 29 | ReplyToMessageId = message.MessageId, 30 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 31 | }); 32 | return; 33 | } 34 | 35 | string command = message.Text!.Split(" ")[0].Remove(0, 1); 36 | if (command.Contains("@")) 37 | { 38 | if (!string.Equals(command.Split("@")[1], 39 | Manager.Username, StringComparison.CurrentCultureIgnoreCase)) 40 | return; 41 | command = command.Split("@")[0]; 42 | } 43 | message.Text = message.Text.Remove(0, command.Length + 2); 44 | 45 | string messageHeader = CacheData.GetTranslation("en", "command_announce_header"); 46 | string parsedMessage = messageHeader + "\n" + message.Text; 47 | MessageQueueManager.EnqueueMessage( 48 | new Models.ChatMessage() 49 | { 50 | Timestamp = DateTime.UtcNow, 51 | Chat = message.Chat, 52 | ParseMode = ParseMode.Html, 53 | Text = parsedMessage, 54 | PostSentAction = Models.ChatMessage.PostSentActions.Pin 55 | }); 56 | } 57 | 58 | public void Execute(CallbackQuery callbackQuery) { } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Call.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Types; 9 | using Telegram.Bot.Types.Enums; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class Call : ICommand 14 | { 15 | public void Execute(Message message) 16 | { 17 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 18 | 19 | if (!Utils.BotTools.IsUserOperator(message.From.Id) && 20 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 21 | { 22 | MessageQueueManager.EnqueueMessage( 23 | new Models.ChatMessage() 24 | { 25 | Timestamp = DateTime.UtcNow, 26 | Chat = message.Chat, 27 | ReplyToMessageId = message.MessageId, 28 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 29 | }); 30 | return; 31 | } 32 | 33 | if (!String.IsNullOrEmpty(message.Chat.Username)) 34 | { 35 | Manager.BotClient.SendTextMessageAsync( 36 | chatId: CacheData.ControlChatId, 37 | parseMode: ParseMode.Markdown, 38 | text: String.Format( 39 | "*[Request]*\n" + 40 | "🙋🏼‍♂️User *{0}:{1}* from group *{2}:[{3}]({4})* is requesting an Operator\n" + 41 | "\n\n*hash_code:* #UB{5}-{6}", 42 | message.From.Id, 43 | message.From.Username, 44 | message.Chat.Id, 45 | message.Chat.Title, 46 | "https://t.me/" + message.Chat.Username, 47 | message.Chat.Id.ToString().Replace("-",""), 48 | Guid.NewGuid()) 49 | ); 50 | 51 | Manager.BotClient.SendTextMessageAsync( 52 | chatId: message.Chat.Id, 53 | parseMode: ParseMode.Markdown, 54 | text: String.Format( 55 | "The Operators have been advised about your call." + 56 | "Wait of any of them to join your group.") 57 | ); 58 | } 59 | else 60 | { 61 | Manager.BotClient.SendTextMessageAsync( 62 | chatId: CacheData.ControlChatId, 63 | parseMode: ParseMode.Markdown, 64 | text: String.Format( 65 | "*[Request]*\n" + 66 | "🙋🏼‍♂️User *{0}:{1}* from group *{2}:{3}* is requesting an Operator.\n" + 67 | "The group is private. Check for him in our [support group](https://t.me/unifiedban_group)." + 68 | "\n\n*hash_code:* #UB{4}-{5}", 69 | message.From.Id, 70 | message.From.Username, 71 | message.Chat.Id, 72 | message.Chat.Title, 73 | message.Chat.Id.ToString().Replace("-",""), 74 | Guid.NewGuid()) 75 | ); 76 | 77 | Manager.BotClient.SendTextMessageAsync( 78 | chatId: message.Chat.Id, 79 | parseMode: ParseMode.Markdown, 80 | text: String.Format( 81 | "The Operators have been advised but your group is private.\n" + 82 | "Please join our [support group](https://t.me/unifiedban_group).") 83 | ); 84 | } 85 | } 86 | 87 | public void Execute(CallbackQuery callbackQuery) { } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Captcha.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using Telegram.Bot; 9 | using Telegram.Bot.Types; 10 | using Telegram.Bot.Types.ReplyMarkups; 11 | using Telegram.Bot.Types.Enums; 12 | using Unifiedban.Models; 13 | using Unifiedban.Models.Group; 14 | 15 | 16 | namespace Unifiedban.Terminal.Bot.Command 17 | { 18 | public class Captcha : ICommand 19 | { 20 | public void Execute(Message message) { } 21 | 22 | public void Execute(CallbackQuery callbackQuery) 23 | { 24 | string[] args = callbackQuery.Data.Split(" "); 25 | long captchaId = Convert.ToInt64(args[1]); 26 | 27 | if (captchaId != callbackQuery.From.Id) 28 | return; 29 | 30 | if (args.Length > 2) 31 | { 32 | if (CacheData.CaptchaAutoKickTimers.ContainsKey(args[2])) 33 | { 34 | CacheData.CaptchaAutoKickTimers[args[2]].Stop(); 35 | CacheData.CaptchaAutoKickTimers.TryRemove(args[2], out var timer); 36 | } 37 | } 38 | 39 | Manager.BotClient.DeleteMessageAsync( 40 | callbackQuery.Message.Chat.Id, 41 | callbackQuery.Message.MessageId); 42 | 43 | Manager.BotClient.RestrictChatMemberAsync( 44 | callbackQuery.Message.Chat.Id, 45 | callbackQuery.From.Id, 46 | Manager.BotClient.GetChatAsync(callbackQuery.Message.Chat.Id).Result.Permissions); 47 | 48 | if (CacheData.CaptchaStrikes.ContainsKey(callbackQuery.From.Id)) 49 | { 50 | CacheData.CaptchaStrikes.Remove(callbackQuery.From.Id); 51 | } 52 | 53 | string name = callbackQuery.From.Username != null ? "@" + callbackQuery.From.Username : callbackQuery.From.FirstName; 54 | 55 | bool welcomeMessage = false; 56 | ConfigurationParameter welcomeMessageConfig = CacheData.GroupConfigs[callbackQuery.Message.Chat.Id] 57 | .Where(x => x.ConfigurationParameterId == "WelcomeMessage") 58 | .FirstOrDefault(); 59 | if (welcomeMessageConfig != null) 60 | if (welcomeMessageConfig.Value.ToLower() == "true") 61 | welcomeMessage = true; 62 | 63 | if (welcomeMessage) 64 | { 65 | BusinessLogic.ButtonLogic buttonLogic = new BusinessLogic.ButtonLogic(); 66 | List> buttons = new List>(); 67 | foreach (Button btn in buttonLogic 68 | .GetByChat(CacheData.Groups[callbackQuery.Message.Chat.Id] 69 | .GroupId)) 70 | { 71 | buttons.Add(new List()); 72 | buttons[buttons.Count -1].Add(InlineKeyboardButton.WithUrl(btn.Name, btn.Content)); 73 | } 74 | 75 | MessageQueueManager.EnqueueMessage( 76 | new Models.ChatMessage() 77 | { 78 | Timestamp = DateTime.UtcNow, 79 | Chat = callbackQuery.Message.Chat, 80 | ParseMode = ParseMode.Html, 81 | Text = Utils.Parsers.VariablesParser( 82 | CacheData.Groups[callbackQuery.Message.Chat.Id].WelcomeText, 83 | callbackQuery), 84 | ReplyMarkup = new InlineKeyboardMarkup( 85 | buttons 86 | ) 87 | }); 88 | 89 | return; 90 | } 91 | 92 | MessageQueueManager.EnqueueMessage( 93 | new Models.ChatMessage() 94 | { 95 | Timestamp = DateTime.UtcNow, 96 | Chat = callbackQuery.Message.Chat, 97 | ParseMode = ParseMode.Markdown, 98 | Text = CacheData.GetTranslation(CacheData.Groups[callbackQuery.Message.Chat.Id].SettingsLanguage, 99 | "captcha_ok", true).Replace("{{name}}", name), 100 | DisableNotification = true, 101 | PostSentAction = ChatMessage.PostSentActions.Destroy, 102 | AutoDestroyTimeInSeconds = 60 * 2 103 | }); 104 | 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/CaptchaError.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using Telegram.Bot; 7 | using Telegram.Bot.Types; 8 | using Telegram.Bot.Types.Enums; 9 | using Unifiedban.Terminal.Utils; 10 | 11 | 12 | namespace Unifiedban.Terminal.Bot.Command 13 | { 14 | public class CaptchaError : ICommand 15 | { 16 | public void Execute(Message message) { } 17 | 18 | public void Execute(CallbackQuery callbackQuery) 19 | { 20 | string[] args = callbackQuery.Data.Split(" "); 21 | long captchaId = Convert.ToInt64(args[1]); 22 | 23 | if (captchaId != callbackQuery.From.Id) 24 | return; 25 | 26 | if (CacheData.CaptchaStrikes.ContainsKey(callbackQuery.From.Id)) 27 | { 28 | CacheData.CaptchaStrikes[callbackQuery.From.Id] += 1; 29 | } 30 | else 31 | { 32 | CacheData.CaptchaStrikes[callbackQuery.From.Id] = 1; 33 | } 34 | 35 | if (CacheData.CaptchaStrikes[callbackQuery.From.Id] >= 2) 36 | { 37 | Manager.BotClient.DeleteMessageAsync( 38 | callbackQuery.Message.Chat.Id, 39 | callbackQuery.Message.MessageId); 40 | 41 | try 42 | { 43 | Manager.BotClient.BanChatMemberAsync(callbackQuery.Message.Chat.Id, callbackQuery.From.Id); 44 | if (callbackQuery.Message.Chat.Type == ChatType.Supergroup) 45 | Manager.BotClient.UnbanChatMemberAsync(callbackQuery.Message.Chat.Id, callbackQuery.From.Id); 46 | } 47 | catch 48 | { 49 | MessageQueueManager.EnqueueMessage( 50 | new Models.ChatMessage() 51 | { 52 | Timestamp = DateTime.UtcNow, 53 | Chat = callbackQuery.Message.Chat, 54 | ParseMode = ParseMode.Markdown, 55 | Text = CacheData.GetTranslation(CacheData.Groups[callbackQuery.Message.Chat.Id].SettingsLanguage, "command_kick_error") 56 | }); 57 | return; 58 | } 59 | 60 | UserTools.AddPenalty(callbackQuery.Message.Chat.Id, callbackQuery.From.Id, 61 | Models.TrustFactorLog.TrustFactorAction.kick, Manager.MyId); 62 | 63 | if (args.Length > 2) 64 | { 65 | if (CacheData.CaptchaAutoKickTimers.ContainsKey(args[2])) 66 | { 67 | CacheData.CaptchaAutoKickTimers[args[2]].Stop(); 68 | CacheData.CaptchaAutoKickTimers.TryRemove(args[2], out var timer); 69 | } 70 | } 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Check.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using Telegram.Bot; 10 | using Telegram.Bot.Types; 11 | using Telegram.Bot.Types.Enums; 12 | 13 | namespace Unifiedban.Terminal.Bot.Command 14 | { 15 | public class Check : ICommand 16 | { 17 | public void Execute(Message message) 18 | { 19 | if (!Utils.BotTools.IsUserOperator(message.From.Id) && 20 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 21 | { 22 | MessageQueueManager.EnqueueMessage( 23 | new Models.ChatMessage() 24 | { 25 | Timestamp = DateTime.UtcNow, 26 | Chat = message.Chat, 27 | ReplyToMessageId = message.MessageId, 28 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 29 | }); 30 | return; 31 | } 32 | 33 | bool canRestrictMembers = false; 34 | bool canDeleteMessages = false; 35 | bool canPinMessages = false; 36 | string text = CacheData.SysConfigs 37 | .Single(x => x.SysConfigId == "CommandCheckKoText").Value; 38 | 39 | var me = Manager.BotClient.GetChatMemberAsync(message.Chat.Id, Manager.MyId).Result; 40 | if (me is ChatMemberAdministrator chatMemberAdministrator) 41 | { 42 | canRestrictMembers = chatMemberAdministrator.CanRestrictMembers; 43 | canDeleteMessages = chatMemberAdministrator.CanDeleteMessages; 44 | canPinMessages = chatMemberAdministrator.CanPinMessages ?? false; 45 | } 46 | 47 | if (canRestrictMembers && canDeleteMessages) 48 | text = CacheData.SysConfigs.Single(x => x.SysConfigId == "CommandCheckOkText").Value; 49 | if(canDeleteMessages) 50 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 51 | 52 | text = text.Replace("{{has_ban_users}}", canRestrictMembers ? "{{true}}" : "{{false}}"); 53 | text = text.Replace("{{has_delete_messages}}", canDeleteMessages ? "{{true}}" : "{{false}}"); 54 | text = text.Replace("{{has_pin_messages}}", canPinMessages ? "{{true}}" : "{{false}}"); 55 | 56 | text = Utils.Parsers.VariablesParser(text); // TODO select group's settings language 57 | 58 | MessageQueueManager.EnqueueMessage( 59 | new Models.ChatMessage() 60 | { 61 | Timestamp = DateTime.UtcNow, 62 | Chat = message.Chat, 63 | ParseMode = ParseMode.Markdown, 64 | Text = text 65 | }); 66 | } 67 | 68 | public void Execute(CallbackQuery callbackQuery) { } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Disable.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Types; 9 | using Telegram.Bot.Types.Enums; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class Disable : ICommand 14 | { 15 | public void Execute(Message message) 16 | { 17 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 18 | 19 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Advanced)) 20 | { 21 | MessageQueueManager.EnqueueMessage( 22 | new Models.ChatMessage() 23 | { 24 | Timestamp = DateTime.UtcNow, 25 | Chat = message.Chat, 26 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 27 | }); 28 | Manager.BotClient.SendTextMessageAsync( 29 | chatId: CacheData.ControlChatId, 30 | parseMode: ParseMode.Markdown, 31 | text: String.Format( 32 | "User *{0}:{1}* tried to use command Disable!", 33 | message.From.Id, 34 | message.From.Username) 35 | ); 36 | return; 37 | } 38 | 39 | long chatId = 0; 40 | 41 | string[] data = message.Text.Split(" "); 42 | if (data.Length >= 2) 43 | { 44 | bool isInt = long.TryParse(data[1], out chatId); 45 | if (!isInt) 46 | { 47 | Manager.BotClient.SendTextMessageAsync( 48 | chatId: message.Chat.Id, 49 | parseMode: ParseMode.Markdown, 50 | text: "The provided chatId is not a number.\n" 51 | + "**Syntax:**\n/disable (current group)\n/disable {chatId}" 52 | ); 53 | return; 54 | } 55 | } 56 | else 57 | chatId = message.Chat.Id; 58 | 59 | CacheData.Groups[message.Chat.Id].State = Models.Group.TelegramGroup.Status.Inactive; 60 | 61 | MessageQueueManager.EnqueueMessage( 62 | new Models.ChatMessage() 63 | { 64 | Timestamp = DateTime.UtcNow, 65 | Chat = message.Chat, 66 | Text = CacheData.GetTranslation("en", "command_disable_successful") 67 | }); 68 | Manager.BotClient.SendTextMessageAsync( 69 | chatId: CacheData.ControlChatId, 70 | parseMode: ParseMode.Markdown, 71 | text: String.Format( 72 | "Operator *{0}* has disabled group {1}:{2}", 73 | message.From.Id, 74 | message.Chat.Id, message.Chat.Title) 75 | ); 76 | } 77 | 78 | public void Execute(CallbackQuery callbackQuery) { } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Echo.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | using System.Threading.Tasks; 11 | using Telegram.Bot.Types; 12 | using Telegram.Bot.Types.Enums; 13 | using Telegram.Bot.Types.ReplyMarkups; 14 | using Unifiedban.Models.Translation; 15 | 16 | namespace Unifiedban.Terminal.Bot.Command 17 | { 18 | public class Echo : ICommand 19 | { 20 | public void Execute(Message message) 21 | { 22 | if (CacheData.Operators 23 | .SingleOrDefault(x => x.TelegramUserId == message.From.Id 24 | && x.Level == Models.Operator.Levels.Super) == null) 25 | { 26 | MessageQueueManager.EnqueueMessage( 27 | new Models.ChatMessage() 28 | { 29 | Timestamp = DateTime.UtcNow, 30 | Chat = message.Chat, 31 | ReplyToMessageId = message.MessageId, 32 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 33 | }); 34 | return; 35 | } 36 | 37 | if(message.ReplyToMessage == null) 38 | { 39 | MessageQueueManager.EnqueueMessage( 40 | new Models.ChatMessage() 41 | { 42 | Timestamp = DateTime.UtcNow, 43 | Chat = message.Chat, 44 | ReplyToMessageId = message.MessageId, 45 | Text = "This command works only as reply to an exsisting message" 46 | }); 47 | return; 48 | } 49 | 50 | MessageQueueManager.EnqueueMessage( 51 | new Models.ChatMessage() 52 | { 53 | Timestamp = DateTime.UtcNow, 54 | Chat = message.Chat, 55 | ReplyToMessageId = message.MessageId, 56 | ParseMode = ParseMode.Markdown, 57 | Text = Utils.Parsers.VariablesParser(message.ReplyToMessage.Text, message) 58 | }); 59 | } 60 | 61 | public void Execute(CallbackQuery callbackQuery) { } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Enable.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Types; 9 | using Telegram.Bot.Types.Enums; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class Enable : ICommand 14 | { 15 | public void Execute(Message message) 16 | { 17 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 18 | 19 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Advanced)) 20 | { 21 | MessageQueueManager.EnqueueMessage( 22 | new Models.ChatMessage() 23 | { 24 | Timestamp = DateTime.UtcNow, 25 | Chat = message.Chat, 26 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 27 | }); 28 | Manager.BotClient.SendTextMessageAsync( 29 | chatId: CacheData.ControlChatId, 30 | parseMode: ParseMode.Markdown, 31 | text: String.Format( 32 | "User *{0}:{1}* tried to use command Enable!", 33 | message.From.Id, 34 | message.From.Username) 35 | ); 36 | return; 37 | } 38 | 39 | long chatId = 0; 40 | 41 | string[] data = message.Text.Split(" "); 42 | if (data.Length >= 2) 43 | { 44 | bool isInt = long.TryParse(data[1], out chatId); 45 | if (!isInt) 46 | { 47 | Manager.BotClient.SendTextMessageAsync( 48 | chatId: message.Chat.Id, 49 | parseMode: ParseMode.Markdown, 50 | text: "The provided chatId is not a number.\n" 51 | + "**Syntax:**\n/enable (current group)\n/enable {chatId}" 52 | ); 53 | return; 54 | } 55 | } 56 | else 57 | chatId = message.Chat.Id; 58 | 59 | CacheData.Groups[message.Chat.Id].State = Models.Group.TelegramGroup.Status.Active; 60 | 61 | MessageQueueManager.EnqueueMessage( 62 | new Models.ChatMessage() 63 | { 64 | Timestamp = DateTime.UtcNow, 65 | Chat = message.Chat, 66 | Text = CacheData.GetTranslation("en", "command_enable_successful") 67 | }); 68 | Manager.BotClient.SendTextMessageAsync( 69 | chatId: CacheData.ControlChatId, 70 | parseMode: ParseMode.Markdown, 71 | text: String.Format( 72 | "Operator *{0}* has enabled group {1}:{2}", 73 | message.From.Id, 74 | message.Chat.Id, message.Chat.Title) 75 | ); 76 | } 77 | 78 | public void Execute(CallbackQuery callbackQuery) { } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/EndSupport.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using Telegram.Bot; 9 | using Telegram.Bot.Types; 10 | using Telegram.Bot.Types.Enums; 11 | using Telegram.Bot.Types.ReplyMarkups; 12 | using Unifiedban.Models; 13 | 14 | namespace Unifiedban.Terminal.Bot.Command 15 | { 16 | public class EndSupport : ICommand 17 | { 18 | public void Execute(Message message) 19 | { 20 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic)) 21 | { 22 | MessageQueueManager.EnqueueMessage( 23 | new Models.ChatMessage() 24 | { 25 | Timestamp = DateTime.UtcNow, 26 | Chat = message.Chat, 27 | Text = CacheData.GetTranslation("en", "feedback_command_error_notoperator") 28 | }); 29 | return; 30 | } 31 | 32 | if (CacheData.ActiveSupport.Contains(message.Chat.Id)) 33 | { 34 | CacheData.ActiveSupport.Remove(message.Chat.Id); 35 | CacheData.CurrentChatOperators.Remove(message.Chat.Id); 36 | 37 | Manager.BotClient.SendTextMessageAsync( 38 | chatId: message.Chat.Id, 39 | parseMode: ParseMode.Markdown, 40 | text: String.Format( 41 | "Operator *{0}* ended the support session.", 42 | message.From.Username) 43 | ); 44 | MessageQueueManager.EnqueueLog(new ChatMessage() 45 | { 46 | ParseMode = ParseMode.Markdown, 47 | Text = String.Format( 48 | "*[Log]*" + 49 | "\n\nSupport session ended by operator *{0}*" + 50 | "\nChatId: `{1}`" + 51 | "\nChat: `{2}`" + 52 | "\nUserId: `{3}`" + 53 | "\n\n*hash_code:* #UB{4}-{5}", 54 | message.From.Username, 55 | message.Chat.Id, 56 | message.Chat.Title, 57 | message.From.Id, 58 | message.Chat.Id.ToString().Replace("-", ""), 59 | Guid.NewGuid()) 60 | }); 61 | } 62 | } 63 | 64 | public void Execute(CallbackQuery callbackQuery) { } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Feedback.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Types; 9 | using Telegram.Bot.Types.Enums; 10 | using Telegram.Bot.Types.ReplyMarkups; 11 | 12 | namespace Unifiedban.Terminal.Bot.Command 13 | { 14 | public class Feedback : ICommand 15 | { 16 | public void Execute(Message message) 17 | { 18 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic) && 19 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 20 | { 21 | MessageQueueManager.EnqueueMessage( 22 | new Models.ChatMessage() 23 | { 24 | Timestamp = DateTime.UtcNow, 25 | Chat = message.Chat, 26 | Text = CacheData.GetTranslation("en", "feedback_command_error_notadmin") 27 | }); 28 | return; 29 | } 30 | 31 | List> buttons = new List>(); 32 | buttons.Add(new List(){ 33 | InlineKeyboardButton.WithCallbackData( 34 | CacheData.GetTranslation("en", "feedback_type_suggestion"), 35 | $"/feedback type:suggestion" 36 | ) 37 | }); 38 | buttons.Add(new List(){ 39 | InlineKeyboardButton.WithCallbackData( 40 | CacheData.GetTranslation("en", "feedback_type_reportBug"), 41 | $"/feedback type:reportBug" 42 | ) 43 | }); 44 | buttons.Add(new List(){ 45 | InlineKeyboardButton.WithCallbackData( 46 | CacheData.GetTranslation("en", "feedback_type_reportUser"), 47 | $"/feedback type:reportUser" 48 | ) 49 | }); 50 | 51 | MessageQueueManager.EnqueueMessage( 52 | new Models.ChatMessage() 53 | { 54 | Timestamp = DateTime.UtcNow, 55 | Chat = message.Chat, 56 | ReplyToMessageId = message.MessageId, 57 | ParseMode = ParseMode.Markdown, 58 | Text = "*[ADMIN]*\nSelect feedback type:", 59 | ReplyMarkup = new InlineKeyboardMarkup( 60 | buttons 61 | ) 62 | }); 63 | } 64 | 65 | public void Execute(CallbackQuery callbackQuery) 66 | { 67 | if (!Utils.BotTools.IsUserOperator(callbackQuery.From.Id, Models.Operator.Levels.Basic) && 68 | !Utils.ChatTools.IsUserAdmin(callbackQuery.Message.Chat.Id, callbackQuery.From.Id)) 69 | { 70 | return; 71 | } 72 | 73 | Manager.BotClient.DeleteMessageAsync(callbackQuery.Message.Chat.Id, callbackQuery.Message.MessageId); 74 | 75 | string data = callbackQuery.Data.Replace("/feedback ", ""); 76 | string type = data.Split(':')[1]; 77 | 78 | CommandMessage commandMessage = new CommandMessage() 79 | { 80 | Command = "Feedback", 81 | Value = type, 82 | Message = callbackQuery.Message, 83 | Timestamp = DateTime.UtcNow 84 | }; 85 | CommandQueueManager.EnqueueMessage(commandMessage); 86 | 87 | MessageQueueManager.EnqueueMessage( 88 | new Models.ChatMessage() 89 | { 90 | Timestamp = DateTime.UtcNow, 91 | Chat = callbackQuery.Message.Chat, 92 | ReplyToMessageId = callbackQuery.Message.ReplyToMessage.MessageId, 93 | ParseMode = ParseMode.Markdown, 94 | Text = $"*[ADMIN] [r:{callbackQuery.Message.MessageId}]*\nProvide feedback text:", 95 | ReplyMarkup = new ForceReplyMarkup() { Selective = true } 96 | }); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/GetTrustFactor.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Types; 9 | using Telegram.Bot.Types.Enums; 10 | using Unifiedban.Terminal.Utils; 11 | 12 | namespace Unifiedban.Terminal.Bot.Command 13 | { 14 | public class GetTrustFactor : ICommand 15 | { 16 | public void Execute(Message message) 17 | { 18 | long userId; 19 | 20 | if (message.ReplyToMessage == null) 21 | { 22 | if (!message.Text.Trim().Contains(" ")) 23 | { 24 | userId = message.From.Id; 25 | } 26 | else if (message.Text.Split(" ")[1].StartsWith("@")) 27 | { 28 | if (!CacheData.Usernames.Keys.Contains(message.Text.Split(" ")[1].Remove(0, 1))) 29 | { 30 | MessageQueueManager.EnqueueMessage( 31 | new Models.ChatMessage() 32 | { 33 | Timestamp = DateTime.UtcNow, 34 | Chat = message.Chat, 35 | Text = CacheData.GetTranslation("en", "gettrustfactor_command_error_invalidUsername") 36 | }); 37 | return; 38 | } 39 | userId = CacheData.Usernames[message.Text.Split(" ")[1].Remove(0, 1)]; 40 | } 41 | else 42 | { 43 | bool isValid = long.TryParse(message.Text.Split(" ")[1], out userId); 44 | if (!isValid) 45 | { 46 | MessageQueueManager.EnqueueMessage( 47 | new Models.ChatMessage() 48 | { 49 | Timestamp = DateTime.UtcNow, 50 | Chat = message.Chat, 51 | Text = CacheData.GetTranslation("en", "gettrustfactor_command_error_invalidUserId") 52 | }); 53 | return; 54 | } 55 | } 56 | } 57 | else 58 | userId = message.ReplyToMessage.From.Id; 59 | 60 | int points = 100; 61 | if (CacheData.TrustFactors.ContainsKey(userId)) 62 | { 63 | points = CacheData.TrustFactors[userId].Points; 64 | } 65 | 66 | string answerNoUsername = CacheData.GetTranslation("en", "gettrustfactor_command_text"); 67 | string answerWithUsername = CacheData.GetTranslation("en", "gettrustfactor_command_text_wuser"); 68 | string username = CacheData.Usernames.Single(x => x.Value == userId).Key; 69 | if (String.IsNullOrEmpty(username)) 70 | { 71 | MessageQueueManager.EnqueueMessage( 72 | new Models.ChatMessage() 73 | { 74 | Timestamp = DateTime.UtcNow, 75 | Chat = message.Chat, 76 | ReplyToMessageId = message.MessageId, 77 | Text = String.Format(answerNoUsername, userId, points) 78 | }); 79 | Manager.BotClient.SendTextMessageAsync( 80 | chatId: CacheData.ControlChatId, 81 | parseMode: ParseMode.Markdown, 82 | text: String.Format(answerNoUsername, userId, points)); 83 | 84 | Manager.BotClient.SendTextMessageAsync( 85 | chatId: CacheData.ControlChatId, 86 | parseMode: ParseMode.Markdown, 87 | text: String.Format( 88 | "*[Report]*\n" + 89 | "ℹ️Requested trust factor of user.\n" + 90 | "\n*Chat:* {0}" + 91 | "\n*ChatId:* {1}" + 92 | "\n*UserId:* {2}" + 93 | "\n*Username:* `{3}`" + 94 | "\n*Trust factor:* {4}/100" + (points < 71 ? " ⚠️" : "") + 95 | "\n\n*hash_code:* #UB{5}-{6}", 96 | message.Chat.Title, 97 | message.Chat.Id, 98 | userId, 99 | username, 100 | points, 101 | message.Chat.Id.ToString().Replace("-",""), 102 | Guid.NewGuid()) 103 | ); 104 | } 105 | else 106 | { 107 | MessageQueueManager.EnqueueMessage( 108 | new Models.ChatMessage() 109 | { 110 | Timestamp = DateTime.UtcNow, 111 | Chat = message.Chat, 112 | ReplyToMessageId = message.MessageId, 113 | Text = String.Format(answerWithUsername, userId, points, username) 114 | }); 115 | Manager.BotClient.SendTextMessageAsync( 116 | chatId: CacheData.ControlChatId, 117 | parseMode: ParseMode.Markdown, 118 | text: String.Format( 119 | "*[Report]*\n" + 120 | "ℹ️ Requested trust factor of user.\n" + 121 | "\n*Chat:* {0}" + 122 | "\n*ChatId:* {1}" + 123 | "\n*UserId:* {2}" + 124 | "\n*Trust factor:* {4}/100" + (points < 71 ? " ⚠️" : "") + 125 | "\n\n*hash_code:* #UB{5}-{6}", 126 | message.Chat.Title, 127 | message.Chat.Id, 128 | userId, 129 | username, 130 | points, 131 | message.Chat.Id.ToString().Replace("-",""), 132 | Guid.NewGuid()) 133 | ); 134 | } 135 | } 136 | 137 | public void Execute(CallbackQuery callbackQuery) { } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Help.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Types; 9 | using Telegram.Bot.Types.Enums; 10 | using Unifiedban.Terminal.Utils; 11 | 12 | namespace Unifiedban.Terminal.Bot.Command 13 | { 14 | public class Help : ICommand 15 | { 16 | public void Execute(Message message) 17 | { 18 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 19 | 20 | string text = Utils.Parsers.VariablesParser(CacheData.SysConfigs 21 | .Single(x => x.SysConfigId == "HelpMenu") 22 | .Value); 23 | 24 | if (ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 25 | { 26 | text += Environment.NewLine; 27 | text += CacheData.SysConfigs 28 | .Single(x => x.SysConfigId == "HelpMenuAdmin") 29 | .Value; 30 | } 31 | 32 | if (BotTools.IsUserOperator(message.From.Id)) 33 | { 34 | text += Environment.NewLine; 35 | text += CacheData.SysConfigs 36 | .Single(x => x.SysConfigId == "HelpMenuOperatorBase") 37 | .Value; 38 | 39 | if (BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Advanced)) 40 | { 41 | text += Environment.NewLine; 42 | text += CacheData.SysConfigs 43 | .Single(x => x.SysConfigId == "HelpMenuOperatorAdv") 44 | .Value; 45 | } 46 | } 47 | 48 | text += Environment.NewLine; 49 | text += Environment.NewLine; 50 | text += "* usernames are saved in cache and never stored on database or file. The cache is cleared at every reboot or update."; 51 | 52 | MessageQueueManager.EnqueueMessage( 53 | new Models.ChatMessage() 54 | { 55 | Timestamp = DateTime.UtcNow, 56 | Chat = message.Chat, 57 | ParseMode = ParseMode.Html, 58 | Text = text 59 | }); 60 | } 61 | 62 | public void Execute(CallbackQuery callbackQuery) { } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/ICommand.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Telegram.Bot.Types; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public interface ICommand 14 | { 15 | void Execute(Message message); 16 | void Execute(CallbackQuery callbackQuery); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Id.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using Telegram.Bot; 10 | using Telegram.Bot.Types; 11 | using Telegram.Bot.Types.Enums; 12 | 13 | namespace Unifiedban.Terminal.Bot.Command 14 | { 15 | public class Id : ICommand 16 | { 17 | public void Execute(Message message) 18 | { 19 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 20 | 21 | string replyText = ""; 22 | 23 | if (message.ReplyToMessage != null) 24 | { 25 | if (message.ReplyToMessage.ForwardFrom != null) 26 | { 27 | if (!Utils.BotTools.IsUserOperator(message.ReplyToMessage.ForwardFrom.Id)) 28 | { 29 | replyText = CacheData.GetTranslation("en", "command_id_fromReply_negative"); 30 | replyText = Utils.Parsers.VariablesParser( 31 | replyText.Replace("replyToMessage_from_username", "replyToMessage_forwardFrom_from_username"), 32 | message); 33 | goto doReply; 34 | } 35 | else 36 | { 37 | replyText = CacheData.GetTranslation("en", "command_id_fromReply_positive"); 38 | replyText = Utils.Parsers.VariablesParser( 39 | replyText.Replace("replyToMessage_from_username", "replyToMessage_forwardFrom_from_username"), 40 | message); 41 | goto doReply; 42 | } 43 | } 44 | 45 | if (!Utils.BotTools.IsUserOperator(message.ReplyToMessage.From.Id)) 46 | { 47 | replyText = CacheData.GetTranslation("en", "command_id_fromReply_negative"); 48 | replyText = Utils.Parsers.VariablesParser(replyText, message); 49 | goto doReply; 50 | } 51 | else 52 | { 53 | replyText = CacheData.GetTranslation("en", "command_id_fromReply_positive"); 54 | replyText = Utils.Parsers.VariablesParser(replyText, message); 55 | goto doReply; 56 | } 57 | } 58 | 59 | if (!Utils.BotTools.IsUserOperator(message.From.Id)) 60 | { 61 | replyText = CacheData.GetTranslation("en", "command_id_negative"); 62 | replyText = Utils.Parsers.VariablesParser(replyText, message); 63 | 64 | Manager.BotClient.SendTextMessageAsync( 65 | chatId: CacheData.ControlChatId, 66 | parseMode: ParseMode.Markdown, 67 | text: String.Format( 68 | "*[Report]*\n" + 69 | "⚠️ Non operator used command /id\n" + 70 | "\n*Chat:* {0}" + 71 | "\n*ChatId:* {1}" + 72 | "\n*UserId:* {2}" + 73 | "\n*Username:* {3}" + 74 | "\n\n*hash_code:* #UB{4}-{5}", 75 | message.Chat.Title, 76 | message.Chat.Id, 77 | message.From.Id, 78 | message.From.Username, 79 | message.Chat.Id.ToString().Replace("-",""), 80 | Guid.NewGuid()) 81 | ); 82 | 83 | goto doReply; 84 | } 85 | 86 | 87 | replyText = CacheData.GetTranslation("en", "command_id_positive"); 88 | replyText = Utils.Parsers.VariablesParser(replyText, message); 89 | 90 | doReply: 91 | MessageQueueManager.EnqueueMessage( 92 | new Models.ChatMessage() 93 | { 94 | Timestamp = DateTime.UtcNow, 95 | Chat = message.Chat, 96 | ParseMode = ParseMode.Markdown, 97 | Text = replyText 98 | }); 99 | } 100 | 101 | public void Execute(CallbackQuery callbackQuery) { } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Invite.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Types; 9 | using Unifiedban.Models; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class Invite : ICommand 14 | { 15 | public void Execute(Message message) 16 | { 17 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 18 | 19 | var me = Manager.BotClient.GetChatMemberAsync(message.Chat.Id, Manager.MyId).Result; 20 | if (me is ChatMemberAdministrator { CanInviteUsers: false }) return; 21 | 22 | var memberAdmin = Manager.BotClient.GetChatAdministratorsAsync(message.Chat.Id).Result 23 | .Single(x => x.User.Id == message.From.Id); 24 | if (memberAdmin is ChatMemberAdministrator { CanInviteUsers: false }) return; 25 | 26 | try 27 | { 28 | var link = CacheData.Groups[message.Chat.Id].InviteLink ?? 29 | Manager.BotClient.ExportChatInviteLinkAsync(message.Chat).Result; 30 | 31 | MessageQueueManager.EnqueueMessage( 32 | new ChatMessage() 33 | { 34 | Timestamp = DateTime.UtcNow, 35 | ReplyToMessageId = message.MessageId, 36 | Chat = message.Chat, 37 | Text = link, 38 | PostSentAction = ChatMessage.PostSentActions.Destroy, 39 | AutoDestroyTimeInSeconds = 15 40 | }); 41 | } 42 | catch 43 | { 44 | MessageQueueManager.EnqueueMessage( 45 | new ChatMessage() 46 | { 47 | Timestamp = DateTime.UtcNow, 48 | Chat = message.Chat, 49 | Text = "Error generating invite link.", 50 | PostSentAction = ChatMessage.PostSentActions.Destroy, 51 | AutoDestroyTimeInSeconds = 10 52 | }); 53 | } 54 | } 55 | 56 | public void Execute(CallbackQuery callbackQuery) 57 | { 58 | return; 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/InviteToPrivate.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Requests; 9 | using Telegram.Bot.Types; 10 | using Unifiedban.Models; 11 | 12 | namespace Unifiedban.Terminal.Bot.Command 13 | { 14 | public class InviteToPrivate : ICommand 15 | { 16 | public void Execute(Message message) 17 | { 18 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 19 | 20 | var me = Manager.BotClient.GetChatMemberAsync(message.Chat.Id, Manager.MyId).Result; 21 | if (me is ChatMemberAdministrator { CanInviteUsers: false }) return; 22 | 23 | var memberAdmin = Manager.BotClient.GetChatAdministratorsAsync(message.Chat.Id).Result 24 | .Single(x => x.User.Id == message.From.Id); 25 | if (memberAdmin is ChatMemberAdministrator { CanInviteUsers: false }) return; 26 | 27 | try 28 | { 29 | var link = CacheData.Groups[message.Chat.Id].InviteLink ?? 30 | Manager.BotClient.ExportChatInviteLinkAsync(message.Chat).Result; 31 | 32 | var msg = $"Invite link for chat {message.Chat.Title} is {link}"; 33 | Manager.BotClient.SendTextMessageAsync(message.From.Id, msg); 34 | } 35 | catch 36 | { 37 | MessageQueueManager.EnqueueMessage( 38 | new ChatMessage() 39 | { 40 | Timestamp = DateTime.UtcNow, 41 | Chat = message.Chat, 42 | Text = "Error generating invite link.", 43 | PostSentAction = ChatMessage.PostSentActions.Destroy, 44 | AutoDestroyTimeInSeconds = 10 45 | }); 46 | } 47 | } 48 | 49 | public void Execute(CallbackQuery callbackQuery) 50 | { 51 | return; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Kick.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Types; 9 | using Telegram.Bot.Types.Enums; 10 | using Unifiedban.Terminal.Utils; 11 | 12 | namespace Unifiedban.Terminal.Bot.Command 13 | { 14 | public class Kick : ICommand 15 | { 16 | public void Execute(Message message) 17 | { 18 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 19 | 20 | if (!BotTools.IsUserOperator(message.From.Id) || 21 | !ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 22 | { 23 | MessageQueueManager.EnqueueMessage( 24 | new Models.ChatMessage() 25 | { 26 | Timestamp = DateTime.UtcNow, 27 | Chat = message.Chat, 28 | ReplyToMessageId = message.MessageId, 29 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 30 | }); 31 | return; 32 | } 33 | long userToKick; 34 | 35 | if (message.ReplyToMessage == null) 36 | { 37 | if (!message.Text.Contains(" ")) 38 | { 39 | MessageQueueManager.EnqueueMessage( 40 | new Models.ChatMessage() 41 | { 42 | Timestamp = DateTime.UtcNow, 43 | Chat = message.Chat, 44 | Text = CacheData.GetTranslation("en", "kick_command_error_invalidUserId") 45 | }); 46 | return; 47 | } 48 | 49 | if (message.Text.Split(" ")[1].StartsWith("@")) 50 | { 51 | if (!CacheData.Usernames.Keys.Contains(message.Text.Split(" ")[1].Remove(0, 1))) 52 | { 53 | MessageQueueManager.EnqueueMessage( 54 | new Models.ChatMessage() 55 | { 56 | Timestamp = DateTime.UtcNow, 57 | Chat = message.Chat, 58 | Text = CacheData.GetTranslation("en", "kick_command_error_invalidUsername") 59 | }); 60 | return; 61 | } 62 | userToKick = CacheData.Usernames[message.Text.Split(" ")[1].Remove(0, 1)]; 63 | } 64 | else 65 | { 66 | bool isValid = long.TryParse(message.Text.Split(" ")[1], out userToKick); 67 | if (!isValid) 68 | { 69 | MessageQueueManager.EnqueueMessage( 70 | new Models.ChatMessage() 71 | { 72 | Timestamp = DateTime.UtcNow, 73 | Chat = message.Chat, 74 | Text = CacheData.GetTranslation("en", "kick_command_error_invalidUserId") 75 | }); 76 | return; 77 | } 78 | } 79 | } 80 | else 81 | userToKick = message.ReplyToMessage.From.Id; 82 | 83 | if (userToKick == 777000) // Telegram's official updateServiceNotification 84 | { 85 | Manager.BotClient.SendTextMessageAsync( 86 | chatId: message.Chat.Id, 87 | parseMode: ParseMode.Markdown, 88 | text: String.Format( 89 | "*[Error]*\n" + 90 | "This is an official Telegram's user/id.") 91 | ); 92 | 93 | return; 94 | } 95 | 96 | if (BotTools.IsUserOperator(userToKick)) 97 | { 98 | MessageQueueManager.EnqueueMessage( 99 | new Models.ChatMessage() 100 | { 101 | Timestamp = DateTime.UtcNow, 102 | Chat = message.Chat, 103 | Text = CacheData.GetTranslation("en", "command_to_operator_not_allowed") 104 | }); 105 | 106 | return; 107 | } 108 | 109 | if (!ChatTools.IsUserAdmin(message.Chat.Id, Manager.MyId)) 110 | { 111 | MessageQueueManager.EnqueueMessage( 112 | new Models.ChatMessage() 113 | { 114 | Timestamp = DateTime.UtcNow, 115 | Chat = message.Chat, 116 | Text = CacheData.GetTranslation("en", "ban_command_error_adminPrivilege") 117 | }); 118 | return; 119 | } 120 | 121 | if (!CacheData.ChatAdmins[message.Chat.Id][Manager.MyId].CanRestrictMembers) 122 | { 123 | MessageQueueManager.EnqueueMessage( 124 | new Models.ChatMessage() 125 | { 126 | Timestamp = DateTime.UtcNow, 127 | Chat = message.Chat, 128 | Text = CacheData.GetTranslation("en", "ban_command_error_adminPrivilege") 129 | }); 130 | return; 131 | } 132 | 133 | try 134 | { 135 | Manager.BotClient.BanChatMemberAsync(message.Chat.Id, userToKick); 136 | if (message.Chat.Type == ChatType.Supergroup) 137 | { 138 | System.Threading.Thread.Sleep(200); 139 | Manager.BotClient.UnbanChatMemberAsync(message.Chat.Id, userToKick); 140 | } 141 | } 142 | catch 143 | { 144 | MessageQueueManager.EnqueueMessage( 145 | new Models.ChatMessage() 146 | { 147 | Timestamp = DateTime.UtcNow, 148 | Chat = message.Chat, 149 | ParseMode = ParseMode.Markdown, 150 | Text = CacheData.GetTranslation("en", "command_kick_error") 151 | }); 152 | return; 153 | } 154 | 155 | UserTools.AddPenalty(message.Chat.Id, userToKick, 156 | Models.TrustFactorLog.TrustFactorAction.kick, Manager.MyId); 157 | } 158 | 159 | public void Execute(CallbackQuery callbackQuery) { } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Leave.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using Telegram.Bot; 10 | using Telegram.Bot.Types; 11 | using Telegram.Bot.Types.Enums; 12 | using Telegram.Bot.Types.ReplyMarkups; 13 | 14 | namespace Unifiedban.Terminal.Bot.Command 15 | { 16 | public class Leave : ICommand 17 | { 18 | public void Execute(Message message) 19 | { 20 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 21 | 22 | var sender = message.SenderChat?.Id ?? message.From?.Id ?? 0; 23 | var isOperator = Utils.BotTools.IsUserOperator(sender, Models.Operator.Levels.Basic); 24 | var isAdmin = Utils.ChatTools.IsUserAdmin(message.Chat.Id, sender); 25 | if (!isOperator && !isAdmin) 26 | { 27 | MessageQueueManager.EnqueueMessage( 28 | new Models.ChatMessage() 29 | { 30 | Timestamp = DateTime.UtcNow, 31 | Chat = message.Chat, 32 | Text = CacheData.GetTranslation("en", "ban_command_error_notadmin") 33 | }); 34 | return; 35 | } 36 | 37 | if (isAdmin) 38 | { 39 | var adminPermissions = CacheData.ChatAdmins[message.Chat.Id][sender]; 40 | if (!adminPermissions.CanManageChat) 41 | { 42 | MessageQueueManager.EnqueueMessage( 43 | new Models.ChatMessage() 44 | { 45 | Timestamp = DateTime.UtcNow, 46 | Chat = message.Chat, 47 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 48 | }); 49 | return; 50 | } 51 | } 52 | 53 | List confirmationButton = new List(); 54 | confirmationButton.Add(InlineKeyboardButton.WithCallbackData( 55 | CacheData.GetTranslation("en", "yes", true), 56 | $"/Leave yes" 57 | )); 58 | confirmationButton.Add(InlineKeyboardButton.WithCallbackData( 59 | CacheData.GetTranslation("en", "no", true), 60 | $"/Leave no" 61 | )); 62 | 63 | Manager.BotClient.SendTextMessageAsync( 64 | chatId: message.Chat.Id, 65 | parseMode: ParseMode.Markdown, 66 | text: "*[ADMIN]*\nAre you sure you want to leave?", 67 | replyMarkup: new InlineKeyboardMarkup( 68 | confirmationButton 69 | ) 70 | ); 71 | } 72 | 73 | public void Execute(CallbackQuery callbackQuery) 74 | { 75 | if (!Utils.BotTools.IsUserOperator(callbackQuery.From.Id) && 76 | !Utils.ChatTools.IsUserAdmin(callbackQuery.Message.Chat.Id, 77 | callbackQuery.From.Id)) 78 | { 79 | Manager.BotClient.SendTextMessageAsync( 80 | chatId: CacheData.ControlChatId, 81 | parseMode: ParseMode.Markdown, 82 | text: String.Format( 83 | "User *{0}:{1}* tried to use answer to command Leave.", 84 | callbackQuery.Message.From.Id, 85 | callbackQuery.Message.From.Username) 86 | ); 87 | return; 88 | } 89 | 90 | Manager.BotClient.DeleteMessageAsync(callbackQuery.Message.Chat.Id, callbackQuery.Message.MessageId); 91 | 92 | string data = callbackQuery.Data.Replace("/Leave ", ""); 93 | if(data == "yes") 94 | { 95 | Manager.BotClient.SendTextMessageAsync( 96 | chatId: callbackQuery.Message.Chat.Id, 97 | parseMode: ParseMode.Markdown, 98 | text: "Well, I hope to see you soon...\n\nGood bye! 👋🏼" 99 | ); 100 | 101 | Manager.BotClient.SendTextMessageAsync( 102 | chatId: CacheData.ControlChatId, 103 | parseMode: ParseMode.Markdown, 104 | text: String.Format( 105 | "*[Log]*\n" + 106 | "😢 Group left due to command /leave\n" + 107 | "\n*Chat:* {0}" + 108 | "\n*ChatId:* {1}" + 109 | "\n*UserId:* {2}" + 110 | "\n\n*hash_code:* #UB{3}-{4}", 111 | callbackQuery.Message.Chat.Title, 112 | callbackQuery.Message.Chat.Id, 113 | callbackQuery.From.Id, 114 | callbackQuery.Message.Chat.Id.ToString().Replace("-",""), 115 | Guid.NewGuid()) 116 | ); 117 | 118 | System.Threading.Thread.Sleep(1000); // Wait that the goodbye message is sent 119 | Manager.BotClient.LeaveChatAsync(callbackQuery.Message.Chat.Id); 120 | } 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Motd.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using System.Linq; 9 | using System.Threading.Tasks; 10 | using Telegram.Bot.Types; 11 | 12 | namespace Unifiedban.Terminal.Bot.Command 13 | { 14 | public class Motd : ICommand 15 | { 16 | public void Execute(Message message) 17 | { 18 | MessageQueueManager.EnqueueMessage( 19 | new Models.ChatMessage() 20 | { 21 | Timestamp = DateTime.UtcNow, 22 | Chat = message.Chat, 23 | Text = CacheData.SysConfigs 24 | .Single(x => x.SysConfigId == "motd") 25 | .Value 26 | }); 27 | } 28 | 29 | public void Execute(CallbackQuery callbackQuery) 30 | { 31 | return; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Parser.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Threading.Tasks; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Types; 9 | using Unifiedban.Models; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class Parser 14 | { 15 | public static async Task Parse(Message message) 16 | { 17 | string command = message.Text.Split(" ")[0].Remove(0, 1); 18 | if (command.Contains("@")) 19 | { 20 | if (!String.Equals(command.Split("@")[1], 21 | Manager.Username, StringComparison.CurrentCultureIgnoreCase)) 22 | return false; 23 | command = command.Split("@")[0]; 24 | } 25 | 26 | if (!Commands.CommandsList.TryGetValue(command.ToUpper(), out ICommand parsedCommand)) 27 | { 28 | #if DEBUG 29 | if(CacheData.AnswerInvalidCommand) 30 | await Manager.BotClient.SendTextMessageAsync( 31 | chatId: message.Chat.Id, 32 | text: CacheData.GetTranslation("en", "error_invalid_command") 33 | ); 34 | #endif 35 | return false; 36 | } 37 | 38 | string parameters = message.Text.Contains(" ") ? "a- " + message.Text.Substring(command.Length + 1) : ""; 39 | 40 | if (message.ReplyToMessage != null && !message.Text.Contains(" ")) 41 | { 42 | parameters = " r- " + message.ReplyToMessage.MessageId.ToString(); 43 | } 44 | 45 | if (message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Group || 46 | message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Supergroup) 47 | { 48 | await Task.Run(() => Utils.LogTools.AddOperationLog(new OperationLog() 49 | { 50 | UtcDate = DateTime.UtcNow, 51 | GroupId = CacheData.Groups[message.Chat.Id].GroupId, 52 | TelegramUserId = message.From.Id, 53 | Action = command, 54 | Parameters = parameters.Trim() 55 | })); 56 | } 57 | await Task.Run(() => parsedCommand.Execute(message)); 58 | return true; 59 | } 60 | 61 | public static async Task Parse(CallbackQuery callbackQuery) 62 | { 63 | string command = callbackQuery.Data.Split(" ")[0].Remove(0, 1); 64 | 65 | if (!Commands.CommandsList.TryGetValue(command.ToUpper(), out ICommand parsedCommand)) 66 | { 67 | #if DEBUG 68 | await Manager.BotClient.SendTextMessageAsync( 69 | chatId: callbackQuery.Message.Chat.Id, 70 | text: CacheData.GetTranslation("en", "error_invalid_command") 71 | ); 72 | #endif 73 | return false; 74 | } 75 | 76 | await Task.Run(() => parsedCommand.Execute(callbackQuery)); 77 | return true; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Pin.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using Telegram.Bot; 10 | using Telegram.Bot.Types; 11 | using Telegram.Bot.Types.Enums; 12 | 13 | namespace Unifiedban.Terminal.Bot.Command 14 | { 15 | public class Pin : ICommand 16 | { 17 | public void Execute(Message message) 18 | { 19 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 20 | 21 | if (!Utils.BotTools.IsUserOperator(message.From.Id) && 22 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 23 | { 24 | MessageQueueManager.EnqueueMessage( 25 | new Models.ChatMessage() 26 | { 27 | Timestamp = DateTime.UtcNow, 28 | Chat = message.Chat, 29 | ReplyToMessageId = message.MessageId, 30 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 31 | }); 32 | return; 33 | } 34 | 35 | if(message.ReplyToMessage == null) 36 | { 37 | MessageQueueManager.EnqueueMessage( 38 | new Models.ChatMessage() 39 | { 40 | Timestamp = DateTime.UtcNow, 41 | Chat = message.Chat, 42 | ParseMode = ParseMode.Markdown, 43 | Text = CacheData.GetTranslation("en", "command_pin_missingMessage") 44 | }); 45 | return; 46 | } 47 | 48 | Manager.BotClient.PinChatMessageAsync(message.Chat.Id, message.ReplyToMessage.MessageId); 49 | } 50 | 51 | public void Execute(CallbackQuery callbackQuery) { } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/ReloadConf.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using Telegram.Bot; 11 | using Telegram.Bot.Types; 12 | using Telegram.Bot.Types.Enums; 13 | 14 | namespace Unifiedban.Terminal.Bot.Command 15 | { 16 | public class ReloadConf : ICommand 17 | { 18 | public void Execute(Message message) 19 | { 20 | if(CacheData.Operators 21 | .SingleOrDefault(x => x.TelegramUserId == message.From.Id 22 | && x.Level == Models.Operator.Levels.Super) == null) 23 | { 24 | MessageQueueManager.EnqueueMessage( 25 | new Models.ChatMessage() 26 | { 27 | Timestamp = DateTime.UtcNow, 28 | Chat = message.Chat, 29 | ReplyToMessageId = message.MessageId, 30 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 31 | }); 32 | Manager.BotClient.SendTextMessageAsync( 33 | chatId: CacheData.ControlChatId, 34 | parseMode: ParseMode.Markdown, 35 | text: String.Format( 36 | "*[Report]*\n" + 37 | "⚠️ Non operator tried to use /reload\n" + 38 | "\n*Chat:* {0}" + 39 | "\n*ChatId:* {1}" + 40 | "\n*UserId:* {2}" + 41 | "\n\n*hash_code:* #UB{3}-{4}", 42 | message.Chat.Title, 43 | message.Chat.Id, 44 | message.From.Id, 45 | message.Chat.Id.ToString().Replace("-",""), 46 | Guid.NewGuid()) 47 | ); 48 | 49 | return; 50 | } 51 | 52 | try 53 | { 54 | BusinessLogic.SysConfigLogic sysConfigLogic = new BusinessLogic.SysConfigLogic(); 55 | CacheData.SysConfigs = new List(sysConfigLogic.Get()); 56 | 57 | Data.Utils.Logging.AddLog(new Models.SystemLog() 58 | { 59 | LoggerName = CacheData.LoggerName, 60 | Date = DateTime.Now, 61 | Function = "Unifiedban.Terminal.Command.ReloadConf", 62 | Level = Models.SystemLog.Levels.Info, 63 | Message = "Conf reloaded successfully.", 64 | UserId = -1 65 | 66 | }); 67 | Manager.BotClient.SendTextMessageAsync( 68 | chatId: message.Chat.Id, 69 | text: "Conf reloaded successfully." 70 | ); 71 | } 72 | catch (Exception ex) 73 | { 74 | Data.Utils.Logging.AddLog(new Models.SystemLog() 75 | { 76 | LoggerName = CacheData.LoggerName, 77 | Date = DateTime.Now, 78 | Function = "Unifiedban.Terminal.Command.ReloadConf", 79 | Level = Models.SystemLog.Levels.Error, 80 | Message = ex.Message, 81 | UserId = -1 82 | }); 83 | 84 | Manager.BotClient.SendTextMessageAsync( 85 | chatId: message.Chat.Id, 86 | text: "Error reloading conf. Check logs." 87 | ); 88 | } 89 | } 90 | 91 | public void Execute(CallbackQuery callbackQuery) 92 | { 93 | return; 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/ReloadTranslations.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using Telegram.Bot; 11 | using Telegram.Bot.Types; 12 | using Telegram.Bot.Types.Enums; 13 | using Telegram.Bot.Types.ReplyMarkups; 14 | using Unifiedban.Models.Translation; 15 | 16 | namespace Unifiedban.Terminal.Bot.Command 17 | { 18 | public class ReloadTranslations : ICommand 19 | { 20 | public void Execute(Message message) 21 | { 22 | if (CacheData.Operators 23 | .SingleOrDefault(x => x.TelegramUserId == message.From.Id 24 | && x.Level == Models.Operator.Levels.Super) == null) 25 | { 26 | MessageQueueManager.EnqueueMessage( 27 | new Models.ChatMessage() 28 | { 29 | Timestamp = DateTime.UtcNow, 30 | Chat = message.Chat, 31 | ReplyToMessageId = message.MessageId, 32 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 33 | }); 34 | Manager.BotClient.SendTextMessageAsync( 35 | chatId: CacheData.ControlChatId, 36 | parseMode: ParseMode.Markdown, 37 | text: String.Format( 38 | "*[Report]*\n" + 39 | "⚠️ Non operator tried to use /reloadtranslations\n" + 40 | "\n*Chat:* {0}" + 41 | "\n*ChatId:* {1}" + 42 | "\n*UserId:* {2}" + 43 | "\n\n*hash_code:* #UB{3}-{4}", 44 | message.Chat.Title, 45 | message.Chat.Id, 46 | message.From.Id, 47 | message.Chat.Id.ToString().Replace("-",""), 48 | Guid.NewGuid()) 49 | ); 50 | return; 51 | } 52 | 53 | Program.InitializeTranslations(); 54 | MessageQueueManager.EnqueueMessage( 55 | new Models.ChatMessage() 56 | { 57 | Timestamp = DateTime.UtcNow, 58 | Chat = message.Chat, 59 | ReplyToMessageId = message.MessageId, 60 | Text = CacheData.GetTranslation("en", "done", true) 61 | }); 62 | } 63 | 64 | public void Execute(CallbackQuery callbackQuery) { } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/RemoveBadWord.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using Telegram.Bot; 7 | using Telegram.Bot.Types; 8 | 9 | namespace Unifiedban.Terminal.Bot.Command 10 | { 11 | public class RemoveBadWord : ICommand 12 | { 13 | public void Execute(Message message) 14 | { 15 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic) && 16 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 17 | { 18 | return; 19 | } 20 | 21 | string[] arguments = message.Text.Split(" "); 22 | 23 | if (arguments.Length < 2) 24 | { 25 | MessageQueueManager.EnqueueMessage( 26 | new Models.ChatMessage() 27 | { 28 | Timestamp = DateTime.UtcNow, 29 | Chat = message.Chat, 30 | Text = CacheData.GetTranslation("en", "rembadword_command_error_missingargument") 31 | }); 32 | return; 33 | } 34 | 35 | bool removed = Filters.BadWordFilter.RemoveBadWord( 36 | CacheData.Groups[message.Chat.Id].GroupId, 37 | arguments[1].Trim()); 38 | 39 | if (!removed) 40 | { 41 | MessageQueueManager.EnqueueMessage( 42 | new Models.ChatMessage() 43 | { 44 | Timestamp = DateTime.UtcNow, 45 | Chat = message.Chat, 46 | Text = CacheData.GetTranslation("en", "rembadword_command_error") 47 | }); 48 | return; 49 | } 50 | 51 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 52 | MessageQueueManager.EnqueueMessage( 53 | new Models.ChatMessage() 54 | { 55 | Timestamp = DateTime.UtcNow, 56 | Chat = message.Chat, 57 | Text = CacheData.GetTranslation("en", "rembadword_command_success") 58 | }); 59 | return; 60 | } 61 | 62 | public void Execute(CallbackQuery callbackQuery) { } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/RemoveFlood.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using Telegram.Bot; 9 | using Telegram.Bot.Types; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class RemoveFlood : ICommand 14 | { 15 | public void Execute(Message message){ } 16 | 17 | public void Execute(CallbackQuery callbackQuery) 18 | { 19 | if (!Utils.BotTools.IsUserOperator(callbackQuery.From.Id) && 20 | !Utils.ChatTools.IsUserAdmin(callbackQuery.Message.Chat.Id, callbackQuery.From.Id)) 21 | { 22 | return; 23 | } 24 | 25 | bool parsed = long.TryParse(callbackQuery.Data.Split(" ")[1], out long userId); 26 | if (!parsed) 27 | return; 28 | 29 | Manager.BotClient.DeleteMessageAsync( 30 | callbackQuery.Message.Chat.Id, 31 | callbackQuery.Message.MessageId); 32 | 33 | Manager.BotClient.RestrictChatMemberAsync( 34 | callbackQuery.Message.Chat.Id, 35 | userId, 36 | new ChatPermissions() 37 | { 38 | CanSendMessages = true, 39 | CanSendAudios = true, 40 | CanSendDocuments = true, 41 | CanSendPhotos = true, 42 | CanSendVideos = true, 43 | CanSendVideoNotes = true, 44 | CanSendVoiceNotes = true, 45 | CanSendPolls = true, 46 | CanSendOtherMessages = true, 47 | CanAddWebPagePreviews = true, 48 | CanChangeInfo = true, 49 | CanInviteUsers = true, 50 | CanPinMessages = true, 51 | CanManageTopics = true 52 | }); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/RemoveFromBlacklist.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using Microsoft.EntityFrameworkCore.Metadata.Internal; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using Telegram.Bot.Types; 10 | using Telegram.Bot.Types.Enums; 11 | using Telegram.Bot.Types.ReplyMarkups; 12 | 13 | namespace Unifiedban.Terminal.Bot.Command 14 | { 15 | public class RemoveFromBlacklist : ICommand 16 | { 17 | public void Execute(Message message) 18 | { 19 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Advanced)) 20 | { 21 | MessageQueueManager.EnqueueMessage( 22 | new Models.ChatMessage() 23 | { 24 | Timestamp = DateTime.UtcNow, 25 | Chat = message.Chat, 26 | Text = CacheData.GetTranslation("en", "white_command_error_notoperator") 27 | }); 28 | return; 29 | } 30 | 31 | long userToUnban; 32 | 33 | if (message.ReplyToMessage == null) 34 | { 35 | if (message.Text.Split(" ")[1].StartsWith("@")) 36 | { 37 | if (!CacheData.Usernames.Keys.Contains(message.Text.Split(" ")[1].Remove(0, 1))) 38 | { 39 | MessageQueueManager.EnqueueMessage( 40 | new Models.ChatMessage() 41 | { 42 | Timestamp = DateTime.UtcNow, 43 | Chat = message.Chat, 44 | Text = CacheData.GetTranslation("en", "white_command_error_invalidUsername") 45 | }); 46 | return; 47 | } 48 | userToUnban = CacheData.Usernames[message.Text.Split(" ")[1].Remove(0, 1)]; 49 | } 50 | else 51 | { 52 | bool isValid = long.TryParse(message.Text.Split(" ")[1], out userToUnban); 53 | if (!isValid) 54 | { 55 | MessageQueueManager.EnqueueMessage( 56 | new Models.ChatMessage() 57 | { 58 | Timestamp = DateTime.UtcNow, 59 | Chat = message.Chat, 60 | Text = CacheData.GetTranslation("en", "white_command_error_invalidUserId") 61 | }); 62 | return; 63 | } 64 | } 65 | } 66 | else 67 | userToUnban = message.ReplyToMessage.From.Id; 68 | 69 | Utils.UserTools.RemoveUserFromBlacklist(message, userToUnban); 70 | } 71 | 72 | public void Execute(CallbackQuery callbackQuery) { } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/RemoveNote.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using System.Text.RegularExpressions; 8 | using Telegram.Bot; 9 | using Telegram.Bot.Types; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class RemoveNote : ICommand 14 | { 15 | BusinessLogic.Group.NoteLogic noteLogic = new BusinessLogic.Group.NoteLogic(); 16 | 17 | public void Execute(Message message) 18 | { 19 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic) && 20 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 21 | { 22 | return; 23 | } 24 | 25 | Message messageToCheck = message; 26 | if (message.ReplyToMessage != null) 27 | messageToCheck = message.ReplyToMessage; 28 | 29 | if(messageToCheck.From.Id != Manager.MyId && 30 | !messageToCheck.Text.Contains("NoteId:")) 31 | { 32 | MessageQueueManager.EnqueueMessage( 33 | new Models.ChatMessage() 34 | { 35 | Timestamp = DateTime.UtcNow, 36 | Chat = message.Chat, 37 | ReplyToMessageId = message.MessageId, 38 | Text = CacheData.GetTranslation("en", "error_removenote_command_invalidmessage") 39 | }); 40 | return; 41 | } 42 | 43 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 44 | 45 | string noteId = messageToCheck.Text.Split("NoteId:")[1].Trim(); 46 | 47 | Models.Group.Note note = noteLogic.GetById(noteId); 48 | if (note == null) 49 | { 50 | MessageQueueManager.EnqueueMessage( 51 | new Models.ChatMessage() 52 | { 53 | Timestamp = DateTime.UtcNow, 54 | Chat = message.Chat, 55 | Text = CacheData.GetTranslation("en", "error_removenote_command_invalidNoteId") 56 | }); 57 | return; 58 | } 59 | 60 | if (note.GroupId != CacheData.Groups[messageToCheck.Chat.Id].GroupId) 61 | { 62 | MessageQueueManager.EnqueueMessage( 63 | new Models.ChatMessage() 64 | { 65 | Timestamp = DateTime.UtcNow, 66 | Chat = message.Chat, 67 | Text = CacheData.GetTranslation("en", "error_removenote_command_invalidOwner") 68 | }); 69 | return; 70 | } 71 | 72 | Models.SystemLog.ErrorCodes removed = noteLogic.Remove(noteId, -2); 73 | if(removed == Models.SystemLog.ErrorCodes.Error) 74 | MessageQueueManager.EnqueueMessage( 75 | new Models.ChatMessage() 76 | { 77 | Timestamp = DateTime.UtcNow, 78 | Chat = message.Chat, 79 | Text = CacheData.GetTranslation("en", "error_removenote_command_generic") 80 | }); 81 | 82 | if(message.MessageId != messageToCheck.MessageId) 83 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, messageToCheck.MessageId); 84 | 85 | MessageQueueManager.EnqueueMessage( 86 | new Models.ChatMessage() 87 | { 88 | Timestamp = DateTime.UtcNow, 89 | Chat = message.Chat, 90 | Text = CacheData.GetTranslation("en", "removenote_command_success"), 91 | AutoDestroyTimeInSeconds = 5, 92 | PostSentAction = Models.ChatMessage.PostSentActions.Destroy 93 | }); 94 | } 95 | 96 | public void Execute(CallbackQuery callbackQuery) { } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/RemoveSafeGroup.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using Telegram.Bot.Types; 7 | 8 | namespace Unifiedban.Terminal.Bot.Command 9 | { 10 | public class RemoveSafeGroup : ICommand 11 | { 12 | public void Execute(Message message) 13 | { 14 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic) && 15 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 16 | { 17 | MessageQueueManager.EnqueueMessage( 18 | new Models.ChatMessage() 19 | { 20 | Timestamp = DateTime.UtcNow, 21 | Chat = message.Chat, 22 | Text = CacheData.GetTranslation("en", "remsafe_command_error_notadmin") 23 | }); 24 | return; 25 | } 26 | 27 | string url = message.Text.Split(" ")[1]; 28 | 29 | if (message.Text.Split(" ")[1].StartsWith("@")) 30 | url = "https://t.me/" + message.Text.Split(" ")[1].Remove(0, 1); 31 | 32 | if (!Controls.Manager.IsTelegramLink(url)) 33 | { 34 | MessageQueueManager.EnqueueMessage( 35 | new Models.ChatMessage() 36 | { 37 | Timestamp = DateTime.UtcNow, 38 | Chat = message.Chat, 39 | Text = CacheData.GetTranslation("en", "remsafe_command_error_invalidgroupname") 40 | }); 41 | return; 42 | } 43 | 44 | BusinessLogic.Group.SafeGroupLogic safeGroupLogic = 45 | new BusinessLogic.Group.SafeGroupLogic(); 46 | Models.SystemLog.ErrorCodes removed = safeGroupLogic.Remove( 47 | CacheData.Groups[message.Chat.Id].GroupId, 48 | url, -2); 49 | if (removed == Models.SystemLog.ErrorCodes.Error) 50 | { 51 | MessageQueueManager.EnqueueMessage( 52 | new Models.ChatMessage() 53 | { 54 | Timestamp = DateTime.UtcNow, 55 | Chat = message.Chat, 56 | Text = CacheData.GetTranslation("en", "remsafe_command_error_general") 57 | }); 58 | return; 59 | } 60 | 61 | string confirmationMessage = CacheData.GetTranslation("en", "remsafe_command_success"); 62 | MessageQueueManager.EnqueueMessage( 63 | new Models.ChatMessage() 64 | { 65 | Timestamp = DateTime.UtcNow, 66 | Chat = message.Chat, 67 | Text = confirmationMessage.Replace("{{groupname}}", 68 | message.Text.Split(" ")[1].Trim()) 69 | }); 70 | 71 | Filters.SafeGroupFilter.LoadCache(); 72 | } 73 | 74 | public void Execute(CallbackQuery callbackQuery) { } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/RemoveWelcomeButton.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using Telegram.Bot; 9 | using Telegram.Bot.Types; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class RemoveWelcomeButton : ICommand 14 | { 15 | public void Execute(Message message) 16 | { 17 | if (!Utils.BotTools.IsUserOperator(message.From.Id) && 18 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 19 | { 20 | MessageQueueManager.EnqueueMessage( 21 | new Models.ChatMessage() 22 | { 23 | Timestamp = DateTime.UtcNow, 24 | Chat = message.Chat, 25 | ReplyToMessageId = message.MessageId, 26 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 27 | }); 28 | return; 29 | } 30 | 31 | string[] arguments = message.Text.Split(" "); 32 | if (arguments.Length < 2) 33 | { 34 | MessageQueueManager.EnqueueMessage( 35 | new Models.ChatMessage() 36 | { 37 | Timestamp = DateTime.UtcNow, 38 | Chat = message.Chat, 39 | ReplyToMessageId = message.MessageId, 40 | Text = CacheData.GetTranslation("en", "rwb_command_error_invalidsyntax") 41 | }); 42 | return; 43 | } 44 | 45 | BusinessLogic.ButtonLogic buttonLogic = new BusinessLogic.ButtonLogic(); 46 | Models.SystemLog.ErrorCodes removed = buttonLogic.Remove(CacheData.Groups[message.Chat.Id].GroupId, 47 | message.Text.Remove(0, arguments[0].Length + 1), -2); 48 | if (removed == Models.SystemLog.ErrorCodes.Error) 49 | { 50 | MessageQueueManager.EnqueueMessage( 51 | new Models.ChatMessage() 52 | { 53 | Timestamp = DateTime.UtcNow, 54 | Chat = message.Chat, 55 | ReplyToMessageId = message.MessageId, 56 | Text = CacheData.GetTranslation("en", "rwb_command_error_general") 57 | }); 58 | return; 59 | } 60 | 61 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 62 | string successMsg = CacheData.GetTranslation("en", "rwb_command_success"); 63 | MessageQueueManager.EnqueueMessage( 64 | new Models.ChatMessage() 65 | { 66 | Timestamp = DateTime.UtcNow, 67 | Chat = message.Chat, 68 | Text = successMsg.Replace("{{wbName}}", arguments[1]) 69 | }); 70 | } 71 | 72 | public void Execute(CallbackQuery callbackQuery) { } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Report.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using Telegram.Bot.Types; 9 | using Telegram.Bot.Types.Enums; 10 | using Unifiedban.Models; 11 | 12 | namespace Unifiedban.Terminal.Bot.Command 13 | { 14 | public class Report : ICommand 15 | { 16 | static Dictionary lastReport = new Dictionary(); 17 | 18 | public void Execute(Message message) 19 | { 20 | DateTime last; 21 | lastReport.TryGetValue(message.Chat.Id, out last); 22 | if (last != null) 23 | if ((DateTime.UtcNow - last).TotalSeconds < 30) 24 | return; 25 | 26 | string author = message.From.Username == null 27 | ? message.From.FirstName + " " + message.From.LastName 28 | : "@" + message.From.Username; 29 | string logMessage = String.Format( 30 | "*[Report]*\n" + 31 | "A user has reported a message\n" + 32 | "⚠ do not open links you don't know ⚠\n" + 33 | "\nChat: `{0}`" + 34 | "\nAuthor: `{1}`" + 35 | "\nUserId: `{2}`" + 36 | "\nOriginal message link: https://t.me/c/{4}/{3}\n" + 37 | "\n\n*hash_code:* #UB{4}-{5}", 38 | message.Chat.Title, 39 | author, 40 | message.From.Id, 41 | message.MessageId, 42 | message.Chat.Id.ToString().Replace("-", ""), 43 | Guid.NewGuid()); 44 | 45 | 46 | MessageQueueManager.EnqueueLog(new ChatMessage() 47 | { 48 | ParseMode = ParseMode.Markdown, 49 | Text = logMessage 50 | }); 51 | 52 | if (!String.IsNullOrEmpty(message.Chat.Username)) 53 | { 54 | MessageQueueManager.EnqueueMessage( 55 | new ChatMessage() 56 | { 57 | Timestamp = DateTime.UtcNow, 58 | Chat = message.Chat, 59 | Text = "The Operators have been advised about your call.\n" + 60 | "Wait of any of them to join your group." 61 | }); 62 | } 63 | else 64 | { 65 | MessageQueueManager.EnqueueMessage( 66 | new ChatMessage() 67 | { 68 | Timestamp = DateTime.UtcNow, 69 | Chat = message.Chat, 70 | ParseMode = ParseMode.Markdown, 71 | Text = "The Operators have been advised of your report but your group is private.\n" + 72 | "Please join our [support group](https://t.me/unifiedban_group)." 73 | }); 74 | } 75 | } 76 | 77 | public void Execute(CallbackQuery callbackQuery) 78 | { 79 | throw new NotImplementedException(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Rm.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using Telegram.Bot; 6 | using Telegram.Bot.Types; 7 | using Telegram.Bot.Types.Enums; 8 | 9 | namespace Unifiedban.Terminal.Bot.Command 10 | { 11 | public class Rm : ICommand 12 | { 13 | public void Execute(Message message) 14 | { 15 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 16 | 17 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic) && 18 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 19 | { 20 | return; 21 | } 22 | 23 | int amount = 1; 24 | 25 | string[] data = message.Text.Split(" "); 26 | if (data.Length >= 2) 27 | { 28 | bool isInt = int.TryParse(data[1], out amount); 29 | if (!isInt) 30 | { 31 | Manager.BotClient.SendTextMessageAsync( 32 | chatId: message.Chat.Id, 33 | parseMode: ParseMode.Markdown, 34 | text: "The provided ammount is not a number.\n" 35 | + "**Syntax:** /rm {number = 1}" 36 | ); 37 | return; 38 | } 39 | } 40 | 41 | deleteLastMessages(message, amount); 42 | } 43 | 44 | public void Execute(CallbackQuery callbackQuery) { } 45 | 46 | private void deleteLastMessages(Message message, int amount = 1) 47 | { 48 | int startMessage = message.ReplyToMessage != null ? message.ReplyToMessage.MessageId : (message.MessageId - 1); 49 | int nextMessage = message.ReplyToMessage != null ? message.ReplyToMessage.MessageId : (message.MessageId - 1); 50 | 51 | while (nextMessage > startMessage - amount) 52 | { 53 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, nextMessage); 54 | nextMessage--; 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Rules.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using Telegram.Bot; 9 | using Telegram.Bot.Types; 10 | using Telegram.Bot.Types.Enums; 11 | 12 | namespace Unifiedban.Terminal.Bot.Command 13 | { 14 | public class Rules : ICommand 15 | { 16 | public void Execute(Message message) 17 | { 18 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 19 | 20 | Manager.BotClient.SendTextMessageAsync( 21 | chatId: message.Chat.Id, 22 | parseMode: ParseMode.Markdown, 23 | text: CacheData.Groups[message.Chat.Id].RulesText 24 | ); 25 | } 26 | 27 | public void Execute(CallbackQuery callbackQuery) { } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/SetRules.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | using System.Threading.Tasks; 11 | using Telegram.Bot; 12 | using Telegram.Bot.Types; 13 | using Telegram.Bot.Types.Enums; 14 | using Telegram.Bot.Types.ReplyMarkups; 15 | using Unifiedban.Models.Translation; 16 | 17 | namespace Unifiedban.Terminal.Bot.Command 18 | { 19 | public class SetRules : ICommand 20 | { 21 | public void Execute(Message message) 22 | { 23 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic) && 24 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 25 | { 26 | MessageQueueManager.EnqueueMessage( 27 | new Models.ChatMessage() 28 | { 29 | Timestamp = DateTime.UtcNow, 30 | Chat = message.Chat, 31 | ReplyToMessageId = message.MessageId, 32 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 33 | }); 34 | return; 35 | } 36 | 37 | string[] hasMessage = message.Text.Split(" "); 38 | if(hasMessage.Length > 1) 39 | { 40 | bool result = Utils.ConfigTools.UpdateRulesText(message.Chat.Id, message.Text.Remove(0, hasMessage[0].Length + 1)); 41 | if (result) 42 | { 43 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 44 | } 45 | return; 46 | } 47 | 48 | CommandMessage commandMessage = new CommandMessage() 49 | { 50 | Command = "SetRulesText", 51 | Value = "", 52 | Message = message, 53 | Timestamp = DateTime.UtcNow 54 | }; 55 | CommandQueueManager.EnqueueMessage(commandMessage); 56 | MessageQueueManager.EnqueueMessage( 57 | new Models.ChatMessage() 58 | { 59 | Timestamp = DateTime.UtcNow, 60 | Chat = message.Chat, 61 | ReplyToMessageId = message.MessageId, 62 | ParseMode = ParseMode.Html, 63 | Text = $"[ADMIN] [r:{message.MessageId}]\n" 64 | + CacheData.GetTranslation( 65 | CacheData.Groups[message.Chat.Id].SettingsLanguage, 66 | "command_setrules_instructions"), 67 | ReplyMarkup = new ForceReplyMarkup() { Selective = true } 68 | }); 69 | } 70 | 71 | public void Execute(CallbackQuery callbackQuery) {} 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/SetWelcome.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | using System.Threading.Tasks; 11 | using Telegram.Bot; 12 | using Telegram.Bot.Types; 13 | using Telegram.Bot.Types.Enums; 14 | using Telegram.Bot.Types.ReplyMarkups; 15 | using Unifiedban.Models.Translation; 16 | 17 | namespace Unifiedban.Terminal.Bot.Command 18 | { 19 | public class SetWelcome : ICommand 20 | { 21 | public void Execute(Message message) 22 | { 23 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic) && 24 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 25 | { 26 | MessageQueueManager.EnqueueMessage( 27 | new Models.ChatMessage() 28 | { 29 | Timestamp = DateTime.UtcNow, 30 | Chat = message.Chat, 31 | ReplyToMessageId = message.MessageId, 32 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 33 | }); 34 | return; 35 | } 36 | 37 | string[] hasMessage = message.Text.Split(" "); 38 | if (hasMessage.Length > 1) 39 | { 40 | bool result = Utils.ConfigTools.UpdateWelcomeText(message.Chat.Id, message.Text.Remove(0, hasMessage[0].Length + 1)); 41 | if (result) 42 | { 43 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 44 | } 45 | return; 46 | } 47 | 48 | CommandMessage commandMessage = new CommandMessage() 49 | { 50 | Command = "SetWelcomeText", 51 | Value = "", 52 | Message = message, 53 | Timestamp = DateTime.UtcNow 54 | }; 55 | CommandQueueManager.EnqueueMessage(commandMessage); 56 | MessageQueueManager.EnqueueMessage( 57 | new Models.ChatMessage() 58 | { 59 | Timestamp = DateTime.UtcNow, 60 | Chat = message.Chat, 61 | ReplyToMessageId = message.MessageId, 62 | ParseMode = ParseMode.Html, 63 | Text = $"[ADMIN] [r:{message.MessageId}]\n" 64 | + CacheData.GetTranslation( 65 | CacheData.Groups[message.Chat.Id].SettingsLanguage, 66 | "command_setwelcome_instructions"), 67 | ReplyMarkup = new ForceReplyMarkup() { Selective = true } 68 | }); 69 | } 70 | 71 | public void Execute(CallbackQuery callbackQuery) { } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Start.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using Newtonsoft.Json; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Threading.Tasks; 10 | using Telegram.Bot; 11 | using Telegram.Bot.Types; 12 | using Telegram.Bot.Types.ReplyMarkups; 13 | 14 | namespace Unifiedban.Terminal.Bot.Command 15 | { 16 | public class Start : ICommand 17 | { 18 | public void Execute(Message message) 19 | { 20 | if (message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Private 21 | || message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Channel) { 22 | 23 | Manager.BotClient.SendTextMessageAsync( 24 | chatId: message.Chat.Id, 25 | text: $"This bot works only in groups. Add it to a group and will auto-start." 26 | ); 27 | return; 28 | } 29 | 30 | if (message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Group 31 | || message.Chat.Type == Telegram.Bot.Types.Enums.ChatType.Supergroup) 32 | { 33 | return; 34 | } 35 | 36 | Manager.BotClient.SendTextMessageAsync( 37 | chatId: message.Chat.Id, 38 | text: $"Error: chat type not recognized. Please contact our support." 39 | ); 40 | } 41 | 42 | public void Execute(CallbackQuery callbackQuery) 43 | { 44 | return; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/StartSupport.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using Telegram.Bot; 9 | using Telegram.Bot.Types; 10 | using Telegram.Bot.Types.Enums; 11 | using Telegram.Bot.Types.ReplyMarkups; 12 | using Unifiedban.Models; 13 | 14 | namespace Unifiedban.Terminal.Bot.Command 15 | { 16 | public class StartSupport : ICommand 17 | { 18 | public void Execute(Message message) 19 | { 20 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Basic)) 21 | { 22 | MessageQueueManager.EnqueueMessage( 23 | new Models.ChatMessage() 24 | { 25 | Timestamp = DateTime.UtcNow, 26 | Chat = message.Chat, 27 | Text = CacheData.GetTranslation("en", "feedback_command_error_notoperator") 28 | }); 29 | Manager.BotClient.SendTextMessageAsync( 30 | chatId: CacheData.ControlChatId, 31 | parseMode: ParseMode.Markdown, 32 | text: String.Format( 33 | "*[Report]*\n" + 34 | "⚠️ Non operator tried to use /startsupport\n" + 35 | "\n*Chat:* {0}" + 36 | "\n*ChatId:* {1}" + 37 | "\n*UserId:* {2}" + 38 | "\n\n*hash_code:* #UB{3}-{4}", 39 | message.Chat.Title, 40 | message.Chat.Id, 41 | message.From.Id, 42 | message.Chat.Id.ToString().Replace("-",""), 43 | Guid.NewGuid()) 44 | ); 45 | return; 46 | } 47 | 48 | if (!CacheData.ActiveSupport.Contains(message.Chat.Id)) 49 | { 50 | CacheData.ActiveSupport.Add(message.Chat.Id); 51 | CacheData.CurrentChatOperators.Add(message.Chat.Id, 52 | Utils.ChatTools.GetChatAdminIds(message.Chat.Id)); 53 | 54 | Manager.BotClient.SendTextMessageAsync( 55 | chatId: message.Chat.Id, 56 | parseMode: ParseMode.Markdown, 57 | text: String.Format( 58 | "Operator *{0}* started a support session.", 59 | message.From.Username) 60 | ); 61 | MessageQueueManager.EnqueueLog(new ChatMessage() 62 | { 63 | ParseMode = ParseMode.Markdown, 64 | Text = String.Format( 65 | "*[Log]*" + 66 | "\n\nSupport session started by operator *{0}*" + 67 | "\nChatId: `{1}`" + 68 | "\nChat: `{2}`" + 69 | "\nUserId: `{3}`" + 70 | "\n\n*hash_code:* #UB{4}-{5}", 71 | message.From.Username, 72 | message.Chat.Id, 73 | message.Chat.Title, 74 | message.From.Id, 75 | message.Chat.Id.ToString().Replace("-", ""), 76 | Guid.NewGuid()) 77 | }); 78 | } 79 | } 80 | 81 | public void Execute(CallbackQuery callbackQuery) { } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Status.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Diagnostics; 7 | using System.Collections.Generic; 8 | using System.Text; 9 | using Telegram.Bot.Types; 10 | using Telegram.Bot.Types.Enums; 11 | using Telegram.Bot.Types.ReplyMarkups; 12 | using System.Threading.Tasks; 13 | using System.Linq; 14 | using Telegram.Bot; 15 | 16 | namespace Unifiedban.Terminal.Bot.Command 17 | { 18 | public class Status : ICommand 19 | { 20 | public void Execute(Message message) 21 | { 22 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 23 | 24 | if (CacheData.Operators 25 | .SingleOrDefault(x => x.TelegramUserId == message.From.Id 26 | && x.Level >= Models.Operator.Levels.Advanced) == null) 27 | { 28 | return; 29 | } 30 | 31 | Process proc = Process.GetCurrentProcess(); 32 | float usedRam = (proc.WorkingSet64 / 1024f) / 1024f; 33 | string SQLStatus = "*Offline* ⚠"; 34 | if(SQLOnline()) 35 | SQLStatus = "Online"; 36 | string env = "production"; 37 | #if DEBUG 38 | env = "🛠 *BETA* 🛠"; 39 | #endif 40 | 41 | MessageQueueManager.EnqueueMessage( 42 | new Models.ChatMessage() 43 | { 44 | Timestamp = DateTime.UtcNow, 45 | Chat = message.Chat, 46 | ParseMode = ParseMode.Markdown, 47 | Text = $"*Version*: {Utils.BotTools.CurrentVersion()}\n" + 48 | $"Instance *started*: {proc.StartTime}\n" + 49 | $"Used *RAM* is {Math.Round(usedRam, 2)}MB\n" + 50 | $"Used *CPU* is {Math.Round(GetCpuUsageForProcess().Result, 2)}%\n" + 51 | $"*Database* status is {SQLStatus}\n" + 52 | $"*Environment* is {env}\n" + 53 | $"*Messages since start:* {CacheData.HandledMessages}\n" + 54 | $"*Blacklist count:* {CacheData.BannedUsers.Count()}" 55 | }); 56 | } 57 | 58 | public void Execute(CallbackQuery callbackQuery) 59 | { 60 | if (!Utils.BotTools.IsUserOperator(callbackQuery.From.Id, Models.Operator.Levels.Super)) 61 | { 62 | return; 63 | } 64 | } 65 | 66 | private async Task GetCpuUsageForProcess() 67 | { 68 | var startTime = DateTime.UtcNow; 69 | var startCpuUsage = Process.GetCurrentProcess().TotalProcessorTime; 70 | await Task.Delay(500); 71 | var endTime = DateTime.UtcNow; 72 | var endCpuUsage = Process.GetCurrentProcess().TotalProcessorTime; 73 | var cpuUsedMs = (endCpuUsage - startCpuUsage).TotalMilliseconds; 74 | var totalMsPassed = (endTime - startTime).TotalMilliseconds; 75 | var cpuUsageTotal = cpuUsedMs / (Environment.ProcessorCount * totalMsPassed); 76 | 77 | return cpuUsageTotal * 100; 78 | } 79 | 80 | private bool SQLOnline() 81 | { 82 | BusinessLogic.SysConfigLogic sysConfigLogic = new BusinessLogic.SysConfigLogic(); 83 | var conf = sysConfigLogic.GetById("motd"); 84 | return conf != null ? true : false; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/TSSRenewLinks.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Diagnostics; 7 | using Telegram.Bot.Types; 8 | using Telegram.Bot.Types.Enums; 9 | using System.Threading.Tasks; 10 | using System.Linq; 11 | using Hangfire; 12 | using Quartz; 13 | using Telegram.Bot; 14 | 15 | namespace Unifiedban.Terminal.Bot.Command 16 | { 17 | public class TSSRenewLinks : ICommand 18 | { 19 | public void Execute(Message message) 20 | { 21 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 22 | 23 | if (CacheData.Operators 24 | .SingleOrDefault(x => x.TelegramUserId == message.From.Id 25 | && x.Level >= Models.Operator.Levels.Advanced) == null) 26 | { 27 | return; 28 | } 29 | 30 | //RecurringJob.Trigger("ChatTools_RenewInviteLinks"); 31 | Program.Scheduler?.TriggerJob(new JobKey("ChatTools_RenewInviteLinks")); 32 | } 33 | 34 | public void Execute(CallbackQuery callbackQuery) 35 | { 36 | return; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/TestCommand.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using Telegram.Bot; 9 | using Telegram.Bot.Types; 10 | using Telegram.Bot.Types.Enums; 11 | using Telegram.Bot.Types.ReplyMarkups; 12 | 13 | namespace Unifiedban.Terminal.Bot.Command 14 | { 15 | public class TestCommand : ICommand 16 | { 17 | public void Execute(Message message) 18 | { 19 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 20 | 21 | if (!Utils.BotTools.IsUserOperator(message.From.Id, Models.Operator.Levels.Super)) 22 | { 23 | return; 24 | } 25 | 26 | string[] data = message.Text.Split(" "); 27 | if (data.Length >= 2) 28 | { 29 | handleRequest(data, message); 30 | return; 31 | } 32 | 33 | List confirmationButton = new List(); 34 | confirmationButton.Add(InlineKeyboardButton.WithUrl("Start with command", "http://t.me/LinuxPixelHubBot?start=motd")); 35 | confirmationButton.Add(InlineKeyboardButton.WithCallbackData( 36 | CacheData.GetTranslation("en", "captcha_iamhuman", true), 37 | $"/test1 " + message.From.Id 38 | )); 39 | confirmationButton.Add(InlineKeyboardButton.WithCallbackData( 40 | "RM", 41 | $"/test1 rm" 42 | )); 43 | confirmationButton.Add(InlineKeyboardButton.WithCallbackData( 44 | "Switch invalid command" + (CacheData.AnswerInvalidCommand ? " ✅" : " ❌"), 45 | $"/test1 switchinvalidcommand" 46 | )); 47 | 48 | MessageQueueManager.EnqueueMessage( 49 | new Models.ChatMessage() 50 | { 51 | Timestamp = DateTime.UtcNow, 52 | Chat = message.Chat, 53 | ParseMode = ParseMode.Markdown, 54 | Text = "*[ADMIN]*\nSelect a test", 55 | ReplyMarkup = new InlineKeyboardMarkup( 56 | confirmationButton 57 | ) 58 | }); 59 | } 60 | 61 | public void Execute(CallbackQuery callbackQuery) 62 | { 63 | if (!Utils.BotTools.IsUserOperator(callbackQuery.From.Id, Models.Operator.Levels.Super)) 64 | { 65 | return; 66 | } 67 | 68 | string[] data = callbackQuery.Data.Split(" "); 69 | if (data.Length < 2) 70 | return; 71 | 72 | handleRequest(data, callbackQuery.Message); 73 | } 74 | 75 | private void handleRequest(string[] data, Message message) 76 | { 77 | switch (data[1]) 78 | { 79 | case "rm": 80 | if (data.Length == 3) 81 | deleteLastMessages(message, Convert.ToInt32(data[2])); 82 | else 83 | deleteLastMessages(message); 84 | break; 85 | case "switchinvalidcommand": 86 | CacheData.AnswerInvalidCommand = !CacheData.AnswerInvalidCommand; 87 | break; 88 | default: 89 | break; 90 | } 91 | } 92 | 93 | private void deleteLastMessages(Message message, int amount = 1) 94 | { 95 | int startMessage = message.ReplyToMessage != null ? message.ReplyToMessage.MessageId : message.MessageId - 1; 96 | int nextMessage = message.ReplyToMessage != null ? message.ReplyToMessage.MessageId : message.MessageId - 1; 97 | 98 | while (nextMessage >= startMessage - amount) 99 | { 100 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, nextMessage); 101 | nextMessage--; 102 | } 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Unban.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Linq; 7 | using Telegram.Bot; 8 | using Telegram.Bot.Types; 9 | using Telegram.Bot.Types.Enums; 10 | using Unifiedban.Terminal.Utils; 11 | 12 | namespace Unifiedban.Terminal.Bot.Command 13 | { 14 | public class Unban : ICommand 15 | { 16 | public void Execute(Message message) 17 | { 18 | var sender = message.SenderChat?.Id ?? message.From?.Id ?? 0; 19 | var isOperator = BotTools.IsUserOperator(sender, Models.Operator.Levels.Basic); 20 | var isAdmin = ChatTools.IsUserAdmin(message.Chat.Id, sender); 21 | if (!isOperator && !isAdmin) 22 | { 23 | MessageQueueManager.EnqueueMessage( 24 | new Models.ChatMessage() 25 | { 26 | Timestamp = DateTime.UtcNow, 27 | Chat = message.Chat, 28 | Text = CacheData.GetTranslation("en", "unban_command_error_notadmin") 29 | }); 30 | return; 31 | } 32 | 33 | if (isAdmin) 34 | { 35 | if (!ChatTools.IsUserAdmin(message.Chat.Id, Manager.MyId)) 36 | { 37 | MessageQueueManager.EnqueueMessage( 38 | new Models.ChatMessage() 39 | { 40 | Timestamp = DateTime.UtcNow, 41 | Chat = message.Chat, 42 | Text = CacheData.GetTranslation("en", "ban_command_error_adminPrivilege") 43 | }); 44 | return; 45 | } 46 | 47 | if (!CacheData.ChatAdmins[message.Chat.Id][Manager.MyId].CanRestrictMembers) 48 | { 49 | MessageQueueManager.EnqueueMessage( 50 | new Models.ChatMessage() 51 | { 52 | Timestamp = DateTime.UtcNow, 53 | Chat = message.Chat, 54 | Text = CacheData.GetTranslation("en", "ban_command_error_adminPrivilege") 55 | }); 56 | return; 57 | } 58 | } 59 | else if (!isOperator) 60 | { 61 | MessageQueueManager.EnqueueMessage( 62 | new Models.ChatMessage() 63 | { 64 | Timestamp = DateTime.UtcNow, 65 | Chat = message.Chat, 66 | Text = CacheData.GetTranslation("en", "ban_command_error_adminPrivilege") 67 | }); 68 | return; 69 | } 70 | 71 | if (message.Chat.Type != ChatType.Supergroup) 72 | { 73 | MessageQueueManager.EnqueueMessage( 74 | new Models.ChatMessage() 75 | { 76 | Timestamp = DateTime.UtcNow, 77 | Chat = message.Chat, 78 | Text = CacheData.GetTranslation("en", "unban_command_notSuperGroup") 79 | }); 80 | return; 81 | } 82 | 83 | long userId; 84 | 85 | if (message.ReplyToMessage == null) 86 | { 87 | if (!message.Text.Contains(" ")) 88 | { 89 | MessageQueueManager.EnqueueMessage( 90 | new Models.ChatMessage() 91 | { 92 | Timestamp = DateTime.UtcNow, 93 | Chat = message.Chat, 94 | Text = CacheData.GetTranslation("en", "unban_command_error_invalidUserId") 95 | }); 96 | return; 97 | } 98 | 99 | if (message.Text.Split(" ")[1].StartsWith("@")) 100 | { 101 | if (!CacheData.Usernames.Keys.Contains(message.Text.Split(" ")[1].Remove(0, 1))) 102 | { 103 | MessageQueueManager.EnqueueMessage( 104 | new Models.ChatMessage() 105 | { 106 | Timestamp = DateTime.UtcNow, 107 | Chat = message.Chat, 108 | Text = CacheData.GetTranslation("en", "unban_command_error_invalidUsername") 109 | }); 110 | return; 111 | } 112 | userId = CacheData.Usernames[message.Text.Split(" ")[1].Remove(0, 1)]; 113 | } 114 | else 115 | { 116 | bool isValid = long.TryParse(message.Text.Split(" ")[1], out userId); 117 | if (!isValid) 118 | { 119 | MessageQueueManager.EnqueueMessage( 120 | new Models.ChatMessage() 121 | { 122 | Timestamp = DateTime.UtcNow, 123 | Chat = message.Chat, 124 | Text = CacheData.GetTranslation("en", "unban_command_error_invalidUserId") 125 | }); 126 | return; 127 | } 128 | } 129 | } 130 | else 131 | userId = message.ReplyToMessage!.SenderChat?.Id ?? message.ReplyToMessage.From!.Id; 132 | 133 | try 134 | { 135 | 136 | Manager.BotClient.UnbanChatMemberAsync(message.Chat.Id, userId); 137 | MessageQueueManager.EnqueueMessage( 138 | new Models.ChatMessage() 139 | { 140 | Timestamp = DateTime.UtcNow, 141 | Chat = message.Chat, 142 | Text = CacheData.GetTranslation("en", "unban_command_success") 143 | }); 144 | } 145 | catch 146 | { 147 | MessageQueueManager.EnqueueMessage( 148 | new Models.ChatMessage() 149 | { 150 | Timestamp = DateTime.UtcNow, 151 | Chat = message.Chat, 152 | Text = CacheData.GetTranslation("en", "unban_command_error") 153 | }); 154 | } 155 | } 156 | 157 | public void Execute(CallbackQuery callbackQuery) { } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/Unmute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Telegram.Bot; 3 | using Telegram.Bot.Types; 4 | using Telegram.Bot.Types.Enums; 5 | 6 | namespace Unifiedban.Terminal.Bot.Command 7 | { 8 | public class Unmute : ICommand 9 | { 10 | public void Execute(Message message) 11 | { 12 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 13 | 14 | var sender = message.SenderChat?.Id ?? message.From?.Id ?? 0; 15 | var isOperator = Utils.BotTools.IsUserOperator(sender, Models.Operator.Levels.Basic); 16 | var isAdmin = Utils.ChatTools.IsUserAdmin(message.Chat.Id, sender); 17 | if (!isOperator && !isAdmin) 18 | { 19 | MessageQueueManager.EnqueueMessage( 20 | new Models.ChatMessage() 21 | { 22 | Timestamp = DateTime.UtcNow, 23 | Chat = message.Chat, 24 | ReplyToMessageId = message.MessageId, 25 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 26 | }); 27 | return; 28 | } 29 | 30 | if (!isOperator && isAdmin) 31 | { 32 | var adminPermissions = CacheData.ChatAdmins[message.Chat.Id][sender]; 33 | if (!adminPermissions.CanRestrictMembers) 34 | { 35 | MessageQueueManager.EnqueueMessage( 36 | new Models.ChatMessage() 37 | { 38 | Timestamp = DateTime.UtcNow, 39 | Chat = message.Chat, 40 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 41 | }); 42 | return; 43 | } 44 | } 45 | 46 | long userId = 0; 47 | if (message.ReplyToMessage != null) 48 | { 49 | userId = message.ReplyToMessage.From.Id; 50 | } 51 | else if (message.Text.Contains(" ")) 52 | { 53 | long.TryParse(message.Text.Split(" ")[1], out userId); 54 | } 55 | 56 | if (userId == 0) 57 | { 58 | MessageQueueManager.EnqueueMessage( 59 | new Models.ChatMessage() 60 | { 61 | Timestamp = DateTime.UtcNow, 62 | Chat = message.Chat, 63 | ParseMode = ParseMode.Markdown, 64 | Text = CacheData.GetTranslation("en", "command_unmute_missingMessage") 65 | }); 66 | return; 67 | } 68 | 69 | Manager.BotClient.RestrictChatMemberAsync( 70 | message.Chat.Id, 71 | userId, 72 | new ChatPermissions() 73 | { 74 | CanSendMessages = true, 75 | CanSendAudios = true, 76 | CanSendDocuments = true, 77 | CanSendPhotos = true, 78 | CanSendVideos = true, 79 | CanSendVideoNotes = true, 80 | CanSendVoiceNotes = true, 81 | CanSendPolls = true, 82 | CanSendOtherMessages = true, 83 | CanAddWebPagePreviews = true, 84 | CanChangeInfo = true, 85 | CanInviteUsers = true, 86 | CanPinMessages = true, 87 | CanManageTopics = true 88 | }); 89 | } 90 | 91 | public void Execute(CallbackQuery callbackQuery) { } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/Command/WelcomeButtonsList.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using Telegram.Bot.Types; 9 | using Unifiedban.Models; 10 | 11 | namespace Unifiedban.Terminal.Bot.Command 12 | { 13 | public class WelcomeButtonsList : ICommand 14 | { 15 | public void Execute(Message message) 16 | { 17 | if (!Utils.BotTools.IsUserOperator(message.From.Id) && 18 | !Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 19 | { 20 | MessageQueueManager.EnqueueMessage( 21 | new Models.ChatMessage() 22 | { 23 | Timestamp = DateTime.UtcNow, 24 | Chat = message.Chat, 25 | ReplyToMessageId = message.MessageId, 26 | Text = CacheData.GetTranslation("en", "error_not_auth_command") 27 | }); 28 | return; 29 | } 30 | 31 | string btnList = "This is the list of welcome buttons:"; 32 | BusinessLogic.ButtonLogic buttonLogic = new BusinessLogic.ButtonLogic(); 33 | foreach (Button btn in buttonLogic 34 | .GetByChat(CacheData.Groups[message.Chat.Id] 35 | .GroupId)) 36 | { 37 | btnList += Environment.NewLine; 38 | btnList += "* " + btn.Name + " -> " + btn.Content; 39 | } 40 | 41 | MessageQueueManager.EnqueueMessage( 42 | new Models.ChatMessage() 43 | { 44 | Timestamp = DateTime.UtcNow, 45 | Chat = message.Chat, 46 | Text = btnList, 47 | DisableWebPagePreview = true 48 | }); 49 | } 50 | 51 | public void Execute(CallbackQuery callbackQuery) { } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Bot/CommandQueueManager.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System.Linq; 6 | using System.Collections.Concurrent; 7 | using Telegram.Bot.Types.Enums; 8 | using Telegram.Bot.Types; 9 | using System; 10 | using Telegram.Bot; 11 | 12 | namespace Unifiedban.Terminal.Bot 13 | { 14 | public class CommandQueueManager 15 | { 16 | static bool isInitialized = false; 17 | static bool isDisposing = false; 18 | 19 | public static ConcurrentDictionary CommandsWaitingReply = 20 | new ConcurrentDictionary(); 21 | 22 | public static void Initialize() 23 | { 24 | if (CacheData.FatalError) 25 | return; 26 | 27 | isInitialized = true; 28 | 29 | Data.Utils.Logging.AddLog(new Models.SystemLog() 30 | { 31 | LoggerName = CacheData.LoggerName, 32 | Date = DateTime.Now, 33 | Function = "Unifiedban Terminal Startup", 34 | Level = Models.SystemLog.Levels.Info, 35 | Message = "Command Queue Manager initialized", 36 | UserId = -2 37 | }); 38 | } 39 | 40 | public static void Dispose() 41 | { 42 | isDisposing = true; 43 | } 44 | 45 | public static void EnqueueMessage(CommandMessage commandMessage) 46 | { 47 | if (!isInitialized || isDisposing) 48 | return; 49 | 50 | if (CommandsWaitingReply 51 | .ContainsKey(commandMessage.Message.MessageId)) 52 | return; 53 | 54 | CommandsWaitingReply.TryAdd(commandMessage.Message.MessageId, 55 | commandMessage); 56 | } 57 | public static void DenqueueMessage(CommandMessage commandMessage) 58 | { 59 | if (!isInitialized || isDisposing) 60 | return; 61 | 62 | if (!CommandsWaitingReply 63 | .ContainsKey(commandMessage.Message.MessageId)) 64 | return; 65 | 66 | CommandsWaitingReply.TryRemove(commandMessage.Message.MessageId, 67 | out CommandMessage removed); 68 | } 69 | 70 | public static void ReplyMessage(Message message) 71 | { 72 | if (!isInitialized || isDisposing) 73 | return; 74 | 75 | try 76 | { 77 | long realReplyToMessage = Convert.ToInt64(message.ReplyToMessage.Text.Split("[r:")[1].Split(']')[0]); 78 | if (!CommandsWaitingReply 79 | .TryGetValue(realReplyToMessage, 80 | out CommandMessage commandMessage)) 81 | return; 82 | 83 | switch (commandMessage.Command) 84 | { 85 | case "AddTranslationKey": 86 | Command.AddTranslation.AddTranslationKey(commandMessage, message); 87 | break; 88 | case "AddTranslationEntry": 89 | Command.AddTranslation.AddTranslationEntry(commandMessage, message); 90 | break; 91 | case "SetWelcomeText": 92 | if (String.IsNullOrEmpty(message.Text)) 93 | break; 94 | if (Utils.ConfigTools.UpdateWelcomeText(message.Chat.Id, message.Text)) 95 | { 96 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.ReplyToMessage.MessageId); 97 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 98 | } 99 | break; 100 | case "SetRulesText": 101 | if (string.IsNullOrEmpty(message.Text)) 102 | break; 103 | if(Utils.ConfigTools.UpdateRulesText(message.Chat.Id, message.Text)) 104 | { 105 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.ReplyToMessage.MessageId); 106 | Manager.BotClient.DeleteMessageAsync(message.Chat.Id, message.MessageId); 107 | } 108 | break; 109 | case "Feedback": 110 | if (string.IsNullOrEmpty(message.Text)) 111 | break; 112 | DenqueueMessage(commandMessage); 113 | Utils.BotTools.RecordFeedback(message); 114 | break; 115 | case "AddUserToBlacklist": 116 | if (string.IsNullOrEmpty(message.Text)) 117 | break; 118 | DenqueueMessage(commandMessage); 119 | Utils.UserTools.AddUserToBlacklist(message.From.Id, message, 120 | Convert.ToInt64(commandMessage.Value), Models.User.Banned.BanReasons.Other, 121 | message.Text); 122 | break; 123 | } 124 | } 125 | catch 126 | { 127 | return; 128 | } 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/CacheData.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using Microsoft.Extensions.Configuration; 6 | using System; 7 | using System.Collections.Concurrent; 8 | using System.Collections.Generic; 9 | using System.Text; 10 | using System.Timers; 11 | using Telegram.Bot.Types; 12 | using Unifiedban.Plugin.Common; 13 | 14 | namespace Unifiedban.Terminal 15 | { 16 | public class CacheData 17 | { 18 | // [[ Program control ]] 19 | public static string LoggerName = "Unifiedban-Terminal"; 20 | public static bool FatalError = false; 21 | public static bool IsDisposing = false; 22 | public static IConfigurationRoot Configuration; 23 | public static DateTime StartupDateTimeUtc = DateTime.UtcNow; 24 | public static bool AnswerInvalidCommand = false; 25 | public static long ControlChatId = 0; 26 | public static int CaptchaAutoKickTimer = 1; 27 | 28 | // [[ Instance data ]] 29 | public static List SysConfigs = new(); 30 | public static List Operators = new(); 31 | public static Dictionary Languages = new(); 32 | public static Dictionary> Translations = new(); 33 | public static List GroupDefaultConfigs = new(); 34 | public static int HandledMessages { get; private set; } 35 | private static object lockHandledMessages = new(); 36 | 37 | public static List PreCaptchaAndWelcomePlugins = new(); 38 | public static List PostCaptchaAndWelcomePlugins = new(); 39 | public static List PreFiltersPlugins = new(); 40 | public static List PostFiltersPlugins = new(); 41 | public static List PreControlsPlugins = new(); 42 | public static List PostControlsPlugins = new(); 43 | 44 | // [[ Cache ]] 45 | public static object GroupsLockObj = new (); 46 | public static readonly Dictionary Groups = new(); 47 | public static Dictionary> GroupConfigs = new(); 48 | public static Dictionary NightSchedules = new(); 49 | 50 | public static Dictionary> ChatAdmins 51 | { 52 | get 53 | { 54 | lock (chatAdminsLockObj) 55 | { 56 | return chatAdmins; 57 | } 58 | } 59 | } 60 | private static object chatAdminsLockObj = new(); 61 | private static Dictionary> chatAdmins = new(); 62 | 63 | public static List BannedUsers = new(); 64 | public static List BadWords = new(); 65 | public static List BannedImagesHash = new(); 66 | 67 | public static Dictionary TrustFactors = new(); 68 | public static Dictionary Usernames = new(); 69 | 70 | public static List ActiveSupport = new(); 71 | public static Dictionary> CurrentChatOperators = new(); 72 | 73 | public static ConcurrentDictionary CaptchaAutoKickTimers = new(); 74 | public static Dictionary CaptchaStrikes = new(); 75 | 76 | public static List IgnoredChats = new(); 77 | public static List BetaAuthChats = new(); 78 | 79 | public static string GetTranslation( 80 | string languageId, 81 | string keyId, 82 | bool firstCapital = false) 83 | { 84 | if (!Translations.ContainsKey(languageId)) 85 | return keyId; 86 | 87 | if (!Translations[languageId].ContainsKey(keyId)) 88 | { 89 | if (!Translations["en"].ContainsKey(keyId)) 90 | { 91 | return keyId; 92 | } 93 | 94 | languageId = "en"; 95 | } 96 | 97 | var value = Translations[languageId][keyId].Translation; 98 | 99 | if (firstCapital) 100 | { 101 | return value.Substring(0, 1).ToUpper() + value.Substring(1, value.Length - 1); 102 | } 103 | 104 | return value; 105 | } 106 | 107 | public static void IncrementHandledMessages() 108 | { 109 | lock (lockHandledMessages) 110 | { 111 | HandledMessages++; 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/CommandMessage.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using Telegram.Bot.Types; 7 | using Telegram.Bot.Types.Enums; 8 | using Telegram.Bot.Types.ReplyMarkups; 9 | 10 | namespace Unifiedban.Terminal 11 | { 12 | public class CommandMessage 13 | 14 | { 15 | public Message Message { get; set; } 16 | public string Command { get; set; } 17 | public string Value { get; set; } 18 | public DateTime Timestamp { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Controls/IControl.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using Telegram.Bot.Types; 9 | 10 | namespace Unifiedban.Terminal.Controls 11 | { 12 | public interface IControl 13 | { 14 | public enum ControlResultType 15 | { 16 | positive, 17 | negative, 18 | skipped 19 | } 20 | ControlResult DoCheck(Message message); 21 | } 22 | 23 | public class ControlResult 24 | { 25 | public IControl.ControlResultType Result { get; set; } 26 | public string CheckName { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Controls/Notes.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | using Telegram.Bot.Types; 11 | using Unifiedban.Terminal.Bot; 12 | 13 | namespace Unifiedban.Terminal.Controls 14 | { 15 | public class Notes : IControl 16 | { 17 | BusinessLogic.Group.NoteLogic noteLogic = new BusinessLogic.Group.NoteLogic(); 18 | 19 | public ControlResult DoCheck(Message message) 20 | { 21 | Models.Group.ConfigurationParameter configValue = CacheData.GroupConfigs[message.Chat.Id] 22 | .Where(x => x.ConfigurationParameterId == "GroupNotes") 23 | .SingleOrDefault(); 24 | if (configValue != null) 25 | if (configValue.Value == "false") 26 | return new ControlResult() 27 | { 28 | CheckName = "Group notes", 29 | Result = IControl.ControlResultType.skipped 30 | }; 31 | 32 | Regex reg = new Regex("#[A-z0-9]+", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); 33 | MatchCollection matchedTags = reg.Matches(message.Text); 34 | if (matchedTags.Count == 0) 35 | return new ControlResult() 36 | { 37 | CheckName = "Group notes", 38 | Result = IControl.ControlResultType.skipped 39 | }; 40 | 41 | List notes = new List(); 42 | foreach(Match match in matchedTags) 43 | { 44 | notes.AddRange(noteLogic.GetByTag(match.Value, CacheData.Groups[message.Chat.Id].GroupId)); 45 | } 46 | 47 | List distNotes = new List(notes.Distinct()); 48 | foreach(Models.Group.Note note in distNotes) 49 | { 50 | note.Message += Environment.NewLine; 51 | note.Message += "NoteId: " + note.NoteId; 52 | 53 | MessageQueueManager.EnqueueMessage( 54 | new Models.ChatMessage() 55 | { 56 | Timestamp = DateTime.UtcNow, 57 | Chat = message.Chat, 58 | Text = note.Message 59 | }); 60 | } 61 | 62 | return new ControlResult() 63 | { 64 | CheckName = "Group notes", 65 | Result = IControl.ControlResultType.negative 66 | }; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Controls/SafeGroupControl.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | using Telegram.Bot; 11 | using Telegram.Bot.Types; 12 | 13 | namespace Unifiedban.Terminal.Controls 14 | { 15 | public class SafeGroupControl : IControl 16 | { 17 | Filters.SafeGroupFilter safeGroupFilter = new Filters.SafeGroupFilter(); 18 | 19 | public ControlResult DoCheck(Message message) 20 | { 21 | if (Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 22 | { 23 | return new ControlResult() 24 | { 25 | CheckName = "Safe Group", 26 | Result = IControl.ControlResultType.skipped 27 | }; 28 | } 29 | 30 | Models.Group.ConfigurationParameter configValue = CacheData.GroupConfigs[message.Chat.Id] 31 | .Where(x => x.ConfigurationParameterId == "SafeGroupControl") 32 | .SingleOrDefault(); 33 | if (configValue != null) 34 | if (configValue.Value == "false") 35 | return new ControlResult() 36 | { 37 | CheckName = "Safe Group", 38 | Result = IControl.ControlResultType.skipped 39 | }; 40 | 41 | string regex = @"(((http|https):\/\/)|(tg:\/\/)|(t.me\/))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?|(?![\w_])(@[\w_]+)(?!.)"; 42 | Regex reg = new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); 43 | MatchCollection matchedWords = reg.Matches(message.Text); 44 | if (matchedWords.Count == 0) 45 | { 46 | return new ControlResult() 47 | { 48 | CheckName = "Safe Group", 49 | Result = IControl.ControlResultType.negative 50 | }; 51 | 52 | } 53 | 54 | foreach (Match match in matchedWords) 55 | { 56 | string url = match.Value; 57 | if (url.StartsWith("@")) 58 | { 59 | if (message.Chat.Username != null) 60 | { 61 | if(match.Value.Remove(0, 1) == message.Chat.Username) 62 | { 63 | return new ControlResult() 64 | { 65 | CheckName = "Safe Group", 66 | Result = IControl.ControlResultType.skipped 67 | }; 68 | } 69 | } 70 | url = "https://t.me/" + match.Value.Remove(0, 1); 71 | } 72 | 73 | if (url.StartsWith("t.me")) 74 | url = "https://" + match.Value; 75 | if (url.Contains("t.me/") && 76 | url.StartsWith("http") && 77 | !url.StartsWith("https")) 78 | url = url.Replace("http", "https"); 79 | 80 | string inviteLink = Bot.Manager.BotClient.GetChatAsync(message.Chat.Id).Result.InviteLink; 81 | if (inviteLink != null) 82 | { 83 | if(match.Value == inviteLink) 84 | { 85 | return new ControlResult() 86 | { 87 | CheckName = "Safe Group", 88 | Result = IControl.ControlResultType.skipped 89 | }; 90 | } 91 | } 92 | 93 | if (url.Contains("/c/")) 94 | { 95 | if (url.Split("/c/")[1].Split('/')[0] == message.Chat.Id.ToString()) 96 | { 97 | return new ControlResult() 98 | { 99 | CheckName = "Safe Group", 100 | Result = IControl.ControlResultType.skipped 101 | }; 102 | } 103 | } 104 | 105 | if (url == "https://t.me/unifiedban_group" || 106 | url == "https://t.me/unifiedban_news" || 107 | url == "https://t.me/unifiedban_bot" || 108 | url == "https://t.me/unifiedbanBeta_bot" || 109 | url == "https://t.me/joinchat/B35YY0QbLfd034CFnvCtCA" || // Support chat of the TelegramBots library 110 | url == "https://t.me/dotnetgram") // .NET global discussion and support chat 111 | { 112 | return new ControlResult() 113 | { 114 | CheckName = "Safe Group", 115 | Result = IControl.ControlResultType.skipped 116 | }; 117 | } 118 | 119 | if (Manager.IsTelegramLink(url)) 120 | if (safeGroupFilter.DoCheck( 121 | CacheData.Groups[message.Chat.Id].GroupId, url) 122 | .Result == Filters.IFilter.FilterResultType.positive) 123 | return new ControlResult() 124 | { 125 | CheckName = "Safe Group", 126 | Result = IControl.ControlResultType.positive 127 | }; 128 | } 129 | 130 | return new ControlResult() 131 | { 132 | CheckName = "Safe Group", 133 | Result = IControl.ControlResultType.negative 134 | }; 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Controls/SpamNameControl.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Concurrent; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Text.RegularExpressions; 11 | using Telegram.Bot.Types; 12 | 13 | namespace Unifiedban.Terminal.Controls 14 | { 15 | public class SpamNameControl : IControl 16 | { 17 | static ConcurrentDictionary isNameSafe = new ConcurrentDictionary(); 18 | 19 | public ControlResult DoCheck(Message message) 20 | { 21 | if (Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 22 | { 23 | return new ControlResult() 24 | { 25 | CheckName = "Spam Names", 26 | Result = IControl.ControlResultType.skipped 27 | }; 28 | } 29 | 30 | Models.Group.ConfigurationParameter configValue = CacheData.GroupConfigs[message.Chat.Id] 31 | .Where(x => x.ConfigurationParameterId == "SpamNameControl") 32 | .SingleOrDefault(); 33 | if (configValue != null) 34 | if (configValue.Value == "false") 35 | return new ControlResult() 36 | { 37 | CheckName = "Spam Names", 38 | Result = IControl.ControlResultType.skipped 39 | }; 40 | 41 | Filters.BadWordFilter badWordFilter = new Filters.BadWordFilter(); 42 | Filters.FilterResult badName = badWordFilter 43 | .DoCheck(message, message.From.FirstName + " " + message.From.LastName); 44 | if(badName.Result == Filters.IFilter.FilterResultType.positive) 45 | return new ControlResult() 46 | { 47 | CheckName = "Spam Names", 48 | Result = IControl.ControlResultType.positive 49 | }; 50 | 51 | if(!String.IsNullOrEmpty(message.From.FirstName)) 52 | if (!isNameSafe.TryGetValue(message.From.FirstName, out bool nameIsValid)) 53 | { 54 | CheckIfNameIsValid(message.From.FirstName); 55 | } 56 | 57 | if (!String.IsNullOrEmpty(message.From.LastName)) 58 | if (!isNameSafe.TryGetValue(message.From.LastName, out bool surnameIsValid)) 59 | { 60 | CheckIfNameIsValid(message.From.LastName); 61 | } 62 | 63 | if (!String.IsNullOrEmpty(message.From.FirstName)) 64 | if (!isNameSafe[message.From.FirstName]) 65 | return new ControlResult() 66 | { 67 | CheckName = "Spam Names", 68 | Result = IControl.ControlResultType.positive 69 | }; 70 | if (!String.IsNullOrEmpty(message.From.LastName)) 71 | if (!isNameSafe[message.From.LastName]) 72 | return new ControlResult() 73 | { 74 | CheckName = "Spam Names", 75 | Result = IControl.ControlResultType.positive 76 | }; 77 | 78 | return new ControlResult() 79 | { 80 | CheckName = "Spam Names", 81 | Result = IControl.ControlResultType.negative 82 | }; 83 | } 84 | 85 | void CheckIfNameIsValid(string name) 86 | { 87 | string regex = @"((http|ftp|https):\/\/)?([\w_-]+\s?(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?"; 88 | Regex reg = new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); 89 | MatchCollection matchedWords = reg.Matches(name); 90 | if (matchedWords.Count == 0) 91 | { 92 | isNameSafe[name] = true; 93 | return; 94 | } 95 | using (WebClientWithTimeout client = new WebClientWithTimeout()) 96 | { 97 | string siteUri = name; 98 | if (!name.Contains("http://") && !name.Contains("https://")) 99 | siteUri = "http://" + name; 100 | 101 | string htmlCode = ""; 102 | try 103 | { 104 | htmlCode = client.DownloadString(siteUri); 105 | } 106 | catch { } 107 | 108 | if (htmlCode.Contains("tgme_page_extra")) 109 | isNameSafe[name] = false; 110 | else 111 | isNameSafe[name] = true; 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Filters/IFilter.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using Telegram.Bot.Types; 9 | 10 | namespace Unifiedban.Terminal.Filters 11 | { 12 | public interface IFilter 13 | { 14 | public enum FilterResultType 15 | { 16 | positive, 17 | negative, 18 | skipped 19 | } 20 | FilterResult DoCheck(Message message); 21 | } 22 | 23 | public class FilterResult 24 | { 25 | public IFilter.FilterResultType Result { get; set; } 26 | public string CheckName { get; set; } 27 | public string Rule { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Filters/NonLatinFilter.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | using Telegram.Bot.Types; 11 | using Unifiedban.Models.Filters; 12 | 13 | namespace Unifiedban.Terminal.Filters 14 | { 15 | public class NonLatinFilter : IFilter 16 | { 17 | public FilterResult DoCheck(Message message) 18 | { 19 | if (Utils.ChatTools.IsUserAdmin(message.Chat.Id, message.From.Id)) 20 | { 21 | return new FilterResult() 22 | { 23 | CheckName = "BadWord", 24 | Result = IFilter.FilterResultType.skipped 25 | }; 26 | } 27 | 28 | Models.Group.ConfigurationParameter configValue = CacheData.GroupConfigs[message.Chat.Id] 29 | .Where(x => x.ConfigurationParameterId == "NonLatinFilter") 30 | .SingleOrDefault(); 31 | if (configValue != null) 32 | if (configValue.Value == "false") 33 | return new FilterResult() 34 | { 35 | CheckName = "Non-Latin Filter", 36 | Result = IFilter.FilterResultType.skipped 37 | }; 38 | 39 | string regex = @"[^\x00-\x7FÀ-ÖØ-öø-ÿ"; // non latin chars 40 | regex += @"\p{IsCurrencySymbols}\p{IsMiscellaneousSymbols}\p{IsMiscellaneousTechnical}"; 41 | regex += @"p{IsArrows}\p{IsMiscellaneousSymbolsandArrows}\p{IsMathematicalOperators}]+"; 42 | 43 | Regex reg = new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); 44 | MatchCollection matchedWords = reg.Matches(removeEmojis(message.Text)); 45 | if (matchedWords.Count > 0) 46 | return new FilterResult() 47 | { 48 | CheckName = "Non-Latin Filter", 49 | Result = IFilter.FilterResultType.positive, 50 | Rule = "Non-Latin Filter" 51 | }; 52 | 53 | return new FilterResult() 54 | { 55 | CheckName = "Non-Latin Filter", 56 | Result = IFilter.FilterResultType.negative 57 | }; 58 | } 59 | 60 | private string removeEmojis(string text) 61 | { 62 | string regex = @"(¯\\_\(ツ\)_\/¯)|(_\/\(ツ\)\\_)|\( ͡° ͜ʖ ͡°\)|" + // commonly used smiles 63 | @"(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])"; // Emojis 64 | 65 | Regex reg = new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); 66 | MatchCollection matchedWords = reg.Matches(text); 67 | foreach (Match match in matchedWords) 68 | text = text.Replace(match.Value, string.Empty); 69 | 70 | text = Regex.Replace(text, @"\uFE0F+", string.Empty); // remove all Control and non-printable chars 71 | text = Regex.Replace(text, @"º|µ|¶|«|»|´|¿|¡|µ|¾|½|¼|¤|¹|²|³|¤|×|¨|°|÷|£|¢|’|ª|·|“|”|?", string.Empty); // whitelisted chars 72 | return text; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Filters/RTLNameFilter.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | using Telegram.Bot.Types; 11 | using Unifiedban.Models.Filters; 12 | 13 | namespace Unifiedban.Terminal.Filters 14 | { 15 | public class RTLNameFilter : IFilter 16 | { 17 | public FilterResult DoCheck(Message message) 18 | { 19 | return DoCheck(message, message.From.FirstName + " " + message.From.LastName); 20 | } 21 | public FilterResult DoCheck(Message message, string fullName) 22 | { 23 | Models.Group.ConfigurationParameter configValue = CacheData.GroupConfigs[message.Chat.Id] 24 | .Where(x => x.ConfigurationParameterId == "RTLNameFilter") 25 | .SingleOrDefault(); 26 | if (configValue != null) 27 | if (configValue.Value == "false") 28 | return new FilterResult() 29 | { 30 | CheckName = "RTLNameFilter", 31 | Result = IFilter.FilterResultType.skipped 32 | }; 33 | 34 | if(Utils.UserTools.NameIsRTL(fullName)) 35 | return new FilterResult() 36 | { 37 | CheckName = "RTLNameFilter", 38 | Result = IFilter.FilterResultType.positive, 39 | Rule = "Name has RTL characters" 40 | }; 41 | 42 | return new FilterResult() 43 | { 44 | CheckName = "BadWord", 45 | Result = IFilter.FilterResultType.negative 46 | }; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Filters/SafeGroupFilter.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using Telegram.Bot.Types; 8 | using Unifiedban.Models.Group; 9 | 10 | namespace Unifiedban.Terminal.Filters 11 | { 12 | public class SafeGroupFilter : IFilter 13 | { 14 | public SafeGroupFilter() 15 | { 16 | LoadCache(); 17 | } 18 | 19 | static List safeGroups = new List(); 20 | public FilterResult DoCheck(Message message) 21 | { 22 | return DoCheck(CacheData.Groups[message.Chat.Id].GroupId, 23 | message.Text); 24 | } 25 | 26 | public FilterResult DoCheck(string groupId, string text) 27 | { 28 | SafeGroup isKnown = safeGroups 29 | .Where(x => x.GroupId == groupId && x.GroupName == text) 30 | .FirstOrDefault(); 31 | if (isKnown == null) 32 | return new FilterResult() 33 | { 34 | CheckName = "SafeGroup", 35 | Result = IFilter.FilterResultType.positive 36 | }; 37 | 38 | return new FilterResult() 39 | { 40 | CheckName = "SafeGroup", 41 | Result = IFilter.FilterResultType.negative 42 | }; 43 | } 44 | 45 | public static void LoadCache() 46 | { 47 | BusinessLogic.Group.SafeGroupLogic safeGroupLogic = 48 | new BusinessLogic.Group.SafeGroupLogic(); 49 | safeGroups = new List(safeGroupLogic.Get()); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Jobs/ChatToolsJob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Quartz; 4 | using Unifiedban.Models; 5 | using Unifiedban.Terminal.Utils; 6 | 7 | namespace Unifiedban.Terminal.Jobs 8 | { 9 | public class ChatToolsJob : IJob 10 | { 11 | public Task Execute(IJobExecutionContext context) 12 | { 13 | Data.Utils.Logging.AddLog(new SystemLog() 14 | { 15 | LoggerName = CacheData.LoggerName, 16 | Date = DateTime.Now, 17 | Function = "ChatToolsJob", 18 | Level = SystemLog.Levels.Debug, 19 | Message = "Executing ChatToolsJob", 20 | UserId = -1 21 | }); 22 | 23 | ChatTools.CheckNightSchedule(); 24 | ChatTools.RenewInviteLinks().Wait(); 25 | 26 | return Task.CompletedTask; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Unifiedban.Terminal/Jobs/ConfigToolsJob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Quartz; 4 | using Unifiedban.Models; 5 | using Unifiedban.Terminal.Utils; 6 | 7 | namespace Unifiedban.Terminal.Jobs 8 | { 9 | public class ConfigToolsJob : IJob 10 | { 11 | public Task Execute(IJobExecutionContext context) 12 | { 13 | Data.Utils.Logging.AddLog(new SystemLog() 14 | { 15 | LoggerName = CacheData.LoggerName, 16 | Date = DateTime.Now, 17 | Function = "ConfigToolsJob", 18 | Level = SystemLog.Levels.Debug, 19 | Message = "Executing ConfigToolsJob", 20 | UserId = -1 21 | }); 22 | 23 | ConfigTools.SyncGroupsConfigToDatabase(); 24 | ConfigTools.SyncWelcomeAndRulesText(); 25 | ConfigTools.SyncGroupsToDatabase(); 26 | ConfigTools.SyncNightScheduleToDatabase(); 27 | 28 | return Task.CompletedTask; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Unifiedban.Terminal/Jobs/LogsJob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Threading.Tasks; 4 | using Quartz; 5 | using Unifiedban.Models; 6 | using Unifiedban.Terminal.Utils; 7 | 8 | namespace Unifiedban.Terminal.Jobs 9 | { 10 | public class LogsJob : IJob 11 | { 12 | public Task Execute(IJobExecutionContext context) 13 | { 14 | Data.Utils.Logging.AddLog(new SystemLog() 15 | { 16 | LoggerName = CacheData.LoggerName, 17 | Date = DateTime.Now, 18 | Function = "LogsJob", 19 | Level = SystemLog.Levels.Debug, 20 | Message = "Executing LogsJob", 21 | UserId = -1 22 | }); 23 | 24 | LogTools.SyncSystemLog(); 25 | LogTools.SyncActionLog(); 26 | LogTools.SyncTrustFactorLog(); 27 | LogTools.SyncOperationLog(); 28 | LogTools.SyncSupportSessionLog(); 29 | 30 | return Task.CompletedTask; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Unifiedban.Terminal/Jobs/UptimeJob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Threading.Tasks; 4 | using Quartz; 5 | using Unifiedban.Models; 6 | 7 | namespace Unifiedban.Terminal.Jobs 8 | { 9 | public class UptimeJob : IJob 10 | { 11 | public Task Execute(IJobExecutionContext context) 12 | { 13 | if (CacheData.Configuration?["UptimeMonitor:URL"] is null) return Task.CompletedTask; 14 | Data.Utils.Logging.AddLog(new SystemLog() 15 | { 16 | LoggerName = CacheData.LoggerName, 17 | Date = DateTime.Now, 18 | Function = "UptimeJob", 19 | Level = SystemLog.Levels.Debug, 20 | Message = "Sending Uptime Hearthbeat", 21 | UserId = -1 22 | }); 23 | 24 | WebClient wc = new(); 25 | try 26 | { 27 | wc.DownloadString(CacheData.Configuration["UptimeMonitor:URL"]); 28 | } 29 | catch (Exception ex) 30 | { 31 | Data.Utils.Logging.AddLog(new SystemLog() 32 | { 33 | LoggerName = CacheData.LoggerName, 34 | Date = DateTime.Now, 35 | Function = "UptimeJob", 36 | Level = SystemLog.Levels.Warn, 37 | Message = $"Can't send heartbeat: \n{ex.Message}", 38 | UserId = -1 39 | }); 40 | } 41 | 42 | return Task.CompletedTask; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Unifiedban.Terminal/Jobs/UserToolsJob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Quartz; 4 | using Unifiedban.Models; 5 | using Unifiedban.Terminal.Utils; 6 | 7 | namespace Unifiedban.Terminal.Jobs 8 | { 9 | public class UserToolsJob : IJob 10 | { 11 | public Task Execute(IJobExecutionContext context) 12 | { 13 | Data.Utils.Logging.AddLog(new SystemLog() 14 | { 15 | LoggerName = CacheData.LoggerName, 16 | Date = DateTime.Now, 17 | Function = "UserToolsJob", 18 | Level = SystemLog.Levels.Debug, 19 | Message = "Executing UserToolsJob", 20 | UserId = -1 21 | }); 22 | 23 | UserTools.SyncTrustFactor(); 24 | UserTools.SyncBlacklist(); 25 | 26 | return Task.CompletedTask; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Unifiedban.Terminal/TestArea.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using Newtonsoft.Json; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Text; 9 | using Telegram.Bot.Types.ReplyMarkups; 10 | 11 | namespace Unifiedban.Terminal 12 | { 13 | public class TestArea 14 | { 15 | #if DEBUG 16 | public static void DoTest() 17 | { 18 | if (CacheData.FatalError) 19 | return; 20 | 21 | //Gimmeconf(); 22 | //RegisterOperators(); 23 | // var user = Bot.Manager.BotClient.GetChatMemberAsync(-1001125553456, 560445026).Result; 24 | // Console.WriteLine(user.User.Username); 25 | } 26 | 27 | static void Gimmeconf() 28 | { 29 | InlineKeyboardMarkup conf = new InlineKeyboardMarkup( 30 | new List() 31 | { 32 | InlineKeyboardButton.WithUrl( 33 | "Project website", 34 | "https://unifiedban.solutions" 35 | ) 36 | } 37 | ); 38 | 39 | string confString = JsonConvert.SerializeObject(conf); 40 | Console.WriteLine(confString); 41 | } 42 | 43 | static void RegisterOperators() 44 | { 45 | BusinessLogic.OperatorLogic operatorLogic = new BusinessLogic.OperatorLogic(); 46 | //operatorLogic.Add(799698579, Models.Operator.Levels.Super, -1); 47 | //operatorLogic.Add(339380551, Models.Operator.Levels.Super, -1); 48 | } 49 | #endif 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Unifiedban.Terminal.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net7.0 6 | 3.14.1 7 | fabricators 8 | Unifiedban Terminal 9 | Fabricators 2022 10 | https://github.com/unified-ban/Terminal 11 | GIT 12 | 3.14.1 13 | 3.14.1.1 14 | 9 15 | enable 16 | 17 | 18 | 19 | full 20 | true 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | Always 43 | 44 | 45 | Always 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/UserPrivileges.cs: -------------------------------------------------------------------------------- 1 | namespace Unifiedban.Terminal 2 | { 3 | public class UserPrivileges 4 | { 5 | public bool CanManageChat { get; set; } 6 | public bool CanPostMessages { get; set; } 7 | public bool CanEditMessages { get; set; } 8 | public bool CanDeleteMessages { get; set; } 9 | public bool CanManageVoiceChats { get; set; } 10 | public bool CanRestrictMembers { get; set; } 11 | public bool CanPromoteMembers { get; set; } 12 | public bool CanChangeInfo { get; set; } 13 | public bool CanInviteUsers { get; set; } 14 | public bool CanPinMessages { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Unifiedban.Terminal/Utils/BotTools.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Diagnostics; 8 | using System; 9 | using System.Text.RegularExpressions; 10 | using Telegram.Bot; 11 | using Telegram.Bot.Types; 12 | using Telegram.Bot.Types.Enums; 13 | using Telegram.Bot.Types.ReplyMarkups; 14 | 15 | namespace Unifiedban.Terminal.Utils 16 | { 17 | public class BotTools 18 | { 19 | public static bool IsUserOperator(long userId) 20 | { 21 | return CacheData.Operators 22 | .SingleOrDefault(x => x.TelegramUserId == userId) != null ? true : false; 23 | } 24 | 25 | public static bool IsUserOperator(long userId, Models.Operator.Levels level) 26 | { 27 | return CacheData.Operators 28 | .SingleOrDefault(x => x.TelegramUserId == userId && 29 | x.Level >= level) != null ? true : false; 30 | } 31 | 32 | public static string CurrentVersion() 33 | { 34 | Assembly assembly = Assembly.GetExecutingAssembly(); 35 | FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(assembly.Location); 36 | return fileVersionInfo.ProductVersion; 37 | } 38 | 39 | public static bool IsValidUrl(string url) 40 | { 41 | string regex = @"(((http|ftp|https):\/\/)|(tg:\/\/))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?|(?![\w_])(@[\w_]+)(?!.)"; 42 | Regex reg = new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); 43 | MatchCollection matchedWords = reg.Matches(url); 44 | 45 | return matchedWords.Count == 1; 46 | } 47 | 48 | public static void RecordFeedback(Message message) 49 | { 50 | Bot.Manager.BotClient.SendTextMessageAsync( 51 | chatId: CacheData.ControlChatId, 52 | parseMode: ParseMode.Markdown, 53 | text: String.Format( 54 | "User *{0}:{1}* from group *{2}:[{3}]({4})* has sent a feedback:\n\n" + 55 | message.Text, 56 | message.From.Id, 57 | message.From.Username, 58 | message.Chat.Id, 59 | message.Chat.Title, 60 | "https://t.me/" + message.Chat.Username) 61 | ); 62 | 63 | string replyMessage = "Thank you {{from_username}} for your feedback!\nIt has been recorded."; 64 | Bot.Manager.BotClient.SendTextMessageAsync( 65 | chatId: message.Chat.Id, 66 | parseMode: ParseMode.Markdown, 67 | text: Parsers.VariablesParser(replyMessage, message), 68 | replyMarkup: new ReplyKeyboardRemove() { Selective = true } 69 | ); 70 | } 71 | } 72 | 73 | public class WebClientWithTimeout : System.Net.WebClient 74 | { 75 | protected override System.Net.WebRequest GetWebRequest(Uri address) 76 | { 77 | System.Net.WebRequest wr = base.GetWebRequest(address); 78 | wr.Timeout = 5000; // timeout in milliseconds (ms) 79 | return wr; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Utils/ImageHash.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.IO; 9 | 10 | namespace Unifiedban.Terminal.Utils 11 | { 12 | [Serializable] 13 | public class ImageHash 14 | { 15 | private readonly int _hashSide; 16 | 17 | private bool[] _hashData; 18 | public bool[] HashData 19 | { 20 | get { return _hashData; } 21 | } 22 | 23 | public Image Img 24 | { 25 | get 26 | { 27 | return Bitmap.FromFile(FilePath); 28 | } 29 | } 30 | 31 | public string FilePath { get; private set; } 32 | 33 | public string FileName 34 | { 35 | get 36 | { 37 | return Path.GetFileName(FilePath); 38 | } 39 | } 40 | 41 | public string FileLocation 42 | { 43 | get { return Path.GetDirectoryName(FilePath); } 44 | } 45 | 46 | private string _imgSize; 47 | public string ImgSize 48 | { 49 | get { return _imgSize; } 50 | } 51 | 52 | 53 | public ImageHash(int hashSideSize = 16) 54 | { 55 | _hashSide = hashSideSize; 56 | 57 | _hashData = new bool[hashSideSize * hashSideSize]; 58 | } 59 | 60 | /// 61 | /// Method to compare 2 image hashes 62 | /// 63 | /// % of similarity 64 | public double CompareWith(ImageHash compareWith) 65 | { 66 | if (HashData.Length != compareWith.HashData.Length) 67 | { 68 | throw new Exception("Cannot compare hashes with different sizes"); 69 | } 70 | 71 | int differenceCounter = 0; 72 | 73 | for (int i = 0; i < HashData.Length; i++) 74 | { 75 | if (HashData[i] != compareWith.HashData[i]) 76 | { 77 | differenceCounter++; 78 | } 79 | } 80 | 81 | return 100 - differenceCounter / 100.0 * HashData.Length / 2.0; 82 | } 83 | 84 | public void GenerateFromPath(string path) 85 | { 86 | FilePath = path; 87 | 88 | Bitmap image = (Bitmap)Image.FromFile(path, true); 89 | 90 | _imgSize = $"{image.Size.Width}x{image.Size.Height}"; 91 | 92 | GenerateFromImage(image); 93 | 94 | image.Dispose(); 95 | } 96 | public void GenerateFromPathReversed(string path) 97 | { 98 | FilePath = path; 99 | 100 | Bitmap image = (Bitmap)Image.FromFile(path, true); 101 | 102 | _imgSize = $"{image.Size.Width}x{image.Size.Height}"; 103 | 104 | GenerateFromImageReversed(image); 105 | 106 | image.Dispose(); 107 | } 108 | 109 | private void GenerateFromImage(Bitmap img) 110 | { 111 | List lResult = new List(); 112 | 113 | //resize img to 16x16px (by default) or with configured size 114 | Bitmap bmpMin = new Bitmap(img, new Size(_hashSide, _hashSide)); 115 | 116 | for (int j = 0; j < bmpMin.Height; j++) 117 | { 118 | for (int i = 0; i < bmpMin.Width; i++) 119 | { 120 | //reduce colors to true and false 121 | lResult.Add(bmpMin.GetPixel(i, j).GetBrightness() < 0.5f); 122 | } 123 | } 124 | 125 | _hashData = lResult.ToArray(); 126 | 127 | bmpMin.Dispose(); 128 | } 129 | private void GenerateFromImageReversed(Bitmap img) 130 | { 131 | List lResult = new List(); 132 | 133 | //resize img to 16x16px (by default) or with configured size 134 | Bitmap bmpMin = new Bitmap(img, new Size(_hashSide, _hashSide)); 135 | bmpMin.RotateFlip(RotateFlipType.RotateNoneFlipX); 136 | 137 | for (int j = 0; j < bmpMin.Height; j++) 138 | { 139 | for (int i = 0; i < bmpMin.Width; i++) 140 | { 141 | //reduce colors to true and false 142 | lResult.Add(bmpMin.GetPixel(i, j).GetBrightness() < 0.5f); 143 | } 144 | } 145 | 146 | _hashData = lResult.ToArray(); 147 | 148 | bmpMin.Dispose(); 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/Utils/LogTools.cs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | using Hangfire; 6 | using Newtonsoft.Json; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using Quartz; 11 | using Unifiedban.BusinessLogic; 12 | using Unifiedban.Models; 13 | 14 | namespace Unifiedban.Terminal.Utils 15 | { 16 | public class LogTools 17 | { 18 | static SystemLogLogic sll = new SystemLogLogic(); 19 | static List systemLogs = new List(); 20 | static object systemLogLock = new object(); 21 | 22 | static ActionLogLogic all = new ActionLogLogic(); 23 | static List actionLogs = new List(); 24 | static object actionLogLock = new object(); 25 | 26 | static TrustFactorLogLogic tfll = new TrustFactorLogLogic(); 27 | static List trustFactorLogs = new List(); 28 | static object trustFactorLogLock = new object(); 29 | 30 | static OperationLogLogic oll = new OperationLogLogic(); 31 | static List operationLogs = new List(); 32 | static object operatorLogLock = new object(); 33 | 34 | static SupportSessionLogLogic ssl = new SupportSessionLogLogic(); 35 | static List supportSessionLogs = new List(); 36 | static object supportSessionLogLock = new object(); 37 | 38 | public static void Initialize() 39 | { 40 | // RecurringJob.AddOrUpdate("LogTools_SyncSystemLog", () => SyncSystemLog(), "0/30 * * ? * *"); 41 | // RecurringJob.AddOrUpdate("LogTools_SyncActionLog", () => SyncActionLog(), "0/30 * * ? * *"); 42 | // RecurringJob.AddOrUpdate("LogTools_SyncTrustFactorLog", () => SyncTrustFactorLog(), "0/30 * * ? * *"); 43 | // RecurringJob.AddOrUpdate("LogTools_SyncOperationLog", () => SyncOperationLog(), "0/30 * * ? * *"); 44 | // RecurringJob.AddOrUpdate("LogTools_SyncSupportSessionLog", () => SyncSupportSessionLog(), "0/30 * * ? * *"); 45 | 46 | var syncLogJob = JobBuilder.Create() 47 | .WithIdentity("syncLogJob", "logs") 48 | .Build(); 49 | var syncLogJobTrigger = TriggerBuilder.Create() 50 | .WithIdentity("syncLogJobTrigger", "logs") 51 | .StartNow() 52 | .WithSimpleSchedule(x => x 53 | .WithIntervalInSeconds(30) 54 | .RepeatForever()) 55 | .Build(); 56 | Program.Scheduler?.ScheduleJob(syncLogJob, syncLogJobTrigger).Wait(); 57 | } 58 | 59 | public static void Dispose() 60 | { 61 | SyncSystemLog(); 62 | SyncActionLog(); 63 | SyncTrustFactorLog(); 64 | SyncOperationLog(); 65 | SyncSupportSessionLog(); 66 | } 67 | 68 | internal static void SyncSystemLog() 69 | { 70 | List logsToSync = new List(); 71 | lock (systemLogLock) 72 | { 73 | logsToSync = new List(systemLogs); 74 | systemLogs.Clear(); 75 | } 76 | 77 | if (logsToSync.Count() != 0) 78 | { 79 | sll.Add(logsToSync, -2); 80 | } 81 | } 82 | internal static void SyncActionLog() 83 | { 84 | List logsToSync = new List(); 85 | lock (actionLogLock) 86 | { 87 | logsToSync = new List(actionLogs); 88 | actionLogs.Clear(); 89 | } 90 | 91 | if (logsToSync.Count() != 0) 92 | { 93 | all.Add(logsToSync, -2); 94 | } 95 | } 96 | internal static void SyncTrustFactorLog() 97 | { 98 | List logsToSync = new List(); 99 | lock (trustFactorLogs) 100 | { 101 | logsToSync = new List(trustFactorLogs); 102 | trustFactorLogs.Clear(); 103 | } 104 | 105 | if (logsToSync.Count() != 0) 106 | { 107 | tfll.Add(logsToSync, -2); 108 | } 109 | } 110 | internal static void SyncOperationLog() 111 | { 112 | List logsToSync = new List(); 113 | lock (operatorLogLock) 114 | { 115 | logsToSync = new List(operationLogs); 116 | operationLogs.Clear(); 117 | } 118 | 119 | if (logsToSync.Count() != 0) 120 | { 121 | foreach (var log in logsToSync) 122 | { 123 | oll.Add(log, -2); 124 | } 125 | } 126 | } 127 | internal static void SyncSupportSessionLog() 128 | { 129 | List logsToSync = new List(); 130 | lock (supportSessionLogLock) 131 | { 132 | logsToSync = new List(supportSessionLogs); 133 | systemLogs.Clear(); 134 | } 135 | 136 | if (logsToSync.Count() != 0) 137 | { 138 | ssl.Add(logsToSync, -2); 139 | } 140 | } 141 | 142 | public static void AddSystemLog(SystemLog log) 143 | { 144 | lock (systemLogLock) 145 | { 146 | systemLogs.Add(log); 147 | } 148 | } 149 | public static void AddActionLog(ActionLog log) 150 | { 151 | lock (actionLogLock) 152 | { 153 | actionLogs.Add(log); 154 | } 155 | } 156 | public static void AddTrustFactorLog(TrustFactorLog log) 157 | { 158 | lock (trustFactorLogLock) 159 | { 160 | trustFactorLogs.Add(log); 161 | } 162 | } 163 | public static void AddOperationLog(OperationLog log) 164 | { 165 | lock (operationLogs) 166 | { 167 | operationLogs.Add(log); 168 | } 169 | } 170 | public static void AddSupportSessionLog(SupportSessionLog log) 171 | { 172 | lock (supportSessionLogLock) 173 | { 174 | supportSessionLogs.Add(log); 175 | } 176 | } 177 | } 178 | } -------------------------------------------------------------------------------- /Unifiedban.Terminal/appsettings.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "LoggerName": "Unifiedban-Terminal", 3 | "Database": "Data Source=SERVER\\Instance;Initial Catalog=DatabaseName;Trusted_Connection=True", 4 | "HFDatabase": "Server=SERVER\\Instance;Database=DatabaseName_Hangfire;Trusted_Connection=True", 5 | "HFPrepareSchema": true, // (default) false, 6 | "UseHF": false, 7 | "APIKEY": "***REMOVED***", 8 | "ControlChatId": -1001125553456, 9 | "motd": "Yay!", 10 | "HelpMenu": "{\"inline_keyboard\":[[{\"text\":\"Project website\",\"url\":\"https://unifiedban.solutions\"},{\"text\":\"Project website\",\"url\":\"https://unifiedban.solutions\"}],[{\"text\":\"Project website\",\"url\":\"https://unifiedban.solutions\"},{\"text\":\"Project website\",\"url\":\"https://unifiedban.solutions\"}]]}", 11 | "TFLimitPenalty": -1, 12 | "TFKickPenalty": -3, 13 | "TFBanPenalty": -5, 14 | "HubServerAddress": "https://api.unifiedban.solutions/MainHub", 15 | "HubServerToken": "***", 16 | "CaptchaAutoKickTimer": 1, // minutes 17 | "GroupAliasLinkPrefix": "https://entermy.group/p/?", 18 | "UptimeMonitor": { 19 | "URL": "", 20 | "Seconds": 30 21 | }, 22 | "RabbitMQ": { 23 | "HostName": "10.0.0.0", 24 | "Port": 5672, 25 | "VirtualHost": "/", 26 | "Username": "", 27 | "Password": "" 28 | }, 29 | "PastHoursToSkip": 12, 30 | "ThrowPendingUpdates": false 31 | } 32 | -------------------------------------------------------------------------------- /Unifiedban.Terminal/log4net.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | --------------------------------------------------------------------------------