add project
This commit is contained in:
231
Pilz.Administration/Discord/DiscordBot.cs
Normal file
231
Pilz.Administration/Discord/DiscordBot.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
17
Pilz.Administration/Discord/DiscordBotConfig.cs
Normal file
17
Pilz.Administration/Discord/DiscordBotConfig.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
11
Pilz.Administration/My Project/Application.Designer.cs
generated
Normal file
11
Pilz.Administration/My Project/Application.Designer.cs
generated
Normal 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>
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
10
Pilz.Administration/My Project/Application.myapp
Normal file
10
Pilz.Administration/My Project/Application.myapp
Normal 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>
|
||||
192
Pilz.Administration/My Project/MyNamespace.Static.1.Designer.cs
generated
Normal file
192
Pilz.Administration/My Project/MyNamespace.Static.1.Designer.cs
generated
Normal 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 */
|
||||
253
Pilz.Administration/My Project/MyNamespace.Static.2.Designer.cs
generated
Normal file
253
Pilz.Administration/My Project/MyNamespace.Static.2.Designer.cs
generated
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Pilz.Administration/My Project/MyNamespace.Static.3.Designer.cs
generated
Normal file
14
Pilz.Administration/My Project/MyNamespace.Static.3.Designer.cs
generated
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
117
Pilz.Administration/My Project/Resources.resx
Normal file
117
Pilz.Administration/My Project/Resources.resx
Normal 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>
|
||||
107
Pilz.Administration/Packaging/UpdatePackageManager.cs
Normal file
107
Pilz.Administration/Packaging/UpdatePackageManager.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
52
Pilz.Administration/Packaging/UpdatePackagePackager.cs
Normal file
52
Pilz.Administration/Packaging/UpdatePackagePackager.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Pilz.Administration/Packaging/UpdatePackageTemplate.cs
Normal file
10
Pilz.Administration/Packaging/UpdatePackageTemplate.cs
Normal 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>();
|
||||
}
|
||||
}
|
||||
122
Pilz.Administration/Pilz.Updating.Administration.csproj
Normal file
122
Pilz.Administration/Pilz.Updating.Administration.csproj
Normal 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>
|
||||
10
Pilz.Administration/Properties/AssemblyInfo.cs
Normal file
10
Pilz.Administration/Properties/AssemblyInfo.cs
Normal 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")]
|
||||
|
||||
63
Pilz.Administration/Properties/Resources.Designer.cs
generated
Normal file
63
Pilz.Administration/Properties/Resources.Designer.cs
generated
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
Pilz.Administration/Properties/Resources.resx
Normal file
117
Pilz.Administration/Properties/Resources.resx
Normal 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>
|
||||
26
Pilz.Administration/Properties/Settings.Designer.cs
generated
Normal file
26
Pilz.Administration/Properties/Settings.Designer.cs
generated
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
Pilz.Administration/Properties/Settings.settings
Normal file
7
Pilz.Administration/Properties/Settings.settings
Normal 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>
|
||||
16
Pilz.Administration/ProxyConfiguration.cs
Normal file
16
Pilz.Administration/ProxyConfiguration.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
31
Pilz.Administration/UpdateProject.cs
Normal file
31
Pilz.Administration/UpdateProject.cs
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Pilz.Administration/UpdateServerConfig.cs
Normal file
35
Pilz.Administration/UpdateServerConfig.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
405
Pilz.Administration/UpdateServerManager.cs
Normal file
405
Pilz.Administration/UpdateServerManager.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Pilz.Administration/app.config
Normal file
23
Pilz.Administration/app.config
Normal 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>
|
||||
Reference in New Issue
Block a user