This commit is contained in:
2022-07-09 09:48:58 +03:00
parent a66ebc43d9
commit 3839e4d838
17 changed files with 215 additions and 177 deletions

13
.idea/.idea.SethDiscordBot/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/projectSettingsUpdater.xml
/contentModel.xml
/.idea.SethDiscordBot.iml
/modules.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@@ -8,12 +8,25 @@
".NETCoreApp,Version=v6.0": {
"MusicCommands/1.0.0": {
"dependencies": {
"PluginManager": "1.0.0"
"PluginManager": "1.0.0",
"YoutubeExplode": "6.2.0"
},
"runtime": {
"MusicCommands.dll": {}
}
},
"AngleSharp/0.17.0": {
"dependencies": {
"System.Buffers": "4.5.1",
"System.Text.Encoding.CodePages": "5.0.0"
},
"runtime": {
"lib/netstandard2.0/AngleSharp.dll": {
"assemblyVersion": "0.17.0.0",
"fileVersion": "0.17.0.0"
}
}
},
"Discord.Net/3.7.2": {
"dependencies": {
"Discord.Net.Commands": "3.7.2",
@@ -108,6 +121,7 @@
}
}
},
"Microsoft.NETCore.Platforms/5.0.0": {},
"Newtonsoft.Json/13.0.1": {
"runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {
@@ -116,6 +130,7 @@
}
}
},
"System.Buffers/4.5.1": {},
"System.Collections.Immutable/5.0.0": {},
"System.Interactive.Async/5.0.0": {
"dependencies": {
@@ -144,7 +159,23 @@
}
}
},
"System.Text.Encoding.CodePages/5.0.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "5.0.0"
}
},
"System.ValueTuple/4.5.0": {},
"YoutubeExplode/6.2.0": {
"dependencies": {
"AngleSharp": "0.17.0"
},
"runtime": {
"lib/net5.0/YoutubeExplode.dll": {
"assemblyVersion": "6.2.0.0",
"fileVersion": "6.2.0.0"
}
}
},
"PluginManager/1.0.0": {
"dependencies": {
"Discord.Net": "3.7.2"
@@ -161,6 +192,13 @@
"serviceable": false,
"sha512": ""
},
"AngleSharp/0.17.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-74haoXINcj4SdMsmiNzk+9VUwIX1U9P61O6AZd5Uao8SGNnJJB8Y/r8VJRc8orn4c7Vk/oURAKSNF9XcSDxbfA==",
"path": "anglesharp/0.17.0",
"hashPath": "anglesharp.0.17.0.nupkg.sha512"
},
"Discord.Net/3.7.2": {
"type": "package",
"serviceable": true,
@@ -217,6 +255,13 @@
"path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512"
},
"Microsoft.NETCore.Platforms/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==",
"path": "microsoft.netcore.platforms/5.0.0",
"hashPath": "microsoft.netcore.platforms.5.0.0.nupkg.sha512"
},
"Newtonsoft.Json/13.0.1": {
"type": "package",
"serviceable": true,
@@ -224,6 +269,13 @@
"path": "newtonsoft.json/13.0.1",
"hashPath": "newtonsoft.json.13.0.1.nupkg.sha512"
},
"System.Buffers/4.5.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==",
"path": "system.buffers/4.5.1",
"hashPath": "system.buffers.4.5.1.nupkg.sha512"
},
"System.Collections.Immutable/5.0.0": {
"type": "package",
"serviceable": true,
@@ -252,6 +304,13 @@
"path": "system.reactive/5.0.0",
"hashPath": "system.reactive.5.0.0.nupkg.sha512"
},
"System.Text.Encoding.CodePages/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-NyscU59xX6Uo91qvhOs2Ccho3AR2TnZPomo1Z0K6YpyztBPM/A5VbkzOO19sy3A3i1TtEnTxA7bCe3Us+r5MWg==",
"path": "system.text.encoding.codepages/5.0.0",
"hashPath": "system.text.encoding.codepages.5.0.0.nupkg.sha512"
},
"System.ValueTuple/4.5.0": {
"type": "package",
"serviceable": true,
@@ -259,6 +318,13 @@
"path": "system.valuetuple/4.5.0",
"hashPath": "system.valuetuple.4.5.0.nupkg.sha512"
},
"YoutubeExplode/6.2.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-oH5kst4w1QkUwRjJco0alF57JOmFofSGlPkr4OniODB8R6MEyRWn1xFg3JS2wFYd6scZluoXRDhM3/uyUjO9/g==",
"path": "youtubeexplode/6.2.0",
"hashPath": "youtubeexplode.6.2.0.nupkg.sha512"
},
"PluginManager/1.0.0": {
"type": "project",
"serviceable": false,

Binary file not shown.

Binary file not shown.

View File

@@ -17,4 +17,8 @@
<ProjectReference Include="..\PluginManager\PluginManager.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="YoutubeExplode" Version="6.2.0" />
</ItemGroup>
</Project>

View File

@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Discord;
using Discord.Audio;
using Discord.Commands;
@@ -12,11 +13,11 @@ namespace MusicCommands;
internal class Play : DBCommand
{
public string Command => "fplay";
public string Command => "play";
public string Description => "Play music from a file";
public string Usage => "fplay [name]";
public string Usage => "fplay [name/url]";
public bool canUseDM => false;
@@ -26,15 +27,43 @@ internal class Play : DBCommand
public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM)
{
var path = "./Music";
var FileName = Functions.GetArguments(message).ToArray().MergeStrings(0);
path += "/" + FileName + ".ogg";
if (!File.Exists(path))
Directory.CreateDirectory("Music");
var path = "./Music/";
string[] splitted = message.Content.Split(' ');
if (splitted.Length < 2)
return;
do
{
Console.WriteLine("Unknown path " + path);
if (splitted.Length == 2)
{
if (!splitted[1].Contains("youtube.com"))
{
await context.Channel.SendMessageAsync("Invalid link");
return;
}
string url = splitted[1];
path += $"{Functions.CreateMD5(url)}";
if (File.Exists(path))
break;
//await context.Channel.SendMessageAsync("Searching for " + url);
await GetMusicAudio(url, path);
//await context.Channel.SendMessageAsync("Playing: " + url);
}
else
{
string searchString = Functions.MergeStrings(splitted, 1);
path += $"{Functions.CreateMD5(searchString)}";
if (File.Exists(path))
break;
await context.Channel.SendMessageAsync("Searching for " + searchString);
await GetMusicAudio(searchString, path);
await context.Channel.SendMessageAsync("Playing: " + searchString);
}
}
while (false);
Data.voiceChannel = (context.User as IGuildUser)?.VoiceChannel;
if (Data.voiceChannel == null)
@@ -59,4 +88,16 @@ internal class Play : DBCommand
{
return Process.Start(new ProcessStartInfo { FileName = "ffmpeg", Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1", UseShellExecute = false, RedirectStandardOutput = true });
}
private async Task GetMusicAudio(string url, string location)
{
Process proc = new Process();
proc.StartInfo.FileName = "MusicDownloader.exe";
proc.StartInfo.Arguments = $"{url},{location}";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
await proc.WaitForExitAsync();
}
}

View File

@@ -1,49 +0,0 @@
using Discord;
using Discord.Audio;
using Discord.Commands;
using Discord.WebSocket;
using PluginManager.Interfaces;
namespace MusicCommands;
internal class lplay : DBCommand
{
public string Command => "lplay";
public string Description => "Play music from a link";
public string Usage => "lplay [url]";
public bool canUseDM => false;
public bool canUseServer => false;
public bool requireAdmin => false;
public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM)
{
var URL = message.Content.Split(' ')[1];
if (!URL.EndsWith(".mp3") && !URL.EndsWith(".wav") && !URL.EndsWith(".flac") && !URL.EndsWith(".ogg"))
{
await message.Channel.SendMessageAsync("Invalid URL");
return;
}
Data.voiceChannel = (context.User as IGuildUser)?.VoiceChannel;
if (Data.voiceChannel == null)
{
await context.Channel.SendMessageAsync("User must be in a voice channel, or a voice channel must be passed as an argument.");
return;
}
Data.audioClient = await Data.voiceChannel.ConnectAsync();
using (var discord = Data.audioClient.CreatePCMStream(AudioApplication.Mixed))
{
await message.Channel.SendMessageAsync("Loading...");
Data.CurrentlyRunning = new MusicPlayer(discord);
await Data.CurrentlyRunning.StartSendAudioFromLink(URL);
}
}
}

View File

@@ -22,7 +22,7 @@ public class ConsoleCommandsHandler
{
this.client = client;
InitializeBasicCommands();
Console.WriteLine("Initialized console command handler !");
//Console.WriteLine("Initialized console command handler !");
}
private void InitializeBasicCommands()
@@ -128,9 +128,10 @@ public class ConsoleCommandsHandler
string path;
if (info[0] == "Command" || info[0] == "Event")
path = "./Data/Plugins/" + info[0] + "s/" + name + ".dll";
path = "./Data/Plugins/" + info[0] + "s/" + name + "." + (info[0] == "Command" ? PluginLoader.pluginCMDExtension : PluginLoader.pluginEVEExtension);
else
path = $"./{info[1].Split('/')[info[1].Split('/').Length - 1]}";
//Console.WriteLine("Downloading: " + path + " [" + info[1] + "]");
await ServerCom.DownloadFileAsync(info[1], path);
if (info[0] == "Command" || info[0] == "Event")
if (info[0] == "Event")
@@ -156,27 +157,32 @@ public class ConsoleCommandsHandler
await ServerCom.DownloadFileAsync(split[0], "./" + split[1]);
Console.WriteLine();
if (split[0].EndsWith(".zip"))
if (split[0].EndsWith(".zip") || split[0].EndsWith(".pak") || split[0].EndsWith(".pkg"))
{
Console.WriteLine($"Extracting {split[1]}");
var proc = 0d;
var proc = 0f;
var isExtracting = true;
var bar = new Console_Utilities.ProgressBar { Max = 100, Color = ConsoleColor.Green };
var bar = new Console_Utilities.ProgressBar { Max = 100f, Color = ConsoleColor.Green };
IProgress<float> extractProgress = new Progress<float>(value => { proc = value; });
IProgress<float> extractProgress = new Progress<float>(value =>
{
proc = value;
}
);
new Thread(new Task(() =>
{
while (isExtracting)
{
bar.Update((int)proc);
if (proc >= 99.9f) break;
bar.Update(proc);
if (proc >= 99.9f)
isExtracting = false;
Thread.Sleep(500);
}
}
).Start
).Start();
await Functions.ExtractArchive("./" + split[1], "./", extractProgress);
bar.Update(100);
await Functions.ExtractArchive("./" + split[1], "./", extractProgress, UnzipProgressType.PercentageFromTotalSize);
bar.Update(100f);
isExtracting = false;
await Task.Delay(1000);
bar.Update(100);

View File

@@ -10,12 +10,12 @@ namespace PluginManager.Others
/// </summary>
public class ProgressBar
{
public int Max { get; init; }
public float Max { get; init; }
public ConsoleColor Color { get; init; }
public bool NoColor { get; init; }
public void Update(int progress, double speed = -1, string? unit = null)
public void Update(float progress, double speed = -1, string? unit = null)
{
Console.CursorLeft = 0;
Console.Write("[");
@@ -146,6 +146,9 @@ namespace PluginManager.Others
Console.Write(m + " ");
}
Console.CursorLeft--;
if (appendNewLine)
Console.Write('\n');

View File

@@ -27,3 +27,5 @@ public enum OutputLogLevel { NONE, INFO, WARNING, ERROR, CRITICAL }
/// Plugin Type
/// </summary>
public enum PluginType { Command, Event, Unknown }
public enum UnzipProgressType { PercentageFromNumberOfFiles, PercentageFromTotalSize }

View File

@@ -4,6 +4,7 @@ using System;
using System.Threading.Tasks;
using System.Linq;
using System.Collections.Generic;
using System.Security.Cryptography;
using Discord.WebSocket;
using PluginManager.Items;
using System.Threading;
@@ -169,13 +170,17 @@ namespace PluginManager.Others
/// </summary>
/// <param name="zip">The zip location</param>
/// <param name="folder">The target location</param>
/// <param name="progress">The progress that is updated as a file is processed</param>
/// <param name="type">The type of progress</param>
/// <returns></returns>
public static async Task ExtractArchive(string zip, string folder, IProgress<float> progress)
public static async Task ExtractArchive(string zip, string folder, IProgress<float> progress, UnzipProgressType type)
{
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
using (ZipArchive archive = ZipFile.OpenRead(zip))
{
if (type == UnzipProgressType.PercentageFromNumberOfFiles)
{
int totalZIPFiles = archive.Entries.Count();
int currentZIPFile = 0;
@@ -189,8 +194,9 @@ namespace PluginManager.Others
{
entry.ExtractToFile(Path.Combine(folder, entry.FullName), true);
}
catch
catch (Exception ex)
{
Console.WriteLine($"Failed to extract {entry.Name}. Exception: {ex.Message}");
}
currentZIPFile++;
@@ -198,6 +204,37 @@ namespace PluginManager.Others
progress.Report((float)currentZIPFile / totalZIPFiles * 100);
}
}
else if (type == UnzipProgressType.PercentageFromTotalSize)
{
ulong zipSize = 0;
foreach (ZipArchiveEntry entry in archive.Entries)
zipSize += (ulong)entry.CompressedLength;
ulong currentSize = 0;
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.FullName.EndsWith("/"))
{
Directory.CreateDirectory(Path.Combine(folder, entry.FullName));
continue;
}
try
{
entry.ExtractToFile(Path.Combine(folder, entry.FullName), true);
currentSize += (ulong)entry.CompressedLength;
}
catch (Exception ex)
{
Console.WriteLine($"Failed to extract {entry.Name}. Exception: {ex.Message}");
}
await Task.Delay(10);
progress.Report((float)currentSize / zipSize * 100);
}
}
}
}
@@ -303,5 +340,15 @@ namespace PluginManager.Others
var data = jsonObject.RootElement.TryGetProperty(codeName, out element);
return data;
}
public static string CreateMD5(string input)
{
using (MD5 md5 = MD5.Create())
{
byte[] inputBytes = Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
return Convert.ToHexString(hashBytes);
}
}
}
}

