add project

This commit is contained in:
schedpas
2022-02-09 14:28:56 +01:00
parent c135bfd114
commit 7015072aae
257 changed files with 180435 additions and 92 deletions

View File

@@ -0,0 +1,231 @@
using Discord;
using Discord.Net.Rest;
using Discord.Net.WebSockets;
using Discord.WebSocket;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SM64_ROM_Manager.Updating.Administration.Discord
{
public class DiscordBot
{
public delegate void LoggedMsgEventHandler(object sender, string logmsg, bool isError);
public event EventHandler GotReady;
public event EventHandler HasDisconnected;
public event LoggedMsgEventHandler LoggedMsg;
public DiscordBotConfig Config { get; private set; }
public DiscordSocketClient Client { get; private set; }
public bool IsReady { get; private set; } = false;
// C o n s t r u c t o r
public DiscordBot(DiscordBotConfig config)
{
Config = config;
}
// M a i n
public async void Start()
{
if (!string.IsNullOrEmpty(Config.DiscordBotToken))
{
var socketConfig = new DiscordSocketConfig();
socketConfig.RestClientProvider = DefaultRestClientProvider.Create(useProxy: true);
socketConfig.WebSocketProvider = DefaultWebSocketProvider.Create(System.Net.WebRequest.DefaultWebProxy);
Client = new DiscordSocketClient(socketConfig);
Client.Log += Client_Log;
Client.Ready += Client_Ready;
Client.Disconnected += Client_Disconnected;
await Client.LoginAsync(TokenType.Bot, Config.DiscordBotToken);
await Client.StartAsync();
}
else
LoggedMsg?.Invoke(this, "Disabled or Token invalid", true);
}
public async void Stop()
{
await Client.StopAsync();
await Client.LogoutAsync();
}
// C l i e n t - E v e n t s
private Task Client_Disconnected(Exception exception)
{
Task.Run(() => HasDisconnected?.Invoke(this, new EventArgs()));
return Task.CompletedTask;
}
private Task Client_Ready()
{
Task.Run(() =>
{
Task.Delay(10);
IsReady = true;
GotReady?.Invoke(this, new EventArgs());
});
return Task.CompletedTask;
}
private Task Client_Log(LogMessage msg)
{
Task.Run(() => LoggedMsg?.Invoke(this, msg.Message, msg.Exception is object));
return Task.CompletedTask;
}
// F e a t u r e s
public IReadOnlyDictionary<ulong, string> GetGuilds()
{
var dic = new Dictionary<ulong, string>();
foreach (var guild in Client.Guilds)
dic.Add(guild.Id, guild.Name);
return dic;
}
public IReadOnlyDictionary<ulong, string> GetTextChannels(ulong guildID)
{
var dic = new Dictionary<ulong, string>();
var guild = Client.GetGuild(guildID);
if (guild is object)
{
foreach (var channel in guild.TextChannels)
dic.Add(channel.Id, channel.Name);
}
return dic;
}
public IReadOnlyDictionary<ulong, string> GetRoles(ulong guildID)
{
var dic = new Dictionary<ulong, string>();
foreach (var role in Client.GetGuild(guildID).Roles)
dic.Add(role.Id, role.Name);
return dic;
}
private string GetPingMessage(ulong? pingRole)
{
return pingRole != null ? $"<@&{pingRole ?? default}>" : string.Empty;
}
//private async Task<string> BuildUpdateMsg(string versionName, ApplicationVersion version, string changelog, ulong guildID, ulong channelID, string appName, string message, bool addChangelog, ulong? pingRole)
//{
// string msg = string.Empty;
// // Add ping
// if (pingRole != null)
// msg += $"<{GetPingMessage(pingRole)}\n\n";
// // Add version as titel
// var versionString = version.ToString();
// if (version.Channel == Channels.Stable && version.Build == 1)
// versionString = versionString.Remove(versionString.IndexOf(" "));
// msg += $"**Update:** {appName} **Version __{versionString}__**";
// // Add titel
// if (!string.IsNullOrEmpty(versionName))
// msg += $"\n> {versionName}";
// // Add message
// if (!string.IsNullOrEmpty(message))
// msg += "\n\n" + message;
// // Add changelog
// if (addChangelog && !string.IsNullOrEmpty(changelog))
// {
// var sr = new StringReader(changelog);
// var sw = new StringWriter();
// while (sr.Peek() != -1)
// {
// var line = await sr.ReadLineAsync();
// await sw.WriteLineAsync($"> {line}");
// }
// msg += "\n\nChangelog:\n" + sw.ToString();
// sr.Close();
// sw.Close();
// }
// return msg;
//}
public async Task SendUpdateNotification(UpdatePackageInfo package, ulong guildID, ulong channelID, string appName, string message, bool addChangelog, bool pingEveryone)
{
ulong? pingRole;
var updateNotifyRoleLower = Config.UpdateNotificationRoll.ToLower();
if (pingEveryone)
pingRole = GetRoles(guildID).FirstOrDefault(n => n.Value.ToLower() == updateNotifyRoleLower).Key;
else
pingRole = null;
string msg = GetPingMessage(pingRole); //await BuildUpdateMsg(versionName, version, changelog, guildID, channelID, appName, message, addChangelog, pingRole);
var embed = BuildEmbed(package, appName, message, addChangelog);
var channel = Client.GetGuild(guildID)?.GetTextChannel(channelID);
if (string.IsNullOrEmpty(msg))
msg = null;
if (channel != null)
await channel.SendMessageAsync(text:msg, embed:embed);
}
private Embed BuildEmbed(UpdatePackageInfo package, string appName, string message, bool addChangelog)
{
var embed = new EmbedBuilder();
// Add titel
var versionString = package.Version.ToString();
if (package.Version.Channel == Channels.Stable && package.Version.Build == 1)
versionString = versionString.Remove(versionString.IndexOf(" "));
var strTitle = $"**Update:** {appName} **Version __{versionString}__**";
if (!string.IsNullOrEmpty(package.Name))
strTitle += $"\n{package.Name}";
embed.Title = strTitle;
// Add Description
if (!string.IsNullOrEmpty(message))
embed.Description += message;
// Add changelog
if (addChangelog && !string.IsNullOrEmpty(package.Notes.Content) && package.Notes.ContentType != UpdateNotesContentType.HTML)
{
switch (true)
{
case object _ when package.Notes.ContentType == UpdateNotesContentType.PlainText && package.Notes.Content.Length <= 2048:
embed.AddField("Changelog:", package.Notes.Content);
break;
case object _ when package.Notes.ContentType == UpdateNotesContentType.PlainText:
case object _ when package.Notes.ContentType == UpdateNotesContentType.Markdown:
embed.AddField("Changelog:", Markdig.Markdown.ToPlainText(package.Notes.Content));
break;
}
}
// Author
// ...
return embed.Build();
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SM64_ROM_Manager.Updating.Administration.Discord
{
public class DiscordBotConfig
{
public string DiscordBotToken { get; set; } = string.Empty;
public string DefaultUpdateMessage { get; set; } = string.Empty;
public string DefaultAppName { get; set; } = string.Empty;
public string UpdateNotificationRoll { get; set; } = string.Empty;
public bool UseProxy { get; set; } = true;
}
}

View File

@@ -0,0 +1,11 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
// ------------------------------------------------------------------------------

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>false</MySubMain>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<ApplicationType>1</ApplicationType>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -0,0 +1,192 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using Microsoft.VisualBasic;
/* TODO ERROR: Skipped IfDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
/* TODO ERROR: Skipped IfDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia */
/* TODO ERROR: Skipped DefineDirectiveTrivia *//* TODO ERROR: Skipped DefineDirectiveTrivia *//* TODO ERROR: Skipped DefineDirectiveTrivia *//* TODO ERROR: Skipped DefineDirectiveTrivia */
/* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
/* TODO ERROR: Skipped IfDirectiveTrivia */
namespace SM64_ROM_Manager.Updating.My
{
/* TODO ERROR: Skipped IfDirectiveTrivia */
[System.CodeDom.Compiler.GeneratedCode("MyTemplate", "11.0.0.0")]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
/* TODO ERROR: Skipped IfDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia */
internal partial class MyApplication : Microsoft.VisualBasic.ApplicationServices.ApplicationBase
{
/* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
}
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
/* TODO ERROR: Skipped IfDirectiveTrivia */
[System.CodeDom.Compiler.GeneratedCode("MyTemplate", "11.0.0.0")]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
/* TODO ERROR: Skipped IfDirectiveTrivia */
internal partial class MyComputer : Microsoft.VisualBasic.Devices.Computer
{
/* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
[DebuggerHidden()]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public MyComputer() : base()
{
}
}
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
[HideModuleName()]
[System.CodeDom.Compiler.GeneratedCode("MyTemplate", "11.0.0.0")]
internal static class MyProject
{
/* TODO ERROR: Skipped IfDirectiveTrivia */
[System.ComponentModel.Design.HelpKeyword("My.Computer")]
internal static MyComputer Computer
{
[DebuggerHidden()]
get
{
return m_ComputerObjectProvider.GetInstance;
}
}
private readonly static ThreadSafeObjectProvider<MyComputer> m_ComputerObjectProvider = new ThreadSafeObjectProvider<MyComputer>();
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
/* TODO ERROR: Skipped IfDirectiveTrivia */
[System.ComponentModel.Design.HelpKeyword("My.Application")]
internal static MyApplication Application
{
[DebuggerHidden()]
get
{
return m_AppObjectProvider.GetInstance;
}
}
private readonly static ThreadSafeObjectProvider<MyApplication> m_AppObjectProvider = new ThreadSafeObjectProvider<MyApplication>();
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
/* TODO ERROR: Skipped IfDirectiveTrivia */
[System.ComponentModel.Design.HelpKeyword("My.User")]
internal static Microsoft.VisualBasic.ApplicationServices.User User
{
[DebuggerHidden()]
get
{
return m_UserObjectProvider.GetInstance;
}
}
private readonly static ThreadSafeObjectProvider<Microsoft.VisualBasic.ApplicationServices.User> m_UserObjectProvider = new ThreadSafeObjectProvider<Microsoft.VisualBasic.ApplicationServices.User>();
/* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
/* TODO ERROR: Skipped IfDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
/* TODO ERROR: Skipped IfDirectiveTrivia */
[System.ComponentModel.Design.HelpKeyword("My.WebServices")]
internal static MyWebServices WebServices
{
[DebuggerHidden()]
get
{
return m_MyWebServicesObjectProvider.GetInstance;
}
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
[MyGroupCollection("System.Web.Services.Protocols.SoapHttpClientProtocol", "Create__Instance__", "Dispose__Instance__", "")]
internal sealed class MyWebServices
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
[DebuggerHidden()]
public override bool Equals(object o)
{
return base.Equals(o);
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
[DebuggerHidden()]
public override int GetHashCode()
{
return base.GetHashCode();
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
[DebuggerHidden()]
internal new Type GetType()
{
return typeof(MyWebServices);
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
[DebuggerHidden()]
public override string ToString()
{
return base.ToString();
}
[DebuggerHidden()]
private static T Create__Instance__<T>(T instance) where T : new()
{
if (instance == null)
{
return new T();
}
else
{
return instance;
}
}
[DebuggerHidden()]
private void Dispose__Instance__<T>(ref T instance)
{
instance = default;
}
[DebuggerHidden()]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public MyWebServices() : base()
{
}
}
private readonly static ThreadSafeObjectProvider<MyWebServices> m_MyWebServicesObjectProvider = new ThreadSafeObjectProvider<MyWebServices>();
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
/* TODO ERROR: Skipped IfDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
[System.Runtime.InteropServices.ComVisible(false)]
internal sealed class ThreadSafeObjectProvider<T> where T : new()
{
internal T GetInstance
{
/* TODO ERROR: Skipped IfDirectiveTrivia */
[DebuggerHidden()]
get
{
var Value = m_Context.Value;
if (Value == null)
{
Value = new T();
m_Context.Value = Value;
}
return Value;
}
/* TODO ERROR: Skipped ElseDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
}
[DebuggerHidden()]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public ThreadSafeObjectProvider() : base()
{
}
/* TODO ERROR: Skipped IfDirectiveTrivia */
private readonly Microsoft.VisualBasic.MyServices.Internal.ContextValue<T> m_Context = new Microsoft.VisualBasic.MyServices.Internal.ContextValue<T>();
/* TODO ERROR: Skipped ElseDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
}
}
}
/* TODO ERROR: Skipped EndIfDirectiveTrivia */

View File

@@ -0,0 +1,253 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// See Compiler::LoadXmlSolutionExtension
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Xml.Linq;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;
namespace SM64_ROM_Manager.Updating.My
{
[Embedded()]
[DebuggerNonUserCode()]
[System.Runtime.CompilerServices.CompilerGenerated()]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
internal sealed class InternalXmlHelper
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
private InternalXmlHelper()
{
}
public static string get_Value(IEnumerable<XElement> source)
{
foreach (XElement item in source)
return item.Value;
return null;
}
public static void set_Value(IEnumerable<XElement> source, string value)
{
foreach (XElement item in source)
{
item.Value = value;
break;
}
}
public static string get_AttributeValue(IEnumerable<XElement> source, XName name)
{
foreach (XElement item in source)
return Conversions.ToString(item.Attribute(name));
return null;
}
public static void set_AttributeValue(IEnumerable<XElement> source, XName name, string value)
{
foreach (XElement item in source)
{
item.SetAttributeValue(name, value);
break;
}
}
public static string get_AttributeValue(XElement source, XName name)
{
return Conversions.ToString(source.Attribute(name));
}
public static void set_AttributeValue(XElement source, XName name, string value)
{
source.SetAttributeValue(name, value);
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public static XAttribute CreateAttribute(XName name, object value)
{
if (value is null)
{
return null;
}
return new XAttribute(name, value);
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public static XAttribute CreateNamespaceAttribute(XName name, XNamespace ns)
{
var a = new XAttribute(name, ns.NamespaceName);
a.AddAnnotation(ns);
return a;
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public static object RemoveNamespaceAttributes(string[] inScopePrefixes, XNamespace[] inScopeNs, List<XAttribute> attributes, object obj)
{
if (obj is object)
{
XElement elem = obj as XElement;
if (elem is object)
{
return RemoveNamespaceAttributes(inScopePrefixes, inScopeNs, attributes, elem);
}
else
{
IEnumerable elems = obj as IEnumerable;
if (elems is object)
{
return RemoveNamespaceAttributes(inScopePrefixes, inScopeNs, attributes, elems);
}
}
}
return obj;
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public static IEnumerable RemoveNamespaceAttributes(string[] inScopePrefixes, XNamespace[] inScopeNs, List<XAttribute> attributes, IEnumerable obj)
{
if (obj is object)
{
IEnumerable<XElement> elems = obj as IEnumerable<XElement>;
if (elems is object)
{
return elems.Select(new RemoveNamespaceAttributesClosure(inScopePrefixes, inScopeNs, attributes).ProcessXElement);
}
else
{
return obj.Cast<object>().Select(new RemoveNamespaceAttributesClosure(inScopePrefixes, inScopeNs, attributes).ProcessObject);
}
}
return obj;
}
[DebuggerNonUserCode()]
[System.Runtime.CompilerServices.CompilerGenerated()]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
private sealed class RemoveNamespaceAttributesClosure
{
private readonly string[] m_inScopePrefixes;
private readonly XNamespace[] m_inScopeNs;
private readonly List<XAttribute> m_attributes;
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
internal RemoveNamespaceAttributesClosure(string[] inScopePrefixes, XNamespace[] inScopeNs, List<XAttribute> attributes)
{
m_inScopePrefixes = inScopePrefixes;
m_inScopeNs = inScopeNs;
m_attributes = attributes;
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
internal XElement ProcessXElement(XElement elem)
{
return RemoveNamespaceAttributes(m_inScopePrefixes, m_inScopeNs, m_attributes, elem);
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
internal object ProcessObject(object obj)
{
XElement elem = obj as XElement;
if (elem is object)
{
return RemoveNamespaceAttributes(m_inScopePrefixes, m_inScopeNs, m_attributes, elem);
}
else
{
return obj;
}
}
}
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public static XElement RemoveNamespaceAttributes(string[] inScopePrefixes, XNamespace[] inScopeNs, List<XAttribute> attributes, XElement e)
{
if (e is object)
{
var a = e.FirstAttribute;
while (a is object)
{
var nextA = a.NextAttribute;
if (a.IsNamespaceDeclaration)
{
var ns = a.Annotation<XNamespace>();
string prefix = a.Name.LocalName;
if (ns is object)
{
if (inScopePrefixes is object && inScopeNs is object)
{
int lastIndex = inScopePrefixes.Length - 1;
for (int i = 0, loopTo = lastIndex; i <= loopTo; i++)
{
string currentInScopePrefix = inScopePrefixes[i];
var currentInScopeNs = inScopeNs[i];
if (prefix.Equals(currentInScopePrefix))
{
if (ns == currentInScopeNs)
{
// prefix and namespace match. Remove the unneeded ns attribute
a.Remove();
}
// prefix is in scope but refers to something else. Leave the ns attribute.
a = null;
break;
}
}
}
if (a is object)
{
// Prefix is not in scope
// Now check whether it's going to be in scope because it is in the attributes list
if (attributes is object)
{
int lastIndex = attributes.Count - 1;
for (int i = 0, loopTo1 = lastIndex; i <= loopTo1; i++)
{
var currentA = attributes[i];
string currentInScopePrefix = currentA.Name.LocalName;
var currentInScopeNs = currentA.Annotation<XNamespace>();
if (currentInScopeNs is object)
{
if (prefix.Equals(currentInScopePrefix))
{
if (ns == currentInScopeNs)
{
// prefix and namespace match. Remove the unneeded ns attribute
a.Remove();
}
// prefix is in scope but refers to something else. Leave the ns attribute.
a = null;
break;
}
}
}
}
if (a is object)
{
// Prefix is definitely not in scope
a.Remove();
// namespace is not defined either. Add this attributes list
attributes.Add(a);
}
}
}
}
a = nextA;
}
}
return e;
}
}
}

View File

@@ -0,0 +1,14 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.VisualBasic
{
[Embedded()]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Module | AttributeTargets.Assembly, Inherited = false)]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
[System.Runtime.CompilerServices.CompilerGenerated()]
internal sealed class Embedded : Attribute
{
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,107 @@
using System.Collections.Generic;
using global::System.IO;
using global::System.Reflection;
using Microsoft.VisualBasic.CompilerServices;
using global::Newtonsoft.Json.Linq;
using Z.Collections.Extensions;
using SM64_ROM_Manager.Updating.UpdateInstaller;
namespace SM64_ROM_Manager.Updating.Administration.Packaging
{
internal class UpdatePackageManager
{
// F i e l d s
private UpdatePackageTemplate template;
// P r o p e r t i e s
public string FilesToCopyPath
{
get
{
return template.FilesToCopyPath;
}
set
{
template.FilesToCopyPath = value;
}
}
// C o n s t r u c o t r s
public UpdatePackageManager()
{
NewTemplate();
}
// F e a t u r e s
public void LoadTemplate(string filePath)
{
template = JObject.Parse(File.ReadAllText(filePath)).ToObject<UpdatePackageTemplate>();
}
public void SaveTemplate(string filePath)
{
File.WriteAllText(filePath, JObject.FromObject(template).ToString());
}
public void NewTemplate()
{
template = new UpdatePackageTemplate();
}
public void ExportPackage(string path)
{
var exporter = new UpdatePackagePackager(template);
exporter.Export(path);
}
private bool CheckUpdateInstallerAddOn(string path)
{
var asm = Assembly.ReflectionOnlyLoadFrom(path);
var t = asm.GetType($"{UpdateInstallerAddOnNameDefinitions.UPDATE_INSTALLER_ADDON_NAMESPACE}.{UpdateInstallerAddOnNameDefinitions.UPDATE_INSTALLER_ADDON_TYPE}", false);
bool isSupported = false;
if (t is object)
{
var mi = t.GetMethod(UpdateInstallerAddOnNameDefinitions.UPDATE_INSTALLER_ADDON_METHOD, BindingFlags.Static | BindingFlags.Public);
if (mi is object)
{
var @params = mi.GetParameters();
if (@params.Length == 1 && @params.GetType() == typeof(Dictionary<string, object>))
{
isSupported = true;
}
}
}
return isSupported;
}
public bool AddUpdateInstallerAddOn(string path)
{
if (Conversions.ToBoolean(!template.UpdateInstallerAddOns.Contains(path) && CheckUpdateInstallerAddOn(path)))
{
template.UpdateInstallerAddOns.Add(path);
return true;
}
else
{
return false;
}
}
public IEnumerable<string> GetAllUpdateInstallerÁddOn()
{
return template.UpdateInstallerAddOns;
}
public void RemoveUpdateInstallerAddOn(string path)
{
template.UpdateInstallerAddOns.RemoveIfContains(path);
}
}
}

View File

@@ -0,0 +1,52 @@
using global::System.IO;
using global::System.IO.Compression;
using SM64_ROM_Manager.Updating.UpdateInstaller;
using Z.IO.Extensions;
namespace SM64_ROM_Manager.Updating.Administration.Packaging
{
public class UpdatePackagePackager
{
public UpdatePackageTemplate UpdatePackageTemplate { get; set; }
public UpdatePackagePackager(UpdatePackageTemplate updatePackageTemplate)
{
UpdatePackageTemplate = updatePackageTemplate;
}
public void Export(string exportPath)
{
string tempPath = MyPaths.GetMyAppDataPath();
var packageDir = new DirectoryInfo(Path.Combine(tempPath, "UpdatePackageCreation"));
// Ensure package directory exists and is empty
if (packageDir.Exists)
packageDir.Delete(true);
packageDir.Create();
// Copy local data to temp data directory
var dataDir = packageDir.CreateSubdirectory(PackageFileNameDefinations.ZIP_APP_DATA_FILES_DIRECTORY);
var localDataDir = new DirectoryInfo(UpdatePackageTemplate.FilesToCopyPath);
localDataDir.CopyTo(dataDir.FullName, SearchOption.AllDirectories);
// Copy all UpdateInstaller AddOns
var addOnsDir = packageDir.CreateSubdirectory(PackageFileNameDefinations.ZIP_UPDATE_INSTALLER_ADDONS_DIRECTORY);
uint curAddOnID = 0;
foreach (string fAddOn in UpdatePackageTemplate.UpdateInstallerAddOns)
{
File.Copy(fAddOn, Path.Combine(addOnsDir.FullName, $"installer_addon_{curAddOnID}.dll"));
curAddOnID += 1;
}
// Ensure destination file doesn't exist
if (File.Exists(exportPath))
File.Delete(exportPath);
// Export to ZIP
ZipFile.CreateFromDirectory(packageDir.FullName, exportPath);
// Delete temp directory
packageDir.Delete(true);
}
}
}

View File

@@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace SM64_ROM_Manager.Updating.Administration.Packaging
{
public class UpdatePackageTemplate
{
public string FilesToCopyPath { get; set; }
public List<string> UpdateInstallerAddOns { get; set; } = new List<string>();
}
}

View File

@@ -0,0 +1,122 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<RootNamespace>SM64_ROM_Manager.Updating.Administration</RootNamespace>
<MyType>Windows</MyType>
<TargetFramework>net48</TargetFramework>
<DefaultItemExcludes>$(DefaultItemExcludes);$(ProjectDir)**\*.vb</DefaultItemExcludes>
<LangVersion>latest</LangVersion>
<AssemblyTitle>Pilz.Updating.Server</AssemblyTitle>
<Company>Pilzinsel64</Company>
<Product>Pilz.Updating.Server</Product>
<Copyright>Copyright © Pilzinsel64 2019 - 2020</Copyright>
<DocumentationFile>Pilz.Updating.Administration.xml</DocumentationFile>
<DefineTrace>true</DefineTrace>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,CS1591,CS0660,CS0661,CS0436</NoWarn>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DefineDebug>true</DefineDebug>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DefineDebug>false</DefineDebug>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'RelMono|AnyCPU'">
<Optimize>true</Optimize>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<DefineConstants>TRACE;RelMono</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup>
<Reference Include="drsPwEnc">
<HintPath>..\Shared Libs\drsPwEnc.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="Pilz.Cryptography">
<HintPath>..\Shared Libs\Pilz.Cryptography.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
<Import Include="Z.Collections.Extensions" />
<Import Include="Z.Compression.Extensions" />
<Import Include="Z.IO.Extensions" />
</ItemGroup>
<ItemGroup>
<Compile Update="My Project\Application.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Update="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<CustomToolNamespace>SM64_ROM_Manager.Updating.My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.cs</LastGenOutput>
</None>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>SM64_ROM_Manager.Updating.My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pilz.Updating\Pilz.Updating.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Discord.Net" Version="2.4.0" />
<PackageReference Include="Markdig" Version="0.25.0" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.Collections.Immutable" Version="5.0.0" />
<PackageReference Include="System.Interactive.Async" Version="5.0.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" />
<PackageReference Include="WebDav.Client" Version="2.7.0" />
<PackageReference Include="Z.ExtensionMethods.WithNamespace" Version="2.1.1" />
</ItemGroup>
<ItemGroup>
<Compile Remove="obj\RelMono\TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs" />
<Compile Remove="obj\RelMono\TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs" />
<Compile Remove="obj\RelMono\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
using global::System;
using global::System.Reflection;
using global::System.Runtime.CompilerServices;
using global::System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird.
[assembly: Guid("3c112a6a-bafa-4a84-be28-e9b69ca8f6e0")]
[assembly: InternalsVisibleTo("SM64 ROM Manager.Updating.Administration.GUI")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace SM64_ROM_Manager.Updating.My.Resources {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SM64_ROM_Manager.Updating.Administration.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace SM64_ROM_Manager.Updating.My {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,16 @@
using Pilz.Cryptography;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SM64_ROM_Manager.Updating.Administration
{
public class ProxyConfiguration
{
public bool UseProxyAuth { get; set; }
public string Username { get; set; }
public SecureString Password { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
namespace SM64_ROM_Manager.Updating.UpdateInstaller
{
public static partial class UpdateInstallerAddOnNameDefinitions
{
public const string UPDATE_INSTALLER_ADDON_NAMESPACE = "UpdateInstaller";
public const string UPDATE_INSTALLER_ADDON_TYPE = "AddOn";
public const string UPDATE_INSTALLER_ADDON_METHOD = "Main";
}
}

View File

@@ -0,0 +1,10 @@
namespace SM64_ROM_Manager.Updating.UpdateInstaller
{
public static class PackageFileNameDefinations
{
public const string ZIP_PACKAGE_FILENAME = "updatepackage.zip";
public const string ZIP_UPDATE_INSTALLER_ADDONS_DIRECTORY = "installer_addons";
public const string ZIP_APP_DATA_FILES_DIRECTORY = "appdata";
}
}

View File

@@ -0,0 +1,31 @@
using Newtonsoft.Json.Linq;
using SM64_ROM_Manager.Updating.Administration.Discord;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SM64_ROM_Manager.Updating.Administration
{
public class UpdateProject
{
public UpdateServerConfig UpdateServerConfig { get; } = new UpdateServerConfig();
public DiscordBotConfig DiscordBotConfig { get; } = new DiscordBotConfig();
public ProxyConfiguration ProxyConfig { get; } = new ProxyConfiguration();
public static UpdateProject Load(string filePath)
{
if (File.Exists(filePath))
return JObject.Parse(File.ReadAllText(filePath)).ToObject<UpdateProject>();
else
return new UpdateProject();
}
public void Save(string filePath)
{
File.WriteAllText(filePath, JObject.FromObject(this).ToString());
}
}
}

View File

@@ -0,0 +1,35 @@
using drsPwEnc;
using Newtonsoft.Json;
using Pilz.Cryptography;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SM64_ROM_Manager.Updating.Administration
{
public class UpdateServerConfig
{
public bool UseProxyForWebDAV { get; set; } = false;
public string ServerAdress { get; set; }
public string PublicPackageBaseURL { get; set; }
public string UpdateInfoFilename { get; set; }
public string Username { get; set; }
[JsonProperty("Password")]
private string PasswordOld
{
set
{
if (string.IsNullOrEmpty(value))
Password = string.Empty;
else
Password = new drsPwEnc.drsPwEnc().DecryptData(value);
}
}
[JsonProperty("Password2")]
public SecureString Password { get; set; }
}
}

View File

@@ -0,0 +1,405 @@
using global::System.IO;
using global::Newtonsoft.Json.Linq;
using WebDav;
using System.Net;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using static Microsoft.VisualBasic.CompilerServices.LikeOperator;
using Microsoft.VisualBasic;
namespace SM64_ROM_Manager.Updating.Administration
{
public class UpdateServerManager
{
private const string PKG_SEARCHTEXT = "pkg*.*.*.*.zip";
private const string PKG_FILENAME_TEMPLATE = "pkg{0}{1}.zip";
private const string PKG_FILENAME_ALPHADEFINITION = "a";
private const string PKG_FILENAME_BETADEFINITION = "b";
private const string PKG_FILENAME_RCDEFINITION = "rc";
private const string PKG_FILENAME_RELEASEDEFINITION = "r";
private WebDavClient client;
public UpdateInfo UpdateInfo { get; private set; }
public UpdateServerConfig Config { get; private set; }
public bool IsReady { get; private set; }
public UpdateServerManager(UpdateServerConfig config)
{
GenerateClient(config);
NewInfo();
}
public bool GenerateClient(UpdateServerConfig config)
{
bool success;
try
{
// Create client params
var clientparams = new WebDavClientParams()
{
BaseAddress = new Uri(config.ServerAdress),
Credentials = new NetworkCredential(config.Username, config.Password),
UseProxy = false
};
// Create client
client = new WebDavClient(clientparams);
// Remember config
Config = config;
success = true;
}
catch (Exception)
{
success = false;
Config = null;
client = null;
}
return success;
}
public async Task<bool> LoadInfoFromServer()
{
bool success;
try
{
var response = await client.GetProcessedFile(Config.UpdateInfoFilename);
if (response.IsSuccessful)
{
var sr = new StreamReader(response.Stream);
var raw = await sr.ReadToEndAsync();
sr.Close();
UpdateInfo = JObject.Parse(raw).ToObject<UpdateInfo>();
}
success = true;
}
catch (Exception)
{
success = false;
}
return success;
}
public async Task<bool> SaveInfoToServer()
{
bool success;
try
{
// Remove configs of non-existing packages
await ClearUpdateInfo();
// Update Packagelinks
UpdatePackageLinks();
// Write
var raw = UpdateInfo.ToString();
var ms = new MemoryStream();
var sw = new StreamWriter(ms);
await sw.WriteAsync(raw);
await sw.FlushAsync();
// Upload
ms.Position = 0;
await client.PutFile(Config.UpdateInfoFilename, ms);
ms.Close();
success = true;
}
catch (Exception)
{
success = false;
}
return success;
}
public void LoadInfoFromFile(string filePath)
{
UpdateInfo = JObject.Parse(File.ReadAllText(filePath)).ToObject<UpdateInfo>();
}
public async Task SaveInfoToFile(string filePath)
{
// Remove configs of non-existing packages
await ClearUpdateInfo();
// Update Packagelinks
UpdatePackageLinks();
// Write
File.WriteAllText(filePath, UpdateInfo.ToString());
}
public void NewInfo()
{
UpdateInfo = new UpdateInfo();
}
private async Task ClearUpdateInfo()
{
var pkgs = await GetUpdatePackagesList();
var infosToRemove = new List<UpdatePackageInfo>();
// Find non-existing packages
foreach (var info in UpdateInfo.Packages)
{
if (!pkgs.Where((n) => n == info.Version).Any())
{
infosToRemove.Add(info);
}
}
// Remove found packages
foreach (var info in infosToRemove)
UpdateInfo.Packages.Remove(info);
}
private void UpdatePackageLinks()
{
foreach (var info in UpdateInfo.Packages)
UpdatePackageLink(info);
}
private void UpdatePackageLink(UpdatePackageInfo info)
{
info.Packagelink = Config.PublicPackageBaseURL + BuildPackageFilename(info.Version);
}
public async Task<IEnumerable<ApplicationVersion>> GetUpdatePackagesList()
{
var pkgs = new List<ApplicationVersion>();
var response = await client.Propfind(string.Empty);
if (response.IsSuccessful)
{
foreach (var resource in response.Resources)
{
var fileName = Path.GetFileName(resource.Uri);
if (!string.IsNullOrEmpty(fileName) && fileName.ToLower() != Config.UpdateInfoFilename && LikeString(fileName, "pkg*.*.*.*.zip", CompareMethod.Text))
{
var appVersion = new ApplicationVersion();
bool allowAdd = true;
fileName = Path.GetFileNameWithoutExtension(fileName);
fileName = fileName.Substring(3);
// Get alpha/beta/rc value
{
int indexAlpha, indexBeta, indexRC, indexRelease;
indexAlpha = fileName.IndexOf(PKG_FILENAME_ALPHADEFINITION);
indexBeta = fileName.IndexOf(PKG_FILENAME_BETADEFINITION);
indexRC = fileName.IndexOf(PKG_FILENAME_RCDEFINITION);
indexRelease = fileName.IndexOf(PKG_FILENAME_RELEASEDEFINITION);
int indexDef;
string pkgFilenameDef;
if (indexAlpha > -1)
{
indexDef = indexAlpha;
pkgFilenameDef = PKG_FILENAME_ALPHADEFINITION;
}
else if (indexBeta > -1)
{
indexDef = indexBeta;
pkgFilenameDef = PKG_FILENAME_BETADEFINITION;
}
else if (indexRC > -1)
{
indexDef = indexRC;
pkgFilenameDef = PKG_FILENAME_RCDEFINITION;
}
else if (indexRelease > -1)
{
indexDef = indexRelease;
pkgFilenameDef = PKG_FILENAME_RELEASEDEFINITION;
}
else
{
indexDef = -1;
pkgFilenameDef = null;
}
if (indexDef > -1)
{
// Get def from filename
var def = fileName.Substring(indexDef);
fileName = fileName.Remove(indexDef);
// Get channel
switch (pkgFilenameDef)
{
case PKG_FILENAME_ALPHADEFINITION:
appVersion.Channel = Channels.Alpha;
break;
case PKG_FILENAME_BETADEFINITION:
appVersion.Channel = Channels.Beta;
break;
case PKG_FILENAME_RCDEFINITION:
appVersion.Channel = Channels.PreRelease;
break;
case PKG_FILENAME_RELEASEDEFINITION:
appVersion.Channel = Channels.Stable;
break;
}
// Get build
var defBuild = def.Substring(pkgFilenameDef.Length);
appVersion.Build = Convert.ToInt32(defBuild);
}
else
{
// Set to default
appVersion.Build = 1;
appVersion.Channel = Channels.Stable;
}
}
// Get version
if (Version.TryParse(fileName, out Version version))
appVersion.Version = version;
else
allowAdd = false;
if (allowAdd)
pkgs.Add(appVersion);
}
}
}
return pkgs;
}
public async Task<bool> DeletePackage(ApplicationVersion version)
{
var fileName = BuildPackageFilename(version);
var response = await client.Delete(fileName);
return response.IsSuccessful;
}
public async Task<bool> UploadPackage(string filePath, ApplicationVersion version)
{
bool success;
var fileName = BuildPackageFilename(version);
// Upload
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
var response = await client.PutFile(fileName, fs);
fs.Close();
success = response.IsSuccessful;
// Generate public downloadlink
if (success)
{
var pkgInfo = GetOrCreateUpdatePackageInfo(version);
pkgInfo.Packagelink = Config.PublicPackageBaseURL + fileName;
}
return success;
}
private string BuildPackageFilename(ApplicationVersion version)
{
// Build channel/build definition of filename
string def = string.Empty;
switch (version.Channel)
{
case Channels.Alpha:
def = PKG_FILENAME_ALPHADEFINITION + version.Build;
break;
case Channels.Stable:
if (version.Build != 1)
def = PKG_FILENAME_RELEASEDEFINITION + version.Build;
break;
case Channels.PreRelease:
def = PKG_FILENAME_RCDEFINITION + version.Build;
break;
case Channels.Beta:
def = PKG_FILENAME_BETADEFINITION + version.Build;
break;
}
// Build filename
var fileName = string.Format(PKG_FILENAME_TEMPLATE, version.Version, def);
return fileName;
}
private UpdatePackageInfo GetOrCreateUpdatePackageInfo(ApplicationVersion version)
{
var info = GetUpdatePackageInfo(version);
if (info == null)
info = CreateUpdatePackageInfo(version);
return info;
}
public UpdatePackageInfo GetUpdatePackageInfo(ApplicationVersion version)
{
return UpdateInfo.Packages.FirstOrDefault((n) => n.Version == version);
}
private UpdatePackageInfo CreateUpdatePackageInfo(ApplicationVersion version)
{
var info = new UpdatePackageInfo()
{
Version = version
};
UpdateInfo.Packages.Add(info);
return info;
}
public (string name, string description, UpdateNotesContentType descriptionType) GetPackageDescription(ApplicationVersion version)
{
var pkg = GetUpdatePackageInfo(version);
if (pkg is object)
return (pkg.Name, pkg.Notes.Content, pkg.Notes.ContentType);
else
return default;
}
public void SetPackageDescription(ApplicationVersion version, string name, string description, UpdateNotesContentType descriptionType)
{
var pkg = GetOrCreateUpdatePackageInfo(version);
if (pkg is object)
{
pkg.Name = name;
pkg.Notes.Content = description;
pkg.Notes.ContentType = descriptionType;
}
}
public async Task<bool> ChangePackageVersion(ApplicationVersion currentVersion, ApplicationVersion newVersion)
{
bool success = false;
// Get file names
var currentFilename = BuildPackageFilename(currentVersion);
var newFilename = BuildPackageFilename(newVersion);
// Move
var response = await client.Move(currentFilename, newFilename);
// Change package info version, if exists
if (response.IsSuccessful)
{
var pkg = GetUpdatePackageInfo(currentVersion);
if (pkg is object)
pkg.Version = newVersion;
success = true;
}
return success;
}
}
}

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.5.0" newVersion="1.2.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Linq.Async" publicKeyToken="94bc3704cddfc263" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>