diff --git a/Discord/DiscordWebHook.cs b/Discord/DiscordWebHook.cs
new file mode 100644
index 0000000..25c8640
--- /dev/null
+++ b/Discord/DiscordWebHook.cs
@@ -0,0 +1,103 @@
+using System;
+using System.IO;
+using System.Net;
+using System.Text;
+
+namespace Discord.Webhook
+{
+ public class DiscordWebhook
+ {
+ ///
+ /// Webhook url
+ ///
+ public string Url { get; set; }
+
+ private void AddField(MemoryStream stream, string bound, string cDisposition, string cType, byte[] data)
+ {
+ string prefix = stream.Length > 0 ? "\r\n--" : "--";
+ string fBegin = $"{prefix}{bound}\r\n";
+
+ byte[] fBeginBuffer = Utils.Encode(fBegin);
+ byte[] cDispositionBuffer = Utils.Encode(cDisposition);
+ byte[] cTypeBuffer = Utils.Encode(cType);
+
+ stream.Write(fBeginBuffer, 0, fBeginBuffer.Length);
+ stream.Write(cDispositionBuffer, 0, cDispositionBuffer.Length);
+ stream.Write(cTypeBuffer, 0, cTypeBuffer.Length);
+ stream.Write(data, 0, data.Length);
+ }
+
+ private void SetJsonPayload(MemoryStream stream, string bound, string json)
+ {
+ string cDisposition = "Content-Disposition: form-data; name=\"payload_json\"\r\n";
+ string cType = "Content-Type: application/octet-stream\r\n\r\n";
+ AddField(stream, bound, cDisposition, cType, Utils.Encode(json));
+ }
+
+ private void SetFile(MemoryStream stream, string bound, int index, FileInfo file)
+ {
+ string cDisposition = $"Content-Disposition: form-data; name=\"file_{index}\"; filename=\"{file.Name}\"\r\n";
+ string cType = "Content-Type: application/octet-stream\r\n\r\n";
+ AddField(stream, bound, cDisposition, cType, File.ReadAllBytes(file.FullName));
+ }
+
+ ///
+ /// Send webhook message
+ ///
+ public void Send(DiscordMessage message, params FileInfo[] files)
+ {
+ if (string.IsNullOrEmpty(Url))
+ throw new ArgumentNullException("Invalid Webhook URL.");
+
+ string bound = "------------------------" + DateTime.Now.Ticks.ToString("x");
+ WebClient webhookRequest = new WebClient();
+ webhookRequest.Headers.Add("Content-Type", "multipart/form-data; boundary=" + bound);
+
+ MemoryStream stream = new MemoryStream();
+ for (int i = 0; i < files.Length; i++)
+ SetFile(stream, bound, i, files[i]);
+
+ string json = message.ToString();
+ SetJsonPayload(stream, bound, json);
+
+ byte[] bodyEnd = Utils.Encode($"\r\n--{bound}--");
+ stream.Write(bodyEnd, 0, bodyEnd.Length);
+
+ //byte[] beginBodyBuffer = Encoding.UTF8.GetBytes("--" + bound + "\r\n");
+ //stream.Write(beginBodyBuffer, 0, beginBodyBuffer.Length);
+ //bool flag = file != null && file.Exists;
+ //if (flag)
+ //{
+ // string fileBody = "Content-Disposition: form-data; name=\"file\"; filename=\"" + file.Name + "\"\r\nContent-Type: application/octet-stream\r\n\r\n";
+ // byte[] fileBodyBuffer = Encoding.UTF8.GetBytes(fileBody);
+ // stream.Write(fileBodyBuffer, 0, fileBodyBuffer.Length);
+ // byte[] fileBuffer = File.ReadAllBytes(file.FullName);
+ // stream.Write(fileBuffer, 0, fileBuffer.Length);
+ // string fileBodyEnd = "\r\n--" + bound + "\r\n";
+ // byte[] fileBodyEndBuffer = Encoding.UTF8.GetBytes(fileBodyEnd);
+ // stream.Write(fileBodyEndBuffer, 0, fileBodyEndBuffer.Length);
+ //}
+ //string jsonBody = string.Concat(new string[]
+ //{
+ // "Content-Disposition: form-data; name=\"payload_json\"\r\nContent-Type: application/json\r\n\r\n",
+ // string.Format("{0}\r\n", message),
+ // "--",
+ // bound,
+ // "--"
+ //});
+ //byte[] jsonBodyBuffer = Encoding.UTF8.GetBytes(jsonBody);
+ //stream.Write(jsonBodyBuffer, 0, jsonBodyBuffer.Length);
+
+ try
+ {
+ webhookRequest.UploadData(this.Url, stream.ToArray());
+ }
+ catch (WebException ex)
+ {
+ throw new WebException(Utils.Decode(ex.Response.GetResponseStream()));
+ }
+
+ stream.Dispose();
+ }
+ }
+}
diff --git a/Discord/Structs.cs b/Discord/Structs.cs
new file mode 100644
index 0000000..a528c88
--- /dev/null
+++ b/Discord/Structs.cs
@@ -0,0 +1,229 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+
+namespace Discord
+{
+
+ ///
+ /// Discord message data object
+ ///
+ public struct DiscordMessage
+ {
+ ///
+ /// Message content
+ ///
+ public string Content;
+
+ ///
+ /// Read message to everyone on the channel
+ ///
+ public bool TTS;
+
+ ///
+ /// Webhook profile username to be shown
+ ///
+ public string Username;
+
+ ///
+ /// Webhook profile avater to be shown
+ ///
+ public string AvatarUrl;
+
+ ///
+ /// List of embeds
+ ///
+ public List Embeds;
+
+ public override string ToString() => Utils.StructToJson(this).ToString(Formatting.None);
+ }
+
+ ///
+ /// Discord embed data object
+ ///
+ public struct DiscordEmbed
+ {
+ ///
+ /// Embed title
+ ///
+ public string Title;
+
+ ///
+ /// Embed description
+ ///
+ public string Description;
+
+ ///
+ /// Embed url
+ ///
+ public string Url;
+
+ ///
+ /// Embed timestamp
+ ///
+ public DateTime? Timestamp;
+
+ ///
+ /// Embed color
+ ///
+ public Color? Color;
+
+ ///
+ /// Embed footer
+ ///
+ public EmbedFooter? Footer;
+
+ ///
+ /// Embed image
+ ///
+ public EmbedMedia? Image;
+
+ ///
+ /// Embed thumbnail
+ ///
+ public EmbedMedia? Thumbnail;
+
+ ///
+ /// Embed video
+ ///
+ public EmbedMedia? Video;
+
+ ///
+ /// Embed provider
+ ///
+ public EmbedProvider? Provider;
+
+ ///
+ /// Embed author
+ ///
+ public EmbedAuthor? Author;
+
+ ///
+ /// Embed fields list
+ ///
+ public List Fields;
+
+ public override string ToString() => Utils.StructToJson(this).ToString(Formatting.None);
+ }
+
+ ///
+ /// Discord embed footer data object
+ ///
+ public struct EmbedFooter
+ {
+ ///
+ /// Footer text
+ ///
+ public string Text;
+
+ ///
+ /// Footer icon
+ ///
+ public string IconUrl;
+
+ ///
+ /// Footer icon proxy
+ ///
+ public string ProxyIconUrl;
+
+ public override string ToString() => Utils.StructToJson(this).ToString(Formatting.None);
+ }
+
+ ///
+ /// Discord embed media data object (images/thumbs/videos)
+ ///
+ public struct EmbedMedia
+ {
+ ///
+ /// Media url
+ ///
+ public string Url;
+
+ ///
+ /// Media proxy url
+ ///
+ public string ProxyUrl;
+
+ ///
+ /// Media height
+ ///
+ public int? Height;
+
+ ///
+ /// Media width
+ ///
+ public int? Width;
+
+ public override string ToString() => Utils.StructToJson(this).ToString(Formatting.None);
+ }
+
+ ///
+ /// Discord embed provider data object
+ ///
+ public struct EmbedProvider
+ {
+ ///
+ /// Provider name
+ ///
+ public string Name;
+
+ ///
+ /// Provider url
+ ///
+ public string Url;
+
+ public override string ToString() => Utils.StructToJson(this).ToString(Formatting.None);
+ }
+
+ ///
+ /// Discord embed author data object
+ ///
+ public struct EmbedAuthor
+ {
+ ///
+ /// Author name
+ ///
+ public string Name;
+
+ ///
+ /// Author url
+ ///
+ public string Url;
+
+ ///
+ /// Author icon
+ ///
+ public string IconUrl;
+
+ ///
+ /// Author icon proxy
+ ///
+ public string ProxyIconUrl;
+
+ public override string ToString() => Utils.StructToJson(this).ToString(Formatting.None);
+ }
+
+ ///
+ /// Discord embed field data object
+ ///
+ public struct EmbedField
+ {
+ ///
+ /// Field name
+ ///
+ public string Name;
+
+ ///
+ /// Field value
+ ///
+ public string Value;
+
+ ///
+ /// Field align
+ ///
+ public bool InLine;
+
+ public override string ToString() => Utils.StructToJson(this).ToString(Formatting.None);
+ }
+}
diff --git a/Discord/Utils.cs b/Discord/Utils.cs
new file mode 100644
index 0000000..ce9476e
--- /dev/null
+++ b/Discord/Utils.cs
@@ -0,0 +1,108 @@
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+namespace Discord
+{
+ public static class Utils
+ {
+ ///
+ /// Convert Color object into hex integer
+ ///
+ /// Color to be converted
+ /// Converted hex integer
+ public static int ColorToHex(Color color)
+ {
+ string HS =
+ color.R.ToString("X2") +
+ color.G.ToString("X2") +
+ color.B.ToString("X2");
+
+ return int.Parse(HS, System.Globalization.NumberStyles.HexNumber);
+ }
+
+ internal static JObject StructToJson(object @struct)
+ {
+ Type type = @struct.GetType();
+ JObject json = new JObject();
+
+ FieldInfo[] fields = type.GetFields();
+ foreach (FieldInfo field in fields)
+ {
+ string name = FieldNameToJsonName(field.Name);
+ object value = field.GetValue(@struct);
+ if (value == null)
+ continue;
+
+ if (value is bool)
+ json.Add(name, (bool)value);
+ else if (value is int)
+ json.Add(name, (int)value);
+ else if (value is Color)
+ json.Add(name, ColorToHex((Color)value));
+ else if (value is string)
+ json.Add(name, value as string);
+ else if (value is DateTime)
+ json.Add(name, ((DateTime)value).ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz"));
+ else if (value is IList && value.GetType().IsGenericType)
+ {
+ JArray array = new JArray();
+ foreach (object obj in value as IList)
+ array.Add(StructToJson(obj));
+ json.Add(name, array);
+ }
+ else json.Add(name, StructToJson(value));
+ }
+ return json;
+ }
+
+ static string[] ignore = { "InLine" };
+ internal static string FieldNameToJsonName(string name)
+ {
+ if (ignore.ToList().Contains(name))
+ return name.ToLower();
+
+ List result = new List();
+
+ if (IsFullUpper(name))
+ result.AddRange(name.ToLower().ToCharArray());
+ else
+ for (int i = 0; i < name.Length; i++)
+ {
+ if (i > 0 && char.IsUpper(name[i]))
+ result.AddRange(new[] { '_', char.ToLower(name[i]) });
+ else result.Add(char.ToLower(name[i]));
+ }
+ return string.Join("", result);
+ }
+
+ internal static bool IsFullUpper(string str)
+ {
+ bool upper = true;
+ for (int i = 0; i < str.Length; i++)
+ {
+ if (!char.IsUpper(str[i]))
+ {
+ upper = false;
+ break;
+ }
+ }
+ return upper;
+ }
+
+ public static string Decode(Stream source)
+ {
+ using (StreamReader reader = new StreamReader(source))
+ return reader.ReadToEnd();
+ }
+
+ public static byte[] Encode(string source, string encoding = "utf-8")
+ => Encoding.GetEncoding(encoding).GetBytes(source);
+ }
+}
diff --git a/Process Auto Relaunch.csproj b/Process Auto Relaunch.csproj
index e265fbb..3a337ee 100644
--- a/Process Auto Relaunch.csproj
+++ b/Process Auto Relaunch.csproj
@@ -67,6 +67,9 @@
False
.\CSharpDiscordWebhook.dll
+
+ packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll
+
@@ -80,6 +83,9 @@
+
+
+
Form
@@ -112,6 +118,7 @@
Resources.resx
True
+
SettingsSingleFileGenerator
Settings.Designer.cs
@@ -142,7 +149,7 @@
- copy $(ProjectDir)\CSharpDiscordWebhook\CSharpDiscordWebhook\$(OutDir)\* $(TargetDir)
-copy $(ProjectDir)\CSharpDiscordWebhook\CSharpDiscordWebhook\$(OutDir)\* $(ProjectDir)
+ rem copy $(ProjectDir)\CSharpDiscordWebhook\CSharpDiscordWebhook\$(OutDir)\* $(TargetDir)
+rem copy $(ProjectDir)\CSharpDiscordWebhook\CSharpDiscordWebhook\$(OutDir)\* $(ProjectDir)
\ No newline at end of file
diff --git a/Process Auto Relaunch.sln b/Process Auto Relaunch.sln
index 7188f0d..14cd0e9 100644
--- a/Process Auto Relaunch.sln
+++ b/Process Auto Relaunch.sln
@@ -4,11 +4,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 17.9.34622.214
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Process Auto Relaunch", "Process Auto Relaunch.csproj", "{B48F106C-F4E2-4BFB-9BAA-42FC13C03FDD}"
- ProjectSection(ProjectDependencies) = postProject
- {11C71B78-004A-471F-B29D-C2CBE4673579} = {11C71B78-004A-471F-B29D-C2CBE4673579}
- EndProjectSection
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpDiscordWebhook", "CSharpDiscordWebhook\CSharpDiscordWebhook\CSharpDiscordWebhook.csproj", "{11C71B78-004A-471F-B29D-C2CBE4673579}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -32,18 +27,6 @@ Global
{B48F106C-F4E2-4BFB-9BAA-42FC13C03FDD}.Release|Any CPU.Build.0 = Release|Any CPU
{B48F106C-F4E2-4BFB-9BAA-42FC13C03FDD}.Release|x64.ActiveCfg = Release|x64
{B48F106C-F4E2-4BFB-9BAA-42FC13C03FDD}.Release|x64.Build.0 = Release|x64
- {11C71B78-004A-471F-B29D-C2CBE4673579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.Debug|x64.ActiveCfg = Debug|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.Debug|x64.Build.0 = Debug|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.DebugFULL|Any CPU.ActiveCfg = Debug|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.DebugFULL|Any CPU.Build.0 = Debug|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.DebugFULL|x64.ActiveCfg = DebugFULL|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.DebugFULL|x64.Build.0 = DebugFULL|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.Release|Any CPU.Build.0 = Release|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.Release|x64.ActiveCfg = Release|Any CPU
- {11C71B78-004A-471F-B29D-C2CBE4673579}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/packages.config b/packages.config
new file mode 100644
index 0000000..0b14af3
--- /dev/null
+++ b/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file