code optimization
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
Imports System.Reflection
|
Imports System.Reflection
|
||||||
Imports System.Runtime.InteropServices
|
|
||||||
|
|
||||||
Namespace SimpleHistory
|
Namespace SimpleHistory
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
Imports System.Reflection
|
Namespace SimpleHistory
|
||||||
|
|
||||||
Namespace SimpleHistory
|
|
||||||
|
|
||||||
Public Class HistoryStack
|
Public Class HistoryStack
|
||||||
|
|
||||||
|
|||||||
@@ -1,87 +1,86 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Pilz.Configuration
|
namespace Pilz.Configuration;
|
||||||
|
|
||||||
|
public class AutoSaveConfigurationManager : ConfigurationManager
|
||||||
{
|
{
|
||||||
public class AutoSaveConfigurationManager : ConfigurationManager
|
private bool addedHandler = false;
|
||||||
|
private bool enableAutoSave = false;
|
||||||
|
private string _ConfigFilePath = string.Empty;
|
||||||
|
private bool _AutoLoadConfigOnAccess = false;
|
||||||
|
|
||||||
|
public string ConfigFilePath
|
||||||
{
|
{
|
||||||
private bool addedHandler = false;
|
get => _ConfigFilePath;
|
||||||
private bool enableAutoSave = false;
|
set
|
||||||
private string _ConfigFilePath = string.Empty;
|
|
||||||
private bool _AutoLoadConfigOnAccess = false;
|
|
||||||
|
|
||||||
public string ConfigFilePath
|
|
||||||
{
|
{
|
||||||
get => _ConfigFilePath;
|
_ConfigFilePath = value;
|
||||||
set
|
if (AutoLoadConfigOnAccess)
|
||||||
{
|
Load();
|
||||||
_ConfigFilePath = value;
|
|
||||||
if (AutoLoadConfigOnAccess)
|
|
||||||
Load();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AutoLoadConfigOnAccess
|
|
||||||
{
|
|
||||||
get => _AutoLoadConfigOnAccess;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_AutoLoadConfigOnAccess = value;
|
|
||||||
if (value)
|
|
||||||
Load();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AutoSaveConfigOnExit
|
|
||||||
{
|
|
||||||
get => enableAutoSave;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (enableAutoSave != value)
|
|
||||||
{
|
|
||||||
enableAutoSave = value;
|
|
||||||
if (enableAutoSave)
|
|
||||||
AddAutoSaveHandler();
|
|
||||||
else
|
|
||||||
RemoveAutoSaveHandler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddAutoSaveHandler()
|
|
||||||
{
|
|
||||||
if (!addedHandler)
|
|
||||||
{
|
|
||||||
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
|
|
||||||
addedHandler = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveAutoSaveHandler()
|
|
||||||
{
|
|
||||||
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
|
|
||||||
addedHandler = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Save()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(ConfigFilePath) && Configuration is not null)
|
|
||||||
Configuration.WriteToFile(ConfigFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Load()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(ConfigFilePath))
|
|
||||||
Configuration.ReadFromFile(ConfigFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
~AutoSaveConfigurationManager()
|
|
||||||
{
|
|
||||||
RemoveAutoSaveHandler();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AutoLoadConfigOnAccess
|
||||||
|
{
|
||||||
|
get => _AutoLoadConfigOnAccess;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_AutoLoadConfigOnAccess = value;
|
||||||
|
if (value)
|
||||||
|
Load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AutoSaveConfigOnExit
|
||||||
|
{
|
||||||
|
get => enableAutoSave;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (enableAutoSave != value)
|
||||||
|
{
|
||||||
|
enableAutoSave = value;
|
||||||
|
if (enableAutoSave)
|
||||||
|
AddAutoSaveHandler();
|
||||||
|
else
|
||||||
|
RemoveAutoSaveHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddAutoSaveHandler()
|
||||||
|
{
|
||||||
|
if (!addedHandler)
|
||||||
|
{
|
||||||
|
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
|
||||||
|
addedHandler = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveAutoSaveHandler()
|
||||||
|
{
|
||||||
|
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
|
||||||
|
addedHandler = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Save()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(ConfigFilePath) && Configuration is not null)
|
||||||
|
Configuration.WriteToFile(ConfigFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Load()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(ConfigFilePath))
|
||||||
|
Configuration.ReadFromFile(ConfigFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
~AutoSaveConfigurationManager()
|
||||||
|
{
|
||||||
|
RemoveAutoSaveHandler();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
namespace Pilz.Configuration
|
namespace Pilz.Configuration;
|
||||||
{
|
|
||||||
public abstract class ConfigurationManager
|
|
||||||
{
|
|
||||||
public SimpleConfiguration Configuration { get; private set; }
|
|
||||||
|
|
||||||
internal void SetConfiguration(SimpleConfiguration configuration)
|
public abstract class ConfigurationManager
|
||||||
{
|
{
|
||||||
Configuration = configuration;
|
public SimpleConfiguration Configuration { get; private set; }
|
||||||
}
|
|
||||||
|
internal void SetConfiguration(SimpleConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,88 +1,87 @@
|
|||||||
using System.Collections;
|
using Pilz.GeneralEventArgs;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Pilz.GeneralEventArgs;
|
|
||||||
|
|
||||||
namespace Pilz.Configuration
|
namespace Pilz.Configuration;
|
||||||
|
|
||||||
|
public class ConfigurationManagerList : IList<ConfigurationManager>
|
||||||
{
|
{
|
||||||
public class ConfigurationManagerList : IList<ConfigurationManager>
|
public event GettingParentManagerEventHandler GettingParentManager;
|
||||||
|
|
||||||
|
public delegate void GettingParentManagerEventHandler(object sender, GetValueEventArgs<SimpleConfiguration> e);
|
||||||
|
|
||||||
|
private readonly List<ConfigurationManager> myList = new List<ConfigurationManager>();
|
||||||
|
|
||||||
|
private object GetParentManager()
|
||||||
{
|
{
|
||||||
public event GettingParentManagerEventHandler GettingParentManager;
|
var args = new GetValueEventArgs<SimpleConfiguration>();
|
||||||
|
GettingParentManager?.Invoke(this, args);
|
||||||
public delegate void GettingParentManagerEventHandler(object sender, GetValueEventArgs<SimpleConfiguration> e);
|
return args.Value;
|
||||||
|
|
||||||
private readonly List<ConfigurationManager> myList = new List<ConfigurationManager>();
|
|
||||||
|
|
||||||
private object GetParentManager()
|
|
||||||
{
|
|
||||||
var args = new GetValueEventArgs<SimpleConfiguration>();
|
|
||||||
GettingParentManager?.Invoke(this, args);
|
|
||||||
return args.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigurationManager this[int index]
|
|
||||||
{
|
|
||||||
get => myList[index];
|
|
||||||
set => myList[index] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Count => myList.Count;
|
|
||||||
|
|
||||||
public bool IsReadOnly => false;
|
|
||||||
|
|
||||||
public void Insert(int index, ConfigurationManager item)
|
|
||||||
{
|
|
||||||
myList.Insert(index, item);
|
|
||||||
item.SetConfiguration((SimpleConfiguration)GetParentManager());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAt(int index)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(ConfigurationManager item)
|
|
||||||
{
|
|
||||||
item.SetConfiguration((SimpleConfiguration)GetParentManager());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
foreach (ConfigurationManager item in myList)
|
|
||||||
item.SetConfiguration(null);
|
|
||||||
myList.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CopyTo(ConfigurationManager[] array, int arrayIndex)
|
|
||||||
{
|
|
||||||
myList.CopyTo(array, arrayIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int IndexOf(ConfigurationManager item)
|
|
||||||
{
|
|
||||||
return myList.IndexOf(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Contains(ConfigurationManager item)
|
|
||||||
{
|
|
||||||
return myList.Contains(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Remove(ConfigurationManager item)
|
|
||||||
{
|
|
||||||
item.SetConfiguration(null);
|
|
||||||
return myList.Remove(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerator<ConfigurationManager> GetEnumerator()
|
|
||||||
{
|
|
||||||
return (IEnumerator<ConfigurationManager>)IEnumerable_GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator IEnumerable_GetEnumerator()
|
|
||||||
{
|
|
||||||
return myList.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => IEnumerable_GetEnumerator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConfigurationManager this[int index]
|
||||||
|
{
|
||||||
|
get => myList[index];
|
||||||
|
set => myList[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count => myList.Count;
|
||||||
|
|
||||||
|
public bool IsReadOnly => false;
|
||||||
|
|
||||||
|
public void Insert(int index, ConfigurationManager item)
|
||||||
|
{
|
||||||
|
myList.Insert(index, item);
|
||||||
|
item.SetConfiguration((SimpleConfiguration)GetParentManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveAt(int index)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(ConfigurationManager item)
|
||||||
|
{
|
||||||
|
item.SetConfiguration((SimpleConfiguration)GetParentManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
foreach (ConfigurationManager item in myList)
|
||||||
|
item.SetConfiguration(null);
|
||||||
|
myList.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo(ConfigurationManager[] array, int arrayIndex)
|
||||||
|
{
|
||||||
|
myList.CopyTo(array, arrayIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int IndexOf(ConfigurationManager item)
|
||||||
|
{
|
||||||
|
return myList.IndexOf(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(ConfigurationManager item)
|
||||||
|
{
|
||||||
|
return myList.Contains(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Remove(ConfigurationManager item)
|
||||||
|
{
|
||||||
|
item.SetConfiguration(null);
|
||||||
|
return myList.Remove(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<ConfigurationManager> GetEnumerator()
|
||||||
|
{
|
||||||
|
return (IEnumerator<ConfigurationManager>)IEnumerable_GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator IEnumerable_GetEnumerator()
|
||||||
|
{
|
||||||
|
return myList.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => IEnumerable_GetEnumerator();
|
||||||
}
|
}
|
||||||
@@ -1,139 +1,138 @@
|
|||||||
using System.IO;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Pilz.GeneralEventArgs;
|
using Pilz.GeneralEventArgs;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Pilz.Configuration
|
namespace Pilz.Configuration;
|
||||||
|
|
||||||
|
public static class ConfigurationSerializer
|
||||||
{
|
{
|
||||||
public static class ConfigurationSerializer
|
public static event GettingJsonSerializerEventHandler GettingJsonSerializer;
|
||||||
|
|
||||||
|
public delegate void GettingJsonSerializerEventHandler(object instance, GetValueEventArgs<JsonSerializer> e);
|
||||||
|
|
||||||
|
private static JsonSerializer GetJsonSerializer(SimpleConfiguration instance)
|
||||||
{
|
{
|
||||||
public static event GettingJsonSerializerEventHandler GettingJsonSerializer;
|
var args = new GetValueEventArgs<JsonSerializer>(JsonSerializer.CreateDefault());
|
||||||
|
GettingJsonSerializer?.Invoke(instance, args);
|
||||||
|
return args.Value;
|
||||||
|
}
|
||||||
|
|
||||||
public delegate void GettingJsonSerializerEventHandler(object instance, GetValueEventArgs<JsonSerializer> e);
|
/// <summary>
|
||||||
|
/// Writes the given instance to a string and return it.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The configuration instance that should be serialized.</param>
|
||||||
|
/// <returns>The content of the configuration instance as string.</returns>
|
||||||
|
public static string WriteToString(SimpleConfiguration instance)
|
||||||
|
{
|
||||||
|
var tw = new StringWriter();
|
||||||
|
GetJsonSerializer(instance).Serialize(tw, instance);
|
||||||
|
string txt = tw.ToString();
|
||||||
|
tw.Close();
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
|
||||||
private static JsonSerializer GetJsonSerializer(SimpleConfiguration instance)
|
/// <summary>
|
||||||
{
|
/// Write the given instance to a given stream.
|
||||||
var args = new GetValueEventArgs<JsonSerializer>(JsonSerializer.CreateDefault());
|
/// </summary>
|
||||||
GettingJsonSerializer?.Invoke(instance, args);
|
/// <param name="instance">The configuration instance that should be serialized.</param>
|
||||||
return args.Value;
|
/// <param name="stream">The stream where the content should be written to.</param>
|
||||||
}
|
public static void WriteToStream(SimpleConfiguration instance, Stream stream)
|
||||||
|
{
|
||||||
|
var sr = new StreamWriter(stream);
|
||||||
|
sr.Write(WriteToString(instance));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes the given instance to a string and return it.
|
/// Writes the given instance to the given filePath as text file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="instance">The configuration instance that should be serialized.</param>
|
/// <param name="instance">The configuration instance that should be serialized.</param>
|
||||||
/// <returns>The content of the configuration instance as string.</returns>
|
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
|
||||||
public static string WriteToString(SimpleConfiguration instance)
|
public static void WriteToFile(SimpleConfiguration instance, string filePath)
|
||||||
{
|
{
|
||||||
var tw = new StringWriter();
|
var fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
|
||||||
GetJsonSerializer(instance).Serialize(tw, instance);
|
WriteToStream(instance, fs);
|
||||||
string txt = tw.ToString();
|
fs.Close();
|
||||||
tw.Close();
|
}
|
||||||
return txt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Write the given instance to a given stream.
|
/// Reads a configuratin from the given string and returns an instance of it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="instance">The configuration instance that should be serialized.</param>
|
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||||
/// <param name="stream">The stream where the content should be written to.</param>
|
/// <param name="content">The content of the configuration as string.</param>
|
||||||
public static void WriteToStream(SimpleConfiguration instance, Stream stream)
|
/// <returns></returns>
|
||||||
{
|
public static T ReadFromString<T>(string content) where T : SimpleConfiguration
|
||||||
var sr = new StreamWriter(stream);
|
{
|
||||||
sr.Write(WriteToString(instance));
|
var sr = new StringReader(content);
|
||||||
}
|
T instance = (T)GetJsonSerializer(null).Deserialize(sr, typeof(T));
|
||||||
|
sr.Close();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes the given instance to the given filePath as text file.
|
/// Read a configuration from the given string and put them to the given instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="instance">The configuration instance that should be serialized.</param>
|
/// <param name="instance">The instance to populate with the configuration.</param>
|
||||||
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
|
/// <param name="content">The content of the configuration as string.</param>
|
||||||
public static void WriteToFile(SimpleConfiguration instance, string filePath)
|
public static void ReadFromString(SimpleConfiguration instance, string content)
|
||||||
{
|
{
|
||||||
var fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
|
var sr = new StringReader(content);
|
||||||
WriteToStream(instance, fs);
|
GetJsonSerializer(null).Populate(sr, content);
|
||||||
fs.Close();
|
sr.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a configuratin from the given string and returns an instance of it.
|
/// Reads a configuratin from the given string and returns an instance of it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||||
/// <param name="content">The content of the configuration as string.</param>
|
/// <param name="stream">The stream with the content of the configuration.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static T ReadFromString<T>(string content) where T : SimpleConfiguration
|
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
|
||||||
{
|
{
|
||||||
var sr = new StringReader(content);
|
return ReadFromString<T>(GetContentOfStream(stream));
|
||||||
T instance = (T)GetJsonSerializer(null).Deserialize(sr, typeof(T));
|
}
|
||||||
sr.Close();
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read a configuration from the given string and put them to the given instance.
|
/// Read a configuration from the given string and put them to the given instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="instance">The instance to populate with the configuration.</param>
|
/// <param name="instance">The instance to populate with the configuration.</param>
|
||||||
/// <param name="content">The content of the configuration as string.</param>
|
/// <param name="stream">The stream with the content of the configuration.</param>
|
||||||
public static void ReadFromString(SimpleConfiguration instance, string content)
|
public static void ReadFromStream(SimpleConfiguration instance, Stream stream)
|
||||||
{
|
{
|
||||||
var sr = new StringReader(content);
|
ReadFromString(instance, GetContentOfStream(stream));
|
||||||
GetJsonSerializer(null).Populate(sr, content);
|
}
|
||||||
sr.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a configuratin from the given string and returns an instance of it.
|
/// Reads a configuratin from the given string and returns an instance of it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||||
/// <param name="stream">The stream with the content of the configuration.</param>
|
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
|
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
|
||||||
{
|
{
|
||||||
return ReadFromString<T>(GetContentOfStream(stream));
|
return ReadFromString<T>(GetContentOfFile(filePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read a configuration from the given string and put them to the given instance.
|
/// Read a configuration from the given string and put them to the given instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="instance">The instance to populate with the configuration.</param>
|
/// <param name="instance">The instance to populate with the configuration.</param>
|
||||||
/// <param name="stream">The stream with the content of the configuration.</param>
|
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||||
public static void ReadFromStream(SimpleConfiguration instance, Stream stream)
|
public static void ReadFromFile(SimpleConfiguration instance, string filePath)
|
||||||
{
|
{
|
||||||
ReadFromString(instance, GetContentOfStream(stream));
|
ReadFromString(instance, GetContentOfFile(filePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private static string GetContentOfStream(Stream stream)
|
||||||
/// Reads a configuratin from the given string and returns an instance of it.
|
{
|
||||||
/// </summary>
|
var sr = new StreamReader(stream);
|
||||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
return sr.ReadToEnd();
|
||||||
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
}
|
||||||
/// <returns></returns>
|
|
||||||
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
|
|
||||||
{
|
|
||||||
return ReadFromString<T>(GetContentOfFile(filePath));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
private static string GetContentOfFile(string filePath)
|
||||||
/// Read a configuration from the given string and put them to the given instance.
|
{
|
||||||
/// </summary>
|
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||||
/// <param name="instance">The instance to populate with the configuration.</param>
|
string content = GetContentOfStream(fs);
|
||||||
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
fs.Close();
|
||||||
public static void ReadFromFile(SimpleConfiguration instance, string filePath)
|
return content;
|
||||||
{
|
|
||||||
ReadFromString(instance, GetContentOfFile(filePath));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetContentOfStream(Stream stream)
|
|
||||||
{
|
|
||||||
var sr = new StreamReader(stream);
|
|
||||||
return sr.ReadToEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetContentOfFile(string filePath)
|
|
||||||
{
|
|
||||||
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
|
||||||
string content = GetContentOfStream(fs);
|
|
||||||
fs.Close();
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace Pilz.Configuration
|
namespace Pilz.Configuration;
|
||||||
|
|
||||||
|
public interface IChildSettings
|
||||||
{
|
{
|
||||||
public interface IChildSettings
|
void Reset();
|
||||||
{
|
|
||||||
void Reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Pilz.Configuration
|
namespace Pilz.Configuration;
|
||||||
|
|
||||||
|
public interface ISettings
|
||||||
{
|
{
|
||||||
public interface ISettings
|
IReadOnlyCollection<IChildSettings> Childs { get; }
|
||||||
{
|
T Get<T>() where T : IChildSettings, ISettingsIdentifier;
|
||||||
IReadOnlyCollection<IChildSettings> Childs { get; }
|
void Reset();
|
||||||
T Get<T>() where T : IChildSettings, ISettingsIdentifier;
|
|
||||||
void Reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,6 @@
|
|||||||
using System;
|
namespace Pilz.Configuration;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Configuration
|
public interface ISettingsIdentifier
|
||||||
{
|
{
|
||||||
public interface ISettingsIdentifier
|
static abstract string Identifier { get; }
|
||||||
{
|
|
||||||
static abstract string Identifier { get; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
|
|
||||||
namespace Pilz.Configuration
|
namespace Pilz.Configuration;
|
||||||
|
|
||||||
|
public interface ISettingsManager
|
||||||
{
|
{
|
||||||
public interface ISettingsManager
|
ISettings Instance { get; }
|
||||||
{
|
void Save();
|
||||||
ISettings Instance { get; }
|
void Load();
|
||||||
void Save();
|
void Reset();
|
||||||
void Load();
|
|
||||||
void Reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,37 +1,35 @@
|
|||||||
using System;
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Pilz.Configuration
|
namespace Pilz.Configuration;
|
||||||
|
|
||||||
|
public class Settings : ISettings
|
||||||
{
|
{
|
||||||
public class Settings : ISettings
|
[JsonProperty(nameof(Settings))]
|
||||||
|
protected readonly Dictionary<string, IChildSettings> mySettings = [];
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public IReadOnlyCollection<IChildSettings> Childs => mySettings.Values;
|
||||||
|
|
||||||
|
public T Get<T>() where T : IChildSettings, ISettingsIdentifier
|
||||||
{
|
{
|
||||||
[JsonProperty(nameof(Settings))]
|
if (mySettings.TryGetValue(T.Identifier, out IChildSettings valueExisting) && valueExisting is T settingsExisting)
|
||||||
protected readonly Dictionary<string, IChildSettings> mySettings = [];
|
return settingsExisting;
|
||||||
|
|
||||||
[JsonIgnore]
|
if (Activator.CreateInstance<T>() is T settingsNew)
|
||||||
public IReadOnlyCollection<IChildSettings> Childs => mySettings.Values;
|
|
||||||
|
|
||||||
public T Get<T>() where T : IChildSettings, ISettingsIdentifier
|
|
||||||
{
|
{
|
||||||
if (mySettings.TryGetValue(T.Identifier, out IChildSettings valueExisting) && valueExisting is T settingsExisting)
|
settingsNew.Reset();
|
||||||
return settingsExisting;
|
mySettings.Add(T.Identifier, settingsNew);
|
||||||
|
return settingsNew;
|
||||||
if (Activator.CreateInstance<T>() is T settingsNew)
|
|
||||||
{
|
|
||||||
settingsNew.Reset();
|
|
||||||
mySettings.Add(T.Identifier, settingsNew);
|
|
||||||
return settingsNew;
|
|
||||||
}
|
|
||||||
|
|
||||||
return default;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
return default;
|
||||||
{
|
}
|
||||||
foreach (var s in mySettings.Values)
|
|
||||||
s.Reset();
|
public void Reset()
|
||||||
}
|
{
|
||||||
|
foreach (var s in mySettings.Values)
|
||||||
|
s.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,142 +1,139 @@
|
|||||||
using System;
|
using Newtonsoft.Json;
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Serialization;
|
|
||||||
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
||||||
|
|
||||||
namespace Pilz.Configuration
|
namespace Pilz.Configuration;
|
||||||
|
|
||||||
|
public class SettingsManager : ISettingsManager
|
||||||
{
|
{
|
||||||
public class SettingsManager : ISettingsManager
|
public event EventHandler AutoSavingSettings;
|
||||||
|
public event EventHandler SavingSettings;
|
||||||
|
public event EventHandler SavedSettings;
|
||||||
|
public event EventHandler<ErrorEventArgs> OnSerializationError;
|
||||||
|
|
||||||
|
protected ISettings defaultInstance = null;
|
||||||
|
protected bool enableAutoSave = false;
|
||||||
|
protected bool addedHandler = false;
|
||||||
|
|
||||||
|
public string ConfigFilePath { get; set; }
|
||||||
|
|
||||||
|
public ISettings Instance
|
||||||
{
|
{
|
||||||
public event EventHandler AutoSavingSettings;
|
get
|
||||||
public event EventHandler SavingSettings;
|
|
||||||
public event EventHandler SavedSettings;
|
|
||||||
public event EventHandler<ErrorEventArgs> OnSerializationError;
|
|
||||||
|
|
||||||
protected ISettings defaultInstance = null;
|
|
||||||
protected bool enableAutoSave = false;
|
|
||||||
protected bool addedHandler = false;
|
|
||||||
|
|
||||||
public string ConfigFilePath { get; set; }
|
|
||||||
|
|
||||||
public ISettings Instance
|
|
||||||
{
|
{
|
||||||
get
|
if (defaultInstance is null)
|
||||||
{
|
Load();
|
||||||
if (defaultInstance is null)
|
return defaultInstance;
|
||||||
Load();
|
|
||||||
return defaultInstance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool AutoSaveOnExit
|
public bool AutoSaveOnExit
|
||||||
|
{
|
||||||
|
get => enableAutoSave;
|
||||||
|
set
|
||||||
{
|
{
|
||||||
get => enableAutoSave;
|
if (enableAutoSave != value)
|
||||||
set
|
|
||||||
{
|
{
|
||||||
if (enableAutoSave != value)
|
enableAutoSave = value;
|
||||||
|
if (enableAutoSave)
|
||||||
{
|
{
|
||||||
enableAutoSave = value;
|
if (!addedHandler)
|
||||||
if (enableAutoSave)
|
AddAutoSaveHandler();
|
||||||
{
|
}
|
||||||
if (!addedHandler)
|
else
|
||||||
AddAutoSaveHandler();
|
{
|
||||||
}
|
if (addedHandler)
|
||||||
else
|
RemoveAutoSaveHandler();
|
||||||
{
|
|
||||||
if (addedHandler)
|
|
||||||
RemoveAutoSaveHandler();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public SettingsManager()
|
public SettingsManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SettingsManager(string fileName, bool autoSaveOnExit) : this()
|
||||||
|
{
|
||||||
|
ConfigFilePath = fileName;
|
||||||
|
AutoSaveOnExit = autoSaveOnExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void AddAutoSaveHandler()
|
||||||
|
{
|
||||||
|
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
|
||||||
|
addedHandler = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void RemoveAutoSaveHandler()
|
||||||
|
{
|
||||||
|
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
|
||||||
|
addedHandler = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
AutoSavingSettings?.Invoke(this, new EventArgs());
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(ConfigFilePath) && defaultInstance is not null)
|
||||||
|
SaveInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(ConfigFilePath) && File.Exists(ConfigFilePath))
|
||||||
|
LoadInternal();
|
||||||
|
else
|
||||||
|
CreateNewInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
Instance.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void CreateNewInstance()
|
||||||
|
{
|
||||||
|
defaultInstance = new Settings();
|
||||||
|
defaultInstance.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void LoadInternal()
|
||||||
|
{
|
||||||
|
defaultInstance = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(ConfigFilePath), CreateJsonSerializerSettings());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void SaveInternal()
|
||||||
|
{
|
||||||
|
SavingSettings?.Invoke(this, EventArgs.Empty);
|
||||||
|
File.WriteAllText(ConfigFilePath, JsonConvert.SerializeObject(defaultInstance, CreateJsonSerializerSettings()));
|
||||||
|
SavedSettings?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual JsonSerializerSettings CreateJsonSerializerSettings()
|
||||||
|
{
|
||||||
|
return new JsonSerializerSettings()
|
||||||
{
|
{
|
||||||
}
|
Formatting = Formatting.Indented,
|
||||||
|
TypeNameHandling = TypeNameHandling.Auto,
|
||||||
|
Error = JsonSerializer_OnError,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public SettingsManager(string fileName, bool autoSaveOnExit) : this()
|
protected virtual void JsonSerializer_OnError(object sender, ErrorEventArgs e)
|
||||||
{
|
{
|
||||||
ConfigFilePath = fileName;
|
const string errorResolvingType = "Error resolving type specified in JSON";
|
||||||
AutoSaveOnExit = autoSaveOnExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void AddAutoSaveHandler()
|
// Invoke event
|
||||||
{
|
OnSerializationError?.Invoke(sender, e);
|
||||||
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
|
|
||||||
addedHandler = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void RemoveAutoSaveHandler()
|
// Handle ourself
|
||||||
{
|
if (!e.ErrorContext.Handled && e.ErrorContext.Error is JsonSerializationException serializationException && serializationException.Message.StartsWith(errorResolvingType))
|
||||||
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
|
e.ErrorContext.Handled = true;
|
||||||
addedHandler = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
AutoSavingSettings?.Invoke(this, new EventArgs());
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(ConfigFilePath) && defaultInstance is not null)
|
|
||||||
SaveInternal();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Load()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(ConfigFilePath) && File.Exists(ConfigFilePath))
|
|
||||||
LoadInternal();
|
|
||||||
else
|
|
||||||
CreateNewInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
|
||||||
{
|
|
||||||
Instance.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void CreateNewInstance()
|
|
||||||
{
|
|
||||||
defaultInstance = new Settings();
|
|
||||||
defaultInstance.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void LoadInternal()
|
|
||||||
{
|
|
||||||
defaultInstance = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(ConfigFilePath), CreateJsonSerializerSettings());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void SaveInternal()
|
|
||||||
{
|
|
||||||
SavingSettings?.Invoke(this, EventArgs.Empty);
|
|
||||||
File.WriteAllText(ConfigFilePath, JsonConvert.SerializeObject(defaultInstance, CreateJsonSerializerSettings()));
|
|
||||||
SavedSettings?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual JsonSerializerSettings CreateJsonSerializerSettings()
|
|
||||||
{
|
|
||||||
return new JsonSerializerSettings()
|
|
||||||
{
|
|
||||||
Formatting = Formatting.Indented,
|
|
||||||
TypeNameHandling = TypeNameHandling.Auto,
|
|
||||||
Error = JsonSerializer_OnError,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void JsonSerializer_OnError(object sender, ErrorEventArgs e)
|
|
||||||
{
|
|
||||||
const string errorResolvingType = "Error resolving type specified in JSON";
|
|
||||||
|
|
||||||
// Invoke event
|
|
||||||
OnSerializationError?.Invoke(sender, e);
|
|
||||||
|
|
||||||
// Handle ourself
|
|
||||||
if (!e.ErrorContext.Handled && e.ErrorContext.Error is JsonSerializationException serializationException && serializationException.Message.StartsWith(errorResolvingType))
|
|
||||||
e.ErrorContext.Handled = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,110 +1,109 @@
|
|||||||
using System.IO;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Pilz.GeneralEventArgs;
|
using Pilz.GeneralEventArgs;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Pilz.Configuration
|
namespace Pilz.Configuration;
|
||||||
|
|
||||||
|
public class SimpleConfiguration
|
||||||
{
|
{
|
||||||
public class SimpleConfiguration
|
[JsonIgnore]
|
||||||
|
public readonly ConfigurationManagerList Managers = new ConfigurationManagerList();
|
||||||
|
|
||||||
|
public SimpleConfiguration()
|
||||||
{
|
{
|
||||||
[JsonIgnore]
|
Managers.GettingParentManager += Managers_GettingParentManager;
|
||||||
public readonly ConfigurationManagerList Managers = new ConfigurationManagerList();
|
}
|
||||||
|
|
||||||
public SimpleConfiguration()
|
private void Managers_GettingParentManager(object sender, GetValueEventArgs<SimpleConfiguration> e)
|
||||||
{
|
{
|
||||||
Managers.GettingParentManager += Managers_GettingParentManager;
|
if (ReferenceEquals(sender, Managers))
|
||||||
}
|
e.Value = this;
|
||||||
|
}
|
||||||
|
|
||||||
private void Managers_GettingParentManager(object sender, GetValueEventArgs<SimpleConfiguration> e)
|
/// <summary>
|
||||||
{
|
/// Writes this instance to a string and return it.
|
||||||
if (ReferenceEquals(sender, Managers))
|
/// </summary>
|
||||||
e.Value = this;
|
/// <returns>The content of the configuration instance as string.</returns>
|
||||||
}
|
public string WriteToString()
|
||||||
|
{
|
||||||
|
return ConfigurationSerializer.WriteToString(this);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes this instance to a string and return it.
|
/// Write this instance to a given stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The content of the configuration instance as string.</returns>
|
/// <param name="stream">The stream where the content should be written to.</param>
|
||||||
public string WriteToString()
|
public void WriteToStream(Stream stream)
|
||||||
{
|
{
|
||||||
return ConfigurationSerializer.WriteToString(this);
|
ConfigurationSerializer.WriteToStream(this, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Write this instance to a given stream.
|
/// Writes this instance to the given filePath as text file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">The stream where the content should be written to.</param>
|
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
|
||||||
public void WriteToStream(Stream stream)
|
public void WriteToFile(string filePath)
|
||||||
{
|
{
|
||||||
ConfigurationSerializer.WriteToStream(this, stream);
|
ConfigurationSerializer.WriteToFile(this, filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes this instance to the given filePath as text file.
|
/// Reads a configuratin from the given string and returns an instance of it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
|
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||||
public void WriteToFile(string filePath)
|
/// <param name="content">The content of the configuration as string.</param>
|
||||||
{
|
/// <returns></returns>
|
||||||
ConfigurationSerializer.WriteToFile(this, filePath);
|
public static T ReadFromString<T>(string content) where T : SimpleConfiguration
|
||||||
}
|
{
|
||||||
|
return ConfigurationSerializer.ReadFromString<T>(content);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a configuratin from the given string and returns an instance of it.
|
/// Read a configuration from the given string and put them to this instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
/// <param name="content">The content of the configuration as string.</param>
|
||||||
/// <param name="content">The content of the configuration as string.</param>
|
public void ReadFromString(string content)
|
||||||
/// <returns></returns>
|
{
|
||||||
public static T ReadFromString<T>(string content) where T : SimpleConfiguration
|
ConfigurationSerializer.ReadFromString(this, content);
|
||||||
{
|
}
|
||||||
return ConfigurationSerializer.ReadFromString<T>(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read a configuration from the given string and put them to this instance.
|
/// Reads a configuratin from the given string and returns an instance of it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="content">The content of the configuration as string.</param>
|
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||||
public void ReadFromString(string content)
|
/// <param name="stream">The stream with the content of the configuration.</param>
|
||||||
{
|
/// <returns></returns>
|
||||||
ConfigurationSerializer.ReadFromString(this, content);
|
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
|
||||||
}
|
{
|
||||||
|
return ConfigurationSerializer.ReadFromStream<T>(stream);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a configuratin from the given string and returns an instance of it.
|
/// Read a configuration from the given string and put them to this instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
/// <param name="stream">The stream with the content of the configuration.</param>
|
||||||
/// <param name="stream">The stream with the content of the configuration.</param>
|
public void ReadFromStream(Stream stream)
|
||||||
/// <returns></returns>
|
{
|
||||||
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
|
ConfigurationSerializer.ReadFromStream(this, stream);
|
||||||
{
|
}
|
||||||
return ConfigurationSerializer.ReadFromStream<T>(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read a configuration from the given string and put them to this instance.
|
/// Reads a configuratin from the given string and returns an instance of it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">The stream with the content of the configuration.</param>
|
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||||
public void ReadFromStream(Stream stream)
|
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||||
{
|
/// <returns></returns>
|
||||||
ConfigurationSerializer.ReadFromStream(this, stream);
|
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
|
||||||
}
|
{
|
||||||
|
return ConfigurationSerializer.ReadFromFile<T>(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a configuratin from the given string and returns an instance of it.
|
/// Read a configuration from the given string and put them to this instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||||
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
public void ReadFromFile(string filePath)
|
||||||
/// <returns></returns>
|
{
|
||||||
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
|
ConfigurationSerializer.ReadFromFile(this, filePath);
|
||||||
{
|
|
||||||
return ConfigurationSerializer.ReadFromFile<T>(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Read a configuration from the given string and put them to this instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
|
||||||
public void ReadFromFile(string filePath)
|
|
||||||
{
|
|
||||||
ConfigurationSerializer.ReadFromFile(this, filePath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,55 +1,51 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
|
||||||
using System.Management;
|
using System.Management;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Cryptography
|
namespace Pilz.Cryptography;
|
||||||
|
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
|
public static class Helpers
|
||||||
{
|
{
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
private static string clientSecret = null;
|
||||||
public static class Helpers
|
|
||||||
|
public static string CalculateClientSecret()
|
||||||
{
|
{
|
||||||
private static string clientSecret = null;
|
// Try getting serial number of C drive
|
||||||
|
if (clientSecret == null && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
public static string CalculateClientSecret()
|
|
||||||
{
|
{
|
||||||
// Try getting serial number of C drive
|
ManagementObjectSearcher searcher = new("SELECT * FROM Win32_PhysicalMedia");
|
||||||
if (clientSecret == null && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
string sn = null;
|
||||||
|
|
||||||
|
foreach (var entry in searcher.Get())
|
||||||
{
|
{
|
||||||
ManagementObjectSearcher searcher = new("SELECT * FROM Win32_PhysicalMedia");
|
if (entry is ManagementObject wmi_HD && string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
|
||||||
string sn = null;
|
sn = wmi_HD["SerialNumber"].ToString()?.Trim();
|
||||||
|
|
||||||
foreach (var entry in searcher.Get())
|
|
||||||
{
|
|
||||||
if (entry is ManagementObject wmi_HD && string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
|
|
||||||
sn = wmi_HD["SerialNumber"].ToString()?.Trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
clientSecret = sn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to Mashine name
|
clientSecret = sn;
|
||||||
clientSecret ??= Environment.MachineName;
|
|
||||||
|
|
||||||
return clientSecret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GenerateUniquieID<T>(string var)
|
// Fallback to Mashine name
|
||||||
{
|
clientSecret ??= Environment.MachineName;
|
||||||
var sn = CalculateClientSecret();
|
|
||||||
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
|
|
||||||
var type = typeof(T).ToString();
|
|
||||||
var together = sn + dateTime + type + var;
|
|
||||||
|
|
||||||
var md5 = MD5.Create();
|
return clientSecret;
|
||||||
var hash = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(together))).Replace("-", string.Empty);
|
}
|
||||||
md5.Dispose();
|
|
||||||
|
|
||||||
return hash;
|
public static string GenerateUniquieID<T>(string var)
|
||||||
}
|
{
|
||||||
|
var sn = CalculateClientSecret();
|
||||||
|
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
|
||||||
|
var type = typeof(T).ToString();
|
||||||
|
var together = sn + dateTime + type + var;
|
||||||
|
|
||||||
|
var md5 = MD5.Create();
|
||||||
|
var hash = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(together))).Replace("-", string.Empty);
|
||||||
|
md5.Dispose();
|
||||||
|
|
||||||
|
return hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
using System;
|
namespace Pilz.Cryptography;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Cryptography
|
public interface ICrypter
|
||||||
{
|
{
|
||||||
public interface ICrypter
|
string Encrypt(string plainValue);
|
||||||
{
|
string Decrypt(string encryptedValue);
|
||||||
string Encrypt(string plainValue);
|
|
||||||
string Decrypt(string encryptedValue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Pilz.Cryptography
|
namespace Pilz.Cryptography;
|
||||||
|
|
||||||
|
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
|
||||||
|
public interface IUniquieID
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
|
bool HasID { get; }
|
||||||
public interface IUniquieID
|
string ID { get; }
|
||||||
{
|
|
||||||
bool HasID { get; }
|
|
||||||
string ID { get; }
|
|
||||||
|
|
||||||
void GenerateIfNull();
|
void GenerateIfNull();
|
||||||
void Generate();
|
void Generate();
|
||||||
bool Equals(object obj);
|
bool Equals(object obj);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
using System;
|
namespace Pilz.Cryptography;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Pilz.Cryptography
|
/// <summary>
|
||||||
|
/// Can be implemented on objects that provides an UniquieID.
|
||||||
|
/// </summary>
|
||||||
|
public interface IUniquieIDHost
|
||||||
{
|
{
|
||||||
/// <summary>
|
UniquieID ID { get; }
|
||||||
/// Can be implemented on objects that provides an UniquieID.
|
|
||||||
/// </summary>
|
|
||||||
public interface IUniquieIDHost
|
|
||||||
{
|
|
||||||
UniquieID ID { get; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,35 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Pilz.Cryptography;
|
using Pilz.Cryptography;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Pilz.Json.Converters
|
namespace Pilz.Json.Converters;
|
||||||
|
|
||||||
|
public class UniquieIDStringJsonConverter : JsonConverter
|
||||||
{
|
{
|
||||||
public class UniquieIDStringJsonConverter : JsonConverter
|
public static bool EnableCheckForDepricatedTypes { get; set; } = true;
|
||||||
|
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
{
|
{
|
||||||
public static bool EnableCheckForDepricatedTypes { get; set; } = true;
|
return typeof(IUniquieID).IsAssignableFrom(objectType);
|
||||||
|
}
|
||||||
|
|
||||||
public override bool CanConvert(Type objectType)
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
return typeof(IUniquieID).IsAssignableFrom(objectType);
|
var idString = serializer.Deserialize<string>(reader);
|
||||||
}
|
UniquieID id;
|
||||||
|
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
if (existingValue is UniquieID existingID && (!EnableCheckForDepricatedTypes || existingID.GetType() == typeof(UniquieID)))
|
||||||
{
|
id = existingID;
|
||||||
var idString = serializer.Deserialize<string>(reader);
|
else
|
||||||
UniquieID id;
|
id = new UniquieID();
|
||||||
|
|
||||||
if (existingValue is UniquieID existingID && (!EnableCheckForDepricatedTypes || existingID.GetType() == typeof(UniquieID)))
|
id.ID = idString;
|
||||||
id = existingID;
|
|
||||||
else
|
|
||||||
id = new UniquieID();
|
|
||||||
|
|
||||||
id.ID = idString;
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
return id;
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
}
|
{
|
||||||
|
serializer.Serialize(writer, ((UniquieID)value).ID);
|
||||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
||||||
{
|
|
||||||
serializer.Serialize(writer, ((UniquieID)value).ID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||||
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||||
|
|||||||
@@ -1,78 +1,73 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Cryptography
|
namespace Pilz.Cryptography;
|
||||||
|
|
||||||
|
[JsonConverter(typeof(Json.Converters.SecureStringJsonConverter))]
|
||||||
|
public class SecureString
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(Json.Converters.SecureStringJsonConverter))]
|
public static ICrypter DefaultCrypter { get; set; }
|
||||||
public class SecureString
|
public ICrypter Crypter { get; set; }
|
||||||
|
public string EncryptedValue { get; set; }
|
||||||
|
public string Value
|
||||||
{
|
{
|
||||||
public static ICrypter DefaultCrypter { get; set; }
|
get => GetCrypter()?.Decrypt(EncryptedValue);
|
||||||
public ICrypter Crypter { get; set; }
|
set => EncryptedValue = GetCrypter().Encrypt(value);
|
||||||
public string EncryptedValue { get; set; }
|
|
||||||
public string Value
|
|
||||||
{
|
|
||||||
get => GetCrypter()?.Decrypt(EncryptedValue);
|
|
||||||
set => EncryptedValue = GetCrypter().Encrypt(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonConstructor]
|
|
||||||
private SecureString(JsonConstructorAttribute dummyAttribute)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public SecureString() :
|
|
||||||
this(string.Empty, true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public SecureString(string value, bool isEncrypted) :
|
|
||||||
this(value, isEncrypted, null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public SecureString(string value, bool isEncrypted, ICrypter crypter)
|
|
||||||
{
|
|
||||||
Crypter = crypter;
|
|
||||||
|
|
||||||
if (isEncrypted)
|
|
||||||
EncryptedValue = value;
|
|
||||||
else
|
|
||||||
Value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ICrypter GetCrypter()
|
|
||||||
{
|
|
||||||
if (Crypter == null)
|
|
||||||
{
|
|
||||||
if (DefaultCrypter == null)
|
|
||||||
DefaultCrypter = new SimpleStringCrypter(string.Empty);
|
|
||||||
Crypter = DefaultCrypter;
|
|
||||||
}
|
|
||||||
return Crypter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() => Value;
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
var @string = obj as SecureString;
|
|
||||||
return @string != null &&
|
|
||||||
EncryptedValue == @string.EncryptedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return -2303024 + EqualityComparer<string>.Default.GetHashCode(EncryptedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator string(SecureString value) => value?.Value;
|
|
||||||
public static implicit operator SecureString(string value) => new SecureString(value, false);
|
|
||||||
|
|
||||||
public static bool operator ==(SecureString left, SecureString right) => left?.EncryptedValue == right?.EncryptedValue;
|
|
||||||
public static bool operator !=(SecureString left, SecureString right) => left?.EncryptedValue != right?.EncryptedValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
private SecureString(JsonConstructorAttribute dummyAttribute)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SecureString() :
|
||||||
|
this(string.Empty, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SecureString(string value, bool isEncrypted) :
|
||||||
|
this(value, isEncrypted, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SecureString(string value, bool isEncrypted, ICrypter crypter)
|
||||||
|
{
|
||||||
|
Crypter = crypter;
|
||||||
|
|
||||||
|
if (isEncrypted)
|
||||||
|
EncryptedValue = value;
|
||||||
|
else
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ICrypter GetCrypter()
|
||||||
|
{
|
||||||
|
if (Crypter == null)
|
||||||
|
{
|
||||||
|
if (DefaultCrypter == null)
|
||||||
|
DefaultCrypter = new SimpleStringCrypter(string.Empty);
|
||||||
|
Crypter = DefaultCrypter;
|
||||||
|
}
|
||||||
|
return Crypter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() => Value;
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
var @string = obj as SecureString;
|
||||||
|
return @string != null &&
|
||||||
|
EncryptedValue == @string.EncryptedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return -2303024 + EqualityComparer<string>.Default.GetHashCode(EncryptedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator string(SecureString value) => value?.Value;
|
||||||
|
public static implicit operator SecureString(string value) => new SecureString(value, false);
|
||||||
|
|
||||||
|
public static bool operator ==(SecureString left, SecureString right) => left?.EncryptedValue == right?.EncryptedValue;
|
||||||
|
public static bool operator !=(SecureString left, SecureString right) => left?.EncryptedValue != right?.EncryptedValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,34 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Pilz.Cryptography;
|
using Pilz.Cryptography;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Json.Converters
|
namespace Pilz.Json.Converters;
|
||||||
|
|
||||||
|
public class SecureStringJsonConverter : JsonConverter
|
||||||
{
|
{
|
||||||
public class SecureStringJsonConverter : JsonConverter
|
public override bool CanConvert(Type objectType)
|
||||||
{
|
{
|
||||||
public override bool CanConvert(Type objectType)
|
return typeof(SecureString).IsAssignableFrom(objectType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
var idString = serializer.Deserialize<string>(reader);
|
||||||
|
SecureString id;
|
||||||
|
|
||||||
|
if (existingValue is SecureString)
|
||||||
{
|
{
|
||||||
return typeof(SecureString).IsAssignableFrom(objectType);
|
id = (SecureString)existingValue;
|
||||||
|
id.EncryptedValue = idString;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
id = new SecureString(idString, true);
|
||||||
|
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
return id;
|
||||||
{
|
}
|
||||||
var idString = serializer.Deserialize<string>(reader);
|
|
||||||
SecureString id;
|
|
||||||
|
|
||||||
if (existingValue is SecureString)
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
id = (SecureString)existingValue;
|
serializer.Serialize(writer, ((SecureString)value).EncryptedValue);
|
||||||
id.EncryptedValue = idString;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
id = new SecureString(idString, true);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
||||||
{
|
|
||||||
serializer.Serialize(writer, ((SecureString)value).EncryptedValue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,80 +1,91 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.IO;
|
||||||
|
|
||||||
|
/* Nicht gemergte Änderung aus Projekt "Pilz.Cryptography (net6.0)"
|
||||||
|
Vor:
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
Nach:
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
*/
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Pilz.Cryptography
|
namespace Pilz.Cryptography;
|
||||||
|
|
||||||
|
public class SimpleStringCrypter : ICrypter
|
||||||
{
|
{
|
||||||
public class SimpleStringCrypter : ICrypter
|
private readonly TripleDES TripleDes;
|
||||||
|
public Encoding TextEncoding { get; private set; } = Encoding.Default;
|
||||||
|
|
||||||
|
public SimpleStringCrypter() : this(string.Empty)
|
||||||
{
|
{
|
||||||
private readonly TripleDES TripleDes;
|
}
|
||||||
public Encoding TextEncoding { get; private set; } = Encoding.Default;
|
|
||||||
|
|
||||||
public SimpleStringCrypter() : this(string.Empty)
|
public SimpleStringCrypter(string key) : this(key, Encoding.Default)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleStringCrypter(string key) : this(key, Encoding.Default)
|
public SimpleStringCrypter(string key, Encoding textEncoding)
|
||||||
{
|
{
|
||||||
}
|
TextEncoding = textEncoding;
|
||||||
|
TripleDes = TripleDES.Create();
|
||||||
|
TripleDes.Key = TruncateHash(key, TripleDes.KeySize / 8);
|
||||||
|
TripleDes.IV = TruncateHash(string.Empty, TripleDes.BlockSize / 8);
|
||||||
|
}
|
||||||
|
|
||||||
public SimpleStringCrypter(string key, Encoding textEncoding)
|
private byte[] TruncateHash(string key, int length)
|
||||||
{
|
{
|
||||||
TextEncoding = textEncoding;
|
SHA1 sha1CryptoServiceProvider = SHA1.Create();
|
||||||
TripleDes = TripleDES.Create();
|
var bytes = TextEncoding.GetBytes(key);
|
||||||
TripleDes.Key = TruncateHash(key,TripleDes.KeySize / 8);
|
var array = sha1CryptoServiceProvider.ComputeHash(bytes);
|
||||||
TripleDes.IV = TruncateHash(string.Empty, TripleDes.BlockSize / 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] TruncateHash(string key, int length)
|
var output = new byte[length];
|
||||||
{
|
var lowerLength = Math.Min(array.Length, output.Length);
|
||||||
SHA1 sha1CryptoServiceProvider = SHA1.Create();
|
|
||||||
var bytes = TextEncoding.GetBytes(key);
|
|
||||||
var array = sha1CryptoServiceProvider.ComputeHash(bytes);
|
|
||||||
|
|
||||||
var output = new byte[length];
|
for (int i = 0; i < lowerLength; i++)
|
||||||
var lowerLength = Math.Min(array.Length, output.Length);
|
output[i] = array[i];
|
||||||
|
|
||||||
for (int i = 0; i < lowerLength; i++)
|
|
||||||
output[i] = array[i];
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EncryptData(string plaintext)
|
private string EncryptData(string plaintext)
|
||||||
{
|
{
|
||||||
var bytes = TextEncoding.GetBytes(plaintext);
|
var bytes = TextEncoding.GetBytes(plaintext);
|
||||||
using var memoryStream = new MemoryStream();
|
using var memoryStream = new MemoryStream();
|
||||||
using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateEncryptor(), CryptoStreamMode.Write);
|
using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateEncryptor(), CryptoStreamMode.Write);
|
||||||
cryptoStream.Write(bytes, 0, bytes.Length);
|
cryptoStream.Write(bytes, 0, bytes.Length);
|
||||||
cryptoStream.FlushFinalBlock();
|
cryptoStream.FlushFinalBlock();
|
||||||
return Convert.ToBase64String(memoryStream.ToArray());
|
return Convert.ToBase64String(memoryStream.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private string DecryptData(string encryptedtext)
|
private string DecryptData(string encryptedtext)
|
||||||
{
|
{
|
||||||
var array = Convert.FromBase64String(encryptedtext);
|
var array = Convert.FromBase64String(encryptedtext);
|
||||||
using var memoryStream = new MemoryStream();
|
using var memoryStream = new MemoryStream();
|
||||||
using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateDecryptor(), CryptoStreamMode.Write);
|
using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateDecryptor(), CryptoStreamMode.Write);
|
||||||
cryptoStream.Write(array, 0, array.Length);
|
cryptoStream.Write(array, 0, array.Length);
|
||||||
cryptoStream.FlushFinalBlock();
|
cryptoStream.FlushFinalBlock();
|
||||||
return TextEncoding.GetString(memoryStream.ToArray());
|
return TextEncoding.GetString(memoryStream.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Encrypt(string plainValue)
|
public string Encrypt(string plainValue)
|
||||||
{
|
{
|
||||||
return EncryptData(plainValue ?? string.Empty);
|
return EncryptData(plainValue ?? string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Decrypt(string encryptedValue)
|
public string Decrypt(string encryptedValue)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(encryptedValue))
|
if (string.IsNullOrEmpty(encryptedValue))
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
else
|
else
|
||||||
return DecryptData(encryptedValue);
|
return DecryptData(encryptedValue);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,135 +1,130 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Pilz.Cryptography
|
namespace Pilz.Cryptography;
|
||||||
|
|
||||||
|
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
|
||||||
|
public class UniquieID : IUniquieID
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
|
protected static ulong currentSimpleID = 0;
|
||||||
public class UniquieID : IUniquieID
|
|
||||||
|
[JsonProperty(nameof(ID))]
|
||||||
|
protected string _iD;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual bool SimpleMode { get; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual bool GenerateOnGet { get; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual bool HasID => !string.IsNullOrEmpty(_iD);
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual string ID
|
||||||
{
|
{
|
||||||
protected static ulong currentSimpleID = 0;
|
get
|
||||||
|
|
||||||
[JsonProperty(nameof(ID))]
|
|
||||||
protected string _iD;
|
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public virtual bool SimpleMode { get; }
|
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public virtual bool GenerateOnGet { get; }
|
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public virtual bool HasID => !string.IsNullOrEmpty(_iD);
|
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public virtual string ID
|
|
||||||
{
|
{
|
||||||
get
|
if (GenerateOnGet)
|
||||||
{
|
|
||||||
if (GenerateOnGet)
|
|
||||||
GenerateIfNull();
|
|
||||||
return _iD;
|
|
||||||
}
|
|
||||||
internal set
|
|
||||||
=> _iD = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UniquieID() : this(UniquieIDGenerationMode.None)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public UniquieID(UniquieIDGenerationMode mode) : this(mode, false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public UniquieID(UniquieIDGenerationMode mode, bool simpleMode)
|
|
||||||
{
|
|
||||||
SimpleMode = simpleMode;
|
|
||||||
|
|
||||||
if (mode == UniquieIDGenerationMode.GenerateOnInit)
|
|
||||||
GenerateIfNull();
|
GenerateIfNull();
|
||||||
else if (mode == UniquieIDGenerationMode.GenerateOnGet)
|
return _iD;
|
||||||
GenerateOnGet = true;
|
|
||||||
}
|
}
|
||||||
|
internal set
|
||||||
[Obsolete]
|
=> _iD = value;
|
||||||
public UniquieID(bool autoGenerate) : this(autoGenerate ? UniquieIDGenerationMode.GenerateOnInit : UniquieIDGenerationMode.None)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Generate()
|
|
||||||
{
|
|
||||||
if (SimpleMode)
|
|
||||||
ID = GenerateSimple();
|
|
||||||
else
|
|
||||||
ID = GenerateDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual string GenerateSimple()
|
|
||||||
{
|
|
||||||
return new Random().Next().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + currentSimpleID++.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual string GenerateDefault()
|
|
||||||
{
|
|
||||||
return Helpers.GenerateUniquieID<UniquieID>(currentSimpleID++.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void GenerateIfNull()
|
|
||||||
{
|
|
||||||
if (!HasID) Generate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
if (obj is UniquieID iD)
|
|
||||||
{
|
|
||||||
if (ReferenceEquals(obj, iD))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var leftHasID = iD.HasID;
|
|
||||||
var rightHasID = HasID;
|
|
||||||
|
|
||||||
if (!leftHasID && iD.GenerateOnGet)
|
|
||||||
{
|
|
||||||
iD.Generate();
|
|
||||||
leftHasID = iD.HasID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rightHasID && GenerateOnGet)
|
|
||||||
{
|
|
||||||
Generate();
|
|
||||||
rightHasID = HasID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leftHasID && rightHasID)
|
|
||||||
return _iD.Equals(iD._iD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.Equals(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator string(UniquieID id) => id.ID;
|
|
||||||
public static implicit operator UniquieID(string id) => new UniquieID() { ID = id };
|
|
||||||
public static implicit operator UniquieID(int id) => new UniquieID() { ID = Convert.ToString(id) };
|
|
||||||
|
|
||||||
public static bool operator ==(UniquieID left, UniquieID right) => left.ID.Equals(right.ID);
|
|
||||||
public static bool operator !=(UniquieID left, UniquieID right) => !left.ID.Equals(right.ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UniquieID() : this(UniquieIDGenerationMode.None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniquieID(UniquieIDGenerationMode mode) : this(mode, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniquieID(UniquieIDGenerationMode mode, bool simpleMode)
|
||||||
|
{
|
||||||
|
SimpleMode = simpleMode;
|
||||||
|
|
||||||
|
if (mode == UniquieIDGenerationMode.GenerateOnInit)
|
||||||
|
GenerateIfNull();
|
||||||
|
else if (mode == UniquieIDGenerationMode.GenerateOnGet)
|
||||||
|
GenerateOnGet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
|
public UniquieID(bool autoGenerate) : this(autoGenerate ? UniquieIDGenerationMode.GenerateOnInit : UniquieIDGenerationMode.None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Generate()
|
||||||
|
{
|
||||||
|
if (SimpleMode)
|
||||||
|
ID = GenerateSimple();
|
||||||
|
else
|
||||||
|
ID = GenerateDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual string GenerateSimple()
|
||||||
|
{
|
||||||
|
return new Random().Next().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + currentSimpleID++.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual string GenerateDefault()
|
||||||
|
{
|
||||||
|
return Helpers.GenerateUniquieID<UniquieID>(currentSimpleID++.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void GenerateIfNull()
|
||||||
|
{
|
||||||
|
if (!HasID) Generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is UniquieID iD)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(obj, iD))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var leftHasID = iD.HasID;
|
||||||
|
var rightHasID = HasID;
|
||||||
|
|
||||||
|
if (!leftHasID && iD.GenerateOnGet)
|
||||||
|
{
|
||||||
|
iD.Generate();
|
||||||
|
leftHasID = iD.HasID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rightHasID && GenerateOnGet)
|
||||||
|
{
|
||||||
|
Generate();
|
||||||
|
rightHasID = HasID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftHasID && rightHasID)
|
||||||
|
return _iD.Equals(iD._iD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.Equals(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator string(UniquieID id) => id.ID;
|
||||||
|
public static implicit operator UniquieID(string id) => new UniquieID() { ID = id };
|
||||||
|
public static implicit operator UniquieID(int id) => new UniquieID() { ID = Convert.ToString(id) };
|
||||||
|
|
||||||
|
public static bool operator ==(UniquieID left, UniquieID right) => left.ID.Equals(right.ID);
|
||||||
|
public static bool operator !=(UniquieID left, UniquieID right) => !left.ID.Equals(right.ID);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
using System;
|
namespace Pilz.Cryptography;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Pilz.Cryptography
|
public enum UniquieIDGenerationMode
|
||||||
{
|
{
|
||||||
public enum UniquieIDGenerationMode
|
None,
|
||||||
{
|
GenerateOnGet,
|
||||||
None,
|
GenerateOnInit
|
||||||
GenerateOnGet,
|
|
||||||
GenerateOnInit
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
Imports System.Windows.Forms
|
Imports System.Windows.Forms
|
||||||
|
|
||||||
Imports OpenTK
|
|
||||||
Imports OpenTK.Mathematics
|
Imports OpenTK.Mathematics
|
||||||
|
|
||||||
Namespace CameraN
|
Namespace CameraN
|
||||||
|
|||||||
@@ -1,16 +1,32 @@
|
|||||||
Imports System.Drawing
|
Imports System.Drawing
|
||||||
|
|
||||||
|
' Nicht gemergte Änderung aus Projekt "Pilz.Drawing.Drawing3D.OpenGLFactory (net6.0-windows)"
|
||||||
|
' Vor:
|
||||||
|
' Imports System.Windows.Forms
|
||||||
|
' Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
|
||||||
|
' Nach:
|
||||||
|
' Imports System.Windows.Forms
|
||||||
|
'
|
||||||
|
' Imports OpenTK
|
||||||
|
' Imports OpenTK.Graphics.OpenGL
|
||||||
|
' Imports OpenTK.Mathematics
|
||||||
|
' Imports OpenTK.WinForms
|
||||||
|
'
|
||||||
|
' Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
|
||||||
Imports System.Windows.Forms
|
Imports System.Windows.Forms
|
||||||
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
|
|
||||||
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.RenderingN
|
|
||||||
Imports OpenTK
|
|
||||||
Imports OpenTK.Graphics.OpenGL
|
Imports OpenTK.Graphics.OpenGL
|
||||||
Imports Pilz.S3DFileParser
|
|
||||||
Imports Point = System.Drawing.Point
|
|
||||||
Imports Color = System.Drawing.Color
|
|
||||||
Imports OpenTK.Mathematics
|
Imports OpenTK.Mathematics
|
||||||
Imports OpenTK.WinForms
|
Imports OpenTK.WinForms
|
||||||
|
|
||||||
|
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
|
||||||
|
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.RenderingN
|
||||||
|
Imports Pilz.S3DFileParser
|
||||||
Imports Pilz.Win32.Mapped
|
Imports Pilz.Win32.Mapped
|
||||||
|
|
||||||
|
Imports Color = System.Drawing.Color
|
||||||
|
Imports Point = System.Drawing.Point
|
||||||
|
|
||||||
Namespace PreviewN
|
Namespace PreviewN
|
||||||
|
|
||||||
Public Class ModelPreview
|
Public Class ModelPreview
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
Imports System.Drawing
|
|
||||||
Imports OpenTK
|
' Nicht gemergte Änderung aus Projekt "Pilz.Drawing.Drawing3D.OpenGLFactory (net6.0-windows)"
|
||||||
|
' Vor:
|
||||||
|
' Imports System.Drawing
|
||||||
|
' Imports OpenTK
|
||||||
|
' Nach:
|
||||||
|
' Imports System.Drawing
|
||||||
|
'
|
||||||
|
' Imports OpenTK
|
||||||
|
Imports System.Drawing
|
||||||
|
|
||||||
Imports OpenTK.Graphics.OpenGL
|
Imports OpenTK.Graphics.OpenGL
|
||||||
|
|
||||||
Namespace RenderingN
|
Namespace RenderingN
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
Imports System
|
' Nicht gemergte Änderung aus Projekt "Pilz.Drawing.Drawing3D.OpenGLFactory (net6.0-windows)"
|
||||||
Imports OpenTK
|
' Vor:
|
||||||
Imports OpenTK.Graphics.OpenGL
|
' Imports OpenTK
|
||||||
Imports System.Drawing
|
' Imports OpenTK.Graphics.OpenGL
|
||||||
|
' Imports System.Drawing
|
||||||
|
' Nach:
|
||||||
|
' Imports System.Drawing
|
||||||
|
' Imports System.Drawing.Imaging
|
||||||
|
'
|
||||||
|
' Imports OpenTK
|
||||||
|
.Drawing
|
||||||
Imports System.Drawing.Imaging
|
Imports System.Drawing.Imaging
|
||||||
|
|
||||||
|
Imports OpenTK.Graphics.OpenGL
|
||||||
|
|
||||||
Imports Bitmap = System.Drawing.Bitmap
|
Imports Bitmap = System.Drawing.Bitmap
|
||||||
|
|
||||||
Namespace RenderingN
|
Namespace RenderingN
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
Imports System.Drawing
|
Imports OpenTK.Graphics.OpenGL
|
||||||
Imports System.Threading
|
|
||||||
Imports System.Windows.Forms
|
|
||||||
|
|
||||||
Imports OpenTK
|
|
||||||
Imports OpenTK.Graphics.OpenGL
|
|
||||||
Imports OpenTK.Mathematics
|
Imports OpenTK.Mathematics
|
||||||
|
|
||||||
Imports Pilz.S3DFileParser
|
Imports Pilz.S3DFileParser
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
Imports System.Drawing
|
Imports System.Drawing
|
||||||
Imports System.Drawing.Drawing2D
|
|
||||||
|
|
||||||
Public Module HelpfulDrawingFunctions
|
Public Module HelpfulDrawingFunctions
|
||||||
|
|
||||||
|
|||||||
@@ -1,43 +1,42 @@
|
|||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Pilz.Gaming.Minecraft
|
namespace Pilz.Gaming.Minecraft;
|
||||||
|
|
||||||
|
public static class Utils
|
||||||
{
|
{
|
||||||
public static class Utils
|
public static string GetUUID(string value)
|
||||||
{
|
{
|
||||||
public static string GetUUID(string value)
|
using var md5 = MD5.Create();
|
||||||
{
|
|
||||||
using var md5 = MD5.Create();
|
|
||||||
|
|
||||||
//extracted from the java code:
|
//extracted from the java code:
|
||||||
//new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name));
|
//new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name));
|
||||||
byte[] data = md5.ComputeHash(Encoding.ASCII.GetBytes(value));
|
byte[] data = md5.ComputeHash(Encoding.ASCII.GetBytes(value));
|
||||||
//set the version to 3 -> Name based md5 hash
|
//set the version to 3 -> Name based md5 hash
|
||||||
data[6] = Convert.ToByte(data[6] & 0x0f | 0x30);
|
data[6] = Convert.ToByte(data[6] & 0x0f | 0x30);
|
||||||
//IETF variant
|
//IETF variant
|
||||||
data[8] = Convert.ToByte(data[8] & 0x3f | 0x80);
|
data[8] = Convert.ToByte(data[8] & 0x3f | 0x80);
|
||||||
|
|
||||||
//example: 069a79f4-44e9-4726-a5be-fca90e38aaf5
|
//example: 069a79f4-44e9-4726-a5be-fca90e38aaf5
|
||||||
var striped = Convert.ToHexString(data);
|
var striped = Convert.ToHexString(data);
|
||||||
var components = new string[] {
|
var components = new string[] {
|
||||||
striped[..].Remove(8),
|
striped[..].Remove(8),
|
||||||
striped[8..].Remove(4),
|
striped[8..].Remove(4),
|
||||||
striped[12..].Remove(4),
|
striped[12..].Remove(4),
|
||||||
striped[16..].Remove(4),
|
striped[16..].Remove(4),
|
||||||
striped[20..]
|
striped[20..]
|
||||||
};
|
};
|
||||||
|
|
||||||
return string.Join('-', components).ToLower();
|
return string.Join('-', components).ToLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetPlayerUUID(string username, bool offlineMode)
|
public static string GetPlayerUUID(string username, bool offlineMode)
|
||||||
{
|
{
|
||||||
using var md5 = MD5.Create();
|
using var md5 = MD5.Create();
|
||||||
|
|
||||||
if (!offlineMode)
|
if (!offlineMode)
|
||||||
throw new NotSupportedException("Getting player's online UUID via the Mojang API is not supported at this time.");
|
throw new NotSupportedException("Getting player's online UUID via the Mojang API is not supported at this time.");
|
||||||
|
|
||||||
return GetUUID("OfflinePlayer:" + username);
|
return GetUUID("OfflinePlayer:" + username);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,172 +3,169 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Pilz.IO
|
namespace Pilz.IO;
|
||||||
|
|
||||||
|
public class EmbeddedFilesContainer
|
||||||
{
|
{
|
||||||
public class EmbeddedFilesContainer
|
[JsonProperty("CompressedFiles")]
|
||||||
|
private readonly Dictionary<string, byte[]> compressedFiles = new Dictionary<string, byte[]>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the names of all embedded files.
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public IEnumerable<string> AllFileNames
|
||||||
{
|
{
|
||||||
[JsonProperty("CompressedFiles")]
|
get => compressedFiles.Keys;
|
||||||
private readonly Dictionary<string, byte[]> compressedFiles = new Dictionary<string, byte[]>();
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the names of all embedded files.
|
/// Embeds a file to this container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
/// <param name="fileName">The name how it should be called in this container.</param>
|
||||||
public IEnumerable<string> AllFileNames
|
/// <param name="filePath">The file path to the file that should be embedded.</param>
|
||||||
{
|
/// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
|
||||||
get => compressedFiles.Keys;
|
public Task<bool> AddFileAsync(string fileName, string filePath)
|
||||||
}
|
{
|
||||||
|
return Task.Run(() => AddFile(fileName, filePath));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Embeds a file to this container.
|
/// Embeds a file to this container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileName">The name how it should be called in this container.</param>
|
/// <param name="fileName">The name how it should be called in this container.</param>
|
||||||
/// <param name="filePath">The file path to the file that should be embedded.</param>
|
/// <param name="filePath">The file path to the file that should be embedded.</param>
|
||||||
/// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
|
/// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
|
||||||
public Task<bool> AddFileAsync(string fileName, string filePath)
|
public bool AddFile(string fileName, string filePath)
|
||||||
{
|
{
|
||||||
return Task.Run(() => AddFile(fileName, filePath));
|
bool success;
|
||||||
}
|
FileStream fs = null;
|
||||||
|
MemoryStream compressed = null;
|
||||||
/// <summary>
|
|
||||||
/// Embeds a file to this container.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileName">The name how it should be called in this container.</param>
|
|
||||||
/// <param name="filePath">The file path to the file that should be embedded.</param>
|
|
||||||
/// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
|
|
||||||
public bool AddFile(string fileName, string filePath)
|
|
||||||
{
|
|
||||||
bool success;
|
|
||||||
FileStream fs = null;
|
|
||||||
MemoryStream compressed = null;
|
|
||||||
|
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||||
compressed = new MemoryStream();
|
compressed = new MemoryStream();
|
||||||
using (var compressor = new DeflateStream(compressed, CompressionLevel.Optimal, true))
|
using (var compressor = new DeflateStream(compressed, CompressionLevel.Optimal, true))
|
||||||
fs.CopyTo(compressor);
|
fs.CopyTo(compressor);
|
||||||
success = true;
|
success = true;
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
|
||||||
var compressedBytes = compressed.ToArray();
|
|
||||||
if (compressedFiles.ContainsKey(fileName))
|
|
||||||
compressedFiles[fileName] = compressedBytes;
|
|
||||||
else
|
|
||||||
compressedFiles.Add(fileName, compressedBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
compressed?.Close();
|
|
||||||
fs?.Close();
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a file from this container.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileName">The name how the file is called.</param>
|
|
||||||
public void RemoveFile(string fileName)
|
|
||||||
{
|
{
|
||||||
|
var compressedBytes = compressed.ToArray();
|
||||||
if (compressedFiles.ContainsKey(fileName))
|
if (compressedFiles.ContainsKey(fileName))
|
||||||
compressedFiles.Remove(fileName);
|
compressedFiles[fileName] = compressedBytes;
|
||||||
|
else
|
||||||
|
compressedFiles.Add(fileName, compressedBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
compressed?.Close();
|
||||||
/// Checks if the given file exists in this container.
|
fs?.Close();
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileName">The name how the file is called.</param>
|
return success;
|
||||||
/// <returns>Returns if the given file exists in this container.</returns>
|
}
|
||||||
public bool HasFile(string fileName)
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a file from this container.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name how the file is called.</param>
|
||||||
|
public void RemoveFile(string fileName)
|
||||||
|
{
|
||||||
|
if (compressedFiles.ContainsKey(fileName))
|
||||||
|
compressedFiles.Remove(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the given file exists in this container.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name how the file is called.</param>
|
||||||
|
/// <returns>Returns if the given file exists in this container.</returns>
|
||||||
|
public bool HasFile(string fileName)
|
||||||
|
{
|
||||||
|
return compressedFiles.ContainsKey(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a file from this container as stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name how the file is called.</param>
|
||||||
|
/// <returns>Returns a stream of the file with the given name.</returns>
|
||||||
|
public Task<Stream> GetStreamAsync(string fileName)
|
||||||
|
{
|
||||||
|
return Task.Run(() => GetStream(fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a file from this container as stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name how the file is called.</param>
|
||||||
|
/// <returns>Returns a stream of the file with the given name.</returns>
|
||||||
|
public Stream GetStream(string fileName)
|
||||||
|
{
|
||||||
|
Stream decompressed = null;
|
||||||
|
|
||||||
|
if (compressedFiles.ContainsKey(fileName))
|
||||||
{
|
{
|
||||||
return compressedFiles.ContainsKey(fileName);
|
decompressed = new MemoryStream();
|
||||||
|
DecompressToStream(decompressed, compressedFiles[fileName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
return decompressed;
|
||||||
/// Gets a file from this container as stream.
|
}
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileName">The name how the file is called.</param>
|
/// <summary>
|
||||||
/// <returns>Returns a stream of the file with the given name.</returns>
|
/// Saves a given file to the users temp directory.
|
||||||
public Task<Stream> GetStreamAsync(string fileName)
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name how the file is called.</param>
|
||||||
|
/// <returns>Returns the file path to the temp file.</returns>
|
||||||
|
public Task<string> GetLocalFilePathAsync(string fileName)
|
||||||
|
{
|
||||||
|
return Task.Run(() => GetLocalFilePath(fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves a given file to the users temp directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The name how the file is called.</param>
|
||||||
|
/// <returns>Returns the file path to the temp file.</returns>
|
||||||
|
public string GetLocalFilePath(string fileName)
|
||||||
|
{
|
||||||
|
string filePath = string.Empty;
|
||||||
|
|
||||||
|
if (compressedFiles.ContainsKey(fileName))
|
||||||
{
|
{
|
||||||
return Task.Run(() => GetStream(fileName));
|
filePath = Path.GetTempFileName();
|
||||||
|
|
||||||
|
if (Path.HasExtension(fileName))
|
||||||
|
filePath = Path.ChangeExtension(filePath, Path.GetExtension(fileName));
|
||||||
|
|
||||||
|
var decompressed = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
|
||||||
|
DecompressToStream(decompressed, compressedFiles[fileName]);
|
||||||
|
decompressed.Flush();
|
||||||
|
decompressed.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
return filePath;
|
||||||
/// Gets a file from this container as stream.
|
}
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileName">The name how the file is called.</param>
|
|
||||||
/// <returns>Returns a stream of the file with the given name.</returns>
|
|
||||||
public Stream GetStream(string fileName)
|
|
||||||
{
|
|
||||||
Stream decompressed = null;
|
|
||||||
|
|
||||||
if (compressedFiles.ContainsKey(fileName))
|
private void DecompressToStream(Stream decompressed, byte[] compressedData)
|
||||||
{
|
{
|
||||||
decompressed = new MemoryStream();
|
var compressed = new MemoryStream(compressedData);
|
||||||
DecompressToStream(decompressed, compressedFiles[fileName]);
|
var decompressor = new DeflateStream(compressed, CompressionMode.Decompress, true);
|
||||||
}
|
decompressor.CopyTo(decompressed);
|
||||||
|
decompressor.Close();
|
||||||
return decompressed;
|
compressed.Close();
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves a given file to the users temp directory.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileName">The name how the file is called.</param>
|
|
||||||
/// <returns>Returns the file path to the temp file.</returns>
|
|
||||||
public Task<string> GetLocalFilePathAsync(string fileName)
|
|
||||||
{
|
|
||||||
return Task.Run(() => GetLocalFilePath(fileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves a given file to the users temp directory.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileName">The name how the file is called.</param>
|
|
||||||
/// <returns>Returns the file path to the temp file.</returns>
|
|
||||||
public string GetLocalFilePath(string fileName)
|
|
||||||
{
|
|
||||||
string filePath = string.Empty;
|
|
||||||
|
|
||||||
if (compressedFiles.ContainsKey(fileName))
|
|
||||||
{
|
|
||||||
filePath = Path.GetTempFileName();
|
|
||||||
|
|
||||||
if (Path.HasExtension(fileName))
|
|
||||||
filePath = Path.ChangeExtension(filePath, Path.GetExtension(fileName));
|
|
||||||
|
|
||||||
var decompressed = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
|
|
||||||
DecompressToStream(decompressed, compressedFiles[fileName]);
|
|
||||||
decompressed.Flush();
|
|
||||||
decompressed.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DecompressToStream(Stream decompressed, byte[] compressedData)
|
|
||||||
{
|
|
||||||
var compressed = new MemoryStream(compressedData);
|
|
||||||
var decompressor = new DeflateStream(compressed, CompressionMode.Decompress, true);
|
|
||||||
decompressor.CopyTo(decompressed);
|
|
||||||
decompressor.Close();
|
|
||||||
compressed.Close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Pilz.IO
|
namespace Pilz.IO;
|
||||||
{
|
|
||||||
public class DataEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public readonly byte[] Data;
|
|
||||||
|
|
||||||
public DataEventArgs(byte[] bytes) : base()
|
public class DataEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
Data = bytes;
|
public readonly byte[] Data;
|
||||||
}
|
|
||||||
|
public DataEventArgs(byte[] bytes) : base()
|
||||||
|
{
|
||||||
|
Data = bytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,26 +1,23 @@
|
|||||||
using Pilz.Runtime;
|
using Pilz.Runtime;
|
||||||
using Pilz.Win32.Native;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Pilz.IO
|
namespace Pilz.IO;
|
||||||
{
|
|
||||||
public static class Extensions
|
|
||||||
{
|
|
||||||
static readonly int MAX_PATH = 255;
|
|
||||||
|
|
||||||
public static string GetExecutablePath(bool checkRealOS = false)
|
public static class Extensions
|
||||||
|
{
|
||||||
|
static readonly int MAX_PATH = 255;
|
||||||
|
|
||||||
|
public static string GetExecutablePath(bool checkRealOS = false)
|
||||||
|
{
|
||||||
|
if (RuntimeInformationsEx.IsOSPlatform(OSType.Windows, checkRealOS))
|
||||||
{
|
{
|
||||||
if (RuntimeInformationsEx.IsOSPlatform(OSType.Windows, checkRealOS))
|
var sb = new StringBuilder(MAX_PATH);
|
||||||
{
|
Kernel32.GetModuleFileName(IntPtr.Zero, sb, MAX_PATH);
|
||||||
var sb = new StringBuilder(MAX_PATH);
|
return sb.ToString();
|
||||||
Kernel32.GetModuleFileName(IntPtr.Zero, sb, MAX_PATH);
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return Process.GetCurrentProcess().MainModule.FileName;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return Process.GetCurrentProcess().MainModule.FileName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,118 +1,117 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Pilz.IO
|
namespace Pilz.IO;
|
||||||
|
|
||||||
|
public partial class FileLocker : IDisposable
|
||||||
{
|
{
|
||||||
public partial class FileLocker : IDisposable
|
private FileStream fsLock = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the file path to the file that should be locked.
|
||||||
|
/// </summary>
|
||||||
|
public string FilePath { get; private set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the file path to the lock file that is used to identify the file lock.
|
||||||
|
/// </summary>
|
||||||
|
public string LockFile { get; private set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Defines if the file is locked privatly by this instance.
|
||||||
|
/// </summary>
|
||||||
|
public bool LockedPrivate { get; private set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines if the file is locked by an other instance/program/user.
|
||||||
|
/// </summary>
|
||||||
|
public bool LockedExternal
|
||||||
{
|
{
|
||||||
private FileStream fsLock = null;
|
get
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines the file path to the file that should be locked.
|
|
||||||
/// </summary>
|
|
||||||
public string FilePath { get; private set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Defines the file path to the lock file that is used to identify the file lock.
|
|
||||||
/// </summary>
|
|
||||||
public string LockFile { get; private set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Defines if the file is locked privatly by this instance.
|
|
||||||
/// </summary>
|
|
||||||
public bool LockedPrivate { get; private set; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines if the file is locked by an other instance/program/user.
|
|
||||||
/// </summary>
|
|
||||||
public bool LockedExternal
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (LockedPrivate)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string lockFile = FilePath + ".lock";
|
|
||||||
bool isLocked = false;
|
|
||||||
|
|
||||||
if (File.Exists(lockFile))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var fs = new FileStream(lockFile, FileMode.Open, FileAccess.Read);
|
|
||||||
fs.Close();
|
|
||||||
}
|
|
||||||
catch (IOException)
|
|
||||||
{
|
|
||||||
isLocked = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isLocked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generate a new instance of <see cref="FileLocker"/> and locks the given file automatically.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filePath">The file path to the file that should be locked.</param>
|
|
||||||
public FileLocker(string filePath) : this(filePath, true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generate a new instance of <see cref="FileLocker"/>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filePath">The file path to the file that should be locked.</param>
|
|
||||||
/// <param name="autoLock">Defines if the file should be locked automatically right after creating this instance.</param>
|
|
||||||
public FileLocker(string filePath, bool autoLock)
|
|
||||||
{
|
|
||||||
FilePath = filePath;
|
|
||||||
LockFile = filePath + ".lock";
|
|
||||||
if (autoLock) Lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Locks the file, if not already locked privatly.
|
|
||||||
/// </summary>
|
|
||||||
public void Lock()
|
|
||||||
{
|
|
||||||
if (!LockedPrivate)
|
|
||||||
{
|
|
||||||
fsLock = new FileStream(LockFile, FileMode.Create, FileAccess.ReadWrite);
|
|
||||||
LockedPrivate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unlocks the file, if locked privatly.
|
|
||||||
/// </summary>
|
|
||||||
public void Unlock()
|
|
||||||
{
|
{
|
||||||
if (LockedPrivate)
|
if (LockedPrivate)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
fsLock.Close();
|
string lockFile = FilePath + ".lock";
|
||||||
fsLock.Dispose();
|
bool isLocked = false;
|
||||||
fsLock = null;
|
|
||||||
File.Delete(LockFile);
|
if (File.Exists(lockFile))
|
||||||
LockedPrivate = false;
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var fs = new FileStream(lockFile, FileMode.Open, FileAccess.Read);
|
||||||
|
fs.Close();
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
isLocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isLocked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IDisposable
|
|
||||||
private bool disposedValue;
|
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (!disposedValue)
|
|
||||||
Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
disposedValue = true;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate a new instance of <see cref="FileLocker"/> and locks the given file automatically.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath">The file path to the file that should be locked.</param>
|
||||||
|
public FileLocker(string filePath) : this(filePath, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate a new instance of <see cref="FileLocker"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath">The file path to the file that should be locked.</param>
|
||||||
|
/// <param name="autoLock">Defines if the file should be locked automatically right after creating this instance.</param>
|
||||||
|
public FileLocker(string filePath, bool autoLock)
|
||||||
|
{
|
||||||
|
FilePath = filePath;
|
||||||
|
LockFile = filePath + ".lock";
|
||||||
|
if (autoLock) Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Locks the file, if not already locked privatly.
|
||||||
|
/// </summary>
|
||||||
|
public void Lock()
|
||||||
|
{
|
||||||
|
if (!LockedPrivate)
|
||||||
|
{
|
||||||
|
fsLock = new FileStream(LockFile, FileMode.Create, FileAccess.ReadWrite);
|
||||||
|
LockedPrivate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unlocks the file, if locked privatly.
|
||||||
|
/// </summary>
|
||||||
|
public void Unlock()
|
||||||
|
{
|
||||||
|
if (LockedPrivate)
|
||||||
|
{
|
||||||
|
fsLock.Close();
|
||||||
|
fsLock.Dispose();
|
||||||
|
fsLock = null;
|
||||||
|
File.Delete(LockFile);
|
||||||
|
LockedPrivate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IDisposable
|
||||||
|
private bool disposedValue;
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposedValue)
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
disposedValue = true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -2,66 +2,65 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Pilz.IO
|
namespace Pilz.IO;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// stellt den Erben "Server" und "Client" 2 verschiedene
|
||||||
|
/// Message-Events zur Verfügung, und ein Event-Raisendes Dispose
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ManagedPipe : IDisposable
|
||||||
{
|
{
|
||||||
|
public delegate void EventHandlerWithOneArgument<T0>(T0 Sender);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// stellt den Erben "Server" und "Client" 2 verschiedene
|
/// Zur Ausgabe chat-verwaltungstechnischer Status-Informationen
|
||||||
/// Message-Events zur Verfügung, und ein Event-Raisendes Dispose
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ManagedPipe : IDisposable
|
public event EventHandler<DataEventArgs> StatusMessage;
|
||||||
|
/// <summary>Zur Ausgabe von Chat-Messages</summary>
|
||||||
|
public event EventHandler<DataEventArgs> RetriveData;
|
||||||
|
public event EventHandlerWithOneArgument<ManagedPipe> Disposed;
|
||||||
|
|
||||||
|
private bool _IsDisposed = false;
|
||||||
|
|
||||||
|
protected abstract void Dispose(bool disposing);
|
||||||
|
public abstract void Send(byte[] bytes);
|
||||||
|
public abstract Task SendAsnyc(byte[] bytes);
|
||||||
|
|
||||||
|
protected void OnStatusMessage(DataEventArgs e)
|
||||||
{
|
{
|
||||||
public delegate void EventHandlerWithOneArgument<T0>(T0 Sender);
|
StatusMessage?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
protected void OnRetriveData(DataEventArgs e)
|
||||||
/// Zur Ausgabe chat-verwaltungstechnischer Status-Informationen
|
{
|
||||||
/// </summary>
|
RetriveData?.Invoke(this, e);
|
||||||
public event EventHandler<DataEventArgs> StatusMessage;
|
}
|
||||||
/// <summary>Zur Ausgabe von Chat-Messages</summary>
|
|
||||||
public event EventHandler<DataEventArgs> RetriveData;
|
|
||||||
public event EventHandlerWithOneArgument<ManagedPipe> Disposed;
|
|
||||||
|
|
||||||
private bool _IsDisposed = false;
|
public void RemoveFrom<T>(ICollection<T> Coll) where T : ManagedPipe
|
||||||
|
{
|
||||||
|
Coll.Remove((T)this);
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract void Dispose(bool disposing);
|
public bool IsDisposed
|
||||||
public abstract void Send(byte[] bytes);
|
{
|
||||||
public abstract Task SendAsnyc(byte[] bytes);
|
get
|
||||||
|
|
||||||
protected void OnStatusMessage(DataEventArgs e)
|
|
||||||
{
|
{
|
||||||
StatusMessage?.Invoke(this, e);
|
return _IsDisposed;
|
||||||
}
|
|
||||||
|
|
||||||
protected void OnRetriveData(DataEventArgs e)
|
|
||||||
{
|
|
||||||
RetriveData?.Invoke(this, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveFrom<T>(ICollection<T> Coll) where T : ManagedPipe
|
|
||||||
{
|
|
||||||
Coll.Remove((T)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsDisposed
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _IsDisposed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddTo<T>(ICollection<T> Coll) where T : ManagedPipe
|
|
||||||
{
|
|
||||||
Coll.Add((T)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_IsDisposed)
|
|
||||||
return;
|
|
||||||
_IsDisposed = true;
|
|
||||||
Dispose(true); // rufe die erzwungenen Überschreibungen von Sub Dispose(Boolean)
|
|
||||||
Disposed?.Invoke(this);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddTo<T>(ICollection<T> Coll) where T : ManagedPipe
|
||||||
|
{
|
||||||
|
Coll.Add((T)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_IsDisposed)
|
||||||
|
return;
|
||||||
|
_IsDisposed = true;
|
||||||
|
Dispose(true); // rufe die erzwungenen Überschreibungen von Sub Dispose(Boolean)
|
||||||
|
Disposed?.Invoke(this);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,90 +1,89 @@
|
|||||||
using System;
|
using global::System.IO.Pipes;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using global::System.IO.Pipes;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Pilz.IO
|
namespace Pilz.IO;
|
||||||
|
|
||||||
|
public class ManagedPipeClient : ManagedPipe
|
||||||
{
|
{
|
||||||
public class ManagedPipeClient : ManagedPipe
|
private PipeStream pipeStream;
|
||||||
|
private byte[] _Buf = new byte[1024];
|
||||||
|
|
||||||
|
public ManagedPipeClient(string pipeName) : this(pipeName, ".")
|
||||||
{
|
{
|
||||||
private PipeStream pipeStream;
|
}
|
||||||
private byte[] _Buf = new byte[1024];
|
|
||||||
|
|
||||||
public ManagedPipeClient(string pipeName) : this(pipeName, ".")
|
public ManagedPipeClient(string pipeName, string serverName) : this(pipeName, serverName, -1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManagedPipeClient(string pipeName, int connectionTimeout) : this(pipeName, ".", connectionTimeout)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManagedPipeClient(string pipeName, string serverName, int connectionTimeout)
|
||||||
|
{
|
||||||
|
var clnt = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
|
||||||
|
clnt.Connect(connectionTimeout);
|
||||||
|
if (!clnt.IsConnected)
|
||||||
{
|
{
|
||||||
|
throw new TimeoutException("Connection timeout!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManagedPipeClient(string pipeName, string serverName) : this(pipeName, serverName, -1)
|
SetPipe(clnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManagedPipeClient(PipeStream pipe)
|
||||||
|
{
|
||||||
|
SetPipe(pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetPipe(PipeStream pipe)
|
||||||
|
{
|
||||||
|
pipeStream = pipe;
|
||||||
|
pipeStream.BeginRead(_Buf, 0, _Buf.Length, EndRead, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EndRead(IAsyncResult ar)
|
||||||
|
{
|
||||||
|
if (IsDisposed)
|
||||||
|
return;
|
||||||
|
int bytesCount = pipeStream.EndRead(ar);
|
||||||
|
if (bytesCount == 0) // leere Datenübermittlung signalisiert Verbindungsabbruch
|
||||||
{
|
{
|
||||||
|
Dispose();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManagedPipeClient(string pipeName, int connectionTimeout) : this(pipeName, ".", connectionTimeout)
|
var list = new List<byte>();
|
||||||
|
for (int i = 0, loopTo = bytesCount - 1; i <= loopTo; i++)
|
||||||
|
list.Add(_Buf[i]);
|
||||||
|
while (bytesCount == _Buf.Length)
|
||||||
{
|
{
|
||||||
}
|
bytesCount = pipeStream.Read(_Buf, 0, _Buf.Length);
|
||||||
|
for (int i = 0, loopTo1 = bytesCount - 1; i <= loopTo1; i++)
|
||||||
public ManagedPipeClient(string pipeName, string serverName, int connectionTimeout)
|
|
||||||
{
|
|
||||||
var clnt = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
|
|
||||||
clnt.Connect(connectionTimeout);
|
|
||||||
if (!clnt.IsConnected)
|
|
||||||
{
|
|
||||||
throw new TimeoutException("Connection timeout!");
|
|
||||||
}
|
|
||||||
|
|
||||||
SetPipe(clnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ManagedPipeClient(PipeStream pipe)
|
|
||||||
{
|
|
||||||
SetPipe(pipe);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetPipe(PipeStream pipe)
|
|
||||||
{
|
|
||||||
pipeStream = pipe;
|
|
||||||
pipeStream.BeginRead(_Buf, 0, _Buf.Length, EndRead, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EndRead(IAsyncResult ar)
|
|
||||||
{
|
|
||||||
if (IsDisposed)
|
|
||||||
return;
|
|
||||||
int bytesCount = pipeStream.EndRead(ar);
|
|
||||||
if (bytesCount == 0) // leere Datenübermittlung signalisiert Verbindungsabbruch
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = new List<byte>();
|
|
||||||
for (int i = 0, loopTo = bytesCount - 1; i <= loopTo; i++)
|
|
||||||
list.Add(_Buf[i]);
|
list.Add(_Buf[i]);
|
||||||
while (bytesCount == _Buf.Length)
|
|
||||||
{
|
|
||||||
bytesCount = pipeStream.Read(_Buf, 0, _Buf.Length);
|
|
||||||
for (int i = 0, loopTo1 = bytesCount - 1; i <= loopTo1; i++)
|
|
||||||
list.Add(_Buf[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var deargs = new DataEventArgs(list.ToArray());
|
|
||||||
OnRetriveData(deargs);
|
|
||||||
|
|
||||||
pipeStream.BeginRead(_Buf, 0, _Buf.Length, EndRead, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SendAsnyc(byte[] bytes)
|
var deargs = new DataEventArgs(list.ToArray());
|
||||||
{
|
OnRetriveData(deargs);
|
||||||
return Task.Run(() => Send(bytes));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Send(byte[] data)
|
pipeStream.BeginRead(_Buf, 0, _Buf.Length, EndRead, null);
|
||||||
{
|
}
|
||||||
pipeStream.Write(data, 0, data.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
public override Task SendAsnyc(byte[] bytes)
|
||||||
{
|
{
|
||||||
pipeStream.Dispose();
|
return Task.Run(() => Send(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Send(byte[] data)
|
||||||
|
{
|
||||||
|
pipeStream.Write(data, 0, data.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
pipeStream.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,108 +1,107 @@
|
|||||||
using System;
|
using global::System.IO.Pipes;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using global::System.IO.Pipes;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Pilz.IO
|
namespace Pilz.IO;
|
||||||
|
|
||||||
|
public class ManagedPipeServer : ManagedPipe
|
||||||
{
|
{
|
||||||
public class ManagedPipeServer : ManagedPipe
|
|
||||||
|
// Pro Verbindung (Anfrage) wird ein Client-Objekt generiert, das den Datenaustausch dieser Verbindung abwickelt
|
||||||
|
public List<ManagedPipeClient> Clients { get; private set; } = new List<ManagedPipeClient>();
|
||||||
|
|
||||||
|
private readonly string pipeName = "";
|
||||||
|
private readonly int maxNumbersOfServerInstances;
|
||||||
|
private int numberOfStartedServerInstances = 0;
|
||||||
|
|
||||||
|
public ManagedPipeServer(string pipeName) : this(pipeName, 1)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// Pro Verbindung (Anfrage) wird ein Client-Objekt generiert, das den Datenaustausch dieser Verbindung abwickelt
|
public ManagedPipeServer(string pipeName, int maxNumbersOfServerInstances)
|
||||||
public List<ManagedPipeClient> Clients { get; private set; } = new List<ManagedPipeClient>();
|
{
|
||||||
|
this.pipeName = pipeName;
|
||||||
|
this.maxNumbersOfServerInstances = maxNumbersOfServerInstances;
|
||||||
|
CreateWaitingStream();
|
||||||
|
}
|
||||||
|
|
||||||
private readonly string pipeName = "";
|
private void CreateWaitingStream()
|
||||||
private readonly int maxNumbersOfServerInstances;
|
{
|
||||||
private int numberOfStartedServerInstances = 0;
|
if (numberOfStartedServerInstances < maxNumbersOfServerInstances)
|
||||||
|
|
||||||
public ManagedPipeServer(string pipeName) : this(pipeName, 1)
|
|
||||||
{
|
{
|
||||||
}
|
var strm = new NamedPipeServerStream(pipeName, PipeDirection.InOut, maxNumbersOfServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
||||||
|
numberOfStartedServerInstances += 1;
|
||||||
public ManagedPipeServer(string pipeName, int maxNumbersOfServerInstances)
|
strm.BeginWaitForConnection(EndAccept, strm);
|
||||||
{
|
|
||||||
this.pipeName = pipeName;
|
|
||||||
this.maxNumbersOfServerInstances = maxNumbersOfServerInstances;
|
|
||||||
CreateWaitingStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateWaitingStream()
|
|
||||||
{
|
|
||||||
if (numberOfStartedServerInstances < maxNumbersOfServerInstances)
|
|
||||||
{
|
|
||||||
var strm = new NamedPipeServerStream(pipeName, PipeDirection.InOut, maxNumbersOfServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
|
||||||
numberOfStartedServerInstances += 1;
|
|
||||||
strm.BeginWaitForConnection(EndAccept, strm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EndAccept(IAsyncResult ar)
|
|
||||||
{
|
|
||||||
NamedPipeServerStream strm = (NamedPipeServerStream)ar.AsyncState;
|
|
||||||
strm.EndWaitForConnection(ar);
|
|
||||||
if (IsDisposed)
|
|
||||||
{
|
|
||||||
strm.Dispose();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
var withBlock = new ManagedPipeClient(strm);
|
|
||||||
withBlock.RetriveData += Client_RetriveData;
|
|
||||||
withBlock.StatusMessage += Client_StatusMessage;
|
|
||||||
withBlock.Disposed += Client_Disposed;
|
|
||||||
withBlock.AddTo(Clients);
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateWaitingStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO ERROR: Skipped RegionDirectiveTrivia */
|
|
||||||
private void Client_Disposed(ManagedPipe Sender)
|
|
||||||
{
|
|
||||||
// den Client für die beendete Verbindung entfernen
|
|
||||||
Sender.RemoveFrom(Clients);
|
|
||||||
numberOfStartedServerInstances -= 1;
|
|
||||||
CreateWaitingStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Client_RetriveData(object sender, DataEventArgs e)
|
|
||||||
{
|
|
||||||
// einkommende ChatMessages anzeigen, und an alle versenden
|
|
||||||
OnRetriveData(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Client_StatusMessage(object sender, DataEventArgs e)
|
|
||||||
{
|
|
||||||
// einkommende StatusMessages durchreichen (zur Anzeige)
|
|
||||||
OnStatusMessage(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO ERROR: Skipped EndRegionDirectiveTrivia */
|
|
||||||
public override Task SendAsnyc(byte[] bytes)
|
|
||||||
{
|
|
||||||
return Task.Run(() => Send(bytes));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Send(byte[] data)
|
|
||||||
{
|
|
||||||
foreach (ManagedPipeClient client in Clients) // an alle versenden
|
|
||||||
client.Send(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (numberOfStartedServerInstances < maxNumbersOfServerInstances)
|
|
||||||
{
|
|
||||||
using (var clnt = new NamedPipeClientStream(pipeName))
|
|
||||||
{
|
|
||||||
// Herstellen einer Dummi-Verbindung, damit der ServerStream aus dem Wartezustand herauskommt.
|
|
||||||
clnt.Connect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = Clients.Count - 1; i >= 0; i -= 1)
|
|
||||||
Clients[i].Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void EndAccept(IAsyncResult ar)
|
||||||
|
{
|
||||||
|
NamedPipeServerStream strm = (NamedPipeServerStream)ar.AsyncState;
|
||||||
|
strm.EndWaitForConnection(ar);
|
||||||
|
if (IsDisposed)
|
||||||
|
{
|
||||||
|
strm.Dispose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var withBlock = new ManagedPipeClient(strm);
|
||||||
|
withBlock.RetriveData += Client_RetriveData;
|
||||||
|
withBlock.StatusMessage += Client_StatusMessage;
|
||||||
|
withBlock.Disposed += Client_Disposed;
|
||||||
|
withBlock.AddTo(Clients);
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateWaitingStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO ERROR: Skipped RegionDirectiveTrivia */
|
||||||
|
private void Client_Disposed(ManagedPipe Sender)
|
||||||
|
{
|
||||||
|
// den Client für die beendete Verbindung entfernen
|
||||||
|
Sender.RemoveFrom(Clients);
|
||||||
|
numberOfStartedServerInstances -= 1;
|
||||||
|
CreateWaitingStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Client_RetriveData(object sender, DataEventArgs e)
|
||||||
|
{
|
||||||
|
// einkommende ChatMessages anzeigen, und an alle versenden
|
||||||
|
OnRetriveData(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Client_StatusMessage(object sender, DataEventArgs e)
|
||||||
|
{
|
||||||
|
// einkommende StatusMessages durchreichen (zur Anzeige)
|
||||||
|
OnStatusMessage(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO ERROR: Skipped EndRegionDirectiveTrivia */
|
||||||
|
public override Task SendAsnyc(byte[] bytes)
|
||||||
|
{
|
||||||
|
return Task.Run(() => Send(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Send(byte[] data)
|
||||||
|
{
|
||||||
|
foreach (ManagedPipeClient client in Clients) // an alle versenden
|
||||||
|
client.Send(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (numberOfStartedServerInstances < maxNumbersOfServerInstances)
|
||||||
|
{
|
||||||
|
using (var clnt = new NamedPipeClientStream(pipeName))
|
||||||
|
{
|
||||||
|
// Herstellen einer Dummi-Verbindung, damit der ServerStream aus dem Wartezustand herauskommt.
|
||||||
|
clnt.Connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = Clients.Count - 1; i >= 0; i -= 1)
|
||||||
|
Clients[i].Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using global::System;
|
using global::System;
|
||||||
using global::System.Reflection;
|
|
||||||
using global::System.Runtime.InteropServices;
|
using global::System.Runtime.InteropServices;
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
|||||||
@@ -6,180 +6,179 @@ using System.Runtime.CompilerServices;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
|
||||||
namespace Pilz.LicenseHelper
|
namespace Pilz.LicenseHelper;
|
||||||
|
|
||||||
|
public static class AsposeModifyInMemory
|
||||||
{
|
{
|
||||||
public static class AsposeModifyInMemory
|
private static string AsposeList = "Aspose.3D.dll, Aspose.BarCode.dll, Aspose.BarCode.Compact.dll, Aspose.BarCode.WPF.dll, Aspose.Cells.GridDesktop.dll, Aspose.Cells.GridWeb.dll, Aspose.CAD.dll, Aspose.Cells.dll, Aspose.Diagram.dll, Aspose.Email.dll, Aspose.Imaging.dll, Aspose.Note.dll, Aspose.OCR.dll, Aspose.Pdf.dll, Aspose.Slides.dll, Aspose.Tasks.dll, Aspose.Words.dll";
|
||||||
|
|
||||||
|
public static void ActivateMemoryPatching()
|
||||||
{
|
{
|
||||||
private static string AsposeList = "Aspose.3D.dll, Aspose.BarCode.dll, Aspose.BarCode.Compact.dll, Aspose.BarCode.WPF.dll, Aspose.Cells.GridDesktop.dll, Aspose.Cells.GridWeb.dll, Aspose.CAD.dll, Aspose.Cells.dll, Aspose.Diagram.dll, Aspose.Email.dll, Aspose.Imaging.dll, Aspose.Note.dll, Aspose.OCR.dll, Aspose.Pdf.dll, Aspose.Slides.dll, Aspose.Tasks.dll, Aspose.Words.dll";
|
Assembly[] arr = AppDomain.CurrentDomain.GetAssemblies();
|
||||||
|
foreach (Assembly assembly in arr)
|
||||||
public static void ActivateMemoryPatching()
|
|
||||||
{
|
{
|
||||||
Assembly[] arr = AppDomain.CurrentDomain.GetAssemblies();
|
if (AsposeList.IndexOf(assembly.FullName.Split(',')[0] + ".dll") != -1)
|
||||||
foreach (Assembly assembly in arr)
|
ActivateForAssembly(assembly);
|
||||||
{
|
}
|
||||||
if (AsposeList.IndexOf(assembly.FullName.Split(',')[0] + ".dll") != -1)
|
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(ActivateOnLoad);
|
||||||
ActivateForAssembly(assembly);
|
}
|
||||||
}
|
|
||||||
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(ActivateOnLoad);
|
private static void ActivateOnLoad(object sender, AssemblyLoadEventArgs e)
|
||||||
|
{
|
||||||
|
if (AsposeList.IndexOf(e.LoadedAssembly.FullName.Split(',')[0] + ".dll") != -1)
|
||||||
|
ActivateForAssembly(e.LoadedAssembly);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ActivateForAssembly(Assembly assembly)
|
||||||
|
{
|
||||||
|
MethodInfo miLicensed1 = typeof(AsposeModifyInMemory).GetMethod("InvokeMe1", BindingFlags.NonPublic | BindingFlags.Static);
|
||||||
|
MethodInfo miLicensed2 = typeof(AsposeModifyInMemory).GetMethod("InvokeMe2", BindingFlags.NonPublic | BindingFlags.Static);
|
||||||
|
MethodInfo miEvaluation = null;
|
||||||
|
|
||||||
|
Dictionary<string, MethodInfo> miDict = new Dictionary<string, MethodInfo>()
|
||||||
|
{
|
||||||
|
{"System.DateTime" , miLicensed1},
|
||||||
|
{"System.Xml.XmlElement", miLicensed2}
|
||||||
|
};
|
||||||
|
|
||||||
|
Type[] arrType = null;
|
||||||
|
bool isFound = false;
|
||||||
|
int nCount = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
arrType = assembly.GetTypes();
|
||||||
|
}
|
||||||
|
catch (ReflectionTypeLoadException err)
|
||||||
|
{
|
||||||
|
arrType = err.Types;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ActivateOnLoad(object sender, AssemblyLoadEventArgs e)
|
|
||||||
|
foreach (Type type in arrType)
|
||||||
{
|
{
|
||||||
if (AsposeList.IndexOf(e.LoadedAssembly.FullName.Split(',')[0] + ".dll") != -1)
|
if (isFound) break;
|
||||||
ActivateForAssembly(e.LoadedAssembly);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ActivateForAssembly(Assembly assembly)
|
if (type == null) continue;
|
||||||
{
|
|
||||||
MethodInfo miLicensed1 = typeof(AsposeModifyInMemory).GetMethod("InvokeMe1", BindingFlags.NonPublic | BindingFlags.Static);
|
|
||||||
MethodInfo miLicensed2 = typeof(AsposeModifyInMemory).GetMethod("InvokeMe2", BindingFlags.NonPublic | BindingFlags.Static);
|
|
||||||
MethodInfo miEvaluation = null;
|
|
||||||
|
|
||||||
Dictionary<string, MethodInfo> miDict = new Dictionary<string, MethodInfo>()
|
MethodInfo[] arrMInfo = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Static);
|
||||||
{
|
|
||||||
{"System.DateTime" , miLicensed1},
|
|
||||||
{"System.Xml.XmlElement", miLicensed2}
|
|
||||||
};
|
|
||||||
|
|
||||||
Type[] arrType = null;
|
foreach (MethodInfo info in arrMInfo)
|
||||||
bool isFound = false;
|
|
||||||
int nCount = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
arrType = assembly.GetTypes();
|
|
||||||
}
|
|
||||||
catch (ReflectionTypeLoadException err)
|
|
||||||
{
|
|
||||||
arrType = err.Types;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
foreach (Type type in arrType)
|
|
||||||
{
|
{
|
||||||
if (isFound) break;
|
if (isFound) break;
|
||||||
|
|
||||||
if (type == null) continue;
|
try
|
||||||
|
|
||||||
MethodInfo[] arrMInfo = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Static);
|
|
||||||
|
|
||||||
foreach (MethodInfo info in arrMInfo)
|
|
||||||
{
|
{
|
||||||
if (isFound) break;
|
string strMethod = info.ToString();
|
||||||
|
if ((strMethod.IndexOf("(System.Xml.XmlElement, System.String)") > 0) && (miDict.ContainsKey(info.ReturnType.ToString())))
|
||||||
try
|
|
||||||
{
|
{
|
||||||
string strMethod = info.ToString();
|
miEvaluation = info;
|
||||||
if ((strMethod.IndexOf("(System.Xml.XmlElement, System.String)") > 0) && (miDict.ContainsKey(info.ReturnType.ToString())))
|
MemoryPatching(miEvaluation, miDict[miEvaluation.ReturnType.ToString()]);
|
||||||
{
|
nCount++;
|
||||||
miEvaluation = info;
|
|
||||||
MemoryPatching(miEvaluation, miDict[miEvaluation.ReturnType.ToString()]);
|
|
||||||
nCount++;
|
|
||||||
|
|
||||||
if ((assembly.FullName.IndexOf("Aspose.3D") != -1) && (nCount == 2))
|
if ((assembly.FullName.IndexOf("Aspose.3D") != -1) && (nCount == 2))
|
||||||
{
|
{
|
||||||
isFound = true;
|
isFound = true;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
}
|
||||||
{
|
catch
|
||||||
throw new InvalidOperationException("MemoryPatching for \"" + assembly.FullName + "\" failed !");
|
{
|
||||||
}
|
throw new InvalidOperationException("MemoryPatching for \"" + assembly.FullName + "\" failed !");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] aParts = assembly.FullName.Split(',');
|
|
||||||
string fName = aParts[0];
|
|
||||||
if (fName.IndexOf("Aspose.BarCode.") != -1)
|
|
||||||
fName = "Aspose.BarCode";
|
|
||||||
else if (fName.IndexOf("Aspose.3D") != -1)
|
|
||||||
fName = "Aspose.ThreeD";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Type type2 = assembly.GetType(fName + ".License");
|
|
||||||
MethodInfo mi = type2.GetMethod("SetLicense", new Type[] { typeof(Stream) });
|
|
||||||
string LData = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPExpY2Vuc2U+CiAgPERhdGE+CiAgICA8TGljZW5zZWRUbz5MaWNlbnNlZTwvTGljZW5zZWRUbz4KICAgIDxFbWFpbFRvPmxpY2Vuc2VlQGVtYWlsLmNvbTwvRW1haWxUbz4KICAgIDxMaWNlbnNlVHlwZT5EZXZlbG9wZXIgT0VNPC9MaWNlbnNlVHlwZT4KICAgIDxMaWNlbnNlTm90ZT5MaW1pdGVkIHRvIDEwMDAgZGV2ZWxvcGVyLCB1bmxpbWl0ZWQgcGh5c2ljYWwgbG9jYXRpb25zPC9MaWNlbnNlTm90ZT4KICAgIDxPcmRlcklEPjc4NDM3ODU3Nzg1PC9PcmRlcklEPgogICAgPFVzZXJJRD4xMTk3ODkyNDM3OTwvVXNlcklEPgogICAgPE9FTT5UaGlzIGlzIGEgcmVkaXN0cmlidXRhYmxlIGxpY2Vuc2U8L09FTT4KICAgIDxQcm9kdWN0cz4KICAgICAgPFByb2R1Y3Q+QXNwb3NlLlRvdGFsIFByb2R1Y3QgRmFtaWx5PC9Qcm9kdWN0PgogICAgPC9Qcm9kdWN0cz4KICAgIDxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT4KICAgIDxTZXJpYWxOdW1iZXI+e0YyQjk3MDQ1LTFCMjktNEIzRi1CRDUzLTYwMUVGRkExNUFBOX08L1NlcmlhbE51bWJlcj4KICAgIDxTdWJzY3JpcHRpb25FeHBpcnk+MjA5OTEyMzE8L1N1YnNjcmlwdGlvbkV4cGlyeT4KICAgIDxMaWNlbnNlVmVyc2lvbj4zLjA8L0xpY2Vuc2VWZXJzaW9uPgogIDwvRGF0YT4KICA8U2lnbmF0dXJlPlFYTndiM05sTGxSdmRHRnNJRkJ5YjJSMVkzUWdSbUZ0YVd4NTwvU2lnbmF0dXJlPgo8L0xpY2Vuc2U+";
|
|
||||||
Stream stream = new MemoryStream(Convert.FromBase64String(LData));
|
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
|
||||||
mi.Invoke(Activator.CreateInstance(type2, null), new Stream[] { stream });
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("SetLicense for \"" + assembly.FullName + "\" failed !");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String[] aParts = assembly.FullName.Split(',');
|
||||||
|
string fName = aParts[0];
|
||||||
|
if (fName.IndexOf("Aspose.BarCode.") != -1)
|
||||||
|
fName = "Aspose.BarCode";
|
||||||
|
else if (fName.IndexOf("Aspose.3D") != -1)
|
||||||
|
fName = "Aspose.ThreeD";
|
||||||
|
|
||||||
private static DateTime InvokeMe1(XmlElement element, string name)
|
try
|
||||||
{
|
{
|
||||||
return DateTime.MaxValue;
|
Type type2 = assembly.GetType(fName + ".License");
|
||||||
|
MethodInfo mi = type2.GetMethod("SetLicense", new Type[] { typeof(Stream) });
|
||||||
|
string LData = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPExpY2Vuc2U+CiAgPERhdGE+CiAgICA8TGljZW5zZWRUbz5MaWNlbnNlZTwvTGljZW5zZWRUbz4KICAgIDxFbWFpbFRvPmxpY2Vuc2VlQGVtYWlsLmNvbTwvRW1haWxUbz4KICAgIDxMaWNlbnNlVHlwZT5EZXZlbG9wZXIgT0VNPC9MaWNlbnNlVHlwZT4KICAgIDxMaWNlbnNlTm90ZT5MaW1pdGVkIHRvIDEwMDAgZGV2ZWxvcGVyLCB1bmxpbWl0ZWQgcGh5c2ljYWwgbG9jYXRpb25zPC9MaWNlbnNlTm90ZT4KICAgIDxPcmRlcklEPjc4NDM3ODU3Nzg1PC9PcmRlcklEPgogICAgPFVzZXJJRD4xMTk3ODkyNDM3OTwvVXNlcklEPgogICAgPE9FTT5UaGlzIGlzIGEgcmVkaXN0cmlidXRhYmxlIGxpY2Vuc2U8L09FTT4KICAgIDxQcm9kdWN0cz4KICAgICAgPFByb2R1Y3Q+QXNwb3NlLlRvdGFsIFByb2R1Y3QgRmFtaWx5PC9Qcm9kdWN0PgogICAgPC9Qcm9kdWN0cz4KICAgIDxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT4KICAgIDxTZXJpYWxOdW1iZXI+e0YyQjk3MDQ1LTFCMjktNEIzRi1CRDUzLTYwMUVGRkExNUFBOX08L1NlcmlhbE51bWJlcj4KICAgIDxTdWJzY3JpcHRpb25FeHBpcnk+MjA5OTEyMzE8L1N1YnNjcmlwdGlvbkV4cGlyeT4KICAgIDxMaWNlbnNlVmVyc2lvbj4zLjA8L0xpY2Vuc2VWZXJzaW9uPgogIDwvRGF0YT4KICA8U2lnbmF0dXJlPlFYTndiM05sTGxSdmRHRnNJRkJ5YjJSMVkzUWdSbUZ0YVd4NTwvU2lnbmF0dXJlPgo8L0xpY2Vuc2U+";
|
||||||
|
Stream stream = new MemoryStream(Convert.FromBase64String(LData));
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
mi.Invoke(Activator.CreateInstance(type2, null), new Stream[] { stream });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("SetLicense for \"" + assembly.FullName + "\" failed !");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static XmlElement InvokeMe2(XmlElement element, string name)
|
|
||||||
|
private static DateTime InvokeMe1(XmlElement element, string name)
|
||||||
|
{
|
||||||
|
return DateTime.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static XmlElement InvokeMe2(XmlElement element, string name)
|
||||||
|
{
|
||||||
|
if (element.LocalName == "License")
|
||||||
{
|
{
|
||||||
if (element.LocalName == "License")
|
string License64 = "PERhdGE+PExpY2Vuc2VkVG8+R3JvdXBEb2NzPC9MaWNlbnNlZFRvPjxMaWNlbnNlVHlwZT5TaXRlIE9FTTwvTGljZW5zZVR5cGU+PExpY2Vuc2VOb3RlPkxpbWl0ZWQgdG8gMTAgZGV2ZWxvcGVyczwvTGljZW5zZU5vdGU+PE9yZGVySUQ+MTMwNzI0MDQwODQ5PC9PcmRlcklEPjxPRU0+VGhpcyBpcyBhIHJlZGlzdHJpYnV0YWJsZSBsaWNlbnNlPC9PRU0+PFByb2R1Y3RzPjxQcm9kdWN0PkFzcG9zZS5Ub3RhbDwvUHJvZHVjdD48L1Byb2R1Y3RzPjxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT48U2VyaWFsTnVtYmVyPjliNTc5NTAxLTUyNjEtNDIyMC04NjcwLWZjMmQ4Y2NkZDkwYzwvU2VyaWFsTnVtYmVyPjxTdWJzY3JpcHRpb25FeHBpcnk+MjAxNDA3MjQ8L1N1YnNjcmlwdGlvbkV4cGlyeT48TGljZW5zZVZlcnNpb24+Mi4yPC9MaWNlbnNlVmVyc2lvbj48L0RhdGE+PFNpZ25hdHVyZT5udFpocmRoL3I0QS81ZFpsU2dWYnhac0hYSFBxSjZ5UVVYa0RvaW4vS2lVZWhUUWZET0lQdHdzUlR2NmRTUVplOVdXekNnV3RGdkdROWpmR2QySmF4YUQvbkx1ZEk2R0VVajhqeVhUMG4vbWRrMEF1WVZNYlBXRjJYd3dSTnFlTmRrblYyQjhrZVFwbDJ2RzZVbnhxS2J6VVFxS2Rhc1pzZ2w1Q0xqSFVEWms9PC9TaWduYXR1cmU+";
|
||||||
{
|
element.InnerXml = new UTF8Encoding().GetString(Convert.FromBase64String(License64));
|
||||||
string License64 = "PERhdGE+PExpY2Vuc2VkVG8+R3JvdXBEb2NzPC9MaWNlbnNlZFRvPjxMaWNlbnNlVHlwZT5TaXRlIE9FTTwvTGljZW5zZVR5cGU+PExpY2Vuc2VOb3RlPkxpbWl0ZWQgdG8gMTAgZGV2ZWxvcGVyczwvTGljZW5zZU5vdGU+PE9yZGVySUQ+MTMwNzI0MDQwODQ5PC9PcmRlcklEPjxPRU0+VGhpcyBpcyBhIHJlZGlzdHJpYnV0YWJsZSBsaWNlbnNlPC9PRU0+PFByb2R1Y3RzPjxQcm9kdWN0PkFzcG9zZS5Ub3RhbDwvUHJvZHVjdD48L1Byb2R1Y3RzPjxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT48U2VyaWFsTnVtYmVyPjliNTc5NTAxLTUyNjEtNDIyMC04NjcwLWZjMmQ4Y2NkZDkwYzwvU2VyaWFsTnVtYmVyPjxTdWJzY3JpcHRpb25FeHBpcnk+MjAxNDA3MjQ8L1N1YnNjcmlwdGlvbkV4cGlyeT48TGljZW5zZVZlcnNpb24+Mi4yPC9MaWNlbnNlVmVyc2lvbj48L0RhdGE+PFNpZ25hdHVyZT5udFpocmRoL3I0QS81ZFpsU2dWYnhac0hYSFBxSjZ5UVVYa0RvaW4vS2lVZWhUUWZET0lQdHdzUlR2NmRTUVplOVdXekNnV3RGdkdROWpmR2QySmF4YUQvbkx1ZEk2R0VVajhqeVhUMG4vbWRrMEF1WVZNYlBXRjJYd3dSTnFlTmRrblYyQjhrZVFwbDJ2RzZVbnhxS2J6VVFxS2Rhc1pzZ2w1Q0xqSFVEWms9PC9TaWduYXR1cmU+";
|
|
||||||
element.InnerXml = new UTF8Encoding().GetString(Convert.FromBase64String(License64));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.LocalName == "BlackList")
|
|
||||||
{
|
|
||||||
string BlackList64 = "PERhdGE+PC9EYXRhPjxTaWduYXR1cmU+cUJwMEx1cEVoM1ZnOWJjeS8vbUVXUk9KRWZmczRlY25iTHQxYlNhanU2NjY5RHlad09FakJ1eEdBdVBxS1hyd0x5bmZ5VWplYUNGQ0QxSkh2RVUxVUl5eXJOTnBSMXc2NXJIOUFyUCtFbE1lVCtIQkZ4NFMzckFVMnd6dkxPZnhGeU9DQ0dGQ2UraTdiSHlGQk44WHp6R1UwdGRPMGR1RTFoRTQ5M1RNY3pRPTwvU2lnbmF0dXJlPg==";
|
|
||||||
element.InnerXml = new UTF8Encoding().GetString(Convert.FromBase64String(BlackList64));
|
|
||||||
}
|
|
||||||
|
|
||||||
XmlNodeList elementsByTagName = element.GetElementsByTagName(name);
|
|
||||||
if (elementsByTagName.Count <= 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (XmlElement)elementsByTagName[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element.LocalName == "BlackList")
|
||||||
private static unsafe void MemoryPatching(MethodBase miEvaluation, MethodBase miLicensed)
|
|
||||||
{
|
{
|
||||||
IntPtr IntPtrEval = GetMemoryAddress(miEvaluation);
|
string BlackList64 = "PERhdGE+PC9EYXRhPjxTaWduYXR1cmU+cUJwMEx1cEVoM1ZnOWJjeS8vbUVXUk9KRWZmczRlY25iTHQxYlNhanU2NjY5RHlad09FakJ1eEdBdVBxS1hyd0x5bmZ5VWplYUNGQ0QxSkh2RVUxVUl5eXJOTnBSMXc2NXJIOUFyUCtFbE1lVCtIQkZ4NFMzckFVMnd6dkxPZnhGeU9DQ0dGQ2UraTdiSHlGQk44WHp6R1UwdGRPMGR1RTFoRTQ5M1RNY3pRPTwvU2lnbmF0dXJlPg==";
|
||||||
IntPtr IntPtrLicensed = GetMemoryAddress(miLicensed);
|
element.InnerXml = new UTF8Encoding().GetString(Convert.FromBase64String(BlackList64));
|
||||||
|
|
||||||
if (IntPtr.Size == 8)
|
|
||||||
*((long*)IntPtrEval.ToPointer()) = *((long*)IntPtrLicensed.ToPointer());
|
|
||||||
else
|
|
||||||
*((int*)IntPtrEval.ToPointer()) = *((int*)IntPtrLicensed.ToPointer());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XmlNodeList elementsByTagName = element.GetElementsByTagName(name);
|
||||||
private static unsafe IntPtr GetMemoryAddress(MethodBase mb)
|
if (elementsByTagName.Count <= 0)
|
||||||
{
|
{
|
||||||
RuntimeHelpers.PrepareMethod(mb.MethodHandle);
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if ((Environment.Version.Major >= 4) || ((Environment.Version.Major == 2) && (Environment.Version.MinorRevision >= 3053)))
|
return (XmlElement)elementsByTagName[0];
|
||||||
{
|
}
|
||||||
return new IntPtr(((int*)mb.MethodHandle.Value.ToPointer() + 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt64* location = (UInt64*)(mb.MethodHandle.Value.ToPointer());
|
|
||||||
int index = (int)(((*location) >> 32) & 0xFF);
|
private static unsafe void MemoryPatching(MethodBase miEvaluation, MethodBase miLicensed)
|
||||||
if (IntPtr.Size == 8)
|
{
|
||||||
{
|
IntPtr IntPtrEval = GetMemoryAddress(miEvaluation);
|
||||||
ulong* classStart = (ulong*)mb.DeclaringType.TypeHandle.Value.ToPointer();
|
IntPtr IntPtrLicensed = GetMemoryAddress(miLicensed);
|
||||||
ulong* address = classStart + index + 10;
|
|
||||||
return new IntPtr(address);
|
if (IntPtr.Size == 8)
|
||||||
}
|
*((long*)IntPtrEval.ToPointer()) = *((long*)IntPtrLicensed.ToPointer());
|
||||||
else
|
else
|
||||||
{
|
*((int*)IntPtrEval.ToPointer()) = *((int*)IntPtrLicensed.ToPointer());
|
||||||
uint* classStart = (uint*)mb.DeclaringType.TypeHandle.Value.ToPointer();
|
|
||||||
uint* address = classStart + index + 10;
|
}
|
||||||
return new IntPtr(address);
|
|
||||||
}
|
|
||||||
|
private static unsafe IntPtr GetMemoryAddress(MethodBase mb)
|
||||||
|
{
|
||||||
|
RuntimeHelpers.PrepareMethod(mb.MethodHandle);
|
||||||
|
|
||||||
|
if ((Environment.Version.Major >= 4) || ((Environment.Version.Major == 2) && (Environment.Version.MinorRevision >= 3053)))
|
||||||
|
{
|
||||||
|
return new IntPtr(((int*)mb.MethodHandle.Value.ToPointer() + 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64* location = (UInt64*)(mb.MethodHandle.Value.ToPointer());
|
||||||
|
int index = (int)(((*location) >> 32) & 0xFF);
|
||||||
|
if (IntPtr.Size == 8)
|
||||||
|
{
|
||||||
|
ulong* classStart = (ulong*)mb.DeclaringType.TypeHandle.Value.ToPointer();
|
||||||
|
ulong* address = classStart + index + 10;
|
||||||
|
return new IntPtr(address);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint* classStart = (uint*)mb.DeclaringType.TypeHandle.Value.ToPointer();
|
||||||
|
uint* address = classStart + index + 10;
|
||||||
|
return new IntPtr(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||||
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||||
|
|||||||
@@ -1,45 +1,39 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention;
|
||||||
|
|
||||||
|
public class FilesRetentionClient : ClientBase
|
||||||
{
|
{
|
||||||
public class FilesRetentionClient : ClientBase
|
public FilesRetentionClient(NextcloudClient client) : base(client)
|
||||||
{
|
{
|
||||||
public FilesRetentionClient(NextcloudClient client) : base(client)
|
}
|
||||||
|
|
||||||
|
public bool CreateRetentionRule(RetentionRuleInfo rule)
|
||||||
|
{
|
||||||
|
var entry = rule.ToOcsData();
|
||||||
|
return Client.Ocs.GetApi<OcsApiFilesRetention>().CreateRetentionRule(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DeleteRetentionRule(int ruleID)
|
||||||
|
{
|
||||||
|
return Client.Ocs.GetApi<OcsApiFilesRetention>().DeleteRetentionRule(ruleID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RetentionRule[]? GetRetentionRules()
|
||||||
|
{
|
||||||
|
var api = Client.Ocs.GetApi<OcsApiFilesRetention>();
|
||||||
|
var response = api.GetRetentionRules();
|
||||||
|
|
||||||
|
if (response?.Data is not null)
|
||||||
{
|
{
|
||||||
|
var rules = new List<RetentionRule>();
|
||||||
|
|
||||||
|
foreach (var entry in response.Data)
|
||||||
|
rules.Add(new RetentionRule(entry));
|
||||||
|
|
||||||
|
return rules.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CreateRetentionRule(RetentionRuleInfo rule)
|
return null;
|
||||||
{
|
|
||||||
var entry = rule.ToOcsData();
|
|
||||||
return Client.Ocs.GetApi<OcsApiFilesRetention>().CreateRetentionRule(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DeleteRetentionRule(int ruleID)
|
|
||||||
{
|
|
||||||
return Client.Ocs.GetApi<OcsApiFilesRetention>().DeleteRetentionRule(ruleID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RetentionRule[]? GetRetentionRules()
|
|
||||||
{
|
|
||||||
var api = Client.Ocs.GetApi<OcsApiFilesRetention>();
|
|
||||||
var response = api.GetRetentionRules();
|
|
||||||
|
|
||||||
if (response?.Data is not null)
|
|
||||||
{
|
|
||||||
var rules = new List<RetentionRule>();
|
|
||||||
|
|
||||||
foreach (var entry in response.Data)
|
|
||||||
rules.Add(new RetentionRule(entry));
|
|
||||||
|
|
||||||
return rules.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,30 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
|
||||||
|
|
||||||
|
public class RetentionRule : RetentionRuleInfo
|
||||||
{
|
{
|
||||||
public class RetentionRule : RetentionRuleInfo
|
/// <summary>
|
||||||
|
/// The ID for the retention rule.
|
||||||
|
/// </summary>
|
||||||
|
public int ID { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines if a background job has been generated
|
||||||
|
/// </summary>
|
||||||
|
public bool HasJob { get; init; }
|
||||||
|
|
||||||
|
public RetentionRule()
|
||||||
{
|
{
|
||||||
/// <summary>
|
}
|
||||||
/// The ID for the retention rule.
|
|
||||||
/// </summary>
|
|
||||||
public int ID { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
public RetentionRule(OcsResponseDataEntryRetention data)
|
||||||
/// Defines if a background job has been generated
|
{
|
||||||
/// </summary>
|
ID = data.ID ?? -1;
|
||||||
public bool HasJob { get; init; }
|
TagID = data.TagID ?? -1;
|
||||||
|
TimeUnit = (RetentionTimeUnit)(data.TimeUnit ?? 0);
|
||||||
public RetentionRule()
|
TimeAmount = data.TimeAmount ?? -1;
|
||||||
{
|
TimeAfter = (RetentionTimeAfter)(data.TimeAfter ?? 0);
|
||||||
}
|
HasJob = data.HasJob ?? false;
|
||||||
|
|
||||||
public RetentionRule(OcsResponseDataEntryRetention data)
|
|
||||||
{
|
|
||||||
ID = data.ID ?? -1;
|
|
||||||
TagID = data.TagID ?? -1;
|
|
||||||
TimeUnit = (RetentionTimeUnit)(data.TimeUnit ?? 0);
|
|
||||||
TimeAmount = data.TimeAmount ?? -1;
|
|
||||||
TimeAfter = (RetentionTimeAfter)(data.TimeAfter ?? 0);
|
|
||||||
HasJob = data.HasJob ?? false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,37 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
|
||||||
|
|
||||||
|
public class RetentionRuleInfo
|
||||||
{
|
{
|
||||||
public class RetentionRuleInfo
|
/// <summary>
|
||||||
|
/// The ID for the tag that is used for this rule.
|
||||||
|
/// </summary>
|
||||||
|
public int TagID { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The unit used for the time.
|
||||||
|
/// </summary>
|
||||||
|
public RetentionTimeUnit TimeUnit { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents numer of days/weeks/months/years.
|
||||||
|
/// </summary>
|
||||||
|
public int TimeAmount { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The time used for the rule.
|
||||||
|
/// </summary>
|
||||||
|
public RetentionTimeAfter TimeAfter { get; init; }
|
||||||
|
|
||||||
|
public OcsDataRetentionRule ToOcsData()
|
||||||
{
|
{
|
||||||
/// <summary>
|
return new OcsDataRetentionRule
|
||||||
/// The ID for the tag that is used for this rule.
|
|
||||||
/// </summary>
|
|
||||||
public int TagID { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The unit used for the time.
|
|
||||||
/// </summary>
|
|
||||||
public RetentionTimeUnit TimeUnit { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents numer of days/weeks/months/years.
|
|
||||||
/// </summary>
|
|
||||||
public int TimeAmount { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The time used for the rule.
|
|
||||||
/// </summary>
|
|
||||||
public RetentionTimeAfter TimeAfter { get; init; }
|
|
||||||
|
|
||||||
public OcsDataRetentionRule ToOcsData()
|
|
||||||
{
|
{
|
||||||
return new OcsDataRetentionRule
|
TagID = TagID,
|
||||||
{
|
TimeUnit = (int)TimeUnit,
|
||||||
TagID = TagID,
|
TimeAmount = TimeAmount,
|
||||||
TimeUnit = (int)TimeUnit,
|
TimeAfter = (int)TimeAfter
|
||||||
TimeAmount = TimeAmount,
|
};
|
||||||
TimeAfter = (int)TimeAfter
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model
|
public enum RetentionTimeAfter
|
||||||
{
|
{
|
||||||
public enum RetentionTimeAfter
|
CreationDate,
|
||||||
{
|
LastAccess
|
||||||
CreationDate,
|
|
||||||
LastAccess
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,9 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model
|
public enum RetentionTimeUnit
|
||||||
{
|
{
|
||||||
public enum RetentionTimeUnit
|
Day,
|
||||||
{
|
Week,
|
||||||
Day,
|
Month,
|
||||||
Week,
|
Year
|
||||||
Month,
|
|
||||||
Year
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,20 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
|
||||||
|
|
||||||
|
public class OcsDataRetentionRule : OcsData
|
||||||
{
|
{
|
||||||
public class OcsDataRetentionRule : OcsData
|
|
||||||
{
|
|
||||||
|
|
||||||
[JsonProperty("tagid")]
|
[JsonProperty("tagid")]
|
||||||
public int? TagID { get; set; }
|
public int? TagID { get; set; }
|
||||||
|
|
||||||
[JsonProperty("timeunit")]
|
[JsonProperty("timeunit")]
|
||||||
public int? TimeUnit { get; set; }
|
public int? TimeUnit { get; set; }
|
||||||
|
|
||||||
[JsonProperty("timeamount")]
|
[JsonProperty("timeamount")]
|
||||||
public int? TimeAmount { get; set; }
|
public int? TimeAmount { get; set; }
|
||||||
|
|
||||||
[JsonProperty("timeafter")]
|
[JsonProperty("timeafter")]
|
||||||
public int? TimeAfter { get; set; }
|
public int? TimeAfter { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,25 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
|
||||||
|
|
||||||
|
public class OcsResponseDataEntryRetention : OcsResponseDataEntry
|
||||||
{
|
{
|
||||||
public class OcsResponseDataEntryRetention : OcsResponseDataEntry
|
[JsonProperty("id")]
|
||||||
{
|
public int? ID { get; set; }
|
||||||
[JsonProperty("id")]
|
|
||||||
public int? ID { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("tagid")]
|
[JsonProperty("tagid")]
|
||||||
public int? TagID { get; set; }
|
public int? TagID { get; set; }
|
||||||
|
|
||||||
[JsonProperty("timeunit")]
|
[JsonProperty("timeunit")]
|
||||||
public int? TimeUnit { get; set; }
|
public int? TimeUnit { get; set; }
|
||||||
|
|
||||||
[JsonProperty("timeamount")]
|
[JsonProperty("timeamount")]
|
||||||
public int? TimeAmount { get; set; }
|
public int? TimeAmount { get; set; }
|
||||||
|
|
||||||
[JsonProperty("timeafter")]
|
[JsonProperty("timeafter")]
|
||||||
public int? TimeAfter { get; set; }
|
public int? TimeAfter { get; set; }
|
||||||
|
|
||||||
[JsonProperty("hasJob")]
|
[JsonProperty("hasJob")]
|
||||||
public bool? HasJob { get; set; }
|
public bool? HasJob { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
using Newtonsoft.Json;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
|
||||||
|
|
||||||
|
public class OcsResponseRetention : OcsResponse<OcsResponseDataArray<OcsResponseDataEntryRetention>>
|
||||||
{
|
{
|
||||||
public class OcsResponseRetention : OcsResponse<OcsResponseDataArray<OcsResponseDataEntryRetention>>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,31 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention;
|
||||||
|
|
||||||
|
public class OcsApiFilesRetention : OcsApiBase
|
||||||
{
|
{
|
||||||
public class OcsApiFilesRetention : OcsApiBase
|
public static readonly OcsApiUrlPath OCS_FILE_RETENTION_RULES = new("/ocs/v2.php/apps/files_retention/api/v1/retentions");
|
||||||
|
public static readonly OcsApiUrlPath OCS_FILE_RETENTION_RULE = new("/ocs/v2.php/apps/files_retention/api/v1/retentions/{0}");
|
||||||
|
|
||||||
|
public OcsApiFilesRetention(OcsApi manager) : base(manager)
|
||||||
{
|
{
|
||||||
public static readonly OcsApiUrlPath OCS_FILE_RETENTION_RULES = new("/ocs/v2.php/apps/files_retention/api/v1/retentions");
|
}
|
||||||
public static readonly OcsApiUrlPath OCS_FILE_RETENTION_RULE = new("/ocs/v2.php/apps/files_retention/api/v1/retentions/{0}");
|
|
||||||
|
|
||||||
public OcsApiFilesRetention(OcsApi manager) : base(manager)
|
public bool CreateRetentionRule(OcsDataRetentionRule rule)
|
||||||
{
|
{
|
||||||
}
|
var response = Manager.MakeRequest(HttpMethod.Post, OCS_FILE_RETENTION_RULES, content: rule);
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
|
}
|
||||||
|
|
||||||
public bool CreateRetentionRule(OcsDataRetentionRule rule)
|
public bool DeleteRetentionRule(int ruleID)
|
||||||
{
|
{
|
||||||
var response = Manager.MakeRequest(HttpMethod.Post, OCS_FILE_RETENTION_RULES, content: rule);
|
var response = Manager.MakeRequest(HttpMethod.Delete, OCS_FILE_RETENTION_RULE.FillParameters(ruleID));
|
||||||
return response.IsSuccessStatusCode;
|
return response.IsSuccessStatusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteRetentionRule(int ruleID)
|
public OcsResponseRetention? GetRetentionRules()
|
||||||
{
|
{
|
||||||
var response = Manager.MakeRequest(HttpMethod.Delete, OCS_FILE_RETENTION_RULE.FillParameters(ruleID));
|
return Manager.MakeRequestOcs<OcsResponseRetention>(HttpMethod.Get, OCS_FILE_RETENTION_RULES);
|
||||||
return response.IsSuccessStatusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OcsResponseRetention? GetRetentionRules()
|
|
||||||
{
|
|
||||||
return Manager.MakeRequestOcs<OcsResponseRetention>(HttpMethod.Get, OCS_FILE_RETENTION_RULES);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,116 +1,110 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
|
|
||||||
|
public class Column
|
||||||
{
|
{
|
||||||
public class Column
|
[JsonProperty("type")]
|
||||||
|
private string? type;
|
||||||
|
|
||||||
|
[JsonProperty("subtype")]
|
||||||
|
private string? subtype;
|
||||||
|
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public long ColumnId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("tableId")]
|
||||||
|
public long TableId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("title")]
|
||||||
|
public string? Title { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("createdBy")]
|
||||||
|
public string? CreatedBy { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("createdAt")]
|
||||||
|
public DateTime CreatedAt { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("lastEditBy")]
|
||||||
|
public string? LastEditBy { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("lastEditAt")]
|
||||||
|
public DateTime LastEditAt { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("mandatory")]
|
||||||
|
public bool Mandatory { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("description")]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("numberDefault")]
|
||||||
|
public float? NumberDefault { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("numberMin")]
|
||||||
|
public float? NumberMin { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("numberMax")]
|
||||||
|
public float? NumberMax { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("numberDecimals")]
|
||||||
|
public float NumberDecimals { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("numberPrefix")]
|
||||||
|
public string? NumberPrefix { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("numberSuffix")]
|
||||||
|
public string? NumberSuffix { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("textDefault")]
|
||||||
|
public string? TextDefault { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("textAllowedPattern")]
|
||||||
|
public string? TextAllowedPattern { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("textMaxLength")]
|
||||||
|
public int? TextMaxLength { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("selectionOptions")]
|
||||||
|
public List<ColumnSelectionOption> SelectionOptions { get; } = new();
|
||||||
|
|
||||||
|
[JsonProperty("selectionDefault")]
|
||||||
|
public int? SelectionDefault { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("datetimeDefault")]
|
||||||
|
public DateTime? DatetimeDefault { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public ColumnType Type
|
||||||
{
|
{
|
||||||
[JsonProperty("type")]
|
get => type switch
|
||||||
private string? type;
|
|
||||||
|
|
||||||
[JsonProperty("subtype")]
|
|
||||||
private string? subtype;
|
|
||||||
|
|
||||||
[JsonProperty("id")]
|
|
||||||
public long ColumnId { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("tableId")]
|
|
||||||
public long TableId { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("title")]
|
|
||||||
public string? Title { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("createdBy")]
|
|
||||||
public string? CreatedBy { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("createdAt")]
|
|
||||||
public DateTime CreatedAt { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("lastEditBy")]
|
|
||||||
public string? LastEditBy { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("lastEditAt")]
|
|
||||||
public DateTime LastEditAt { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("mandatory")]
|
|
||||||
public bool Mandatory { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("description")]
|
|
||||||
public string? Description { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("numberDefault")]
|
|
||||||
public float? NumberDefault { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("numberMin")]
|
|
||||||
public float? NumberMin { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("numberMax")]
|
|
||||||
public float? NumberMax { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("numberDecimals")]
|
|
||||||
public float NumberDecimals { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("numberPrefix")]
|
|
||||||
public string? NumberPrefix { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("numberSuffix")]
|
|
||||||
public string? NumberSuffix { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("textDefault")]
|
|
||||||
public string? TextDefault { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("textAllowedPattern")]
|
|
||||||
public string? TextAllowedPattern { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("textMaxLength")]
|
|
||||||
public int? TextMaxLength { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("selectionOptions")]
|
|
||||||
public List<ColumnSelectionOption> SelectionOptions { get; } = new();
|
|
||||||
|
|
||||||
[JsonProperty("selectionDefault")]
|
|
||||||
public int? SelectionDefault { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("datetimeDefault")]
|
|
||||||
public DateTime? DatetimeDefault { get; set; }
|
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public ColumnType Type
|
|
||||||
{
|
{
|
||||||
get => type switch
|
"text" => ColumnType.Text,
|
||||||
{
|
"selection" => ColumnType.Selection,
|
||||||
"text" => ColumnType.Text,
|
"datetime" => ColumnType.DateTime,
|
||||||
"selection" => ColumnType.Selection,
|
_ => ColumnType.Unknown,
|
||||||
"datetime" => ColumnType.DateTime,
|
};
|
||||||
_ => ColumnType.Unknown,
|
set => type = value switch
|
||||||
};
|
|
||||||
set => type = value switch
|
|
||||||
{
|
|
||||||
ColumnType.Text => "text",
|
|
||||||
ColumnType.Selection => "selection",
|
|
||||||
ColumnType.DateTime => "datetime",
|
|
||||||
_ => "text"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public ColumnSubtype Subtype
|
|
||||||
{
|
{
|
||||||
get => subtype switch
|
ColumnType.Text => "text",
|
||||||
{
|
ColumnType.Selection => "selection",
|
||||||
"line" => ColumnSubtype.Line,
|
ColumnType.DateTime => "datetime",
|
||||||
"" => ColumnSubtype.None,
|
_ => "text"
|
||||||
_ => ColumnSubtype.Unknown,
|
};
|
||||||
};
|
}
|
||||||
set => subtype = value switch
|
|
||||||
{
|
[JsonIgnore]
|
||||||
ColumnSubtype.Line => "line",
|
public ColumnSubtype Subtype
|
||||||
_ => ""
|
{
|
||||||
};
|
get => subtype switch
|
||||||
}
|
{
|
||||||
|
"line" => ColumnSubtype.Line,
|
||||||
|
"" => ColumnSubtype.None,
|
||||||
|
_ => ColumnSubtype.Unknown,
|
||||||
|
};
|
||||||
|
set => subtype = value switch
|
||||||
|
{
|
||||||
|
ColumnSubtype.Line => "line",
|
||||||
|
_ => ""
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,12 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
|
|
||||||
|
public class ColumnSelectionOption
|
||||||
{
|
{
|
||||||
public class ColumnSelectionOption
|
[JsonProperty("id")]
|
||||||
{
|
public long Id { get; set; }
|
||||||
[JsonProperty("id")]
|
|
||||||
public long Id { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("label")]
|
[JsonProperty("label")]
|
||||||
public string? Label { get; set; }
|
public string? Label { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,8 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
public enum ColumnSubtype
|
||||||
{
|
{
|
||||||
public enum ColumnSubtype
|
None,
|
||||||
{
|
Unknown,
|
||||||
None,
|
Line
|
||||||
Unknown,
|
|
||||||
Line
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,9 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
public enum ColumnType
|
||||||
{
|
{
|
||||||
public enum ColumnType
|
Unknown,
|
||||||
{
|
Text,
|
||||||
Unknown,
|
Selection,
|
||||||
Text,
|
DateTime
|
||||||
Selection,
|
|
||||||
DateTime
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
public class Columns : List<Column>
|
||||||
{
|
{
|
||||||
public class Columns : List<Column>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,27 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
|
|
||||||
|
public class Row
|
||||||
{
|
{
|
||||||
public class Row
|
[JsonProperty("id")]
|
||||||
{
|
public long RowId { get; set; } = -1;
|
||||||
[JsonProperty("id")]
|
|
||||||
public long RowId { get; set; } = -1;
|
|
||||||
|
|
||||||
[JsonProperty("tableId")]
|
[JsonProperty("tableId")]
|
||||||
public long TableId { get; set; } = -1;
|
public long TableId { get; set; } = -1;
|
||||||
|
|
||||||
[JsonProperty("createdBy")]
|
[JsonProperty("createdBy")]
|
||||||
public string? CreatedBy { get; set; }
|
public string? CreatedBy { get; set; }
|
||||||
|
|
||||||
[JsonProperty("createdAt")]
|
[JsonProperty("createdAt")]
|
||||||
public DateTime CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
|
|
||||||
[JsonProperty("lastEditBy")]
|
[JsonProperty("lastEditBy")]
|
||||||
public string? LastEditBy { get; set; }
|
public string? LastEditBy { get; set; }
|
||||||
|
|
||||||
[JsonProperty("lastEditAt")]
|
[JsonProperty("lastEditAt")]
|
||||||
public DateTime LastEditAt { get; set; }
|
public DateTime LastEditAt { get; set; }
|
||||||
|
|
||||||
[JsonProperty("data")]
|
[JsonProperty("data")]
|
||||||
public List<RowData> Data { get; set; } = new();
|
public List<RowData> Data { get; set; } = new();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,12 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
|
|
||||||
|
public class RowData
|
||||||
{
|
{
|
||||||
public class RowData
|
[JsonProperty("columnId")]
|
||||||
{
|
public long ColumnId { get; set; }
|
||||||
[JsonProperty("columnId")]
|
|
||||||
public long ColumnId { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("value")]
|
[JsonProperty("value")]
|
||||||
public object? Value { get; set; }
|
public object? Value { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
public class RowSimple : List<object>
|
||||||
{
|
{
|
||||||
public class RowSimple : List<object>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,9 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
|
|
||||||
|
public class RowUpdate
|
||||||
{
|
{
|
||||||
public class RowUpdate
|
[JsonProperty("data")]
|
||||||
{
|
public Dictionary<long, object?> Data { get; set; } = new();
|
||||||
[JsonProperty("data")]
|
|
||||||
public Dictionary<long, object?> Data { get; set; } = new();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
public class Rows : List<Row>
|
||||||
{
|
{
|
||||||
public class Rows : List<Row>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model
|
public class RowsSimple : List<RowSimple>
|
||||||
{
|
{
|
||||||
public class RowsSimple : List<RowSimple>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,86 +1,79 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables;
|
||||||
|
|
||||||
|
public class OcsApiTables : OcsApiBase
|
||||||
{
|
{
|
||||||
public class OcsApiTables : OcsApiBase
|
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_ROWS = new("/apps/tables/api/1/tables/{0}/rows");
|
||||||
|
public static readonly OcsApiUrlPath OCS_TABLES_VIEW_ROWS = new("/apps/tables/api/1/views/{0}/rows");
|
||||||
|
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_ROWS_SIMPLE = new("/apps/tables/api/1/tables/{0}/rows/simple");
|
||||||
|
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_COLUMNS = new("/apps/tables/api/1/tables/{0}/columns");
|
||||||
|
public static readonly OcsApiUrlPath OCS_TABLES_VIEW_COLUMNS = new("/apps/tables/api/1/views/{0}/columns");
|
||||||
|
public static readonly OcsApiUrlPath OCS_TABLES_ROW = new("/apps/tables/api/1/rows/{0}");
|
||||||
|
public static readonly OcsApiUrlPath OCS_TABLES_COLUMN = new("/apps/tables/api/1/column/{0}");
|
||||||
|
|
||||||
|
public OcsApiTables(OcsApi manager) : base(manager)
|
||||||
{
|
{
|
||||||
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_ROWS = new("/apps/tables/api/1/tables/{0}/rows");
|
}
|
||||||
public static readonly OcsApiUrlPath OCS_TABLES_VIEW_ROWS = new("/apps/tables/api/1/views/{0}/rows");
|
|
||||||
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_ROWS_SIMPLE = new("/apps/tables/api/1/tables/{0}/rows/simple");
|
|
||||||
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_COLUMNS = new("/apps/tables/api/1/tables/{0}/columns");
|
|
||||||
public static readonly OcsApiUrlPath OCS_TABLES_VIEW_COLUMNS = new("/apps/tables/api/1/views/{0}/columns");
|
|
||||||
public static readonly OcsApiUrlPath OCS_TABLES_ROW = new("/apps/tables/api/1/rows/{0}");
|
|
||||||
public static readonly OcsApiUrlPath OCS_TABLES_COLUMN = new("/apps/tables/api/1/column/{0}");
|
|
||||||
|
|
||||||
public OcsApiTables(OcsApi manager) : base(manager)
|
public RowsSimple? GetRowsSimple(long tableId)
|
||||||
{
|
{
|
||||||
}
|
return Manager.MakeRequest<RowsSimple>(HttpMethod.Get, OCS_TABLES_TABLE_ROWS_SIMPLE.FillParameters(tableId));
|
||||||
|
}
|
||||||
|
|
||||||
public RowsSimple? GetRowsSimple(long tableId)
|
public Rows? GetRows(long tableId)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<RowsSimple>(HttpMethod.Get, OCS_TABLES_TABLE_ROWS_SIMPLE.FillParameters(tableId));
|
return Manager.MakeRequest<Rows>(HttpMethod.Get, OCS_TABLES_TABLE_ROWS.FillParameters(tableId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rows? GetRows(long tableId)
|
public Rows? GetViewRows(long viewId)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<Rows>(HttpMethod.Get, OCS_TABLES_TABLE_ROWS.FillParameters(tableId));
|
return Manager.MakeRequest<Rows>(HttpMethod.Get, OCS_TABLES_VIEW_ROWS.FillParameters(viewId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rows? GetViewRows(long viewId)
|
public Row? GetRow(long rowId)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<Rows>(HttpMethod.Get, OCS_TABLES_VIEW_ROWS.FillParameters(viewId));
|
return Manager.MakeRequest<Row>(HttpMethod.Get, OCS_TABLES_ROW.FillParameters(rowId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Row? GetRow(long rowId)
|
public Columns? GetColumns(long tableId)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<Row>(HttpMethod.Get, OCS_TABLES_ROW.FillParameters(rowId));
|
return Manager.MakeRequest<Columns>(HttpMethod.Get, OCS_TABLES_TABLE_COLUMNS.FillParameters(tableId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Columns? GetColumns(long tableId)
|
public Columns? GetViewColumns(long viewId)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<Columns>(HttpMethod.Get, OCS_TABLES_TABLE_COLUMNS.FillParameters(tableId));
|
return Manager.MakeRequest<Columns>(HttpMethod.Get, OCS_TABLES_VIEW_COLUMNS.FillParameters(viewId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Columns? GetViewColumns(long viewId)
|
public Column? GetColumn(long columnId)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<Columns>(HttpMethod.Get, OCS_TABLES_VIEW_COLUMNS.FillParameters(viewId));
|
return Manager.MakeRequest<Column>(HttpMethod.Get, OCS_TABLES_COLUMN.FillParameters(columnId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Column? GetColumn(long columnId)
|
public Row? DeleteRow(long rowId)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<Column>(HttpMethod.Get, OCS_TABLES_COLUMN.FillParameters(columnId));
|
return Manager.MakeRequest<Row>(HttpMethod.Delete, OCS_TABLES_ROW.FillParameters(rowId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Row? DeleteRow(long rowId)
|
public Column? DeleteColumn(long columnId)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<Row>(HttpMethod.Delete, OCS_TABLES_ROW.FillParameters(rowId));
|
return Manager.MakeRequest<Column>(HttpMethod.Delete, OCS_TABLES_COLUMN.FillParameters(columnId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Column? DeleteColumn(long columnId)
|
public Row? UpdateRow(long rowId, RowUpdate values)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<Column>(HttpMethod.Delete, OCS_TABLES_COLUMN.FillParameters(columnId));
|
return Manager.MakeRequest<Row>(HttpMethod.Put, OCS_TABLES_ROW.FillParameters(rowId), content: values);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Row? UpdateRow(long rowId, RowUpdate values)
|
public Row? CreateRow(long tableId, RowUpdate values)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<Row>(HttpMethod.Put, OCS_TABLES_ROW.FillParameters(rowId), content: values);
|
return Manager.MakeRequest<Row>(HttpMethod.Post, OCS_TABLES_TABLE_ROWS.FillParameters(tableId), content: values);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Row? CreateRow(long tableId, RowUpdate values)
|
public Row? CreateViewRow(long viewId, RowUpdate values)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<Row>(HttpMethod.Post, OCS_TABLES_TABLE_ROWS.FillParameters(tableId), content: values);
|
return Manager.MakeRequest<Row>(HttpMethod.Post, OCS_TABLES_VIEW_ROWS.FillParameters(viewId), content: values);
|
||||||
}
|
|
||||||
|
|
||||||
public Row? CreateViewRow(long viewId, RowUpdate values)
|
|
||||||
{
|
|
||||||
return Manager.MakeRequest<Row>(HttpMethod.Post, OCS_TABLES_VIEW_ROWS.FillParameters(viewId), content: values);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,81 +1,75 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables;
|
||||||
|
|
||||||
|
public class TablesClient : ClientBase
|
||||||
{
|
{
|
||||||
public class TablesClient : ClientBase
|
public TablesClient(NextcloudClient client) : base(client)
|
||||||
{
|
{
|
||||||
public TablesClient(NextcloudClient client) : base(client)
|
}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public RowsSimple? GetRowsSimple(long tableId)
|
public RowsSimple? GetRowsSimple(long tableId)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().GetRowsSimple(tableId);
|
return Client.Ocs.GetApi<OcsApiTables>().GetRowsSimple(tableId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rows? GetRows(long tableId)
|
public Rows? GetRows(long tableId)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().GetRows(tableId);
|
return Client.Ocs.GetApi<OcsApiTables>().GetRows(tableId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rows? GetViewRows(long viewId)
|
public Rows? GetViewRows(long viewId)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().GetViewRows(viewId);
|
return Client.Ocs.GetApi<OcsApiTables>().GetViewRows(viewId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Row? GetRow(long rowId)
|
public Row? GetRow(long rowId)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().GetRow(rowId);
|
return Client.Ocs.GetApi<OcsApiTables>().GetRow(rowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Columns? GetColumns(long tableId)
|
public Columns? GetColumns(long tableId)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().GetColumns(tableId);
|
return Client.Ocs.GetApi<OcsApiTables>().GetColumns(tableId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Columns? GetViewColumns(long viewId)
|
public Columns? GetViewColumns(long viewId)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().GetViewColumns(viewId);
|
return Client.Ocs.GetApi<OcsApiTables>().GetViewColumns(viewId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Column? GetColumn(long columnId)
|
public Column? GetColumn(long columnId)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().GetColumn(columnId);
|
return Client.Ocs.GetApi<OcsApiTables>().GetColumn(columnId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteRow(long rowId)
|
public bool DeleteRow(long rowId)
|
||||||
{
|
{
|
||||||
return DeleteRowAdv(rowId) is not null;
|
return DeleteRowAdv(rowId) is not null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Row? DeleteRowAdv(long rowId)
|
public Row? DeleteRowAdv(long rowId)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().DeleteRow(rowId);
|
return Client.Ocs.GetApi<OcsApiTables>().DeleteRow(rowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteColumn(long columnId)
|
public bool DeleteColumn(long columnId)
|
||||||
{
|
{
|
||||||
return DeleteColumnAdv(columnId) is not null;
|
return DeleteColumnAdv(columnId) is not null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Column? DeleteColumnAdv(long columnId)
|
public Column? DeleteColumnAdv(long columnId)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().DeleteColumn(columnId);
|
return Client.Ocs.GetApi<OcsApiTables>().DeleteColumn(columnId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Row? UpdateRow(long rowId, RowUpdate values)
|
public Row? UpdateRow(long rowId, RowUpdate values)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().UpdateRow(rowId, values);
|
return Client.Ocs.GetApi<OcsApiTables>().UpdateRow(rowId, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Row? CreateRow(long tableId, RowUpdate values)
|
public Row? CreateRow(long tableId, RowUpdate values)
|
||||||
{
|
{
|
||||||
return Client.Ocs.GetApi<OcsApiTables>().CreateRow(tableId, values);
|
return Client.Ocs.GetApi<OcsApiTables>().CreateRow(tableId, values);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
|
||||||
|
Vor:
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client
|
||||||
{
|
{
|
||||||
public abstract class ClientBase
|
public abstract class ClientBase
|
||||||
{
|
Nach:
|
||||||
protected NextcloudClient Client { get; init; }
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client;
|
||||||
|
|
||||||
protected ClientBase(NextcloudClient client)
|
public abstract class ClientBase
|
||||||
{
|
*/
|
||||||
Client = client;
|
public abstract class ClientBase
|
||||||
}
|
{
|
||||||
|
protected NextcloudClient Client { get; init; }
|
||||||
|
|
||||||
|
protected ClientBase(NextcloudClient client)
|
||||||
|
{
|
||||||
|
Client = client;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,28 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
|
||||||
|
|
||||||
|
public class CloudClient : ClientBase
|
||||||
{
|
{
|
||||||
public class CloudClient : ClientBase
|
public CloudClient(NextcloudClient client) : base(client)
|
||||||
{
|
{
|
||||||
public CloudClient(NextcloudClient client) : base(client)
|
}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserInfo? GetUserInfo()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(Client.CurrentLogin?.LoginName))
|
|
||||||
return GetUserInfo(Client.CurrentLogin.LoginName);
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserInfo? GetUserInfo(string username)
|
|
||||||
{
|
|
||||||
var result = Client.Ocs.Cloud.GetUserMeta(username);
|
|
||||||
|
|
||||||
if (result?.Data != null)
|
|
||||||
return new UserInfo(result.Data);
|
|
||||||
|
|
||||||
|
public UserInfo? GetUserInfo()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(Client.CurrentLogin?.LoginName))
|
||||||
|
return GetUserInfo(Client.CurrentLogin.LoginName);
|
||||||
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UserInfo? GetUserInfo(string username)
|
||||||
|
{
|
||||||
|
var result = Client.Ocs.Cloud.GetUserMeta(username);
|
||||||
|
|
||||||
|
if (result?.Data != null)
|
||||||
|
return new UserInfo(result.Data);
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,14 @@
|
|||||||
using Newtonsoft.Json;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model
|
public class UserBackendCapabilities
|
||||||
{
|
{
|
||||||
public class UserBackendCapabilities
|
/// <summary>
|
||||||
{
|
/// Defines if the display name can be changed.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Defines if the display name can be changed.
|
public bool SetDisplayName { get; set; }
|
||||||
/// </summary>
|
|
||||||
public bool SetDisplayName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines if the password can be changed.
|
/// Defines if the password can be changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool SetPassword { get; set; }
|
public bool SetPassword { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,131 +1,125 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
|
||||||
|
|
||||||
|
public class UserInfo
|
||||||
{
|
{
|
||||||
public class UserInfo
|
/// <summary>
|
||||||
|
/// Defines if the user is enabled.
|
||||||
|
/// </summary>
|
||||||
|
public bool Enabled { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The location of the user's storage directory.
|
||||||
|
/// </summary>
|
||||||
|
public string? StorageLocation { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The uniquie user id that infos are for.
|
||||||
|
/// </summary>
|
||||||
|
public string? ID { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The last time when the user has logged in to its account.
|
||||||
|
/// </summary>
|
||||||
|
public DateTime LastLogin { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The backend of the user. Common values are "Database" or "LDAP".
|
||||||
|
/// </summary>
|
||||||
|
public string? Backend { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Email address of the user.
|
||||||
|
/// </summary>
|
||||||
|
public string? Email { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The displayname of the user.
|
||||||
|
/// </summary>
|
||||||
|
public string? Displayname { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The displayname of the user.
|
||||||
|
/// </summary>
|
||||||
|
public string? Displayname2 { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The phone number of the user.
|
||||||
|
/// </summary>
|
||||||
|
public string? Phone { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The address of the user.
|
||||||
|
/// </summary>
|
||||||
|
public string? Address { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Website of the user.
|
||||||
|
/// </summary>
|
||||||
|
public string? Website { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The twitter profile name of the user.
|
||||||
|
/// </summary>
|
||||||
|
public string? Twitter { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the groups the user is member of.
|
||||||
|
/// </summary>
|
||||||
|
public string[] Groups { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The configured language of the user.
|
||||||
|
/// </summary>
|
||||||
|
public string? Language { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The configured location of the user.
|
||||||
|
/// </summary>
|
||||||
|
public string? Locale { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Quota informations for the user.
|
||||||
|
/// </summary>
|
||||||
|
public UserQuota Quota { get; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Backend capabilities of the user.
|
||||||
|
/// </summary>
|
||||||
|
public UserBackendCapabilities BackendCapabilities { get; } = new();
|
||||||
|
|
||||||
|
public UserInfo(OcsResponseDataUser responseData)
|
||||||
{
|
{
|
||||||
/// <summary>
|
Enabled = Convert.ToBoolean(responseData.Enabled);
|
||||||
/// Defines if the user is enabled.
|
StorageLocation = responseData.StorageLocation;
|
||||||
/// </summary>
|
ID = responseData.ID;
|
||||||
public bool Enabled { get; init; }
|
LastLogin = responseData.LastLogin.UnixTimeMillisecondsToDateTime();
|
||||||
|
Backend = responseData.Backend;
|
||||||
|
Email = responseData.Email;
|
||||||
|
Displayname = responseData.Displayname;
|
||||||
|
Displayname2 = responseData.Displayname2;
|
||||||
|
Phone = responseData.Phone;
|
||||||
|
Address = responseData.Address;
|
||||||
|
Website = responseData.Website;
|
||||||
|
Twitter = responseData.Twitter;
|
||||||
|
Groups = responseData.Groups ?? Array.Empty<string>();
|
||||||
|
Language = responseData.Language;
|
||||||
|
Locale = responseData.Locale;
|
||||||
|
|
||||||
/// <summary>
|
if (responseData.Quota != null)
|
||||||
/// The location of the user's storage directory.
|
|
||||||
/// </summary>
|
|
||||||
public string? StorageLocation { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The uniquie user id that infos are for.
|
|
||||||
/// </summary>
|
|
||||||
public string? ID { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The last time when the user has logged in to its account.
|
|
||||||
/// </summary>
|
|
||||||
public DateTime LastLogin { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The backend of the user. Common values are "Database" or "LDAP".
|
|
||||||
/// </summary>
|
|
||||||
public string? Backend { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Email address of the user.
|
|
||||||
/// </summary>
|
|
||||||
public string? Email { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The displayname of the user.
|
|
||||||
/// </summary>
|
|
||||||
public string? Displayname { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The displayname of the user.
|
|
||||||
/// </summary>
|
|
||||||
public string? Displayname2 { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The phone number of the user.
|
|
||||||
/// </summary>
|
|
||||||
public string? Phone { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The address of the user.
|
|
||||||
/// </summary>
|
|
||||||
public string? Address { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Website of the user.
|
|
||||||
/// </summary>
|
|
||||||
public string? Website { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The twitter profile name of the user.
|
|
||||||
/// </summary>
|
|
||||||
public string? Twitter { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines the groups the user is member of.
|
|
||||||
/// </summary>
|
|
||||||
public string[] Groups { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The configured language of the user.
|
|
||||||
/// </summary>
|
|
||||||
public string? Language { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The configured location of the user.
|
|
||||||
/// </summary>
|
|
||||||
public string? Locale { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Quota informations for the user.
|
|
||||||
/// </summary>
|
|
||||||
public UserQuota Quota { get; } = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Backend capabilities of the user.
|
|
||||||
/// </summary>
|
|
||||||
public UserBackendCapabilities BackendCapabilities { get; } = new();
|
|
||||||
|
|
||||||
public UserInfo(OcsResponseDataUser responseData)
|
|
||||||
{
|
{
|
||||||
Enabled = Convert.ToBoolean(responseData.Enabled);
|
Quota.Free = responseData.Quota.Free ?? 0;
|
||||||
StorageLocation = responseData.StorageLocation;
|
Quota.Used = responseData.Quota.Used ?? 0;
|
||||||
ID = responseData.ID;
|
Quota.Total = responseData.Quota.Total ?? 0;
|
||||||
LastLogin = responseData.LastLogin.UnixTimeMillisecondsToDateTime();
|
Quota.Relative = responseData.Quota.Relative ?? 0.0F;
|
||||||
Backend = responseData.Backend;
|
Quota.Quota = responseData.Quota.Quota ?? 0;
|
||||||
Email = responseData.Email;
|
}
|
||||||
Displayname = responseData.Displayname;
|
|
||||||
Displayname2 = responseData.Displayname2;
|
|
||||||
Phone = responseData.Phone;
|
|
||||||
Address = responseData.Address;
|
|
||||||
Website = responseData.Website;
|
|
||||||
Twitter = responseData.Twitter;
|
|
||||||
Groups = responseData.Groups ?? Array.Empty<string>();
|
|
||||||
Language = responseData.Language;
|
|
||||||
Locale = responseData.Locale;
|
|
||||||
|
|
||||||
if (responseData.Quota != null)
|
if (responseData.BackendCapabilities != null)
|
||||||
{
|
{
|
||||||
Quota.Free = responseData.Quota.Free ?? 0;
|
BackendCapabilities.SetDisplayName = Convert.ToBoolean(responseData.BackendCapabilities.SetDisplayName);
|
||||||
Quota.Used = responseData.Quota.Used ?? 0;
|
BackendCapabilities.SetPassword = Convert.ToBoolean(responseData.BackendCapabilities.SetPassword);
|
||||||
Quota.Total = responseData.Quota.Total ?? 0;
|
|
||||||
Quota.Relative = responseData.Quota.Relative ?? 0.0F;
|
|
||||||
Quota.Quota = responseData.Quota.Quota ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (responseData.BackendCapabilities != null)
|
|
||||||
{
|
|
||||||
BackendCapabilities.SetDisplayName = Convert.ToBoolean(responseData.BackendCapabilities.SetDisplayName);
|
|
||||||
BackendCapabilities.SetPassword = Convert.ToBoolean(responseData.BackendCapabilities.SetPassword);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,29 @@
|
|||||||
using Newtonsoft.Json;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model
|
public class UserQuota
|
||||||
{
|
{
|
||||||
public class UserQuota
|
/// <summary>
|
||||||
{
|
/// Amount of free bytes left.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Amount of free bytes left.
|
public long Free { get; set; }
|
||||||
/// </summary>
|
|
||||||
public long Free { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Amount of already used bytes.
|
/// Amount of already used bytes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long Used { get; set; }
|
public long Used { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Total amount of all bytes (free + used).
|
/// Total amount of all bytes (free + used).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long Total { get; set; }
|
public long Total { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Relative amount of used quota in percent.
|
/// Relative amount of used quota in percent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float Relative { get; set; }
|
public float Relative { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Total amount of bytes available.
|
/// Total amount of bytes available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long Quota { get; set; }
|
public long Quota { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,91 +1,85 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs;
|
||||||
|
|
||||||
|
public class OcsResponseDataUser : OcsResponseData
|
||||||
{
|
{
|
||||||
public class OcsResponseDataUser : OcsResponseData
|
public class ResponseQuota
|
||||||
{
|
{
|
||||||
public class ResponseQuota
|
[JsonProperty("free")]
|
||||||
{
|
public long? Free { get; set; }
|
||||||
[JsonProperty("free")]
|
|
||||||
public long? Free { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("used")]
|
[JsonProperty("used")]
|
||||||
public long? Used { get; set; }
|
public long? Used { get; set; }
|
||||||
|
|
||||||
[JsonProperty("total")]
|
[JsonProperty("total")]
|
||||||
public long? Total { get; set; }
|
public long? Total { get; set; }
|
||||||
|
|
||||||
[JsonProperty("relative")]
|
[JsonProperty("relative")]
|
||||||
public float? Relative { get; set; }
|
public float? Relative { get; set; }
|
||||||
|
|
||||||
[JsonProperty("quota")]
|
|
||||||
public long? Quota { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ResponseBackendCapabilities
|
|
||||||
{
|
|
||||||
[JsonProperty("setDisplayName")]
|
|
||||||
public bool? SetDisplayName { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("setPassword")]
|
|
||||||
public bool? SetPassword { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty("enabled")]
|
|
||||||
public bool? Enabled { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("storageLocation")]
|
|
||||||
public string? StorageLocation { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("id")]
|
|
||||||
public string? ID { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("lastLogin")]
|
|
||||||
public long? LastLogin { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("backend")]
|
|
||||||
public string? Backend { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("quota")]
|
[JsonProperty("quota")]
|
||||||
public ResponseQuota? Quota { get; set; }
|
public long? Quota { get; set; }
|
||||||
|
|
||||||
[JsonProperty("email")]
|
|
||||||
public string? Email { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("displayname")]
|
|
||||||
public string? Displayname { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("display-name")]
|
|
||||||
public string? Displayname2 { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("phone")]
|
|
||||||
public string? Phone { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("address")]
|
|
||||||
public string? Address { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("website")]
|
|
||||||
public string? Website { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("twitter")]
|
|
||||||
public string? Twitter { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("groups")]
|
|
||||||
public string[]? Groups { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("language")]
|
|
||||||
public string? Language { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("locale")]
|
|
||||||
public string? Locale { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("backendCapabilities")]
|
|
||||||
public ResponseBackendCapabilities? BackendCapabilities { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ResponseBackendCapabilities
|
||||||
|
{
|
||||||
|
[JsonProperty("setDisplayName")]
|
||||||
|
public bool? SetDisplayName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("setPassword")]
|
||||||
|
public bool? SetPassword { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty("enabled")]
|
||||||
|
public bool? Enabled { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("storageLocation")]
|
||||||
|
public string? StorageLocation { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public string? ID { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("lastLogin")]
|
||||||
|
public long? LastLogin { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("backend")]
|
||||||
|
public string? Backend { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("quota")]
|
||||||
|
public ResponseQuota? Quota { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("email")]
|
||||||
|
public string? Email { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("displayname")]
|
||||||
|
public string? Displayname { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("display-name")]
|
||||||
|
public string? Displayname2 { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("phone")]
|
||||||
|
public string? Phone { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("address")]
|
||||||
|
public string? Address { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("website")]
|
||||||
|
public string? Website { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("twitter")]
|
||||||
|
public string? Twitter { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("groups")]
|
||||||
|
public string[]? Groups { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("language")]
|
||||||
|
public string? Language { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("locale")]
|
||||||
|
public string? Locale { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("backendCapabilities")]
|
||||||
|
public ResponseBackendCapabilities? BackendCapabilities { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
using Newtonsoft.Json;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs;
|
||||||
|
|
||||||
|
public class OcsResponseUser : OcsResponse<OcsResponseDataUser>
|
||||||
{
|
{
|
||||||
public class OcsResponseUser : OcsResponse<OcsResponseDataUser>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,18 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
|
||||||
|
|
||||||
|
public class OcsApiCloud : OcsApiBase
|
||||||
{
|
{
|
||||||
public class OcsApiCloud : OcsApiBase
|
public readonly static OcsApiUrlPath OCS_CLOUD_USER_METADATA = new("/ocs/v1.php/cloud/users/{0}");
|
||||||
|
|
||||||
|
public OcsApiCloud(OcsApi manager) : base(manager)
|
||||||
{
|
{
|
||||||
public readonly static OcsApiUrlPath OCS_CLOUD_USER_METADATA = new("/ocs/v1.php/cloud/users/{0}");
|
}
|
||||||
|
|
||||||
public OcsApiCloud(OcsApi manager) : base(manager)
|
public OcsResponseUser? GetUserMeta(string username)
|
||||||
{
|
{
|
||||||
}
|
return Manager.MakeRequestOcs<OcsResponseUser>(HttpMethod.Get, OCS_CLOUD_USER_METADATA.FillParameters(username));
|
||||||
|
|
||||||
public OcsResponseUser? GetUserMeta(string username)
|
|
||||||
{
|
|
||||||
return Manager.MakeRequestOcs<OcsResponseUser>(HttpMethod.Get, OCS_CLOUD_USER_METADATA.FillParameters(username));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,34 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
/* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
|
||||||
using System.Linq;
|
Vor:
|
||||||
using System.Text;
|
using System;
|
||||||
|
Nach:
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
|
using System;
|
||||||
|
*/
|
||||||
|
using
|
||||||
|
/* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
|
||||||
|
Vor:
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
|
Nach:
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
*/
|
||||||
|
Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Core
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Core;
|
||||||
|
|
||||||
|
public class OcsApiCore : OcsApiBase
|
||||||
{
|
{
|
||||||
public class OcsApiCore : OcsApiBase
|
public static readonly OcsApiUrlPath OCS_CORE_APPPASSWORD = "/ocs/v2.php/core/apppassword";
|
||||||
|
|
||||||
|
public OcsApiCore(OcsApi manager) : base(manager)
|
||||||
{
|
{
|
||||||
public static readonly OcsApiUrlPath OCS_CORE_APPPASSWORD = "/ocs/v2.php/core/apppassword";
|
}
|
||||||
|
|
||||||
public OcsApiCore(OcsApi manager) : base(manager)
|
public bool DeleteAppPassword()
|
||||||
{
|
{
|
||||||
}
|
using var msg = Manager.MakeRequest(HttpMethod.Delete, OCS_CORE_APPPASSWORD);
|
||||||
|
return msg != null && msg.IsSuccessStatusCode;
|
||||||
public bool DeleteAppPassword()
|
|
||||||
{
|
|
||||||
using var msg = Manager.MakeRequest(HttpMethod.Delete, OCS_CORE_APPPASSWORD);
|
|
||||||
return msg != null && msg.IsSuccessStatusCode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,34 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
|
||||||
|
|
||||||
|
public class OcsResponseLoginFlowV2
|
||||||
{
|
{
|
||||||
public class OcsResponseLoginFlowV2
|
public class PollData
|
||||||
{
|
{
|
||||||
public class PollData
|
/// <summary>
|
||||||
{
|
/// The login token that has been created for the login process.
|
||||||
/// <summary>
|
/// It can be used to poll the login state.
|
||||||
/// The login token that has been created for the login process.
|
/// </summary>
|
||||||
/// It can be used to poll the login state.
|
[JsonProperty("token")]
|
||||||
/// </summary>
|
public string? Token { get; set; }
|
||||||
[JsonProperty("token")]
|
|
||||||
public string? Token { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("endpoint")]
|
|
||||||
public string? Endpoint { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("poll")]
|
[JsonProperty("endpoint")]
|
||||||
public PollData? Poll { get; set; }
|
public string? Endpoint { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The temporary login url that should be used for login.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("login")]
|
|
||||||
public string? LoginUrl { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("poll")]
|
||||||
|
public PollData? Poll { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The temporary login url that should be used for login.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("login")]
|
||||||
|
public string? LoginUrl { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,24 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
|
||||||
|
|
||||||
|
public class OcsResponseLoginFlowV2Credentials
|
||||||
{
|
{
|
||||||
public class OcsResponseLoginFlowV2Credentials
|
/// <summary>
|
||||||
{
|
/// The server url the login credentials are for.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// The server url the login credentials are for.
|
[JsonProperty("server")]
|
||||||
/// </summary>
|
public string? Server { get; set; }
|
||||||
[JsonProperty("server")]
|
|
||||||
public string? Server { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The login name (username or password) used for the login.
|
/// The login name (username or password) used for the login.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("loginName")]
|
[JsonProperty("loginName")]
|
||||||
public string? LoginName { get; set; }
|
public string? LoginName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The app password that has been generated.
|
/// The app password that has been generated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("appPassword")]
|
[JsonProperty("appPassword")]
|
||||||
public string? AppPassword { get; set; }
|
public string? AppPassword { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,30 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2;
|
||||||
|
|
||||||
|
public class OcsApiLoginFlowV2 : OcsApiBase
|
||||||
{
|
{
|
||||||
public class OcsApiLoginFlowV2 : OcsApiBase
|
private const string OCS_LOGIN_INIT = "/index.php/login/v2";
|
||||||
|
|
||||||
|
public OcsApiLoginFlowV2(OcsApi manager) : base(manager)
|
||||||
{
|
{
|
||||||
private const string OCS_LOGIN_INIT = "/index.php/login/v2";
|
}
|
||||||
|
|
||||||
public OcsApiLoginFlowV2(OcsApi manager) : base(manager)
|
public OcsResponseLoginFlowV2? Init(string url)
|
||||||
{
|
{
|
||||||
}
|
return Manager.MakeRequest<OcsResponseLoginFlowV2>(HttpMethod.Post, url + OCS_LOGIN_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
public OcsResponseLoginFlowV2? Init(string url)
|
public OcsResponseLoginFlowV2Credentials? Poll(OcsResponseLoginFlowV2.PollData poll)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequest<OcsResponseLoginFlowV2>(HttpMethod.Post, url + OCS_LOGIN_INIT);
|
ArgumentNullException.ThrowIfNull(poll?.Endpoint);
|
||||||
}
|
ArgumentNullException.ThrowIfNull(poll?.Token);
|
||||||
|
|
||||||
public OcsResponseLoginFlowV2Credentials? Poll(OcsResponseLoginFlowV2.PollData poll)
|
return Manager.MakeRequest<OcsResponseLoginFlowV2Credentials?>(HttpMethod.Post, poll.Endpoint,
|
||||||
{
|
parameters: new Dictionary<string, string>
|
||||||
ArgumentNullException.ThrowIfNull(poll?.Endpoint);
|
{
|
||||||
ArgumentNullException.ThrowIfNull(poll?.Token);
|
{ "token", poll.Token }
|
||||||
|
});
|
||||||
return Manager.MakeRequest<OcsResponseLoginFlowV2Credentials?>(HttpMethod.Post, poll.Endpoint,
|
|
||||||
parameters: new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "token", poll.Token }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,41 @@
|
|||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud
|
namespace Pilz.Networking.CloudProviders.Nextcloud;
|
||||||
|
|
||||||
|
public static class Extensions
|
||||||
{
|
{
|
||||||
public static class Extensions
|
public static string ToBasicAuth(this OcsApiAuthCredentials? credentials)
|
||||||
{
|
{
|
||||||
public static string ToBasicAuth(this OcsApiAuthCredentials? credentials)
|
if (credentials != null)
|
||||||
{
|
{
|
||||||
if (credentials != null)
|
var creds = $"{credentials?.LoginName}:{credentials?.AppPassword}";
|
||||||
{
|
var bytes = Encoding.UTF8.GetBytes(creds);
|
||||||
var creds = $"{credentials?.LoginName}:{credentials?.AppPassword}";
|
return "Basic " + Convert.ToBase64String(bytes);
|
||||||
var bytes = Encoding.UTF8.GetBytes(creds);
|
|
||||||
return "Basic " + Convert.ToBase64String(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Empty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OcsApiAuthCredentials? ToOcsApiAuthCredentials(this NextcloudLogin? login)
|
return string.Empty;
|
||||||
{
|
}
|
||||||
if (!string.IsNullOrEmpty(login?.LoginName) && !string.IsNullOrEmpty(login?.AppPassword))
|
|
||||||
return new OcsApiAuthCredentials(login.LoginName, login.AppPassword);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static OcsApiUrlPath FillParameters(this OcsApiUrlPath path, params object?[] @params)
|
public static OcsApiAuthCredentials? ToOcsApiAuthCredentials(this NextcloudLogin? login)
|
||||||
{
|
{
|
||||||
return (OcsApiUrlPath)string.Format(path, @params);
|
if (!string.IsNullOrEmpty(login?.LoginName) && !string.IsNullOrEmpty(login?.AppPassword))
|
||||||
}
|
return new OcsApiAuthCredentials(login.LoginName, login.AppPassword);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static DateTime UnixTimeMillisecondsToDateTime(this long? value)
|
public static OcsApiUrlPath FillParameters(this OcsApiUrlPath path, params object?[] @params)
|
||||||
{
|
{
|
||||||
return DateTimeOffset.FromUnixTimeMilliseconds(value ?? 0).DateTime;
|
return (OcsApiUrlPath)string.Format(path, @params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long ToUnixTimeMilliseconds(this DateTime value)
|
public static DateTime UnixTimeMillisecondsToDateTime(this long? value)
|
||||||
{
|
{
|
||||||
return new DateTimeOffset(value).ToUnixTimeMilliseconds();
|
return DateTimeOffset.FromUnixTimeMilliseconds(value ?? 0).DateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long ToUnixTimeMilliseconds(this DateTime value)
|
||||||
|
{
|
||||||
|
return new DateTimeOffset(value).ToUnixTimeMilliseconds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,14 @@
|
|||||||
using System;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client;
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
|
||||||
|
|
||||||
|
/* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
|
||||||
|
Vor:
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
|
Nach:
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -6,150 +16,147 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client;
|
*/
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
|
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
|
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
|
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud
|
namespace Pilz.Networking.CloudProviders.Nextcloud;
|
||||||
|
|
||||||
|
public class NextcloudClient : IDisposable
|
||||||
{
|
{
|
||||||
public class NextcloudClient : IDisposable
|
private readonly List<ClientBase> clients = new();
|
||||||
|
private NextcloudLogin? currentLogin;
|
||||||
|
|
||||||
|
public OcsApi Ocs { get; init; } = new();
|
||||||
|
|
||||||
|
public NextcloudLogin? CurrentLogin
|
||||||
{
|
{
|
||||||
private readonly List<ClientBase> clients = new();
|
get => currentLogin;
|
||||||
private NextcloudLogin? currentLogin;
|
private set
|
||||||
|
|
||||||
public OcsApi Ocs { get; init; } = new();
|
|
||||||
|
|
||||||
public NextcloudLogin? CurrentLogin
|
|
||||||
{
|
{
|
||||||
get => currentLogin;
|
currentLogin = value;
|
||||||
private set
|
Ocs.BaseUrl = value?.Server ?? string.Empty;
|
||||||
{
|
|
||||||
currentLogin = value;
|
|
||||||
Ocs.BaseUrl = value?.Server ?? string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloudClient Cloud => GetClient<CloudClient>();
|
|
||||||
|
|
||||||
public NextcloudClient()
|
|
||||||
{
|
|
||||||
Ocs.GetOcsApiAuthCredentails += Ocs_GetOcsApiAuthCredentails;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Ocs_GetOcsApiAuthCredentails(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
if (sender == Ocs)
|
|
||||||
eventArgs.Credentials = CurrentLogin.ToOcsApiAuthCredentials();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TClient GetClient<TClient>() where TClient : ClientBase
|
|
||||||
{
|
|
||||||
var instance = TryGetClient<TClient>();
|
|
||||||
return instance is null ? throw new NullReferenceException() : instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TClient? TryGetClient<TClient>() where TClient : ClientBase
|
|
||||||
{
|
|
||||||
TClient? instance = (TClient?)clients.FirstOrDefault(n => n is TClient);
|
|
||||||
|
|
||||||
instance ??= (TClient?)Activator.CreateInstance(typeof(TClient), new object[] { this });
|
|
||||||
|
|
||||||
if (instance is not null)
|
|
||||||
clients.Add(instance);
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserInfo? Login(NextcloudLogin login)
|
|
||||||
{
|
|
||||||
return Login(login, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserInfo? Login(NextcloudLogin login, bool checkUser)
|
|
||||||
{
|
|
||||||
// Ensure we are logged out
|
|
||||||
Logout(false);
|
|
||||||
|
|
||||||
// Temporary set user login
|
|
||||||
CurrentLogin = login;
|
|
||||||
|
|
||||||
if (checkUser)
|
|
||||||
{
|
|
||||||
// Try get user info & check if user is enabled
|
|
||||||
var userInfo = Cloud.GetUserInfo();
|
|
||||||
var isValid = userInfo != null /*&& userInfo.Enabled*/; // Enabled is false for some (new) users but they still are able to login??
|
|
||||||
|
|
||||||
// If invalid, reset login credentials
|
|
||||||
if (!isValid)
|
|
||||||
CurrentLogin = null;
|
|
||||||
|
|
||||||
return userInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NextcloudLogin? Login(string baseUrl, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// Ensure we are logged out
|
|
||||||
Logout(false);
|
|
||||||
|
|
||||||
// Init the login process
|
|
||||||
var initResponse = Ocs.LoginFlowV2.Init(baseUrl);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(initResponse?.LoginUrl) && initResponse.Poll != null)
|
|
||||||
{
|
|
||||||
// Open the browser
|
|
||||||
Process.Start(new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = initResponse.LoginUrl,
|
|
||||||
UseShellExecute = true
|
|
||||||
});
|
|
||||||
|
|
||||||
// Poll for credentails in intervals
|
|
||||||
OcsResponseLoginFlowV2Credentials? pollResponse = null;
|
|
||||||
while (!cancellationToken.IsCancellationRequested && pollResponse is null)
|
|
||||||
{
|
|
||||||
// Wait 5 seconds
|
|
||||||
Thread.Sleep(5000);
|
|
||||||
|
|
||||||
// Poll the credentials
|
|
||||||
if (!cancellationToken.IsCancellationRequested)
|
|
||||||
pollResponse = Ocs.LoginFlowV2.Poll(initResponse.Poll);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check login credentials
|
|
||||||
if (pollResponse is not null)
|
|
||||||
CurrentLogin = new(pollResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CurrentLogin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Logout()
|
|
||||||
{
|
|
||||||
Logout(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Logout(bool logoutOnServer)
|
|
||||||
{
|
|
||||||
if (CurrentLogin != null)
|
|
||||||
{
|
|
||||||
// Delete currently used app password
|
|
||||||
if (logoutOnServer)
|
|
||||||
Ocs.Core.DeleteAppPassword();
|
|
||||||
|
|
||||||
// Reset current login infos
|
|
||||||
CurrentLogin = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Ocs.Dispose();
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CloudClient Cloud => GetClient<CloudClient>();
|
||||||
|
|
||||||
|
public NextcloudClient()
|
||||||
|
{
|
||||||
|
Ocs.GetOcsApiAuthCredentails += Ocs_GetOcsApiAuthCredentails;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Ocs_GetOcsApiAuthCredentails(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
if (sender == Ocs)
|
||||||
|
eventArgs.Credentials = CurrentLogin.ToOcsApiAuthCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TClient GetClient<TClient>() where TClient : ClientBase
|
||||||
|
{
|
||||||
|
var instance = TryGetClient<TClient>();
|
||||||
|
return instance is null ? throw new NullReferenceException() : instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TClient? TryGetClient<TClient>() where TClient : ClientBase
|
||||||
|
{
|
||||||
|
TClient? instance = (TClient?)clients.FirstOrDefault(n => n is TClient);
|
||||||
|
|
||||||
|
instance ??= (TClient?)Activator.CreateInstance(typeof(TClient), new object[] { this });
|
||||||
|
|
||||||
|
if (instance is not null)
|
||||||
|
clients.Add(instance);
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserInfo? Login(NextcloudLogin login)
|
||||||
|
{
|
||||||
|
return Login(login, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserInfo? Login(NextcloudLogin login, bool checkUser)
|
||||||
|
{
|
||||||
|
// Ensure we are logged out
|
||||||
|
Logout(false);
|
||||||
|
|
||||||
|
// Temporary set user login
|
||||||
|
CurrentLogin = login;
|
||||||
|
|
||||||
|
if (checkUser)
|
||||||
|
{
|
||||||
|
// Try get user info & check if user is enabled
|
||||||
|
var userInfo = Cloud.GetUserInfo();
|
||||||
|
var isValid = userInfo != null /*&& userInfo.Enabled*/; // Enabled is false for some (new) users but they still are able to login??
|
||||||
|
|
||||||
|
// If invalid, reset login credentials
|
||||||
|
if (!isValid)
|
||||||
|
CurrentLogin = null;
|
||||||
|
|
||||||
|
return userInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NextcloudLogin? Login(string baseUrl, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Ensure we are logged out
|
||||||
|
Logout(false);
|
||||||
|
|
||||||
|
// Init the login process
|
||||||
|
var initResponse = Ocs.LoginFlowV2.Init(baseUrl);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(initResponse?.LoginUrl) && initResponse.Poll != null)
|
||||||
|
{
|
||||||
|
// Open the browser
|
||||||
|
Process.Start(new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = initResponse.LoginUrl,
|
||||||
|
UseShellExecute = true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Poll for credentails in intervals
|
||||||
|
OcsResponseLoginFlowV2Credentials? pollResponse = null;
|
||||||
|
while (!cancellationToken.IsCancellationRequested && pollResponse is null)
|
||||||
|
{
|
||||||
|
// Wait 5 seconds
|
||||||
|
Thread.Sleep(5000);
|
||||||
|
|
||||||
|
// Poll the credentials
|
||||||
|
if (!cancellationToken.IsCancellationRequested)
|
||||||
|
pollResponse = Ocs.LoginFlowV2.Poll(initResponse.Poll);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check login credentials
|
||||||
|
if (pollResponse is not null)
|
||||||
|
CurrentLogin = new(pollResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CurrentLogin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Logout()
|
||||||
|
{
|
||||||
|
Logout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Logout(bool logoutOnServer)
|
||||||
|
{
|
||||||
|
if (CurrentLogin != null)
|
||||||
|
{
|
||||||
|
// Delete currently used app password
|
||||||
|
if (logoutOnServer)
|
||||||
|
Ocs.Core.DeleteAppPassword();
|
||||||
|
|
||||||
|
// Reset current login infos
|
||||||
|
CurrentLogin = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Ocs.Dispose();
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,32 @@
|
|||||||
using Newtonsoft.Json;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud
|
namespace Pilz.Networking.CloudProviders.Nextcloud;
|
||||||
|
|
||||||
|
public class NextcloudLogin
|
||||||
{
|
{
|
||||||
public class NextcloudLogin
|
/// <summary>
|
||||||
|
/// The server url the login credentials are for.
|
||||||
|
/// </summary>
|
||||||
|
public string? Server { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The login name (username or password) used for the login.
|
||||||
|
/// </summary>
|
||||||
|
public string? LoginName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The app password that has been generated.
|
||||||
|
/// </summary>
|
||||||
|
public string? AppPassword { get; set; }
|
||||||
|
|
||||||
|
public NextcloudLogin()
|
||||||
{
|
{
|
||||||
/// <summary>
|
}
|
||||||
/// The server url the login credentials are for.
|
|
||||||
/// </summary>
|
|
||||||
public string? Server { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public NextcloudLogin(OcsResponseLoginFlowV2Credentials response)
|
||||||
/// The login name (username or password) used for the login.
|
{
|
||||||
/// </summary>
|
Server = response.Server;
|
||||||
public string? LoginName { get; set; }
|
LoginName = response.LoginName;
|
||||||
|
AppPassword = response.AppPassword;
|
||||||
/// <summary>
|
|
||||||
/// The app password that has been generated.
|
|
||||||
/// </summary>
|
|
||||||
public string? AppPassword { get; set; }
|
|
||||||
|
|
||||||
public NextcloudLogin()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public NextcloudLogin(OcsResponseLoginFlowV2Credentials response)
|
|
||||||
{
|
|
||||||
Server = response.Server;
|
|
||||||
LoginName = response.LoginName;
|
|
||||||
AppPassword = response.AppPassword;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,8 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs
|
public delegate void GetOcsApiAuthCredentailsEventHandler(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs);
|
||||||
|
|
||||||
|
public class GetOcsApiAuthCredentailsEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public delegate void GetOcsApiAuthCredentailsEventHandler(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs);
|
public OcsApiAuthCredentials? Credentials { get; set; }
|
||||||
|
|
||||||
public class GetOcsApiAuthCredentailsEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public OcsApiAuthCredentials? Credentials { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,218 +1,226 @@
|
|||||||
using System;
|
/* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
|
||||||
|
Vor:
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Diagnostics;
|
Nach:
|
||||||
using System.Net;
|
using Newtonsoft.Json;
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.Core;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.Core;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2;
|
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
|
using System;
|
||||||
|
using System.Json;
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs
|
/* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
|
||||||
|
Vor:
|
||||||
|
using
|
||||||
|
Nach:
|
||||||
|
using
|
||||||
|
*/
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
|
|
||||||
|
public class OcsApi : IDisposable
|
||||||
{
|
{
|
||||||
public class OcsApi : IDisposable
|
public const string CONTENT_TYPE_JSON = "application/json";
|
||||||
|
|
||||||
|
public event GetOcsApiAuthCredentailsEventHandler? GetOcsApiAuthCredentails;
|
||||||
|
|
||||||
|
private readonly HttpClient client = new();
|
||||||
|
private readonly List<OcsApiBase> apis = new();
|
||||||
|
|
||||||
|
public string BaseUrl { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public OcsApiLoginFlowV2 LoginFlowV2 => GetApi<OcsApiLoginFlowV2>();
|
||||||
|
public OcsApiCore Core => GetApi<OcsApiCore>();
|
||||||
|
public OcsApiCloud Cloud => GetApi<OcsApiCloud>();
|
||||||
|
|
||||||
|
public TApi GetApi<TApi>() where TApi : OcsApiBase
|
||||||
{
|
{
|
||||||
public const string CONTENT_TYPE_JSON = "application/json";
|
var instance = TryGetApi<TApi>();
|
||||||
|
return instance is null ? throw new NullReferenceException() : instance;
|
||||||
|
}
|
||||||
|
|
||||||
public event GetOcsApiAuthCredentailsEventHandler? GetOcsApiAuthCredentails;
|
public TApi? TryGetApi<TApi>() where TApi : OcsApiBase
|
||||||
|
{
|
||||||
|
TApi? instance = (TApi?)apis.FirstOrDefault(n => n is TApi);
|
||||||
|
|
||||||
private readonly HttpClient client = new();
|
instance ??= (TApi?)Activator.CreateInstance(typeof(TApi), new object[] { this });
|
||||||
private readonly List<OcsApiBase> apis = new();
|
|
||||||
|
|
||||||
public string BaseUrl { get; set; } = string.Empty;
|
if (instance is not null)
|
||||||
|
apis.Add(instance);
|
||||||
|
|
||||||
public OcsApiLoginFlowV2 LoginFlowV2 => GetApi<OcsApiLoginFlowV2>();
|
return instance;
|
||||||
public OcsApiCore Core => GetApi<OcsApiCore>();
|
}
|
||||||
public OcsApiCloud Cloud => GetApi<OcsApiCloud>();
|
|
||||||
|
|
||||||
public TApi GetApi<TApi>() where TApi : OcsApiBase
|
public string BuildFullUrl(OcsApiUrlPath path)
|
||||||
|
{
|
||||||
|
return BaseUrl + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes an request with the given arguments and deserialize it to the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TResponse"></typeparam>
|
||||||
|
/// <param name="httpMethod"></param>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <param name="useAuthentication"></param>
|
||||||
|
/// <param name="parameters"></param>
|
||||||
|
/// <param name="content"></param>
|
||||||
|
/// <returns>Returns the given OcsResponse type from the deserialized OcsApiResponse content.</returns>
|
||||||
|
public TResponse? MakeRequestOcs<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) where TResponse : IOcsResponse
|
||||||
|
{
|
||||||
|
return MakeRequestOcs<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes an request with the given arguments and deserialize it to the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TResponse"></typeparam>
|
||||||
|
/// <param name="httpMethod"></param>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <param name="useAuthentication"></param>
|
||||||
|
/// <param name="parameters"></param>
|
||||||
|
/// <param name="content"></param>
|
||||||
|
/// <returns>Returns the given OcsResponse type from the deserialized OcsApiResponse content.</returns>
|
||||||
|
public TResponse? MakeRequestOcs<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) where TResponse : IOcsResponse
|
||||||
|
{
|
||||||
|
var response = MakeRequest<OcsApiResponse<TResponse>?>(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
|
||||||
|
|
||||||
|
if (response != null)
|
||||||
|
return response.Ocs;
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes an request with the given arguments and deserialize it to the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TResponse"></typeparam>
|
||||||
|
/// <param name="httpMethod"></param>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <param name="useAuthentication"></param>
|
||||||
|
/// <param name="parameters"></param>
|
||||||
|
/// <param name="content"></param>
|
||||||
|
/// <returns>Returns the deserialized content of type given type.</returns>
|
||||||
|
public TResponse? MakeRequest<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
||||||
|
{
|
||||||
|
return MakeRequest<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes an request with the given arguments and deserialize it to the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TResponse"></typeparam>
|
||||||
|
/// <param name="httpMethod"></param>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <param name="useAuthentication"></param>
|
||||||
|
/// <param name="parameters"></param>
|
||||||
|
/// <param name="content"></param>
|
||||||
|
/// <returns>Returns the deserialized content of type given type.</returns>
|
||||||
|
public TResponse? MakeRequest<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
||||||
|
{
|
||||||
|
using var responseInit = MakeRequest(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
|
||||||
|
|
||||||
|
if (responseInit != null)
|
||||||
{
|
{
|
||||||
var instance = TryGetApi<TApi>();
|
try
|
||||||
return instance is null ? throw new NullReferenceException() : instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TApi? TryGetApi<TApi>() where TApi : OcsApiBase
|
|
||||||
{
|
|
||||||
TApi? instance = (TApi?)apis.FirstOrDefault(n => n is TApi);
|
|
||||||
|
|
||||||
instance ??= (TApi?)Activator.CreateInstance(typeof(TApi), new object[] { this });
|
|
||||||
|
|
||||||
if (instance is not null)
|
|
||||||
apis.Add(instance);
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string BuildFullUrl(OcsApiUrlPath path)
|
|
||||||
{
|
|
||||||
return BaseUrl + path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Makes an request with the given arguments and deserialize it to the given type.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse"></typeparam>
|
|
||||||
/// <param name="httpMethod"></param>
|
|
||||||
/// <param name="url"></param>
|
|
||||||
/// <param name="useAuthentication"></param>
|
|
||||||
/// <param name="parameters"></param>
|
|
||||||
/// <param name="content"></param>
|
|
||||||
/// <returns>Returns the given OcsResponse type from the deserialized OcsApiResponse content.</returns>
|
|
||||||
public TResponse? MakeRequestOcs<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) where TResponse : IOcsResponse
|
|
||||||
{
|
|
||||||
return MakeRequestOcs<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Makes an request with the given arguments and deserialize it to the given type.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse"></typeparam>
|
|
||||||
/// <param name="httpMethod"></param>
|
|
||||||
/// <param name="url"></param>
|
|
||||||
/// <param name="useAuthentication"></param>
|
|
||||||
/// <param name="parameters"></param>
|
|
||||||
/// <param name="content"></param>
|
|
||||||
/// <returns>Returns the given OcsResponse type from the deserialized OcsApiResponse content.</returns>
|
|
||||||
public TResponse? MakeRequestOcs<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) where TResponse : IOcsResponse
|
|
||||||
{
|
|
||||||
var response = MakeRequest<OcsApiResponse<TResponse>?>(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
|
|
||||||
|
|
||||||
if (response != null)
|
|
||||||
return response.Ocs;
|
|
||||||
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Makes an request with the given arguments and deserialize it to the given type.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse"></typeparam>
|
|
||||||
/// <param name="httpMethod"></param>
|
|
||||||
/// <param name="url"></param>
|
|
||||||
/// <param name="useAuthentication"></param>
|
|
||||||
/// <param name="parameters"></param>
|
|
||||||
/// <param name="content"></param>
|
|
||||||
/// <returns>Returns the deserialized content of type given type.</returns>
|
|
||||||
public TResponse? MakeRequest<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
|
||||||
{
|
|
||||||
return MakeRequest<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Makes an request with the given arguments and deserialize it to the given type.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResponse"></typeparam>
|
|
||||||
/// <param name="httpMethod"></param>
|
|
||||||
/// <param name="url"></param>
|
|
||||||
/// <param name="useAuthentication"></param>
|
|
||||||
/// <param name="parameters"></param>
|
|
||||||
/// <param name="content"></param>
|
|
||||||
/// <returns>Returns the deserialized content of type given type.</returns>
|
|
||||||
public TResponse? MakeRequest<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
|
||||||
{
|
|
||||||
using var responseInit = MakeRequest(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
|
|
||||||
|
|
||||||
if (responseInit != null)
|
|
||||||
{
|
{
|
||||||
try
|
var bodyInit = responseInit.Content.ReadAsStringAsync().Result;
|
||||||
{
|
return JsonConvert.DeserializeObject<TResponse>(bodyInit);
|
||||||
var bodyInit = responseInit.Content.ReadAsStringAsync().Result;
|
|
||||||
return JsonConvert.DeserializeObject<TResponse>(bodyInit);
|
|
||||||
}
|
|
||||||
catch(FormatException) { }
|
|
||||||
catch(JsonSerializationException) { }
|
|
||||||
}
|
}
|
||||||
|
catch (FormatException) { }
|
||||||
return default;
|
catch (JsonSerializationException) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
return default;
|
||||||
/// Makes an request with the given arguments.
|
}
|
||||||
/// </summary>
|
|
||||||
/// <param name="httpMethod"></param>
|
/// <summary>
|
||||||
/// <param name="url"></param>
|
/// Makes an request with the given arguments.
|
||||||
/// <param name="useAuthentication"></param>
|
/// </summary>
|
||||||
/// <param name="parameters"></param>
|
/// <param name="httpMethod"></param>
|
||||||
/// <param name="content"></param>
|
/// <param name="url"></param>
|
||||||
/// <returns>Returns a HttpResponseMessage as result.</returns>
|
/// <param name="useAuthentication"></param>
|
||||||
public HttpResponseMessage MakeRequest(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
/// <param name="parameters"></param>
|
||||||
|
/// <param name="content"></param>
|
||||||
|
/// <returns>Returns a HttpResponseMessage as result.</returns>
|
||||||
|
public HttpResponseMessage MakeRequest(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
||||||
|
{
|
||||||
|
return MakeRequest(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes an request with the given arguments.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="httpMethod"></param>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <param name="useAuthentication"></param>
|
||||||
|
/// <param name="parameters"></param>
|
||||||
|
/// <param name="content"></param>
|
||||||
|
/// <returns>Returns a HttpResponseMessage as result.</returns>
|
||||||
|
public HttpResponseMessage MakeRequest(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
||||||
|
{
|
||||||
|
OcsApiAuthCredentials? authentication;
|
||||||
|
string @params;
|
||||||
|
HttpContent? httpContent;
|
||||||
|
|
||||||
|
// Get authentication
|
||||||
|
if (useAuthentication)
|
||||||
{
|
{
|
||||||
return MakeRequest(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
|
var args = new GetOcsApiAuthCredentailsEventArgs();
|
||||||
|
GetOcsApiAuthCredentails?.Invoke(this, args);
|
||||||
|
authentication = args.Credentials;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
authentication = null;
|
||||||
|
|
||||||
/// <summary>
|
// Parse params
|
||||||
/// Makes an request with the given arguments.
|
if (parameters != null)
|
||||||
/// </summary>
|
@params = "?" + string.Join("&", parameters.Select(p => $"{p.Key}={p.Value}"));
|
||||||
/// <param name="httpMethod"></param>
|
else
|
||||||
/// <param name="url"></param>
|
@params = string.Empty;
|
||||||
/// <param name="useAuthentication"></param>
|
|
||||||
/// <param name="parameters"></param>
|
// Create content
|
||||||
/// <param name="content"></param>
|
if (content is HttpContent contentHttp)
|
||||||
/// <returns>Returns a HttpResponseMessage as result.</returns>
|
httpContent = contentHttp;
|
||||||
public HttpResponseMessage MakeRequest(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
else if (content is OcsData || content is not null)
|
||||||
{
|
{
|
||||||
OcsApiAuthCredentials? authentication;
|
var stringContent = JsonConvert.SerializeObject(content);
|
||||||
string @params;
|
httpContent = new StringContent(stringContent, null, CONTENT_TYPE_JSON);
|
||||||
HttpContent? httpContent;
|
|
||||||
|
|
||||||
// Get authentication
|
|
||||||
if (useAuthentication)
|
|
||||||
{
|
|
||||||
var args = new GetOcsApiAuthCredentailsEventArgs();
|
|
||||||
GetOcsApiAuthCredentails?.Invoke(this, args);
|
|
||||||
authentication = args.Credentials;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
authentication = null;
|
|
||||||
|
|
||||||
// Parse params
|
|
||||||
if (parameters != null)
|
|
||||||
@params = "?" + string.Join("&", parameters.Select(p => $"{p.Key}={p.Value}"));
|
|
||||||
else
|
|
||||||
@params = string.Empty;
|
|
||||||
|
|
||||||
// Create content
|
|
||||||
if (content is HttpContent contentHttp)
|
|
||||||
httpContent = contentHttp;
|
|
||||||
else if (content is OcsData || content is not null)
|
|
||||||
{
|
|
||||||
var stringContent = JsonConvert.SerializeObject(content);
|
|
||||||
httpContent = new StringContent(stringContent, null, CONTENT_TYPE_JSON);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
httpContent = null;
|
|
||||||
|
|
||||||
// Send request
|
|
||||||
var request = new HttpRequestMessage
|
|
||||||
{
|
|
||||||
Method = httpMethod ?? HttpMethod.Post,
|
|
||||||
RequestUri = new Uri(url + @params),
|
|
||||||
Headers =
|
|
||||||
{
|
|
||||||
{ "Accept", CONTENT_TYPE_JSON },
|
|
||||||
{ "OCS-APIREQUEST", "true" },
|
|
||||||
//{ "Authorization", authentication.ToBasicAuth() }
|
|
||||||
},
|
|
||||||
Content = httpContent
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add authorization
|
|
||||||
if (authentication != null)
|
|
||||||
request.Headers.Add("Authorization", authentication.ToBasicAuth());
|
|
||||||
|
|
||||||
return client.Send(request);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
httpContent = null;
|
||||||
|
|
||||||
public void Dispose()
|
// Send request
|
||||||
|
var request = new HttpRequestMessage
|
||||||
{
|
{
|
||||||
client.Dispose();
|
Method = httpMethod ?? HttpMethod.Post,
|
||||||
GC.SuppressFinalize(this);
|
RequestUri = new Uri(url + @params),
|
||||||
}
|
Headers =
|
||||||
|
{
|
||||||
|
{ "Accept", CONTENT_TYPE_JSON },
|
||||||
|
{ "OCS-APIREQUEST", "true" },
|
||||||
|
//{ "Authorization", authentication.ToBasicAuth() }
|
||||||
|
},
|
||||||
|
Content = httpContent
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add authorization
|
||||||
|
if (authentication != null)
|
||||||
|
request.Headers.Add("Authorization", authentication.ToBasicAuth());
|
||||||
|
|
||||||
|
return client.Send(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
client.Dispose();
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,13 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection.Emit;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs
|
public struct OcsApiAuthCredentials
|
||||||
{
|
{
|
||||||
public struct OcsApiAuthCredentials
|
public string LoginName { get; set; }
|
||||||
{
|
public string AppPassword { get; set; }
|
||||||
public string LoginName { get; set; }
|
|
||||||
public string AppPassword { get; set; }
|
|
||||||
|
|
||||||
public OcsApiAuthCredentials(string loginName, string appPassword)
|
public OcsApiAuthCredentials(string loginName, string appPassword)
|
||||||
{
|
{
|
||||||
LoginName = loginName;
|
LoginName = loginName;
|
||||||
AppPassword = appPassword;
|
AppPassword = appPassword;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs
|
public abstract class OcsApiBase
|
||||||
{
|
{
|
||||||
public abstract class OcsApiBase
|
protected OcsApi Manager { get; init; }
|
||||||
{
|
|
||||||
protected OcsApi Manager { get; init; }
|
|
||||||
|
|
||||||
protected OcsApiBase(OcsApi manager)
|
protected OcsApiBase(OcsApi manager)
|
||||||
{
|
{
|
||||||
Manager = manager;
|
Manager = manager;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,10 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
|
|
||||||
|
public class OcsApiResponse<TOcsResponse> where TOcsResponse : IOcsResponse
|
||||||
{
|
{
|
||||||
public class OcsApiResponse<TOcsResponse> where TOcsResponse : IOcsResponse
|
[JsonProperty("ocs")]
|
||||||
{
|
public TOcsResponse? Ocs { get; set; }
|
||||||
[JsonProperty("ocs")]
|
|
||||||
public TOcsResponse? Ocs { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,24 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs
|
public readonly struct OcsApiUrlPath
|
||||||
{
|
{
|
||||||
public readonly struct OcsApiUrlPath
|
private readonly string path;
|
||||||
|
|
||||||
|
public OcsApiUrlPath()
|
||||||
{
|
{
|
||||||
private readonly string path;
|
path = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
public OcsApiUrlPath()
|
public OcsApiUrlPath(string path)
|
||||||
{
|
{
|
||||||
path = string.Empty;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OcsApiUrlPath(string path)
|
public static implicit operator string(OcsApiUrlPath o) => o.path;
|
||||||
{
|
public static implicit operator OcsApiUrlPath(string o) => new(o);
|
||||||
this.path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator string(OcsApiUrlPath o) => o.path;
|
public override readonly string ToString()
|
||||||
public static implicit operator OcsApiUrlPath(string o) => new(o);
|
{
|
||||||
|
return path;
|
||||||
public override readonly string ToString()
|
|
||||||
{
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs
|
public class OcsData
|
||||||
{
|
{
|
||||||
public class OcsData
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses
|
public interface IOcsResponse
|
||||||
{
|
{
|
||||||
public interface IOcsResponse
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses
|
public interface IOcsResponseData
|
||||||
{
|
{
|
||||||
public interface IOcsResponseData
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses
|
public interface IOcsResponseMeta
|
||||||
{
|
{
|
||||||
public interface IOcsResponseMeta
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,20 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
|
|
||||||
|
public class OcsResponse<TMeta, TData> : IOcsResponse where TMeta : IOcsResponseMeta where TData : IOcsResponseData
|
||||||
{
|
{
|
||||||
public class OcsResponse<TMeta, TData> : IOcsResponse where TMeta : IOcsResponseMeta where TData : IOcsResponseData
|
[JsonProperty("meta")]
|
||||||
{
|
public TMeta? Meta { get; set; }
|
||||||
[JsonProperty("meta")]
|
|
||||||
public TMeta? Meta { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("data")]
|
[JsonProperty("data")]
|
||||||
public TData? Data { get; set; }
|
public TData? Data { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OcsResponse<TData> : OcsResponse<OcsResponseMeta, TData> where TData : IOcsResponseData
|
public class OcsResponse<TData> : OcsResponse<OcsResponseMeta, TData> where TData : IOcsResponseData
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OcsResponse : OcsResponse<OcsResponseMeta, OcsResponseData>
|
public class OcsResponse : OcsResponse<OcsResponseMeta, OcsResponseData>
|
||||||
{
|
{
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses
|
public class OcsResponseData : IOcsResponseData
|
||||||
{
|
{
|
||||||
public class OcsResponseData : IOcsResponseData
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses
|
public class OcsResponseDataArray<TEntry> : List<TEntry>, IOcsResponseData where TEntry : OcsResponseDataEntry
|
||||||
{
|
{
|
||||||
public class OcsResponseDataArray<TEntry> : List<TEntry>, IOcsResponseData where TEntry : OcsResponseDataEntry
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System;
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses
|
public class OcsResponseDataEntry
|
||||||
{
|
{
|
||||||
public class OcsResponseDataEntry
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,15 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
|
||||||
|
|
||||||
|
public class OcsResponseMeta : IOcsResponseMeta
|
||||||
{
|
{
|
||||||
public class OcsResponseMeta : IOcsResponseMeta
|
[JsonProperty("status")]
|
||||||
{
|
public string? Status { get; set; }
|
||||||
[JsonProperty("status")]
|
|
||||||
public string? Status { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("statuscode")]
|
[JsonProperty("statuscode")]
|
||||||
public int? StatusCode { get; set; }
|
public int? StatusCode { get; set; }
|
||||||
|
|
||||||
[JsonProperty("message")]
|
[JsonProperty("message")]
|
||||||
public string? Message { get; set; }
|
public string? Message { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
Imports System.IO
|
Imports System.IO
|
||||||
Imports System.Net
|
Imports System.Net
|
||||||
|
|
||||||
Imports Newtonsoft.Json.Linq
|
Imports Newtonsoft.Json.Linq
|
||||||
|
|
||||||
Public MustInherit Class ConnectionManagerBase
|
Public MustInherit Class ConnectionManagerBase
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
Imports System.IO
|
Imports System.Net
|
||||||
Imports System.Net
|
|
||||||
Imports System.Net.NetworkInformation
|
' Nicht gemergte Änderung aus Projekt "Pilz.Networking (net8.0-windows)"
|
||||||
|
' Vor:
|
||||||
|
' Imports System.Net.Sockets
|
||||||
|
' Imports Newtonsoft.Json.Linq
|
||||||
|
' Nach:
|
||||||
|
' Imports System.Net.Sockets
|
||||||
|
'
|
||||||
|
' Imports Newtonsoft.Json.Linq
|
||||||
Imports System.Net.Sockets
|
Imports System.Net.Sockets
|
||||||
Imports Newtonsoft.Json.Linq
|
|
||||||
|
|
||||||
Public Class TCPManager
|
Public Class TCPManager
|
||||||
Inherits ConnectionManagerBase
|
Inherits ConnectionManagerBase
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
Imports System.IO
|
Imports System.Net
|
||||||
Imports System.Net
|
|
||||||
Imports System.Net.NetworkInformation
|
|
||||||
Imports System.Net.Sockets
|
Imports System.Net.Sockets
|
||||||
|
|
||||||
|
' Nicht gemergte Änderung aus Projekt "Pilz.Networking (net8.0-windows)"
|
||||||
|
' Vor:
|
||||||
|
' Imports System.Threading
|
||||||
|
' Imports Newtonsoft.Json.Linq
|
||||||
|
' Nach:
|
||||||
|
' Imports System.Threading
|
||||||
|
'
|
||||||
|
' Imports Newtonsoft.Json.Linq
|
||||||
Imports System.Threading
|
Imports System.Threading
|
||||||
Imports Newtonsoft.Json.Linq
|
|
||||||
|
|
||||||
Public Class UDPManager
|
Public Class UDPManager
|
||||||
Inherits ConnectionManagerBase
|
Inherits ConnectionManagerBase
|
||||||
|
|||||||
@@ -1,125 +1,121 @@
|
|||||||
using System.Drawing;
|
using Telerik.WinControls;
|
||||||
using System.Reflection;
|
|
||||||
using Telerik.WinControls;
|
|
||||||
using Telerik.WinControls.Elements;
|
|
||||||
using Telerik.WinControls.UI;
|
using Telerik.WinControls.UI;
|
||||||
|
|
||||||
namespace Pilz.Plugins.Advanced.UI.Telerik
|
namespace Pilz.Plugins.Advanced.UI.Telerik;
|
||||||
|
|
||||||
|
public static class Extensions
|
||||||
{
|
{
|
||||||
public static class Extensions
|
public static Icon? ToIcon(this Image image)
|
||||||
{
|
{
|
||||||
public static Icon? ToIcon(this Image image)
|
if (image is Bitmap bitmap)
|
||||||
{
|
return Icon.FromHandle(bitmap.GetHicon());
|
||||||
if (image is Bitmap bitmap)
|
return null;
|
||||||
return Icon.FromHandle(bitmap.GetHicon());
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RadMenuItem GetAsItem(this PluginModuleBase module)
|
public static RadMenuItem GetAsItem(this PluginModuleBase module)
|
||||||
{
|
{
|
||||||
return GetAsItem(module, true);
|
return GetAsItem(module, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RadMenuItem GetAsItem(this PluginModuleBase module, bool addDefaultHandler)
|
public static RadMenuItem GetAsItem(this PluginModuleBase module, bool addDefaultHandler)
|
||||||
{
|
{
|
||||||
return GetAsItem(module, addDefaultHandler ? RadMenuItem_RMMethod_Click : null);
|
return GetAsItem(module, addDefaultHandler ? RadMenuItem_RMMethod_Click : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RadMenuItem GetAsItem(this PluginFunction function)
|
public static RadMenuItem GetAsItem(this PluginFunction function)
|
||||||
{
|
{
|
||||||
return GetAsItem(function, true);
|
return GetAsItem(function, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RadMenuItem GetAsItem(this PluginFunction function, bool addDefaultHandler)
|
public static RadMenuItem GetAsItem(this PluginFunction function, bool addDefaultHandler)
|
||||||
{
|
{
|
||||||
return GetAsItem(function, addDefaultHandler ? RadMenuItem_RMFunction_Click : null);
|
return GetAsItem(function, addDefaultHandler ? RadMenuItem_RMFunction_Click : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RadMenuItem GetAsItem(this PluginFeature module, EventHandler? clickHandler)
|
public static RadMenuItem GetAsItem(this PluginFeature module, EventHandler? clickHandler)
|
||||||
|
{
|
||||||
|
var item = new RadMenuItem
|
||||||
{
|
{
|
||||||
var item = new RadMenuItem
|
Text = module.Name,
|
||||||
|
Image = module.Icon as Image,
|
||||||
|
SvgImage = module.Icon as RadSvgImage,
|
||||||
|
Tag = module,
|
||||||
|
Visibility = module.Enabled ? ElementVisibility.Visible : ElementVisibility.Collapsed
|
||||||
|
};
|
||||||
|
|
||||||
|
if (clickHandler is not null)
|
||||||
|
item.Click += clickHandler;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inserts all items to an item collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="features"></param>
|
||||||
|
/// <param name="itemsCollection">Examples:<br/>
|
||||||
|
/// - <see cref="RadMenuItem.Items"/><br/>
|
||||||
|
/// - <see cref="RadSplitButtonElement.Items"/><br/>
|
||||||
|
/// - <see cref="RadDropDownButtonElement.Items"/><br/>
|
||||||
|
/// - <see cref="RadContextMenu.Items"/><br/>
|
||||||
|
/// - <see cref="RadRibbonBarGroup.Items"/><br/></param>
|
||||||
|
/// <param name="addDefaultHandler">Will add a default click handler that executes the feature.<br/>
|
||||||
|
/// You usually don't set customClickHandler if you set this parameter to <see cref="true"/>.</param>
|
||||||
|
/// <param name="customClickHandler">Adds a custom click handler. If addDefaultHandler is true, it will only work on <see cref="PluginFeature"/>s.<br/>
|
||||||
|
/// You usually don't set addDefaultHandler to true if you set this parameter to something not null.</param>
|
||||||
|
public static void InsertItemsTo(this IEnumerable<PluginFeature> features, RadItemOwnerCollection itemsCollection, bool addDefaultHandler = false, EventHandler? customClickHandler = null, FeatureInsertMode insertMode = FeatureInsertMode.Default, int? customDefault = null, int? customTop = null, int? customBottom = null, FeatureInsertPosition insertSplitter = FeatureInsertPosition.None)
|
||||||
|
{
|
||||||
|
var insertDefault = customDefault ?? (insertMode.HasFlag(FeatureInsertMode.DefaultStart) ? 0 : itemsCollection.Count);
|
||||||
|
var insertTop = customTop ?? (insertMode.HasFlag(FeatureInsertMode.InsertTop) || insertMode.HasFlag(FeatureInsertMode.DefaultStart) ? 0 : insertDefault);
|
||||||
|
var insertBottom = customBottom ?? (insertMode.HasFlag(FeatureInsertMode.InsertBottom) || insertMode.HasFlag(FeatureInsertMode.DefaultEnd) ? itemsCollection.Count : insertDefault);
|
||||||
|
|
||||||
|
foreach (var feature in features)
|
||||||
|
{
|
||||||
|
RadMenuItem item;
|
||||||
|
|
||||||
|
if (feature is PluginFunction function)
|
||||||
|
item = function.GetAsItem(addDefaultHandler);
|
||||||
|
else if (feature is PluginModuleBase module)
|
||||||
|
item = module.GetAsItem(addDefaultHandler);
|
||||||
|
else
|
||||||
|
item = feature.GetAsItem(null);
|
||||||
|
|
||||||
|
if (!addDefaultHandler && customClickHandler != null)
|
||||||
|
item.Click += customClickHandler;
|
||||||
|
|
||||||
|
switch (feature.Prioritization)
|
||||||
{
|
{
|
||||||
Text = module.Name,
|
case FeaturePrioritization.High:
|
||||||
Image = module.Icon as Image,
|
if (insertDefault >= insertTop) insertDefault++;
|
||||||
SvgImage = module.Icon as RadSvgImage,
|
if (insertBottom >= insertTop) insertBottom++;
|
||||||
Tag = module,
|
// ...
|
||||||
Visibility = module.Enabled ? ElementVisibility.Visible : ElementVisibility.Collapsed
|
itemsCollection.Insert(insertTop++, item);
|
||||||
};
|
break;
|
||||||
|
case FeaturePrioritization.Default:
|
||||||
if (clickHandler is not null)
|
if (insertBottom >= insertDefault) insertBottom++;
|
||||||
item.Click += clickHandler;
|
if (insertTop >= insertDefault) insertTop++;
|
||||||
|
// ...
|
||||||
return item;
|
itemsCollection.Insert(insertDefault++, item);
|
||||||
}
|
break;
|
||||||
|
case FeaturePrioritization.Low:
|
||||||
/// <summary>
|
if (insertTop >= insertBottom) insertTop++;
|
||||||
/// Inserts all items to an item collection.
|
if (insertDefault >= insertBottom) insertDefault++;
|
||||||
/// </summary>
|
// ...
|
||||||
/// <param name="features"></param>
|
itemsCollection.Insert(insertBottom++, item);
|
||||||
/// <param name="itemsCollection">Examples:<br/>
|
break;
|
||||||
/// - <see cref="RadMenuItem.Items"/><br/>
|
|
||||||
/// - <see cref="RadSplitButtonElement.Items"/><br/>
|
|
||||||
/// - <see cref="RadDropDownButtonElement.Items"/><br/>
|
|
||||||
/// - <see cref="RadContextMenu.Items"/><br/>
|
|
||||||
/// - <see cref="RadRibbonBarGroup.Items"/><br/></param>
|
|
||||||
/// <param name="addDefaultHandler">Will add a default click handler that executes the feature.<br/>
|
|
||||||
/// You usually don't set customClickHandler if you set this parameter to <see cref="true"/>.</param>
|
|
||||||
/// <param name="customClickHandler">Adds a custom click handler. If addDefaultHandler is true, it will only work on <see cref="PluginFeature"/>s.<br/>
|
|
||||||
/// You usually don't set addDefaultHandler to true if you set this parameter to something not null.</param>
|
|
||||||
public static void InsertItemsTo(this IEnumerable<PluginFeature> features, RadItemOwnerCollection itemsCollection, bool addDefaultHandler = false, EventHandler? customClickHandler = null, FeatureInsertMode insertMode = FeatureInsertMode.Default, int? customDefault = null, int? customTop = null, int? customBottom = null, FeatureInsertPosition insertSplitter = FeatureInsertPosition.None)
|
|
||||||
{
|
|
||||||
var insertDefault = customDefault ?? (insertMode.HasFlag(FeatureInsertMode.DefaultStart) ? 0 : itemsCollection.Count);
|
|
||||||
var insertTop = customTop ?? (insertMode.HasFlag(FeatureInsertMode.InsertTop) || insertMode.HasFlag(FeatureInsertMode.DefaultStart) ? 0 : insertDefault);
|
|
||||||
var insertBottom = customBottom ?? (insertMode.HasFlag(FeatureInsertMode.InsertBottom) || insertMode.HasFlag(FeatureInsertMode.DefaultEnd) ? itemsCollection.Count : insertDefault);
|
|
||||||
|
|
||||||
foreach (var feature in features)
|
|
||||||
{
|
|
||||||
RadMenuItem item;
|
|
||||||
|
|
||||||
if (feature is PluginFunction function)
|
|
||||||
item = function.GetAsItem(addDefaultHandler);
|
|
||||||
else if (feature is PluginModuleBase module)
|
|
||||||
item = module.GetAsItem(addDefaultHandler);
|
|
||||||
else
|
|
||||||
item = feature.GetAsItem(null);
|
|
||||||
|
|
||||||
if (!addDefaultHandler && customClickHandler != null)
|
|
||||||
item.Click += customClickHandler;
|
|
||||||
|
|
||||||
switch (feature.Prioritization)
|
|
||||||
{
|
|
||||||
case FeaturePrioritization.High:
|
|
||||||
if (insertDefault >= insertTop) insertDefault++;
|
|
||||||
if (insertBottom >= insertTop) insertBottom++;
|
|
||||||
// ...
|
|
||||||
itemsCollection.Insert(insertTop++, item);
|
|
||||||
break;
|
|
||||||
case FeaturePrioritization.Default:
|
|
||||||
if (insertBottom >= insertDefault) insertBottom++;
|
|
||||||
if (insertTop >= insertDefault) insertTop++;
|
|
||||||
// ...
|
|
||||||
itemsCollection.Insert(insertDefault++, item);
|
|
||||||
break;
|
|
||||||
case FeaturePrioritization.Low:
|
|
||||||
if (insertTop >= insertBottom) insertTop++;
|
|
||||||
if (insertDefault >= insertBottom) insertDefault++;
|
|
||||||
// ...
|
|
||||||
itemsCollection.Insert(insertBottom++, item);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void RadMenuItem_RMMethod_Click(object? sender, EventArgs e)
|
private static void RadMenuItem_RMMethod_Click(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is RadMenuItem item && item.Tag is PluginModule function)
|
if (sender is RadMenuItem item && item.Tag is PluginModule function)
|
||||||
function.ShowUI();
|
function.ShowUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RadMenuItem_RMFunction_Click(object? sender, EventArgs e)
|
private static void RadMenuItem_RMFunction_Click(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is RadMenuItem item && item.Tag is PluginFunction function)
|
if (sender is RadMenuItem item && item.Tag is PluginFunction function)
|
||||||
function.Execute();
|
function.Execute();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,39 +1,35 @@
|
|||||||
using Pilz.Plugins.Advanced.UI;
|
using Pilz.UI.Telerik;
|
||||||
using Pilz.UI.Telerik;
|
|
||||||
using Pilz.UI.Telerik.Dialogs;
|
using Pilz.UI.Telerik.Dialogs;
|
||||||
using System.Drawing;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using Telerik.WinControls;
|
using Telerik.WinControls;
|
||||||
|
|
||||||
namespace Pilz.Plugins.Advanced.UI.Telerik
|
namespace Pilz.Plugins.Advanced.UI.Telerik;
|
||||||
|
|
||||||
|
public abstract class PluginModule : PluginModule<PluginModuleUI>
|
||||||
{
|
{
|
||||||
public abstract class PluginModule : PluginModule<PluginModuleUI>
|
/// <summary>
|
||||||
|
/// Wrapper for the <see cref="PluginFeature.Icon"/> property to directly use it as <see cref="RadSvgImage"/>.
|
||||||
|
/// </summary>
|
||||||
|
public RadSvgImage? SvgImage
|
||||||
{
|
{
|
||||||
/// <summary>
|
get => base.Icon as RadSvgImage;
|
||||||
/// Wrapper for the <see cref="PluginFeature.Icon"/> property to directly use it as <see cref="RadSvgImage"/>.
|
set => base.Icon = value;
|
||||||
/// </summary>
|
}
|
||||||
public RadSvgImage? SvgImage
|
|
||||||
{
|
|
||||||
get => base.Icon as RadSvgImage;
|
|
||||||
set => base.Icon = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected PluginModule(string moduleType, string moduleIdentifier) : base(moduleType, moduleIdentifier)
|
protected PluginModule(string moduleType, string moduleIdentifier) : base(moduleType, moduleIdentifier)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PluginModule(string moduleType, string moduleIdentifier, string moduleName) : base(moduleType, moduleIdentifier, moduleName)
|
protected PluginModule(string moduleType, string moduleIdentifier, string moduleName) : base(moduleType, moduleIdentifier, moduleName)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ShowUI()
|
public override void ShowUI()
|
||||||
|
{
|
||||||
|
if (CreateNewUI() is PluginModuleUI ui)
|
||||||
{
|
{
|
||||||
if (CreateNewUI() is PluginModuleUI ui)
|
ui.BackColor = Color.Transparent;
|
||||||
{
|
DialogBase.Show(ui, Name!, SvgImage!.ToImage().ToIcon()!);
|
||||||
ui.BackColor = Color.Transparent;
|
|
||||||
DialogBase.Show(ui, Name!, SvgImage!.ToImage().ToIcon()!);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,15 @@
|
|||||||
using Pilz.UI.Telerik.Dialogs;
|
using Pilz.UI.Telerik.Dialogs;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace Pilz.Plugins.Advanced.UI.Telerik
|
namespace Pilz.Plugins.Advanced.UI.Telerik;
|
||||||
|
|
||||||
|
public class PluginModuleUI : FlyoutBase, ILoadContent
|
||||||
{
|
{
|
||||||
public class PluginModuleUI : FlyoutBase, ILoadContent
|
public PluginModuleUI()
|
||||||
{
|
{
|
||||||
public PluginModuleUI()
|
ActionPanelVisible = false;
|
||||||
{
|
}
|
||||||
ActionPanelVisible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void LoadContent()
|
public virtual void LoadContent()
|
||||||
{
|
{
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,32 @@
|
|||||||
using System;
|
namespace Pilz.Plugins.Advanced.UI;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pilz.Plugins.Advanced.UI
|
[Flags]
|
||||||
|
public enum FeatureInsertMode
|
||||||
{
|
{
|
||||||
[Flags]
|
/// <summary>
|
||||||
public enum FeatureInsertMode
|
/// Features will be inserted at the end of the collection.
|
||||||
{
|
/// </summary>
|
||||||
/// <summary>
|
Default = 0,
|
||||||
/// Features will be inserted at the end of the collection.
|
/// <summary>
|
||||||
/// </summary>
|
/// Features will be inserted at the end of the collection.
|
||||||
Default = 0,
|
/// This is the default behavior and equals <see cref="Default"/>. Will only be used if not set <see cref="UseCustomDefault"/>.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Features will be inserted at the end of the collection.
|
DefaultEnd = Default,
|
||||||
/// This is the default behavior and equals <see cref="Default"/>. Will only be used if not set <see cref="UseCustomDefault"/>.
|
/// <summary>
|
||||||
/// </summary>
|
/// Features will be inserted at the start of the collection.
|
||||||
DefaultEnd = Default,
|
/// Will only be used if not set <see cref="UseCustomDefault"/>.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Features will be inserted at the start of the collection.
|
DefaultStart = 1,
|
||||||
/// Will only be used if not set <see cref="UseCustomDefault"/>.
|
/// <summary>
|
||||||
/// </summary>
|
/// Features with prioritization <see cref="FeaturePrioritization.High"/> will be inserted at the top (or left).
|
||||||
DefaultStart = 1,
|
/// </summary>
|
||||||
/// <summary>
|
InsertTop = 1 << 2,
|
||||||
/// Features with prioritization <see cref="FeaturePrioritization.High"/> will be inserted at the top (or left).
|
/// <summary>
|
||||||
/// </summary>
|
/// Features with prioritization <see cref="FeaturePrioritization.Low"/> will be inserted at the bottom (or right).
|
||||||
InsertTop = 1 << 2,
|
/// </summary>
|
||||||
/// <summary>
|
InsertBottom = 1 << 3,
|
||||||
/// Features with prioritization <see cref="FeaturePrioritization.Low"/> will be inserted at the bottom (or right).
|
/// <summary>
|
||||||
/// </summary>
|
/// Features with prioritization other then <see cref="FeaturePrioritization.Default"/> will be inserted at the top or bottom.
|
||||||
InsertBottom = 1 << 3,
|
/// </summary>
|
||||||
/// <summary>
|
InsertTopAndBottom = InsertTop | InsertBottom,
|
||||||
/// Features with prioritization other then <see cref="FeaturePrioritization.Default"/> will be inserted at the top or bottom.
|
|
||||||
/// </summary>
|
|
||||||
InsertTopAndBottom = InsertTop | InsertBottom,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user