View File

@@ -1,12 +0,0 @@
using Discord;
using Discord.Audio;
namespace YoutubeExtension.Downloader;
internal static class Data
{
internal static IAudioClient audioClient = null;
internal static IVoiceChannel voiceChannel = null;
internal static MusicPlayer CurrentlyRunning = null;
}

View File

@@ -1,50 +0,0 @@
namespace YoutubeExtension.Downloader;
internal class MusicPlayer
{
public MusicPlayer(Stream input, Stream output)
{
inputStream = input;
outputStream = output;
}
public Stream inputStream { get; } // from outside
public Stream outputStream { get; } // to Voice Channel
public bool Paused { get; set; }
private bool _stop { get; set; }
public void Stop()
{
_stop = true;
}
public async Task StartSendAudio()
{
Paused = false;
_stop = false;
while (!_stop)
{
if (Paused) continue;
var bsize = 512;
var buffer = new byte[bsize];
var bcount = await inputStream.ReadAsync(buffer, 0, bsize);
if (bcount <= 0)
{
Stop();
Data.CurrentlyRunning = null;
break;
}
try
{
await outputStream.WriteAsync(buffer, 0, bcount);
}
catch (Exception ex)
{
await outputStream.FlushAsync();
PluginManager.Others.Functions.WriteLogFile(ex.ToString());
}
}
}
}

View File

@@ -1,18 +0,0 @@
using MediaToolkit;
using MediaToolkit.Model;
using VideoLibrary;
namespace YoutubeExtension.Downloader;
public class YoutubeHandler
{
public static async Task<Stream> GetVideoStream(string videoURL)
{
var youtube = YouTube.Default;
var video = await youtube.GetVideoAsync(videoURL);
return await video.StreamAsync();
}
}

View File

@@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -1,6 +0,0 @@
namespace YoutubeExtension;
public class ytPlay
{
}