diff --git a/.env-default b/.env-default new file mode 100644 index 0000000..cc2f8fa --- /dev/null +++ b/.env-default @@ -0,0 +1,4 @@ +DISCORD_BOT_TOKEN=bot_token_here +DISCORD_BOT_ID=bot_id_here +SSL_CERT_PATH=pfx_path_here +SSL_CERT_PASS=pfx_passphase_here \ No newline at end of file diff --git a/.gitignore b/.gitignore index 1fe633e..6a7d6d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,390 +1,130 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj +# Logs +logs *.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov -# Visual Studio 6 build log -*.plg +# Coverage directory used by tools like istanbul +coverage +*.lcov -# Visual Studio 6 workspace options file -*.opt +# nyc test coverage +.nyc_output -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions +# Bower dependency directory (https://bower.io/) +bower_components -# Paket dependency manager -.paket/paket.exe -paket-files/ +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ -# FAKE - F# Make -.fake/ +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ -# CodeRush personal settings -.cr/personal +# TypeScript cache +*.tsbuildinfo -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc +# Optional npm cache directory +.npm -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config +# Optional eslint cache +.eslintcache -# Tabs Studio -*.tss +# Optional stylelint cache +.stylelintcache -# Telerik's JustMock configuration file -*.jmconfig +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs +# Optional REPL history +.node_repl_history -# OpenCover UI analysis results -OpenCover/ +# Output of 'npm pack' +*.tgz -# Azure Stream Analytics local run output -ASALocalRun/ +# Yarn Integrity file +.yarn-integrity -# MSBuild Binary and Structured Log -*.binlog +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local -# NVidia Nsight GPU debugger configuration file -*.nvuser +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache -# MFractors (Xamarin productivity tool) working folder -.mfractor/ +# Next.js build output +.next +out -# Local History for Visual Studio -.localhistory/ +# Nuxt.js build / generate output +.nuxt +dist -# BeatPulse healthcheck temp database -healthchecksdb +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ +# vuepress build output +.vuepress/dist -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ +# vuepress v2.x temp and cache directory +.temp +.cache -# Common IntelliJ Platform excludes +# Docusaurus cache and generated files +.docusaurus -# User specific -**/.idea/**/workspace.xml -**/.idea/**/tasks.xml -**/.idea/shelf/* -**/.idea/dictionaries -**/.idea/httpRequests/ +# Serverless directories +.serverless/ -# Sensitive or high-churn files -**/.idea/**/dataSources/ -**/.idea/**/dataSources.ids -**/.idea/**/dataSources.xml -**/.idea/**/dataSources.local.xml -**/.idea/**/sqlDataSources.xml -**/.idea/**/dynamic.xml +# FuseBox cache +.fusebox/ -# Rider -# Rider auto-generates .iml files, and contentModel.xml -**/.idea/**/*.iml -**/.idea/**/contentModel.xml -**/.idea/**/modules.xml -.idea +# DynamoDB Local files +.dynamodb/ -*.suo -*.user -.vs/ -[Bb]in/ -[Oo]bj/ -_UpgradeReport_Files/ -[Pp]ackages/ - -Thumbs.db -Desktop.ini -.DS_Store +# TernJS port file +.tern-port +# Stores VSCode versions used for testing VSCode extensions +.vscode-test -# Custom ignores -DiscordBot/config.json \ No newline at end of file +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* \ No newline at end of file diff --git a/Discord.Addons.Interactive.dll b/Discord.Addons.Interactive.dll deleted file mode 100644 index 9a25c9f..0000000 Binary files a/Discord.Addons.Interactive.dll and /dev/null differ diff --git a/DiscordBot.sln b/DiscordBot.sln deleted file mode 100644 index afb6f67..0000000 --- a/DiscordBot.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29721.120 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscordBot", "DiscordBot\DiscordBot.csproj", "{80385988-3A9A-010D-0F8C-0C7977AB44F8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {80385988-3A9A-010D-0F8C-0C7977AB44F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {80385988-3A9A-010D-0F8C-0C7977AB44F8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {80385988-3A9A-010D-0F8C-0C7977AB44F8}.Debug|x86.ActiveCfg = Debug|x86 - {80385988-3A9A-010D-0F8C-0C7977AB44F8}.Debug|x86.Build.0 = Debug|x86 - {80385988-3A9A-010D-0F8C-0C7977AB44F8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {80385988-3A9A-010D-0F8C-0C7977AB44F8}.Release|Any CPU.Build.0 = Release|Any CPU - {80385988-3A9A-010D-0F8C-0C7977AB44F8}.Release|x86.ActiveCfg = Release|x86 - {80385988-3A9A-010D-0F8C-0C7977AB44F8}.Release|x86.Build.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {C5E8BCC8-9716-424E-91CB-A33821D053DC} - EndGlobalSection -EndGlobal diff --git a/DiscordBot/DiscordBot.csproj b/DiscordBot/DiscordBot.csproj deleted file mode 100644 index 7f34c98..0000000 --- a/DiscordBot/DiscordBot.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - Exe - DiscordBot - net5.0 - DiscordBot - AnyCPU;x86 - DiscordBot.Program - $(DefaultItemExcludes);$(ProjectDir)**\*.vb - latest - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - PreserveNewest - - - - diff --git a/DiscordBot/Helper/ExtensionMethods.cs b/DiscordBot/Helper/ExtensionMethods.cs deleted file mode 100644 index 7cd0403..0000000 --- a/DiscordBot/Helper/ExtensionMethods.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Discord.Commands; -namespace DiscordBot.Helper -{ - public static class ExtensionMethods - { - public static int CustomPriority(this CommandInfo commandInfo) - { - return commandInfo.Name switch - { - "help" => 0, - "auth" => 1, - "unauth" => 2, - "rec" => 3, - "leave" => 4, - "notify" => 5, - "dnotify" => 6, - "start" => 7, - "stop" => 8, - _ => 99 - }; - } - } -} \ No newline at end of file diff --git a/DiscordBot/Migrations/20210807145627_movingtoef.Designer.cs b/DiscordBot/Migrations/20210807145627_movingtoef.Designer.cs deleted file mode 100644 index e25ed5b..0000000 --- a/DiscordBot/Migrations/20210807145627_movingtoef.Designer.cs +++ /dev/null @@ -1,102 +0,0 @@ -// -using DiscordBot.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -namespace DiscordBot.Migrations -{ - [DbContext(typeof(DatabaseContext))] - [Migration("20210807145627_movingtoef")] - partial class movingtoef - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "5.0.8"); - - modelBuilder.Entity("DiscordBot.Models.Auth", b => - { - b.Property("ID") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("IP") - .HasColumnType("TEXT"); - - b.Property("Serverid") - .HasColumnType("INTEGER"); - - b.Property("Token") - .HasColumnType("TEXT"); - - b.HasKey("ID"); - - b.ToTable("Auth"); - }); - - modelBuilder.Entity("DiscordBot.Models.Notify", b => - { - b.Property("ID") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Channelid") - .HasColumnType("INTEGER"); - - b.Property("Serverid") - .HasColumnType("INTEGER"); - - b.HasKey("ID"); - - b.ToTable("Notify"); - }); - - modelBuilder.Entity("DiscordBot.Models.OnHold", b => - { - b.Property("ID") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("IP") - .HasColumnType("TEXT"); - - b.Property("Token") - .HasColumnType("TEXT"); - - b.HasKey("ID"); - - b.ToTable("OnHold"); - }); - - modelBuilder.Entity("DiscordBot.Models.OnJoin", b => - { - b.Property("ID") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Channelid") - .HasColumnType("INTEGER"); - - b.Property("Messageid") - .HasColumnType("INTEGER"); - - b.Property("Roleid") - .HasColumnType("INTEGER"); - - b.Property("Serverid") - .HasColumnType("INTEGER"); - - b.Property("sevent") - .HasColumnType("INTEGER"); - - b.HasKey("ID"); - - b.ToTable("OnJoin"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/DiscordBot/Migrations/20210807145627_movingtoef.cs b/DiscordBot/Migrations/20210807145627_movingtoef.cs deleted file mode 100644 index 91b7de5..0000000 --- a/DiscordBot/Migrations/20210807145627_movingtoef.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -namespace DiscordBot.Migrations -{ - public partial class movingtoef : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Auth", - columns: table => new - { - ID = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Serverid = table.Column(type: "INTEGER", nullable: false), - Token = table.Column(type: "TEXT", nullable: true), - IP = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Auth", x => x.ID); - }); - - migrationBuilder.CreateTable( - name: "Notify", - columns: table => new - { - ID = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Serverid = table.Column(type: "INTEGER", nullable: false), - Channelid = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Notify", x => x.ID); - }); - - migrationBuilder.CreateTable( - name: "OnHold", - columns: table => new - { - ID = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Token = table.Column(type: "TEXT", nullable: true), - IP = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_OnHold", x => x.ID); - }); - - migrationBuilder.CreateTable( - name: "OnJoin", - columns: table => new - { - ID = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Serverid = table.Column(type: "INTEGER", nullable: false), - Channelid = table.Column(type: "INTEGER", nullable: false), - Roleid = table.Column(type: "INTEGER", nullable: false), - sevent = table.Column(type: "INTEGER", nullable: false), - Messageid = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_OnJoin", x => x.ID); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Auth"); - - migrationBuilder.DropTable( - name: "Notify"); - - migrationBuilder.DropTable( - name: "OnHold"); - - migrationBuilder.DropTable( - name: "OnJoin"); - } - } -} diff --git a/DiscordBot/Migrations/DatabaseContextModelSnapshot.cs b/DiscordBot/Migrations/DatabaseContextModelSnapshot.cs deleted file mode 100644 index a2209fb..0000000 --- a/DiscordBot/Migrations/DatabaseContextModelSnapshot.cs +++ /dev/null @@ -1,100 +0,0 @@ -// -using DiscordBot.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -namespace DiscordBot.Migrations -{ - [DbContext(typeof(DatabaseContext))] - partial class DatabaseContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "5.0.8"); - - modelBuilder.Entity("DiscordBot.Models.Auth", b => - { - b.Property("ID") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("IP") - .HasColumnType("TEXT"); - - b.Property("Serverid") - .HasColumnType("INTEGER"); - - b.Property("Token") - .HasColumnType("TEXT"); - - b.HasKey("ID"); - - b.ToTable("Auth"); - }); - - modelBuilder.Entity("DiscordBot.Models.Notify", b => - { - b.Property("ID") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Channelid") - .HasColumnType("INTEGER"); - - b.Property("Serverid") - .HasColumnType("INTEGER"); - - b.HasKey("ID"); - - b.ToTable("Notify"); - }); - - modelBuilder.Entity("DiscordBot.Models.OnHold", b => - { - b.Property("ID") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("IP") - .HasColumnType("TEXT"); - - b.Property("Token") - .HasColumnType("TEXT"); - - b.HasKey("ID"); - - b.ToTable("OnHold"); - }); - - modelBuilder.Entity("DiscordBot.Models.OnJoin", b => - { - b.Property("ID") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Channelid") - .HasColumnType("INTEGER"); - - b.Property("Messageid") - .HasColumnType("INTEGER"); - - b.Property("Roleid") - .HasColumnType("INTEGER"); - - b.Property("Serverid") - .HasColumnType("INTEGER"); - - b.Property("sevent") - .HasColumnType("INTEGER"); - - b.HasKey("ID"); - - b.ToTable("OnJoin"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/DiscordBot/Models/Database.cs b/DiscordBot/Models/Database.cs deleted file mode 100644 index 6adf7a5..0000000 --- a/DiscordBot/Models/Database.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscordBot.Models -{ - public class Auth - { - [Key] - public int ID { get; set; } - public ulong Serverid { get; set; } - public string Token { get; set; } - public string IP { get; set; } - } - public class Notify - { - [Key] - public int ID { get; set; } - public ulong Serverid { get; set; } - public ulong Channelid { get; set; } - } - public class OnJoin - { - [Key] - public int ID { get; set; } - public ulong Serverid { get; set; } - public ulong Channelid { get; set; } - public ulong Roleid { get; set; } - public int sevent { get; set; } - public ulong Messageid { get; set; } - } - public class OnHold - { - [Key] - public int ID { get; set; } - public string Token { get; set; } - public string IP { get; set; } - } -} diff --git a/DiscordBot/Models/DatabaseContext.cs b/DiscordBot/Models/DatabaseContext.cs deleted file mode 100644 index c4cff50..0000000 --- a/DiscordBot/Models/DatabaseContext.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscordBot.Models -{ - public class DatabaseContext : DbContext - { - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder.UseSqlite($@"Data source= {AppDomain.CurrentDomain.BaseDirectory + "Fork.db"}"); - } - public DbSet Auth { get; set; } - public DbSet Notify { get; set; } - public DbSet OnJoin { get; set; } - public DbSet OnHold { get; set; } - } -} diff --git a/DiscordBot/Modules/BotTools.cs b/DiscordBot/Modules/BotTools.cs deleted file mode 100644 index d18ec68..0000000 --- a/DiscordBot/Modules/BotTools.cs +++ /dev/null @@ -1,797 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Discord; -using Discord.Commands; -using Discord.WebSocket; -using DiscordBot.Helper; -using DiscordBot.Models; -using Interactivity; - - -namespace DiscordBot -{ - public class BotTools : ModuleBase - { - private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); - public InteractivityService Interactivity { get; set; } - /// - /// Int 0 is to modify the message, int 1 is to send a new message - /// - public static async Task NotificationControlAsync(ulong messageid, ulong channelid, string msg, int status, - int num = 0) - { - try - { - if (num == 0) - { - IMessageChannel channel = (IMessageChannel)KKK.Client.GetChannel(channelid); - IUserMessage themessage = (IUserMessage)await channel.GetMessageAsync(messageid); - - await themessage.ModifyAsync(msgProperty => { msgProperty.Embed = Embed(msg, status); }); - } - else if (num == 1) - { - IMessageChannel channel = (IMessageChannel)KKK.Client.GetChannel(channelid); - - await channel.SendMessageAsync(null, false, Embed(msg, status)); - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - } - - public static Embed Embed(string msg, int status = 0) - { - var ebd = new EmbedBuilder(); - if (status == 0) - { - Color Colorr = new Color(21, 22, 34); - ebd.Color = Colorr; - } - else if (status == 20 || status == 21) - { - ebd.Color = Color.Green; - } - else if (status == 40 || status == 44) - { - ebd.Color = Color.Red; - } - - ebd.WithDescription($"{msg}"); - - return ebd.Build(); - } - - - - /// - /// By giving server id, it gets ip and token, and using timout is optional, its on 10 sec default - /// - public static async Task Sendmsg(ulong serverid, string msg, long timeout = 10000) - { - DatabaseContext context = new DatabaseContext(); - - string token = context.Auth.AsQueryable().Where(a => a.Serverid == serverid).Single().Token; - string ip = context.Auth.AsQueryable().Where(a => a.Serverid == serverid).Single().IP; - - if (CheckConnection(ip)) //check if its connected - { - Stopwatch sw = new Stopwatch(); - sw.Start(); - while (true) - { - if (sw.ElapsedMilliseconds > timeout) - { - Console.WriteLine($"Connection Timeout for {ip}"); - return 0; - } - - try - { - var socket = Program.allSockets.Find(client => client.ConnectionInfo.ClientIpAddress == ip); - await socket.Send(msg); -#if DEBUG - Console.WriteLine($"{msg} send to {socket.ConnectionInfo.ClientIpAddress}"); -#endif - return 1; - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - return 0; - } - } - } - - return 0; - } - - [Command("rec", RunMode = RunMode.Async)] - [Alias("rec")] - [Summary("Recreates Fork related role and channel")] - public async Task Rec() - { - await Task.Run(async () => - { - try - { - DatabaseContext context = new DatabaseContext(); - if (context.OnJoin.FirstOrDefault(a => a.Serverid == Context.Guild.Id) != null) - { - context.Remove(context.OnJoin.Single(a => a.Serverid == Context.Guild.Id)); - context.SaveChanges(); - } - - string warning = null; - try - { - if (Context.Guild.Roles.Any(x => x.Name.ToLower() == "Fork-Mods".ToLower())) - { - foreach (var Role in Context.Guild.Roles.Where(x => x.Name.ToLower() == "Fork-Mods".ToLower())) - { - await Role.DeleteAsync(); - } - } - } - catch (Exception ex) - { - warning += - $"`Fork-Mods` role detected, please move my role to top roles then run `$rec` to clean it." + - Environment.NewLine; - } - - try - { - foreach (var channel in Context.Guild.Channels.Where(x => - string.Equals(x.Name, "Fork-Bot", StringComparison.CurrentCultureIgnoreCase))) - { - await channel.DeleteAsync(); - } - } - catch (Exception ex) - { - warning += - $"`Fork-Bot` channel detected, please move my role to top roles then run `$rec` to clean it." + - Environment.NewLine; - } - - if (warning == null) - { - ulong origin = (ulong)GuildPermission.Speak + (ulong)GuildPermission.SendTTSMessages + - (ulong)GuildPermission.SendMessages + (ulong)GuildPermission.ViewChannel + - (ulong)GuildPermission.EmbedLinks + (ulong)GuildPermission.Connect + - (ulong)GuildPermission.AttachFiles + (ulong)GuildPermission.AddReactions; - GuildPermissions perms = new GuildPermissions(origin); - //Color Colorr = new Color(21, 22, 34); - var roleee = await Context.Guild.CreateRoleAsync("Fork-Mods", perms, null, false, false, null); - var vChan = await Context.Guild.CreateTextChannelAsync("Fork-Bot"); - await vChan.AddPermissionOverwriteAsync(roleee, CommandHandler.AdminPermissions()); - await vChan.AddPermissionOverwriteAsync(Context.Guild.EveryoneRole, CommandHandler.NoPermissions()); - - var ebd = new EmbedBuilder(); - ebd.Color = Color.Green; - ebd.WithCurrentTimestamp(); - ebd.WithAuthor($"Fork Server Management", Context.Guild.CurrentUser.GetAvatarUrl()); - ebd.WithDescription( - "Hello there," + - Environment.NewLine + - "I'm Fork Bot if you don't know me, I can help you control your Fork Minecraft servers and display their status in Discord." + - Environment.NewLine + - "I made a private channel for you, please use `$auth [token]` to link this Discord server with your Fork app." + - Environment.NewLine + - "You can check for your token in Fork app settings."); - //var ownerr = KKK.Client.GetGuild(guild.Id).OwnerId; - await vChan.SendMessageAsync($"<@{Context.Guild.OwnerId}>", false, ebd.Build()); - var msgg = await vChan.SendMessageAsync(null, false, - Embed( - "Don't remove this message, this message will be updated continuously and display the status of you Fork servers.", - 20)); - using (var contextt = new DatabaseContext()) - { - OnJoin newset = new OnJoin(); - newset.Serverid = Context.Guild.Id; - newset.Roleid = roleee.Id; - newset.Channelid = vChan.Id; - newset.Messageid = msgg.Id; - contextt.Add(newset); - contextt.SaveChanges(); - } - } - else - { - var ebd = new EmbedBuilder(); - ebd.Color = Color.Red; - ebd.WithCurrentTimestamp(); - ebd.WithAuthor($"Error", Context.Guild.CurrentUser.GetAvatarUrl()); - ebd.WithDescription(warning); - //var ownerr = KKK.Client.GetGuild(guild.Id).OwnerId; - await Context.Guild.DefaultChannel.SendMessageAsync($"<@{Context.Guild.OwnerId}>", false, - ebd.Build()); - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - }); - } - - [Command("stop", RunMode = RunMode.Async)] - [Alias("stop")] - [Summary("Stops a specific Minecraft server")] - public async Task Stop([Remainder] string servername) - { - try - { - var msg = await ReplyAsync(Context.Message.Author.Mention, false, - Embed("Alright give me few seconds please.")); - int result = await Sendmsg(Context.Guild.Id, - $"stop|{servername}|{Context.User.Username}#{Context.User.Discriminator}|{Context.Channel.Id}|{msg.Id}"); - switch (result) - { - case 1: - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed("Command Executed.", 20); - }); - break; - case 0: - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = - Embed( - "Oops. Looks like your fork app isn't online or connection timed out, please restart it.", - 40); - }); - break; - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - } - - [Command("start", RunMode = RunMode.Async)] - [Alias("start")] - [Summary("Starts a specific Minecraft server")] - public async Task Start([Remainder] string servername) - { - try - { - var msg = await ReplyAsync(Context.Message.Author.Mention, false, - Embed("Alright give me few seconds please.")); - int result = await Sendmsg(Context.Guild.Id, - $"start|{servername}|{Context.User.Username}#{Context.User.Discriminator}|{Context.Channel.Id}|{msg.Id}"); - switch (result) - { - case 1: - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed("Command Executed.", 20); - }); - break; - case 0: - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = - Embed( - "Oops. Looks like your fork app isnt online or connection timed out, please restart it.", - 40); - }); - break; - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - } - - [Command("notify", RunMode = RunMode.Async)] - [Alias("notification")] - [Summary("Subscribe to Player join/leave events")] - public async Task Notify(SocketGuildChannel channel) - { - try - { - DatabaseContext context = new DatabaseContext(); - string token = context.Auth.AsQueryable().Where(a => a.Serverid == Context.Guild.Id).Single().Token; - string ip = context.Auth.AsQueryable().Where(a => a.Serverid == Context.Guild.Id).Single().IP; - var msg = await ReplyAsync(Context.Message.Author.Mention, false, - Embed("Alright give me few seconds please.")); - - - if (context.Notify.Any(o => o.Serverid == Context.Guild.Id)) - { - //await msgg.PinAsync(); - var server = context.Notify.First(a => a.Serverid == Context.Guild.Id); - server.Channelid = channel.Id; - context.SaveChanges(); - - string warn = null; - if (CheckConnection(ip)) - { - await Sendmsg(Context.Guild.Id, $"subscribe|playerEvent"); - } - else - { - warn = Environment.NewLine + - "Couldn't connect to your Fork app but don't worry, I'll send you updates as soon as it's connected again."; - } - - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed($"Notification channel updated.{warn}", 20); - }); - } - else if ((context.Notify.Any(o => o.Serverid == Context.Guild.Id))) - { - //await msgg.PinAsync(); - using (var contexttt = new DatabaseContext()) - { - Notify newnotify = new Notify(); - newnotify.Serverid = Context.Guild.Id; - newnotify.Channelid = channel.Id; - contexttt.Add(newnotify); - contexttt.SaveChanges(); - } - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed("Notification channel submitted.", 20); - }); - } - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.Message); - } - } - - [Command("dnotify", RunMode = RunMode.Async)] - [Alias("dnotification")] - [Summary("Unsubscribes from Player join/leave events")] - public async Task DNotify() - { - try - { - DatabaseContext context = new DatabaseContext(); - string token = context.Auth.AsQueryable().Where(a => a.Serverid == Context.Guild.Id).Single().Token; - string ip = context.Auth.AsQueryable().Where(a => a.Serverid == Context.Guild.Id).Single().IP; - var msg = await ReplyAsync(Context.Message.Author.Mention, false, - Embed("Alright give me few seconds please.")); - - if (context.Notify.Any(o => o.Serverid == Context.Guild.Id)) - { - context.Remove(context.Notify.Single(a => a.Serverid == Context.Guild.Id)); - context.SaveChanges(); - if (CheckConnection(ip)) - { - await Sendmsg(Context.Guild.Id, $"unsub|playerEvent"); - } - - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed("Unsubscribed from player notifications successfully.", 20); - }); - } - else if (!(context.Notify.Any(o => o.Serverid == Context.Guild.Id))) - { - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed("You are not subscribed to player notifications.", 40); - }); - } - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.Message); - } - } - - //[Command("sub", RunMode = RunMode.Async)] - //[Alias("subscribe")] - //[Summary("Subscribe to an event. usage: (prefix)sub")] - public async Task Sub(bool check) - { - try - { - DatabaseContext context = new DatabaseContext(); - string token = context.Auth.AsQueryable().Where(a => a.Serverid == Context.Guild.Id).Single().Token; - string ip = context.Auth.AsQueryable().Where(a => a.Serverid == Context.Guild.Id).Single().IP; - int truefalse = check ? 1 : 0; - var msg = await ReplyAsync(Context.Message.Author.Mention, false, - Embed("Alright give me few seconds please.")); - - - - - - if (context.OnJoin.Any(o => o.Serverid == Context.Guild.Id && o.sevent == 1)) - { - if (check) - { - if (!(context.OnJoin.Any(o => o.Serverid == Context.Guild.Id && o.sevent == 1))) - { - - IMessageChannel chan = - (IMessageChannel)Context.Guild.GetChannel(context.OnJoin.AsQueryable().Where(a => a.Serverid == Context.Guild.Id).Single().Channelid); - var msgg = await chan.SendMessageAsync(null, false, - Embed( - "Don't remove this message, this message will be updated continuously and display the status of you Fork servers.", - 20)); - - var server = context.OnJoin.First(a => a.Serverid == Context.Guild.Id); - server.Messageid = msgg.Id; - server.sevent = truefalse; - context.SaveChanges(); - string warn = null; - if (CheckConnection(ip)) - { - await Sendmsg(Context.Guild.Id, $"subscribe|playerEvent"); - } - else - { - warn = Environment.NewLine + - "Couldn't connect to your Fork app but dont worry, I'll send updates as soon as it is connected again."; - } - - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed($"Enabled successfully.{warn}", 20); - }); - } - else - { - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed($"Already enabled.", 40); - }); - } - } - else if (!check) - { - if (context.OnJoin.Any(o => o.Serverid == Context.Guild.Id && o.sevent == 1)) - { - var server = context.OnJoin.First(a => a.Serverid == Context.Guild.Id); - server.Messageid = 0; - server.sevent = truefalse; - context.SaveChanges(); - - if (CheckConnection(ip) == true) - { - await Sendmsg(Context.Guild.Id, $"unsub|serverListEvent"); - } - - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed($"Disabled successfully.", 20); - }); - } - else - { - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed($"Already disabled.", 40); - }); - } - } - } - else - { - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed($"Please use $rec and retry", 40); - }); - } - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.Message); - } - } - - //[Command("ping", RunMode = RunMode.Async)] - //[Alias("latency")] - //[Summary("Shows the websocket connection's latency and time it takes to send a message. usage: (prefix)ping")] - public async Task PingAsync() - { - try - { - var watch = Stopwatch.StartNew(); - var msg = await ReplyAsync("Pong"); - await msg.ModifyAsync(msgProperty => msgProperty.Content = $"🏓 {watch.ElapsedMilliseconds}ms"); - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.Message); - } - } - - [Command("auth", RunMode = RunMode.Async)] - [Alias("authorize")] - [Summary("Links your Discord server to your Fork app")] - public async Task Auth(string token) - { - try - { - DatabaseContext context = new DatabaseContext(); - await Context.Message.DeleteAsync(); - var msg = await ReplyAsync(Context.Message.Author.Mention, false, - Embed("Alright give me few seconds please.")); - - if (context.Auth.Any(o => o.Token == token)) - { - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = - Embed( - "Couldn't connect to your Fork app. Either it is not running, Fork Bot is not enabled or your Fork app is already linked to another Discord server.", - 40); - }); - } - else if (!context.Auth.Any(o => o.Token == token || o.Serverid == Context.Guild.Id) && context.OnHold.Any(o => o.Token == token)) - { - //sorting the token goes here - //After connection if server replies, then its ok - - string ip = context.OnHold.AsQueryable().Where(a => a.Token ==token).Single().IP; - if (CheckConnection(ip)) //check if its connected - { - using (var ctx = new DatabaseContext()) - { - Auth newauth = new Auth(); - newauth.Serverid = Context.Guild.Id; - newauth.Token = token; - newauth.IP = ip; - ctx.Add(newauth); - ctx.SaveChanges(); - } - context.Remove(context.OnHold.Single(a => a.Token == token)); - context.SaveChanges(); - await Sendmsg(Context.Guild.Id, $"status|Linked|{Context.Guild.Name}"); - if (!context.OnJoin.Any(o => o.Serverid == Context.Guild.Id)) - { - await Rec(); - } - Program.AliveTokens.Add(token); - await Sendmsg(Context.Guild.Id, $"subscribe|serverListEvent"); - - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed("Great, your discord server is now linked to your Fork app.", - 20); - }); - } - else - { - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed("Couldn't connect to your Fork app, make sure it's running.", 40); - }); - } - } - else - { - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = - Embed("Sorry, but this Discord server or the token is already authorized or invalid.", 40); - }); - } - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.Message); - } - } - - [Command("help", RunMode = RunMode.Async)] - [Summary("Lists all available commands")] - public async Task Help() - { - try - { - EmbedBuilder eb = new EmbedBuilder { Color = Color.Blue }; - bool onemod = false; - List commands = new(); - foreach (ModuleInfo modulename in KKK.CommandService.Modules) - { - commands.AddRange(modulename.Commands); - } - commands.Sort((a, b) => a.CustomPriority().CompareTo(b.CustomPriority())); - StringBuilder names = new(); - StringBuilder descriptions = new(); - foreach (CommandInfo command in commands) - { - string cmdName = command.Name; - if (command.Parameters.Count > 0) - { - cmdName += " ["; - for (int i = 0; i < command.Parameters.Count; i++) - { - cmdName += command.Parameters[i]; - if (i < command.Parameters.Count - 1) - { - cmdName += " "; - } - } - cmdName += "]"; - } - names.Append($"${cmdName}{Environment.NewLine}"); - descriptions.Append(command.Summary + Environment.NewLine); - } - - eb.AddField("Command", names.ToString(), true); - eb.AddField("Description", descriptions.ToString(), true); - - eb.WithCurrentTimestamp(); - eb.WithAuthor("Command List", Context.Client.CurrentUser.GetAvatarUrl()); - eb.WithFooter("Requested by: " + Context.User.Username); - await ReplyAsync(Context.Message.Author.Mention, false, eb.Build()); - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.Message); - } - } - - [Command("leave", RunMode = RunMode.Async)] - [Alias("leave")] - [Summary("Bot will leave this Discord server")] - public async Task Leave() - { - try - { - DatabaseContext context = new DatabaseContext(); - var msg = await ReplyAsync(Context.Message.Author.Mention, false, - Embed( - $"Please type `{Context.Guild.Name}` to confirm.{Environment.NewLine}Be aware this process cant be recovered.{Environment.NewLine}Type anything else to cancel.")); - - var msgg = await Interactivity.NextMessageAsync(x => x.Author == Context.User); - - if (msgg.IsSuccess) - { - - await ReplyAsync(Context.Message.Author.Mention, false, - Embed($"Sad to see you go.., I'll leave shortly, good bye!", 20)); - if (msgg.Value.Content == Context.Guild.Name) - { - if (context.OnJoin.Any(o => o.Serverid == Context.Guild.Id)) - { - var TheEntry = context.OnJoin.AsQueryable().Where(a => a.Serverid == Context.Guild.Id).Single(); - try - { - if (Context.Guild.GetChannel(TheEntry.Channelid) != null) - { - var channel = - Context.Guild.GetChannel(TheEntry.Channelid); - await channel.DeleteAsync(); - } - - if (Context.Guild.GetRole(TheEntry.Roleid) != null) - { - var Role = Context.Guild.GetRole(TheEntry.Roleid); - await Role.DeleteAsync(); - } - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.Message); - } - } - - await Sendmsg(Context.Guild.Id, $"rec"); - await Sendmsg(Context.Guild.Id, $"status|OnHold"); - await Sendmsg(Context.Guild.Id, $"unsub|serverListEvent"); - await Sendmsg(Context.Guild.Id, $"unsub|playerEvent"); - context.Remove(context.Auth.Single(a => a.Serverid == Context.Guild.Id)); - context.Remove(context.OnJoin.Single(a => a.Serverid == Context.Guild.Id)); - context.Remove(context.Notify.Single(a => a.Serverid == Context.Guild.Id)); - context.SaveChanges(); - - string token = context.Auth.AsQueryable().Where(a => a.Serverid == Context.Guild.Id).Single().Token; - Program.AliveTokens.Remove(token); - try - { - await Context.Guild.LeaveAsync(); - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.Message); - } - } - else - { - await ReplyAsync(Context.Message.Author.Mention, false, Embed($"Canceled.", 20)); - } - } - - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - } - - private static bool CheckConnection(string ip) - { - if (Program.allSockets.Any(client => client.ConnectionInfo.ClientIpAddress == ip)) - { - var socket = Program.allSockets.Find(client => client.ConnectionInfo.ClientIpAddress == ip); - return socket != null && socket.IsAvailable; - } - - return false; - } - - [Command("unauth", RunMode = RunMode.Async)] - [Alias("unauthorize")] - [Summary("Unlinks your Fork app from this Discord server")] - public async Task UnAuth() - { - try - { - DatabaseContext context = new DatabaseContext(); - var msg = await ReplyAsync(Context.Message.Author.Mention, false, - Embed("Alright give me few seconds please.")); - - string token = context.Auth.AsQueryable().Where(a => a.Serverid == Context.Guild.Id).Single().Token; - - if (context.Auth.Any(o => o.Serverid == Context.Guild.Id || o.Token == token)) - { - - await Sendmsg(Context.Guild.Id, $"rec"); - await Sendmsg(Context.Guild.Id, $"status|OnHold"); - await Sendmsg(Context.Guild.Id, $"unsub|serverListEvent"); - await Sendmsg(Context.Guild.Id, $"unsub|playerEvent"); - context.Remove(context.Auth.Single(a => a.Serverid == Context.Guild.Id)); - context.Remove(context.OnJoin.Single(a => a.Serverid == Context.Guild.Id)); - context.Remove(context.Notify.Single(a => a.Serverid == Context.Guild.Id)); - context.SaveChanges(); - Program.AliveTokens.Remove(token); - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed("Your discord server got unlinked from your Fork app successfully.", 20); - }); - } - else - { - await msg.ModifyAsync(msgProperty => - { - msgProperty.Content = $"{Context.Message.Author.Mention}"; - msgProperty.Embed = Embed("Your discord server isn't linked to a Fork app.", 40); - }); - } - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.Message); - } - } - } -} \ No newline at end of file diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs deleted file mode 100644 index 60b311e..0000000 --- a/DiscordBot/Program.cs +++ /dev/null @@ -1,599 +0,0 @@ -using Discord; -using Discord.Commands; -using Discord.WebSocket; -using DiscordBot.Models; -using Fleck; -using Interactivity; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using NLog; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -namespace DiscordBot -{ - class Program - { - private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); - public static List allSockets { get; set; } = new List(); - /// Connected Tokens - /// - public static List AliveTokens { get; set; } = new List(); - - public static void Main() - { - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; - Console.ForegroundColor = ConsoleColor.Green; - - Console.WriteLine(@" -███████╗░█████╗░██████╗░██╗░░██╗  ██████╗░░█████╗░████████╗ -██╔════╝██╔══██╗██╔══██╗██║░██╔╝  ██╔══██╗██╔══██╗╚══██╔══╝ -█████╗░░██║░░██║██████╔╝█████═╝░  ██████╦╝██║░░██║░░░██║░░░ -██╔══╝░░██║░░██║██╔══██╗██╔═██╗░  ██╔══██╗██║░░██║░░░██║░░░ -██║░░░░░╚█████╔╝██║░░██║██║░╚██╗  ██████╦╝╚█████╔╝░░░██║░░░ -╚═╝░░░░░░╚════╝░╚═╝░░╚═╝╚═╝░░╚═╝  ╚═════╝░░╚════╝░░░░╚═╝░░░ ----------------------------------------------------------------"); - Console.WriteLine("- Checking if database exists .."); - if (File.Exists(@"Fork.db")) - { - Console.WriteLine("- Exists."); - } - else - { - using (var context = new DatabaseContext()) - { - context.Database.EnsureCreated(); - } - Console.WriteLine("- Created."); - } - Console.WriteLine("- Migrating Database"); - using (var context = new DatabaseContext()) - { - context.Database.Migrate(); - } - - try - { - if (File.Exists(@"logs.log")) - { - File.Delete(@"Logs.log"); - } - } - catch (Exception xxxx) - { - - } - - var config = new NLog.Config.LoggingConfiguration(); - var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "nlogs.txt" }; - var logconsole = new NLog.Targets.ConsoleTarget("logconsole"); - config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, logconsole); - config.AddRule(NLog.LogLevel.Debug, NLog.LogLevel.Fatal, logfile); - NLog.LogManager.Configuration = config; - - Console.WriteLine("- Done."); - new Program().MainAsync().GetAwaiter().GetResult(); - } - private IConfiguration BuildConfig() - { - return new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("config.json").Build(); - } - public async Task MainAsync() - { - var config = BuildConfig(); - using (var services = ConfigureServices()) - { - var client = services.GetRequiredService(); - services.GetRequiredService(); - - await client.LoginAsync(TokenType.Bot, config["token"]); - await client.StartAsync(); - await services.GetRequiredService().InitializeAsync(); - await Task.Run(async () => await GetReadyWS()); - await Task.Delay(Timeout.Infinite); - } - } - private async Task GetReadyWS() - { - - - if (KKK.IsClientReady != true) - { - Console.WriteLine("Waiting for client to be ready..."); //Dont start events until discord api is ready - } - - do - { - // nothing, just pauses the tasks until discord is ready - } while (KKK.IsClientReady != true); - - Console.WriteLine("It's ready, lets start, shall we?"); - DatabaseContext context = new DatabaseContext(); -#if RELEASE - var server = new WebSocketServer("wss://0.0.0.0:8181"); - var config = BuildConfig(); - server.Certificate = new X509Certificate2(config["certPath"], config["certPassword"]); -#elif DEBUG - var server = new WebSocketServer("ws://0.0.0.0:8181"); -#endif - server.Start(socket => - { - socket.OnOpen = () => - { - if (allSockets.Any(client => - client.ConnectionInfo.ClientIpAddress == socket.ConnectionInfo.ClientIpAddress)) - { - var socket2 = allSockets.Find(client => - client.ConnectionInfo.ClientIpAddress == socket.ConnectionInfo.ClientIpAddress); - try - { - allSockets.Remove(socket2); - } - catch (Exception ex) - { - logger.Warn(ex.ToString(), "An error occured."); - } //Little security, dont let same ip to connect twice - - allSockets.Add(socket); - } - else - { - try - { - allSockets.Remove(socket); - } - catch (Exception ex) - { - logger.Warn(ex.ToString(), "An error occured."); - } - - allSockets.Add(socket); - } - }; - socket.OnClose = () => - { - Console.WriteLine("Closed connection: " + socket.ConnectionInfo.ClientIpAddress); - allSockets.Remove(socket); - if (context.Auth.Any(o => o.IP == socket.ConnectionInfo.ClientIpAddress)) - { - string token = context.Auth.AsQueryable().Where(a => a.IP == socket.ConnectionInfo.ClientIpAddress).Single().Token; - if (AliveTokens.Contains(token)) - { - AliveTokens.Remove(token); - logger.Info($"{socket.ConnectionInfo.ClientIpAddress} Removed from alive tokens list"); - } - } - - }; - socket.OnMessage = message => - { - Task.Run(async () => - { - try - { -#if DEBUG - Console.WriteLine($"Message Received: {message}"); -#endif - string[] codes = message.Split('|'); - switch (codes[0]) - { - case "login": - string token = codes[1]; - if (context.Auth.Any(o => o.Token == token)) - { - - if (!AliveTokens.Contains(context.Auth.AsQueryable().Where(a => a.IP == socket.ConnectionInfo.ClientIpAddress).Single().Token)) - { - try - { - AliveTokens.Add(token); - Console.WriteLine( - $"{socket.ConnectionInfo.ClientIpAddress}:{token} Added to alive tokens list"); -#if DEBUG - Console.WriteLine("Here is Serverid: " + - context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid); -#endif - if (KKK.Client.GetGuild(context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid) != null) - { - var guild = KKK.Client.GetGuild( - context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid); - await socket.Send($"status|Linked|{guild.Name}"); - } - else - { - await socket.Send($"status|Linked|null"); - } - if (context.Notify.Any(o => o.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid)) - { - await socket.Send($"subscribe|playerEvent"); - } - if (context.OnJoin.Any(o => (o.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid) && o.sevent == 1)) - { - await socket.Send($"subscribe|serverListEvent"); - } - } - catch (Exception ex) - { - logger.Warn(ex.ToString(), "An error occured."); - } - } - } - else if (!(context.Auth.Any(o => o.Token == token))) - { - if (!(context.OnHold.Any(o => o.IP == socket.ConnectionInfo.ClientIpAddress))) - { - using (var contextt = new DatabaseContext()) - { - OnHold newonhold = new OnHold(); - newonhold.IP = socket.ConnectionInfo.ClientIpAddress; - newonhold.Token = token; - contextt.Add(newonhold); - contextt.SaveChanges(); - } - } else if ((context.OnHold.Any(o => o.IP == socket.ConnectionInfo.ClientIpAddress))) - { - var onhold = context.OnHold.First(a => a.IP == socket.ConnectionInfo.ClientIpAddress); - onhold.Token = token; - context.SaveChanges(); - } - Console.WriteLine("Token: " + token + - $" IP: {socket.ConnectionInfo.ClientIpAddress} Added to onhold list"); - await socket.Send("status|OnHold"); - } - - break; - case "notify": - - if (AliveTokens.Contains(context.Auth.AsQueryable().Where(a => a.IP == socket.ConnectionInfo.ClientIpAddress).Single().Token)) - { - await Task.Run(async () => - { - try - { - string servername = codes[1]; - string discordname = codes[2]; - string channelid = codes[3]; - string messageid = codes[4]; - string eventt = codes[5]; - string result = codes[6]; - - switch (eventt) - { - case "stop": - - switch (result) - { - //notify|{servername}|{discordname}|{channelid}|{messageid}|{eventt}|400|this is a test - case "20": //ok - await BotTools.NotificationControlAsync( - ulong.Parse(messageid), ulong.Parse(channelid), - $"Your `{servername}` stopped successfully, command was executed by `{discordname}`", - int.Parse(result)); - break; - - case "40": //its stopped already - await BotTools.NotificationControlAsync( - ulong.Parse(messageid), ulong.Parse(channelid), - $"Your `{servername}` is stopped already, command was executed by `{discordname}`", - int.Parse(result)); - break; - - case "44": //server not found - await BotTools.NotificationControlAsync( - ulong.Parse(messageid), ulong.Parse(channelid), - $"I couldnt find your `{servername}` server, please make sure you typed the right name, command was executed by `{discordname}`", - int.Parse(result)); - break; - } - - break; - - case "start": - - switch (result) - { - //notify|{servername}|{discordname}|{channelid}|{messageid}|{eventt}|400|this is a test - case "20": //ok - await BotTools.NotificationControlAsync( - ulong.Parse(messageid), ulong.Parse(channelid), - $"Your `{servername}` server is starting.. , command was executed by `{discordname}`", - int.Parse(result)); - break; - case "21": //ok - await BotTools.NotificationControlAsync( - ulong.Parse(messageid), ulong.Parse(channelid), - $"Your `{servername}` started successfully, command was executed by `{discordname}`", - int.Parse(result)); - break; - case "40": //its stopped already - await BotTools.NotificationControlAsync( - ulong.Parse(messageid), ulong.Parse(channelid), - $"Your `{servername}` is running already, command was executed by `{discordname}`", - int.Parse(result)); - break; - - case "44": //server not found - await BotTools.NotificationControlAsync( - ulong.Parse(messageid), ulong.Parse(channelid), - $"I couldnt find your `{servername}` server, please make sure you typed the right name, command was executed by `{discordname}`", - int.Parse(result)); - break; - } - - break; - } - } - catch (Exception ex) - { - logger.Warn($"Couldn't process request: {ex.Message}"); - } - }); - } - - break; - case "event": - await Task.Run(async () => - { - string eventname = codes[1]; - string servername = codes[2]; - string playername = codes[3]; - try - { - string token = context.Auth.AsQueryable().Where(a => a.IP == socket.ConnectionInfo.ClientIpAddress).Single().Token; - if (AliveTokens.Contains(token)) - { - if (KKK.Client.GetGuild(context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid) != null) - { - if (eventname.StartsWith("p") - && context.Notify.AsQueryable().Any(x => x.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid) - && KKK.Client.GetGuild(context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid) - .GetChannel( - context.Notify.AsQueryable().Where(a => a.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid).Single().Channelid) != null) - { - switch (eventname) - { - case "pjoin": - await BotTools.NotificationControlAsync(0, - context.Notify.AsQueryable().Where(a => a.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid).Single().Channelid, - $"***{playername}*** Just joined ***{servername}***", 0, - 1); - break; - case "pleave": - await BotTools.NotificationControlAsync(0, - context.Notify.AsQueryable().Where(a => a.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid).Single().Channelid, - $"***{playername}*** Just left ***{servername}***", 0, - 1); - break; - } - } - else if (eventname.StartsWith("serverList") && - context.OnJoin.Any(o => (o.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid) && o.sevent == 1) - && KKK.Client - .GetGuild(context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid) - .GetChannel( - context.OnJoin.AsQueryable().Where(a => a.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid).Single().Channelid) != - null) - { - await Task.Run(async () => - { - try - { - if (AliveTokens.Contains(token) && - (context.OnJoin.Any(o => (o.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid) && o.sevent == 1))) - { - ulong guild = context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid; - if (KKK.Client.GetGuild(guild) - .GetChannel( - context.OnJoin.AsQueryable().Where(a => a.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid).Single().Channelid) != null) - { - if (context.OnJoin.AsQueryable().Where(a => a.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid).Single().Messageid != 0) - { - IMessageChannel chan = - (IMessageChannel)KKK.Client.GetChannel(context.OnJoin.AsQueryable().Where(a => a.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid).Single().Channelid); - IUserMessage msg = - (IUserMessage)await chan.GetMessageAsync(context.OnJoin.AsQueryable().Where(a => a.Serverid == context.Auth.AsQueryable().Where(a => a.Token == token).Single().Serverid).Single().Messageid); - if (msg != null) - { - await msg.ModifyAsync(msgProperty => - { - msgProperty.Embed = - BuildServerListEmbed(message); - }); - } - else - { - var msgg = await chan.SendMessageAsync(null, - false, - BotTools.Embed( - "Dont remove this message, this message will be updated continuously", - 20)); - var server = context.OnJoin.First(a => a.Serverid == guild); - server.Messageid = msgg.Id; - server.sevent = 1; - context.SaveChanges(); - await msgg.ModifyAsync(msgProperty => - { - msgProperty.Embed = - BuildServerListEmbed(message); - }); - } - } - } - } - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.ToString()); - } - }); - } - } - } - } - catch (Exception ex) - { - Console.WriteLine("Exception occured: " + ex.ToString()); - } - }); - - break; - - default: - // ban ip in case gets to x requests To-DO - Console.WriteLine($"Someone is trying to troll here, invalid packet: {message}"); - break; - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - }); - - - //Console.WriteLine(message); - - //allSockets.ToList().ForEach(s => s.Send(message)); - }; - }); - var input = Console.ReadLine(); - while (input != "exit") - { - //foreach (var socket in allSockets.ToList()) - //{ - // await socket.Send(input); - //} - //input = Console.ReadLine(); - } - } - private static Embed BuildServerListEmbed(string msg) - { - string[] split = msg.Split('|'); - - //List serverList = new List(); - string serverrr = null; - int i = 2; - while (i < split.Length - 5) - { - string serverName = split[i]; - string serverType = split[i + 1]; - string serverVersion = split[i + 2]; - string serverStatus = split[i + 3]; - string playerCount = split[i + 4]; - string maxPlayers = split[i + 5]; - //TODO replace these with custom cool looking emojis - Emote statusEmote; - if (serverStatus.ToLower().Equals("running")) - { - if (!Emote.TryParse("<:Online:800460070709362739>", out statusEmote)) - { - statusEmote = Emote.Parse(":green_circle:"); - } - } - else if (serverStatus.ToLower().Equals("stopped")) - { - if (!Emote.TryParse("<:Offline:800460061255663646>", out statusEmote)) - { - statusEmote = Emote.Parse(":red_circle:"); - } - } - else if (serverStatus.ToLower().Equals("starting")) - { - if (!Emote.TryParse("<:Starting:800460572268953670>", out statusEmote)) - { - statusEmote = Emote.Parse(":yellow_circle:"); - } - } - else - { - statusEmote = Emote.Parse(":black_circle:"); - } - - string typeEmote; - if (serverType.ToLower().Equals("vanilla")) - { - if (Emote.TryParse("<:Vanilla:800457564403400724>", out _)) - { - typeEmote = "<:Vanilla:800457564403400724>"; - } - else - { - typeEmote = "Vanilla"; - } - } - else if (serverType.ToLower().Equals("paper")) - { - if (Emote.TryParse("<:Paper:800457547907596359>", out _)) - { - typeEmote = "<:Paper:800457547907596359>"; - } - else - { - typeEmote = "Paper"; - } - } - else if (serverType.ToLower().Equals("spigot")) - { - if (Emote.TryParse("<:Spigot:800458118857228298>", out _)) - { - typeEmote = "<:Spigot:800458118857228298>"; - } - else - { - typeEmote = "Spigot"; - } - } - else if (serverType.ToLower().Equals("waterfall")) - { - if (Emote.TryParse("<:Waterfall:800457575590002708>", out _)) - { - typeEmote = "<:Waterfall:800457575590002708>"; - } - else - { - typeEmote = "Waterfall"; - } - } - else - { - typeEmote = "Unknown"; - } - - //Build server string - string server = $"{statusEmote} {serverName} ({typeEmote} {serverVersion}) {playerCount}/{maxPlayers}" + - Environment.NewLine; - serverrr += server; - i = i + 6; - } - - var ebd = new EmbedBuilder(); - Color Colorr = new Color(21, 22, 34); - ebd.WithTitle("Your current servers"); - ebd.WithDescription($"{serverrr}"); - ebd.WithCurrentTimestamp(); - return ebd.Build(); - } - private ServiceProvider ConfigureServices() - { - return new ServiceCollection() - .AddSingleton(new DiscordSocketClient(new DiscordSocketConfig() { MessageCacheSize = 20, AlwaysDownloadUsers = true, LogLevel = LogSeverity.Verbose, - GatewayIntents= GatewayIntents.DirectMessageReactions | GatewayIntents.DirectMessages | - GatewayIntents.GuildBans | GatewayIntents.GuildInvites | GatewayIntents.GuildMembers | - GatewayIntents.GuildMessageReactions | GatewayIntents.GuildMessages | - GatewayIntents.Guilds | GatewayIntents.GuildIntegrations - })) //, .TotalShards = 3})) - .AddSingleton(new CommandService(new CommandServiceConfig() { LogLevel = LogSeverity.Verbose, DefaultRunMode = RunMode.Async })) - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton(new InteractivityConfig { DefaultTimeout = TimeSpan.FromSeconds(40) }) // You can optionally add a custom config - .BuildServiceProvider(); - } - } -} \ No newline at end of file diff --git a/DiscordBot/Services/CommandHandler.cs b/DiscordBot/Services/CommandHandler.cs deleted file mode 100644 index 9d30dd5..0000000 --- a/DiscordBot/Services/CommandHandler.cs +++ /dev/null @@ -1,291 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Sockets; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; -using Discord; -using Discord.Commands; -using Discord.WebSocket; -using DiscordBot.Models; -using NLog; - -namespace DiscordBot -{ - - static class KKK - { - public static string prefix = "$"; - public static CommandService CommandService; - public static DiscordSocketClient Client; - public static bool IsClientReady = false; - } - - public class CommandHandler - { - private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); - private readonly IServiceProvider Services; - - public CommandHandler(DiscordSocketClient client, CommandService commandService, IServiceProvider services) - { - KKK.Client = client; - KKK.CommandService = commandService; - Services = services; - } - - public async Task InitializeAsync() - { - await KKK.CommandService.AddModulesAsync(Assembly.GetEntryAssembly(), Services); - KKK.Client.Ready += OnClientReady; - KKK.Client.UserJoined += welcome; - KKK.Client.MessageReceived += HandleCommandAsync; - KKK.Client.JoinedGuild += OnGuildJoin; - KKK.Client.LeftGuild += OnGuildLeave; - KKK.Client.Disconnected += OnClientDisconnect; - } - - public static OverwritePermissions AdminPermissions() - { - return new(PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Allow, - PermValue.Allow, PermValue.Deny, PermValue.Allow, PermValue.Deny, PermValue.Deny, PermValue.Allow, - PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Deny, - PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Deny); - } - - public static OverwritePermissions NoPermissions() - { - return new(PermValue.Deny, PermValue.Deny, PermValue.Deny, - PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Deny, - PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Deny, - PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Deny, - PermValue.Deny, PermValue.Deny, PermValue.Deny, PermValue.Deny, - PermValue.Deny); - } - - private async Task OnGuildJoin(SocketGuild guild) - { - await Task.Run(async () => - { - try - { - DatabaseContext context = new DatabaseContext(); - - - if (!(context.Auth.Any(o => o.Serverid == guild.Id) && (!(context.OnJoin.Any(o => o.Serverid == guild.Id))))) - { - string warning = null; - try - { - if (guild.Roles.Any(x => x.Name == "Fork-Mods")) - { - foreach (var Role in guild.Roles.Where(x => x.Name == "Fork-Mods")) - { - await Role.DeleteAsync(); - } - } - } - catch (Exception ex) - { - warning += - $"`Fork-Mods` role detected, please move my role above the `Fork-Mods` role and authenticate using `$auth [token]` then run `$rec` to clean it." + - Environment.NewLine; - } - - try - { - if (guild.TextChannels.Any(x => x.Name == "Fork-Bot")) - { - foreach (var Chan in guild.Channels.Where(x => x.Name == "Fork-Bot")) - { - await Chan.DeleteAsync(); - } - } - } - catch (Exception ex) - { - warning += - $"`Fork-Bot` channel detected, please move my role above the `Fork-Mods` role and authenticate using `$auth [token]` then run `$rec` to clean it." + - Environment.NewLine; - } - - if (warning == null) - { - ulong origin = (ulong)GuildPermission.Speak + (ulong)GuildPermission.SendTTSMessages + - (ulong)GuildPermission.SendMessages + (ulong)GuildPermission.ViewChannel + - (ulong)GuildPermission.EmbedLinks + (ulong)GuildPermission.Connect + - (ulong)GuildPermission.AttachFiles + (ulong)GuildPermission.AddReactions; - GuildPermissions perms = new GuildPermissions(origin); - //Color Colorr = new Color(21, 22, 34); - var roleee = await guild.CreateRoleAsync("Fork-Mods", perms, null, false, false, null); - var vChan = await guild.CreateTextChannelAsync("Fork-Bot"); - await vChan.AddPermissionOverwriteAsync(roleee, AdminPermissions()); - await vChan.AddPermissionOverwriteAsync(guild.EveryoneRole, NoPermissions()); - - var ebd = new EmbedBuilder(); - ebd.Color = Color.Green; - ebd.WithCurrentTimestamp(); - ebd.WithAuthor($"Fork Server Management", guild.CurrentUser.GetAvatarUrl()); - ebd.WithDescription( - "Hello there," + - Environment.NewLine + - "I'm Fork Bot if you don't know me, I can help you control your Fork Minecraft servers and display their status in Discord." + - Environment.NewLine + - "I made a private channel for you, please use `$auth [token]` to link this Discord server with your Fork app." + - Environment.NewLine + - "You can check for your token in Fork app settings."); - //var ownerr = KKK.Client.GetGuild(guild.Id).OwnerId; - await vChan.SendMessageAsync($"<@{guild.OwnerId}>", false, ebd.Build()); - var msgg = await vChan.SendMessageAsync(null, false, - BotTools.Embed("Don't remove this message, this message will be updated continuously and display the status of you Fork servers.", 20)); - using (var contextt = new DatabaseContext()) - { - OnJoin newset = new OnJoin(); - newset.Serverid = guild.Id; - newset.Roleid = roleee.Id; - newset.Channelid = vChan.Id; - newset.Messageid = msgg.Id; - contextt.Add(newset); - contextt.SaveChanges(); - } - - } - else - { - var ebd = new EmbedBuilder(); - ebd.Color = Color.Red; - ebd.WithCurrentTimestamp(); - ebd.WithAuthor($"Error", guild.CurrentUser.GetAvatarUrl()); - ebd.WithDescription(warning); - //var ownerr = KKK.Client.GetGuild(guild.Id).OwnerId; - await guild.DefaultChannel.SendMessageAsync($"<@{guild.OwnerId}>", false, ebd.Build()); - } - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - }); - } - - private async Task OnGuildLeave(SocketGuild guild) - { - await Task.Run(async () => - { - try - { - DatabaseContext context = new DatabaseContext(); - if ((context.Auth.Any(o => o.Serverid == guild.Id) || ((context.OnJoin.Any(o => o.Serverid == guild.Id))))) - - { - try - { - string token = context.Auth.AsQueryable().Where(a => a.Serverid == guild.Id).Single().Token; - await BotTools.Sendmsg(guild.Id, $"status|OnHold"); - await BotTools.Sendmsg(guild.Id, $"rec"); - await BotTools.Sendmsg(guild.Id, $"unsub|serverListEvent"); - await BotTools.Sendmsg(guild.Id, $"unsub|playerEvent"); - Program.AliveTokens.Remove(token); - } - catch (Exception ex) - { - logger.Warn($"Exception occured: {ex.ToString()}"); - } - context.Remove(context.Auth.Single(a => a.Serverid == guild.Id)); - context.Remove(context.Notify.Single(a => a.Serverid == guild.Id)); - context.Remove(context.OnJoin.Single(a => a.Serverid == guild.Id)); - context.SaveChanges(); - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - }); - } - - - - private async Task OnClientDisconnect(Exception k) - { - KKK.IsClientReady = false; - } - - private async Task OnClientReady() - { - KKK.IsClientReady = true; - try - { - await KKK.Client.SetGameAsync($"your Minecraft servers", null, ActivityType.Watching); - } - catch (Exception ex) - { - logger.Warn($"Exception occured: {ex.ToString()}"); - } - } - - private async Task welcome(SocketGuildUser user) - { - } - - private async Task HandleCommandAsync(SocketMessage message) - { - _ = Task.Run(async () => - { - - SocketUserMessage userMessage = message as SocketUserMessage; - if (userMessage is null || userMessage.Author.IsBot || userMessage.Author.IsWebhook) - return; - int argPos = 0; - var context = new SocketCommandContext(KKK.Client, userMessage); - try - { - if (message.Channel.GetType().ToString() != "Discord.WebSocket.SocketDMChannel") - { - if (!userMessage.HasMentionPrefix(KKK.Client.CurrentUser, ref argPos) && - !userMessage.HasStringPrefix(KKK.prefix, ref argPos, StringComparison.OrdinalIgnoreCase)) - { - return; - } - DatabaseContext contextt = new DatabaseContext(); - - var authorr = context.Guild.GetUser(context.Message.Author.Id); - var thisss = context.Message.Author as SocketGuildUser; - ulong roleeid = (contextt.OnJoin.AsQueryable().Where(a => a.Serverid == context.Guild.Id).FirstOrDefault() ==null) ? 0 : contextt.OnJoin.AsQueryable().Where(a => a.Serverid == context.Guild.Id).FirstOrDefault().Roleid; - - - - if (authorr.Roles.Any(r => r.Id == roleeid) || thisss.GuildPermissions.ManageGuild) - { - if (userMessage.Content.ToLower().StartsWith($"{KKK.prefix}auth") || - userMessage.Content.ToLower().StartsWith($"{KKK.prefix}leave") - ) //if its for authentication let the command to be executed - { - string command = userMessage.Content.Substring(argPos).Trim(); - var result = await KKK.CommandService.ExecuteAsync(context, command, Services); - - if (!result.IsSuccess) - { - if ((int?)result.Error != (int?)CommandError.UnknownCommand) - { - Console.WriteLine(result.ErrorReason); - } - } - } - } - } - else - { - await context.Channel.SendMessageAsync($"Im Not Working yet", false, null); - } - } - catch (Exception ex) - { - logger.Warn($"Exception occured: {ex.ToString()}"); - } - }); - - } - } -} \ No newline at end of file diff --git a/DiscordBot/Services/LogService.cs b/DiscordBot/Services/LogService.cs deleted file mode 100644 index 5a89b4c..0000000 --- a/DiscordBot/Services/LogService.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Threading.Tasks; -using Discord; -using Discord.Commands; -using Discord.WebSocket; -using Microsoft.VisualBasic; -namespace DiscordBot -{ - - public class LogService - { - public LogService(DiscordSocketClient client, CommandService commands) - { - client.Log += ClientLog; - commands.CommandExecuted += CommandLog; - } - - public static Task ClientLog(LogMessage message) - { - - Console.WriteLine(message.ToString()); - writetolog(message.ToString()); - return Task.CompletedTask; - - } - - public static void writetolog(string text) - { - string location = AppDomain.CurrentDomain.BaseDirectory; - string fullpath = System.IO.Path.Combine(location, "logs.log"); - try - { - System.IO.File.AppendAllText(System.IO.Path.Combine(location, "logs.log"), DateTime.Now + " | " + text + Constants.vbNewLine); - } - catch (Exception ex) - { - } - } - - private Task CommandLog(Optional info, ICommandContext context, IResult result) - { - if (result.IsSuccess) - return Task.CompletedTask; - switch (result.Error.Value) - { - case CommandError.UnknownCommand: - { - return Task.CompletedTask; - } - - case CommandError.ParseFailed: - { - Console.WriteLine(context.Guild.Name + " | " + result.ToString()); - break; - } - - case CommandError.BadArgCount: - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine(context.Guild.Name + " | " + result.ToString()); - Console.ForegroundColor = ConsoleColor.Green; - break; - } - - case CommandError.ObjectNotFound: - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine(context.Guild.Name + " | " + result.ToString()); - Console.ForegroundColor = ConsoleColor.Green; - break; - } - - case CommandError.MultipleMatches: - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(context.Guild.Name + " | " + result.ToString()); - Console.ForegroundColor = ConsoleColor.Green; - break; - } - - case CommandError.UnmetPrecondition: - { - Console.WriteLine(context.Guild.Name + " | " + result.ToString()); - break; - } - - case CommandError.Exception: - { - Console.WriteLine(context.Guild.Name + " | " + result.ToString()); - break; - } - - case CommandError.Unsuccessful: - { - Console.WriteLine(context.Guild.Name + " | " + result.ToString()); - break; - } - - default: - { - break; - } - } - - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 4da5e63..0000000 --- a/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Fork DiscordBot - -This Discord Bot is used to connect a Fork instance to a Discord server for remote controlling and event updates. - -## How to use -This bot is hosted on a public server and is used by every Fork user, if `Enable Discord Bot` is enabled in the Fork settings. - -If you run Fork in `DEBUG` mode it will look for this running locally. - -## Building and Running -To build and run this code please follow these steps: - 1. Clone/fork this repository - 2. Add Discord.NET beta to nuget package sources: https://www.myget.org/F/discord-net/api/v3/index.json - 3. Add a copy of the [config.json](https://github.com/ForkGG/DiscordBot/blob/main/config.json) to the `DiscordBot` directory and add the token of a Discord bot created [here](https://discord.com/developers/applications) - 4. The project should now be able to build and run. To test it you should also run the [Fork project](https://github.com/ForkGG/Fork) in `DEBUG` mode on the same machine - - ## Credits - - Thanks to [Alpha-c0d3r | Illusion](https://github.com/EN1GMA4) for coding most of this project - - Thanks to the [Patrons](https://www.patreon.com/forkgg) helping to cover the hosting costs for this Bot diff --git a/config.json b/config.json index bcab658..740baa7 100644 --- a/config.json +++ b/config.json @@ -1,5 +1 @@ -{ - "token": "", - "certPath": "cert.pfx", - "certPassword": "" -} \ No newline at end of file +{"guilds":{"1022867142275776552":"dxjUaTJnmBpexsQBN4ngUgkeytQ8778/9OkLGSR14XY="}} \ No newline at end of file diff --git a/nodemon.json b/nodemon.json new file mode 100644 index 0000000..4f68445 --- /dev/null +++ b/nodemon.json @@ -0,0 +1,3 @@ +{ + "ignore": ["*.json"] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..edb4985 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,284 @@ +{ + "name": "tests", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "discord.js": "^14.14.1", + "dotenv": "^16.3.1" + } + }, + "node_modules/@discordjs/builders": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz", + "integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==", + "dependencies": { + "@discordjs/formatters": "^0.3.3", + "@discordjs/util": "^1.0.2", + "@sapphire/shapeshift": "^3.9.3", + "discord-api-types": "0.37.61", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.3", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/collection": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/formatters": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz", + "integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==", + "dependencies": { + "discord-api-types": "0.37.61" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/rest": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz", + "integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==", + "dependencies": { + "@discordjs/collection": "^2.0.0", + "@discordjs/util": "^1.0.2", + "@sapphire/async-queue": "^1.5.0", + "@sapphire/snowflake": "^3.5.1", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.61", + "magic-bytes.js": "^1.5.0", + "tslib": "^2.6.2", + "undici": "5.27.2" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/rest/node_modules/@discordjs/collection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz", + "integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@discordjs/util": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz", + "integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==", + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/ws": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz", + "integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==", + "dependencies": { + "@discordjs/collection": "^2.0.0", + "@discordjs/rest": "^2.1.0", + "@discordjs/util": "^1.0.2", + "@sapphire/async-queue": "^1.5.0", + "@types/ws": "^8.5.9", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.61", + "tslib": "^2.6.2", + "ws": "^8.14.2" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/ws/node_modules/@discordjs/collection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz", + "integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@sapphire/async-queue": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.1.tgz", + "integrity": "sha512-1RdpsmDQR/aWfp8oJzPtn4dNQrbpqSL5PIA0uAB/XwerPXUf994Ug1au1e7uGcD7ei8/F63UDjr5GWps1g/HxQ==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/shapeshift": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.5.tgz", + "integrity": "sha512-AGdHe+51gF7D3W8hBfuSFLBocURDCXVQczScTHXDS3RpNjNgrktIx/amlz5y8nHhm8SAdFt/X8EF8ZSfjJ0tnA==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@sapphire/snowflake": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz", + "integrity": "sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@types/node": { + "version": "20.10.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz", + "integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/ws": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", + "integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vladfrangu/async_event_emitter": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz", + "integrity": "sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/discord-api-types": { + "version": "0.37.61", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz", + "integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==" + }, + "node_modules/discord.js": { + "version": "14.14.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz", + "integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==", + "dependencies": { + "@discordjs/builders": "^1.7.0", + "@discordjs/collection": "1.5.3", + "@discordjs/formatters": "^0.3.3", + "@discordjs/rest": "^2.1.0", + "@discordjs/util": "^1.0.2", + "@discordjs/ws": "^1.0.2", + "@sapphire/snowflake": "3.5.1", + "@types/ws": "8.5.9", + "discord-api-types": "0.37.61", + "fast-deep-equal": "3.1.3", + "lodash.snakecase": "4.1.1", + "tslib": "2.6.2", + "undici": "5.27.2", + "ws": "8.14.2" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" + }, + "node_modules/magic-bytes.js": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.7.0.tgz", + "integrity": "sha512-YzVU2+/hrjwx8xcgAw+ffNq3jkactpj+f1iSL4LonrFKhvnwDzHSqtFdk/MMRP53y9ScouJ7cKEnqYsJwsHoYA==" + }, + "node_modules/ts-mixer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", + "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/undici": { + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz", + "integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/ws": { + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..7e1b655 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "tests", + "version": "1.0.0", + "description": "", + "main": "src/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "discord.js": "^14.14.1", + "dotenv": "^16.3.1" + } +} diff --git a/src/commands/StartServerCommand.js b/src/commands/StartServerCommand.js new file mode 100644 index 0000000..4639c2e --- /dev/null +++ b/src/commands/StartServerCommand.js @@ -0,0 +1,54 @@ +const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') +const fs = require('fs'); + +class StartServerCommand { + + data = new SlashCommandBuilder() + .setName('start') + .setDescription('Starts the minecraft server with the given name') + .addStringOption((opt) => opt + .setName('name') + .setDescription('Name of the server to start') + .setRequired(true)); + + async execute (interaction, syncs, iterations) { + const server = interaction.options.getString('name', true); + const issuer = interaction.user; + + let data = fs.readFileSync('config.json', 'utf8'); + data = JSON.parse(data); + let token = data.guilds[interaction.guildId]; + let ws; + if (token) { + ws = syncs.get(token); + } + + if (!ws || ws == null) { + var embed = new EmbedBuilder() + .setColor('#be2230') + .setTitle('Not connected') + .setAuthor({ + name: 'Fork' + }) + .setDescription(`Failed to start server ${server}. We are not connected to any Fork instance`); + + await interaction.reply({ embeds: [embed], ephemeral: true }); + return; + } + + var embed = new EmbedBuilder() + .setColor('#d3902d') + .setTitle('Starting server') + .setAuthor({ + name: 'Fork' + }) + .setDescription(`Trying to start ${server}. Please wait`); + + const response = await interaction.reply({ embeds: [embed], ephemeral: true, fetchReply: true }); + iterations.set(response.id, interaction); + + ws.send(`start|${server}|${response.id}`); + } +} + +module.exports = StartServerCommand; \ No newline at end of file diff --git a/src/commands/StopServerCommand.js b/src/commands/StopServerCommand.js new file mode 100644 index 0000000..a522a19 --- /dev/null +++ b/src/commands/StopServerCommand.js @@ -0,0 +1,54 @@ +const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') +const fs = require('fs'); + +class StopServerCommand { + + data = new SlashCommandBuilder() + .setName('stop') + .setDescription('Stops the minecraft server with the given name') + .addStringOption((opt) => opt + .setName('name') + .setDescription('Name of the server to stop') + .setRequired(true)); + + async execute (interaction, syncs, iterations) { + const server = interaction.options.getString('name', true); + const issuer = interaction.user; + + let data = fs.readFileSync('config.json', 'utf8'); + data = JSON.parse(data); + let token = data.guilds[interaction.guildId]; + let ws; + if (token) { + ws = syncs.get(token); + } + + if (!ws || ws == null) { + var embed = new EmbedBuilder() + .setColor('#be2230') + .setTitle('Not connected') + .setAuthor({ + name: 'Fork' + }) + .setDescription(`Failed to stop server ${server}. We are not connected to any Fork instance`); + + await interaction.reply({ embeds: [embed], ephemeral: true }); + return; + } + + var embed = new EmbedBuilder() + .setColor('#d3902d') + .setTitle('Stopping server') + .setAuthor({ + name: 'Fork' + }) + .setDescription(`Trying to stop ${server}. Please wait`); + + const response = await interaction.reply({ embeds: [embed], ephemeral: true, fetchReply: true }); + iterations.set(response.id, interaction); + + ws.send(`stop|${server}|${response.id}`); + } +} + +module.exports = StopServerCommand; \ No newline at end of file diff --git a/src/commands/SyncServerCommand.js b/src/commands/SyncServerCommand.js new file mode 100644 index 0000000..a92638b --- /dev/null +++ b/src/commands/SyncServerCommand.js @@ -0,0 +1,65 @@ +const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js'); +const fs = require('fs'); + +class SyncServerCommand { + + data = new SlashCommandBuilder() + .setName('sync') + .setDescription('Synchronizes the server with the fork instance') + .addStringOption((opt) => opt + .setName('token') + .setDescription('The fork generated token') + .setRequired(true)) + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator); + + async execute (interaction, syncs, iterations, sockets) { + const token = interaction.options.getString('token', true); + const issuer = interaction.user; + + if (syncs.get(token)) { + embed = new EmbedBuilder() + .setColor('#be2230') + .setTitle('Already synchronized') + .setAuthor({ + name: 'Fork' + }) + .setDescription('We are already synchronized with Fork'); + return; + } + + let data = fs.readFileSync('config.json', 'utf8'); + let embed; + try { + let json = JSON.parse(data); + json.guilds[interaction.guildId] = token; + + fs.writeFileSync('config.json', JSON.stringify(json)); + embed = new EmbedBuilder() + .setColor('#72cc72') + .setTitle('Synchronized') + .setAuthor({ + name: 'Fork' + }) + .setDescription('Success! Your discord server and your fork instance are now connected. Thanks for using Fork'); + + let ws = sockets.get(token); + if (ws) { + console.info('Noticing websocket about connection...') + ws.send(`status|linked|${interaction.guild.name}`) + syncs.set(token, ws); + } + } catch (error) { + embed = new EmbedBuilder() + .setColor('#be2230') + .setTitle('Not synchronized') + .setAuthor({ + name: 'Fork' + }) + .setDescription('There was a problem while synchronizing your server and your fork instance'); + } + + await interaction.reply({ embeds: [embed], ephemeral: true }); + } +} + +module.exports = SyncServerCommand; \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..5b6b6f8 --- /dev/null +++ b/src/index.js @@ -0,0 +1,250 @@ +require('dotenv').config(); + + +const { Client, REST, Routes, Events, ActivityType, IntentsBitField, Collection, EmbedBuilder } = require('discord.js'); +const WebSocket = require('ws'); +const https = require('https'); +const http = require('http'); +const fs = require('fs'); +const path = require('path'); + +const token = process.env.DISCORD_BOT_TOKEN; +const sockets = new Map(); +const syncs = new Map(); +const iterations = new Map(); + +const client = new Client({ + intents: [ + IntentsBitField.Flags.Guilds, + IntentsBitField.Flags.GuildMessages, + IntentsBitField.Flags.GuildMessageReactions, + IntentsBitField.Flags.GuildMembers + ] +}); +const rest = new REST({ + version: 9 +}).setToken(token); + +const certPath = process.env.SSL_CERT_PATH; +let server; +if (fs.existsSync(certPath)) { + server = https.createServer({ + pfx: fs.readFileSync(process.env.SSL_CERT_PATH), + passphrase: process.env.SSL_CERT_PASS + }); +} else { + server = http.createServer(); +} + +const ws = new WebSocket.Server({server}); + + +client.once(Events.ClientReady, function(c) { + console.log('Fork - Bot Loaded - ', c.user.tag); + + client.user.setPresence({ + activities: [ + { + name: "Fork", + type: ActivityType.Playing + } + ], + status: 'online', + }); + + ws.on('connection', (connection) => { + connection.on('message', async(message) => { + if (!message) return; + + message = Buffer.from(message).toString('utf8'); + if (!message.includes('|')) { + return; + } + console.info(message); + + let messageData = message.split('|'); + let code = messageData[0]; + + switch (code) { + case 'login': + let providedToken = messageData[1]; + let data = fs.readFileSync('config.json', 'utf8'); + try { + data = JSON.parse(data); + for (const key in data.guilds) { + let guild = client.guilds.cache.get(key); + if (!guild) continue; + + if (data.guilds[key] == providedToken) { + syncs.set(providedToken, connection); + connection.send(`status|linked|${guild.name}`) + connection.send('serverList|'); + connection.send('playerList|'); + } + } + + sockets.set(providedToken, connection); + } catch (err) { + console.info(err); + } + break; + case 'notify': + let guildId = () => { + let token; + sockets.forEach((value, key) => { + if (value == connection) token = key; + }); + + let k; + let data = fs.readFileSync('config.json', 'utf8'); + data = JSON.parse(data); + + for (const key in data.guilds) { + let guild = client.guilds.cache.get(key); + if (!guild) continue; + + if (data.guilds[key] == token) { + k = key; + } + } + + return k; + } + let gId = guildId(); + let guild = client.guilds.cache.get(gId); + if (!guild) return; + + let serverName = messageData[1]; + let messageId = messageData[2]; + let action = messageData[3]; + let resultCode = messageData[4]; + + let interaction = iterations.get(messageId); + //let message = await channel.messages.fetch(messageId); + + var embed; + switch (resultCode) { + case "44": + embed = new EmbedBuilder() + .setColor('#be2230') + .setTitle('Not started') + .setAuthor({ + name: 'Fork' + }) + .setDescription(`Failed to start server ${serverName} because it does not exist`); + break; + case "40": + embed = new EmbedBuilder() + .setColor('#be2230') + .setTitle('Not started') + .setAuthor({ + name: 'Fork' + }); + + if (action == "start") { + embed.setDescription(`Failed to start server ${serverName}. Probably it is already started`); + } else { + embed.setDescription(`Failed to stop server ${serverName}. Probably it is not started`); + } + break + case "20": + embed = new EmbedBuilder() + .setColor('#72cc72') + .setTitle('Started') + .setAuthor({ + name: 'Fork' + }); + + if (action == "start") { + embed.setDescription(`Sending start task to server ${serverName}.`); + } else { + embed.setDescription(`Sending kill task to server ${serverName}.`); + } + break; + case "21": + embed = new EmbedBuilder() + .setColor('#72cc72') + .setTitle('Started') + .setAuthor({ + name: 'Fork' + }); + + if (action == "start") { + embed.setDescription(`Successfully started server ${serverName}. It might take a few minutes to completely start`); + } else { + embed.setDescription(`Successfully stopped server ${serverName}. It might take a few seconds to complete`); + } + break; + } + + if (resultCode != "20") { + iterations.delete(messageId); + } + return await interaction.editReply({ embeds: [embed], ephemeral: true }); + } + }); + }); + + server.listen(8181, () => { + console.info('Successfully started Fork websocket. SSL:', fs.existsSync(certPath)) + }); +}); + +client.on(Events.InteractionCreate, async interaction => { + if (interaction.isChatInputCommand()) { + const command = interaction.client.commands.get(interaction.commandName); + + if (!command) { + console.error(`No command matching ${interaction.commandName} was found.`); + return; + } + + try { + await command.execute(interaction, syncs, iterations, sockets); + } catch (error) { + console.error(error); + await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true }); + } + } +}); + +const commands = []; +client.commands = new Collection(); + +console.info('Loading commands.'); +const commandsPath = path.join(__dirname, 'commands'); +const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); + +for (const file of commandFiles) { + const filePath = path.join(commandsPath, file); + const command = require(filePath); + let instance = new command(); + + if ('data' in instance && 'execute' in instance) { + if (instance.setClient != undefined) { + instance.setClient(client); + } + + client.commands.set(instance.data.name, instance); + commands.push(instance.data.toJSON()); + } else { + console.warn(`The command at ${filePath} is missing a required "data" or "execute" property.`); + } +} + +client.login(token); + +(async () => { + try { + console.log(`Started refreshing ${commands.length} application (/) commands.`); + + const data = await rest.put( + Routes.applicationCommands(process.env.DISCORD_BOT_ID), + { body: commands }, + ); + + console.log(`Successfully reloaded ${data.length} application (/) commands.`); + } catch (error) { + console.error(error); + } +})(); \ No newline at end of file diff --git a/ssl/cert.pfx b/ssl/cert.pfx new file mode 100644 index 0000000..3792a1b Binary files /dev/null and b/ssl/cert.pfx differ