Compare commits
No commits in common. "master" and "1.1.7468.16963" have entirely different histories.
master
...
1.1.7468.1
87
.github/workflows/main.yml
vendored
Normal file
87
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
name: CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build
|
||||
id: base_init
|
||||
run: |
|
||||
$(new-object System.Net.WebClient).DownloadFile("https://www.github.com/JFronny/UpTool2/releases/latest/download/Tools.zip", "$($(pwd).Path)\Tools.zip")
|
||||
& "C:\Program Files\7-Zip\7z.exe" x .\Tools.zip
|
||||
rm Tools.zip
|
||||
rm Install.bat
|
||||
rm Remove.bat
|
||||
dotnet build --verbosity:m -p:Configuration=Release
|
||||
cp W32.Test\bin\Release\netcoreapp3.1\package.zip .
|
||||
$file = Get-Item $(Resolve-Path W32.Test\bin\Release\netcoreapp3.1\*.exe).Path
|
||||
$asm = $([Reflection.Assembly]::LoadFile($file.DirectoryName + "\" + $file.BaseName + ".dll"))
|
||||
$asmver = $asm.GetName().Version.ToString()
|
||||
echo "::set-output name=vers::$asmver"
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1.0.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ steps.base_init.outputs.vers }}
|
||||
release_name: Release ${{ steps.base_init.outputs.vers }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
- name: Upload Release Asset
|
||||
id: upload_release_asset
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./package.zip
|
||||
asset_name: package.zip
|
||||
asset_content_type: application/zip
|
||||
- name: Generate XML
|
||||
run: |
|
||||
$file = Get-Item $(Resolve-Path W32.Test\bin\Release\netcoreapp3.1\*.exe).Path
|
||||
$asm = [Reflection.Assembly]::LoadFile($file.DirectoryName + "\" + $file.BaseName + ".dll")
|
||||
[System.XML.XMLDocument]$xml=New-Object System.XML.XMLDocument
|
||||
[System.XML.XMLElement]$app=$xml.CreateElement("app")
|
||||
$xml.appendChild($app)
|
||||
$app.appendChild($xml.CreateElement("Name")).InnerText = $asm.GetName().Name
|
||||
$app.appendChild($xml.CreateElement("Description")).InnerText = "Collection of Utilities for manipulating Windows"
|
||||
$app.appendChild($xml.CreateElement("Version")).InnerText = "${{ steps.base_init.outputs.vers }}"
|
||||
$app.appendChild($xml.CreateElement("ID")).InnerText = "3191d2f3-bf48-48ea-97a2-59fb32722d0a"
|
||||
$app.appendChild($xml.CreateElement("File")).InnerText = "${{ steps.upload_release_asset.outputs.browser_download_url }}"
|
||||
$app.appendChild($xml.CreateElement("Hash")).InnerText = $(Get-FileHash .\package.zip).Hash
|
||||
$app.appendChild($xml.CreateElement("MainFile")).InnerText = $file.Name
|
||||
echo NULL > app.xml
|
||||
$xml.save($(gi .\app.xml).Fullname)
|
||||
- name: Upload XML
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./app.xml
|
||||
asset_name: app.xml
|
||||
asset_content_type: text/xml
|
||||
- name: Publish nugets
|
||||
run: |
|
||||
$tmp = "${{ steps.base_init.outputs.vers }}"
|
||||
$tmp1 = $tmp.split('.')[2]
|
||||
$tmp2 = $tmp.split('.')[3]
|
||||
$suffix = "$tmp1.$tmp2"
|
||||
cd Misc
|
||||
dotnet pack --version-suffix "$suffix" -c Release -o .
|
||||
dotnet nuget push $(Get-Item $(Resolve-Path *.nupkg).Path).Name -k ${{secrets.NUGET_API_KEY}} -s https://api.nuget.org/v3/index.json
|
||||
cd ..\W32
|
||||
dotnet pack --version-suffix "$suffix" -c Release -o .
|
||||
dotnet nuget push $(Get-Item $(Resolve-Path *.nupkg).Path).Name -k ${{secrets.NUGET_API_KEY}} -s https://api.nuget.org/v3/index.json
|
||||
cd ..\Commandline
|
||||
dotnet pack --version-suffix "$suffix" -c Release -o .
|
||||
dotnet nuget push $(Get-Item $(Resolve-Path *.nupkg).Path).Name -k ${{secrets.NUGET_API_KEY}} -s https://api.nuget.org/v3/index.json
|
||||
cd ..
|
@ -1,85 +0,0 @@
|
||||
.shared_windows_runners:
|
||||
tags:
|
||||
- windows
|
||||
|
||||
image: mcr.microsoft.com/dotnet/sdk
|
||||
|
||||
uptool:
|
||||
extends:
|
||||
- .shared_windows_runners
|
||||
stage: deploy
|
||||
script: |
|
||||
mkdir i
|
||||
cd i
|
||||
$(new-object System.Net.WebClient).DownloadFile("https://gitlab.com/JFronny/UpTool2/-/jobs/artifacts/master/raw/Installer-generic.zip?job=uptool", "$($(pwd).Path)\Install.zip")
|
||||
& "C:\Program Files\7-Zip\7z.exe" x .\Install.zip
|
||||
.\Installer.exe --basic i -p
|
||||
cd ..
|
||||
rm -R i
|
||||
$Env:Path="$Env:Path;$Env:APPDATA\UpTool2\Install"
|
||||
uptool --basic add-repo DevTools https://gitlab.com/JFronny/UpTool2/-/snippets/2010392/raw
|
||||
uptool --basic update
|
||||
uptool --basic install "UpTool2 package tools"
|
||||
$Env:Path="$Env:Path;$Env:APPDATA\UpTool2\Apps\0e35d154-d0d3-45e0-b080-62f521263a44\app"
|
||||
|
||||
mkdir .\build
|
||||
cd W32.Test
|
||||
dotnet publish -o ..\build -c Release
|
||||
cd ..
|
||||
$file = Get-Item $(Resolve-Path .\build\*.exe).Path
|
||||
pkgtool build --binDir build --mainBin $file --packageFile .\package.zip --noLogo
|
||||
$asm = $([Reflection.Assembly]::LoadFile($file.DirectoryName + "\" + $file.BaseName + ".dll"))
|
||||
$asmver = $asm.GetName().Version.ToString()
|
||||
[System.XML.XMLDocument]$xml=New-Object System.XML.XMLDocument
|
||||
[System.XML.XMLElement]$app=$xml.CreateElement("app")
|
||||
$xml.appendChild($app)
|
||||
$app.appendChild($xml.CreateElement("Name")).InnerText = $asm.GetName().Name
|
||||
$app.appendChild($xml.CreateElement("Description")).InnerText = "Collection of Utilities for manipulating Windows"
|
||||
$app.appendChild($xml.CreateElement("Version")).InnerText = $asmver
|
||||
$app.appendChild($xml.CreateElement("ID")).InnerText = "3191d2f3-bf48-48ea-97a2-59fb32722d0a"
|
||||
$app.appendChild($xml.CreateElement("File")).InnerText = $CI_PROJECT_URL + "/-/jobs/" + $CI_JOB_ID + "/artifacts/raw/package.zip"
|
||||
$app.appendChild($xml.CreateElement("Hash")).InnerText = $(Get-FileHash .\package.zip).Hash
|
||||
$app.appendChild($xml.CreateElement("MainFile")).InnerText = $file.Name
|
||||
echo NULL > app.xml
|
||||
$xml.save($(gi .\app.xml).Fullname)
|
||||
$tmp1 = $asmver.split('.')[2]
|
||||
$tmp2 = $asmver.split('.')[3]
|
||||
$suffix = "$tmp1.$tmp2"
|
||||
cd Core
|
||||
dotnet pack --version-suffix "$suffix" -c Release -o .
|
||||
$tmp = $(Get-Item $(Resolve-Path *.nupkg).Path).Name
|
||||
echo $tmp
|
||||
dotnet nuget push $tmp -s https://api.nuget.org/v3/index.json -k $NUGET
|
||||
cd ..\Misc
|
||||
dotnet pack --version-suffix "$suffix" -c Release -o .
|
||||
$tmp = $(Get-Item $(Resolve-Path *.nupkg).Path).Name
|
||||
echo $tmp
|
||||
dotnet nuget push $tmp -s https://api.nuget.org/v3/index.json -k $NUGET
|
||||
cd ..\AspNet
|
||||
dotnet pack --version-suffix "$suffix" -c Release -o .
|
||||
$tmp = $(Get-Item $(Resolve-Path *.nupkg).Path).Name
|
||||
echo $tmp
|
||||
dotnet nuget push $tmp -s https://api.nuget.org/v3/index.json -k $NUGET
|
||||
cd ..\W32
|
||||
dotnet pack --version-suffix "$suffix" -c Release -o .
|
||||
$tmp = $(Get-Item $(Resolve-Path *.nupkg).Path).Name
|
||||
echo $tmp
|
||||
dotnet nuget push $tmp -s https://api.nuget.org/v3/index.json -k $NUGET
|
||||
cd ..\Commandline
|
||||
dotnet pack --version-suffix "$suffix" -c Release -o .
|
||||
$tmp = $(Get-Item $(Resolve-Path *.nupkg).Path).Name
|
||||
echo $tmp
|
||||
dotnet nuget push $tmp -s https://api.nuget.org/v3/index.json -k $NUGET
|
||||
cd ..
|
||||
mkdir nugets
|
||||
cp .\Core\*.nupkg .\nugets\
|
||||
cp .\Misc\*.nupkg .\nugets\
|
||||
cp .\W32\*.nupkg .\nugets\
|
||||
cp .\Commandline\*.nupkg .\nugets\
|
||||
artifacts:
|
||||
paths:
|
||||
- package.zip
|
||||
- app.xml
|
||||
- nugets
|
||||
only:
|
||||
- master
|
@ -1,33 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>CC_Functions.AspNet</RootNamespace>
|
||||
<AssemblyName>CC_Functions.AspNet</AssemblyName>
|
||||
<Deterministic>false</Deterministic>
|
||||
<PackageId>CC-Functions.AspNet</PackageId>
|
||||
<Title>CC-Functions.AspNet</Title>
|
||||
<Authors>JFronny</Authors>
|
||||
<Description>Random pieces of code for Asp.Net, including my SerialDict integrated Database</Description>
|
||||
<Copyright>Copyright 2020</Copyright>
|
||||
<PackageProjectUrl>https://gitlab.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||
<RepositoryUrl>https://gitlab.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<AssemblyVersion>1.1.*</AssemblyVersion>
|
||||
<FileVersion>1.0.0.0</FileVersion>
|
||||
<VersionSuffix>0.0</VersionSuffix>
|
||||
<PackageVersion>1.1.$(VersionSuffix)</PackageVersion>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DocumentationFile>bin\Debug\Core.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DocumentationFile>bin\Release\Core.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="protobuf-net" Version="3.0.62" />
|
||||
<PackageReference Include="System.Text.Json" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,138 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CC_Functions.AspNet
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides serializing dictionary with Guid keys
|
||||
/// </summary>
|
||||
public class DictionaryGuidConverter : JsonConverterFactory
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override bool CanConvert(Type typeToConvert)
|
||||
{
|
||||
if (!typeToConvert.IsGenericType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeToConvert.GetGenericTypeDefinition() != typeof(Dictionary<,>))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return typeToConvert.GetGenericArguments()[0] == typeof(Guid);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
Type valueType = typeToConvert.GetGenericArguments()[1];
|
||||
|
||||
JsonConverter converter = (JsonConverter)Activator.CreateInstance(
|
||||
typeof(DictionaryGuidConverterInner<>).MakeGenericType(valueType),
|
||||
BindingFlags.Instance | BindingFlags.Public,
|
||||
null,
|
||||
new object[] { options },
|
||||
null);
|
||||
|
||||
return converter;
|
||||
}
|
||||
|
||||
private class DictionaryGuidConverterInner<TValue> : JsonConverter<Dictionary<Guid, TValue>>
|
||||
{
|
||||
private readonly JsonConverter<TValue> _valueConverter;
|
||||
private Type _valueType;
|
||||
|
||||
public DictionaryGuidConverterInner(JsonSerializerOptions options)
|
||||
{
|
||||
// For performance, use the existing converter if available.
|
||||
_valueConverter = (JsonConverter<TValue>)options
|
||||
.GetConverter(typeof(TValue));
|
||||
|
||||
// Cache the key and value types.
|
||||
_valueType = typeof(TValue);
|
||||
}
|
||||
|
||||
public override Dictionary<Guid, TValue> Read(
|
||||
ref Utf8JsonReader reader,
|
||||
Type typeToConvert,
|
||||
JsonSerializerOptions options)
|
||||
{
|
||||
if (reader.TokenType != JsonTokenType.StartObject)
|
||||
{
|
||||
throw new JsonException();
|
||||
}
|
||||
|
||||
Dictionary<Guid, TValue> dictionary = new Dictionary<Guid, TValue>();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.EndObject)
|
||||
{
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
// Get the key.
|
||||
if (reader.TokenType != JsonTokenType.PropertyName)
|
||||
{
|
||||
throw new JsonException();
|
||||
}
|
||||
|
||||
string propertyName = reader.GetString();
|
||||
|
||||
// For performance, parse with ignoreCase:false first.
|
||||
if (!Guid.TryParse(propertyName, out Guid key))
|
||||
{
|
||||
throw new JsonException(
|
||||
$"Unable to convert \"{propertyName}\" to Guid.");
|
||||
}
|
||||
|
||||
// Get the value.
|
||||
TValue v;
|
||||
if (_valueConverter != null)
|
||||
{
|
||||
reader.Read();
|
||||
v = _valueConverter.Read(ref reader, _valueType, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
v = JsonSerializer.Deserialize<TValue>(ref reader, options);
|
||||
}
|
||||
|
||||
// Add to dictionary.
|
||||
dictionary.Add(key, v);
|
||||
}
|
||||
|
||||
throw new JsonException();
|
||||
}
|
||||
|
||||
public override void Write(
|
||||
Utf8JsonWriter writer,
|
||||
Dictionary<Guid, TValue> dictionary,
|
||||
JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
|
||||
foreach (KeyValuePair<Guid, TValue> kvp in dictionary)
|
||||
{
|
||||
writer.WritePropertyName(kvp.Key.ToString());
|
||||
|
||||
if (_valueConverter != null)
|
||||
{
|
||||
_valueConverter.Write(writer, kvp.Value, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonSerializer.Serialize(writer, kvp.Value, options);
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace CC_Functions.AspNet
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for various types
|
||||
/// </summary>
|
||||
public static class GenericExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Include CCF json extensions for this serializer
|
||||
/// </summary>
|
||||
/// <param name="options">The options to include CCF in</param>
|
||||
/// <returns>The options including CCF</returns>
|
||||
public static JsonSerializerOptions AddCcf(this JsonSerializerOptions options)
|
||||
{
|
||||
options.Converters.Add(new DictionaryGuidConverter());
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CC_Functions.AspNet
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides synchronizing for dictionaries with saving/loading backends
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The key type</typeparam>
|
||||
/// <typeparam name="U">The param type</typeparam>
|
||||
public abstract class SaveLoadDict<T, U> : IDictionary<T, U>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IEnumerator<KeyValuePair<T, U>> GetEnumerator()
|
||||
{
|
||||
lock (this) return Load().GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
lock (this) return GetEnumerator();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Add(KeyValuePair<T, U> item)
|
||||
{
|
||||
lock (this) Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Clear()
|
||||
{
|
||||
lock (this) Save(new Dictionary<T, U>());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Contains(KeyValuePair<T, U> item)
|
||||
{
|
||||
lock (this) return Load().Contains(item);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void CopyTo(KeyValuePair<T, U>[] array, int arrayIndex)
|
||||
{
|
||||
lock (this) Load().CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Remove(KeyValuePair<T, U> item)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
IDictionary<T, U> dictionary = Load();
|
||||
try
|
||||
{
|
||||
return dictionary.Remove(item);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Save(dictionary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Count
|
||||
{
|
||||
get { lock (this) return Load().Count; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Add(T key, U value)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
IDictionary<T, U> dictionary = Load();
|
||||
dictionary.Add(key, value);
|
||||
Save(dictionary);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool ContainsKey(T key)
|
||||
{
|
||||
lock (this) return Load().ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Remove(T key)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
IDictionary<T, U> dictionary = Load();
|
||||
try
|
||||
{
|
||||
return dictionary.Remove(key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Save(dictionary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGetValue(T key, out U value)
|
||||
{
|
||||
lock (this) return Load().TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public U this[T key]
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this) return Load()[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
IDictionary<T, U> dictionary = Load();
|
||||
dictionary[key] = value;
|
||||
Save(dictionary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<T> Keys
|
||||
{
|
||||
get { lock (this) return Load().Keys; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<U> Values
|
||||
{
|
||||
get { lock (this) return Load().Values; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replace the current content based on the current state
|
||||
/// </summary>
|
||||
/// <param name="f">Function to mutate the content</param>
|
||||
public void Mutate(Func<IDictionary<T, U>, IDictionary<T, U>> f)
|
||||
{
|
||||
lock (this) Save(f(Load()));
|
||||
}
|
||||
/// <summary>
|
||||
/// Save the dictionary content
|
||||
/// </summary>
|
||||
/// <param name="v">Dictionary content to save</param>
|
||||
protected abstract void Save(IDictionary<T, U> v);
|
||||
/// <summary>
|
||||
/// Load the content to a dictionary
|
||||
/// </summary>
|
||||
/// <returns>The loaded content</returns>
|
||||
protected abstract IDictionary<T, U> Load();
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using ProtoBuf;
|
||||
|
||||
namespace CC_Functions.AspNet
|
||||
{
|
||||
/// <summary>
|
||||
/// An implementation of SaveLoadDict that uses Protobuf-net for serialization and Guid keys
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The data type</typeparam>
|
||||
public abstract class SerialDict<T> : SaveLoadDict<Guid, T>
|
||||
{
|
||||
//Interface
|
||||
/// <summary>
|
||||
/// Gets the directory containing databases
|
||||
/// </summary>
|
||||
public abstract string DatabasesDir { get; }
|
||||
/// <summary>
|
||||
/// Gets the file name for this database. Must not contain the path
|
||||
/// </summary>
|
||||
public abstract string DatabaseFileName { get; }
|
||||
/// <summary>
|
||||
/// Called when the database is loaded. Use for preparing initial entries
|
||||
/// </summary>
|
||||
public event LoadedD Loaded;
|
||||
/// <summary>
|
||||
/// Called when the database is loaded. Use for preparing initial entries
|
||||
/// </summary>
|
||||
/// <param name="v">The current dictionary content</param>
|
||||
public delegate void LoadedD(IDictionary<Guid, T> v);
|
||||
/// <summary>
|
||||
/// Loads the dictionary and replaces Guids with strings. Use for sending
|
||||
/// </summary>
|
||||
/// <returns>The simplified dictionary</returns>
|
||||
public IDictionary<string, T> GetSendable() => Load().ToDictionary(s => s.Key.ToString(), s => s.Value);
|
||||
|
||||
//Internal
|
||||
private string GetRel() => Path.Combine(DatabasesDir, DatabaseFileName);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IDictionary<Guid, T> Load()
|
||||
{
|
||||
if (!Directory.Exists(DatabasesDir))
|
||||
Directory.CreateDirectory(DatabasesDir);
|
||||
IDictionary<Guid, T> v;
|
||||
if (File.Exists(GetRel()))
|
||||
{
|
||||
using (FileStream file = File.OpenRead(GetRel()))
|
||||
v = Serializer.Deserialize<Dictionary<Guid, T>>(file);
|
||||
Loaded?.Invoke(v);
|
||||
return v;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = new Dictionary<Guid, T>();
|
||||
Loaded?.Invoke(v);
|
||||
Save(v);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Save(IDictionary<Guid, T> dict)
|
||||
{
|
||||
if (!Directory.Exists(DatabasesDir))
|
||||
Directory.CreateDirectory(DatabasesDir);
|
||||
using FileStream file = File.Create(GetRel());
|
||||
Serializer.Serialize(file, dict);
|
||||
}
|
||||
}
|
||||
}
|
@ -13,10 +13,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Commandline", "Commandline\
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CLITest", "CLITest\CLITest.csproj", "{3FAB0713-3021-4C6A-BF4A-ABBD542634A6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{780EC190-E223-46DE-B6FB-1CF56ABDF34E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNet", "AspNet\AspNet.csproj", "{1A9F3CD1-559B-4429-B8A6-490AF7188A2E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -43,14 +39,6 @@ Global
|
||||
{3FAB0713-3021-4C6A-BF4A-ABBD542634A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3FAB0713-3021-4C6A-BF4A-ABBD542634A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3FAB0713-3021-4C6A-BF4A-ABBD542634A6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{780EC190-E223-46DE-B6FB-1CF56ABDF34E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{780EC190-E223-46DE-B6FB-1CF56ABDF34E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{780EC190-E223-46DE-B6FB-1CF56ABDF34E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{780EC190-E223-46DE-B6FB-1CF56ABDF34E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1A9F3CD1-559B-4429-B8A6-490AF7188A2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1A9F3CD1-559B-4429-B8A6-490AF7188A2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1A9F3CD1-559B-4429-B8A6-490AF7188A2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1A9F3CD1-559B-4429-B8A6-490AF7188A2E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -1,32 +1,14 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using CC_Functions.Commandline;
|
||||
using CC_Functions.Commandline.TUI;
|
||||
using CC_Functions.Core;
|
||||
|
||||
namespace CLITest
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
private static void Main()
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Thread.CurrentThread.ForceInvariantCulture();
|
||||
//Parse test
|
||||
if (new ArgsParse(new[] { "--meme", "Fuk u", "--meme:yeet", "--meme:yote", "--meme" })["meme"] != "yote")
|
||||
throw new Exception("ArgsParse error 1");
|
||||
if (!new ArgsParse(new[] { "--meme", "Fuk u", "--meme:yeet", "--meme:yote", "--meme" }).GetBool("meme"))
|
||||
throw new Exception("ArgsParse error 2");
|
||||
if (new ArgsParse(new[] {"--meme:"}).GetBool("meme"))
|
||||
throw new Exception("ArgsParse error 3");
|
||||
if (!new ArgsParse(new[] {"--meme:true"}).GetBool("mEme"))
|
||||
throw new Exception("ArgsParse error 4");
|
||||
if (new ArgsParse(new[] {"--meme:1.1.2019"}).Get<DateTime>("meme") != new DateTime(2019, 1, 1))
|
||||
throw new Exception("ArgsParse error 5");
|
||||
if (new ArgsParse(new[] {"--meme:2019"}).Get("meme", s => s == null ? DateTime.Now : DateTime.Parse("1.1." + s)) != new DateTime(2019, 1, 1))
|
||||
throw new Exception("ArgsParse error 6");
|
||||
|
||||
//Display test
|
||||
Console.BackgroundColor = ConsoleColor.Black;
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.Clear();
|
||||
@ -38,7 +20,7 @@ namespace CLITest
|
||||
BackColor = ConsoleColor.DarkGreen
|
||||
};
|
||||
screen.Controls.Add(btn1);
|
||||
btn1.Click += (screen1, eventArgs) => { DiffDraw.Draw(true, true); };
|
||||
btn1.Click += (screen1, eventArgs) => { DiffDraw.FullDraw(true); };
|
||||
Label lab1 = new Label("Meem")
|
||||
{
|
||||
Point = new Point(2, 1),
|
||||
@ -97,11 +79,6 @@ namespace CLITest
|
||||
}
|
||||
Console.ResetColor();
|
||||
Console.Clear();
|
||||
Console.WriteLine("Test2");
|
||||
Thread.Sleep(100);
|
||||
DiffDraw.Clear(10, 10);
|
||||
DiffDraw.Draw(true, false);
|
||||
Console.Clear();
|
||||
Console.WriteLine("Bye");
|
||||
}
|
||||
}
|
||||
|
@ -1,98 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
||||
namespace CC_Functions.Commandline
|
||||
{
|
||||
/// <summary>
|
||||
/// A class to provide basic parsing for program arguments
|
||||
/// </summary>
|
||||
public class ArgsParse : IEnumerable<string>
|
||||
{
|
||||
private readonly string[] _args;
|
||||
/// <summary>
|
||||
/// Create a new instance based on the specified args
|
||||
/// </summary>
|
||||
/// <param name="args">The inputted args. Should be a parameter of the main method</param>
|
||||
public ArgsParse(string[] args) => _args = args ?? throw new NullReferenceException();
|
||||
/// <summary>
|
||||
/// Shadowed from the base args
|
||||
/// </summary>
|
||||
/// <param name="i">The index in the base args</param>
|
||||
public string this[int i]
|
||||
{
|
||||
get => _args[i];
|
||||
set => _args[i] = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Shadowed from the base args
|
||||
/// </summary>
|
||||
/// <returns>An enumerator for the base args</returns>
|
||||
IEnumerator<string> IEnumerable<string>.GetEnumerator() => ((IEnumerable<string>)_args).GetEnumerator();
|
||||
/// <summary>
|
||||
/// Shadowed from the base args
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator GetEnumerator() => _args.GetEnumerator();
|
||||
/// <summary>
|
||||
/// Gets the string specified for this key or null
|
||||
/// </summary>
|
||||
/// <param name="i">The name of the parameter</param>
|
||||
public string? this[string i]
|
||||
{
|
||||
get
|
||||
{
|
||||
string? selected = null;
|
||||
foreach (string s in _args)
|
||||
if (s.TrimStart('-', '/').ToLower().StartsWith($"{i.ToLower()}:"))
|
||||
selected = string.Join("", s.TrimStart('-', '/').Skip(i.Length + 1));
|
||||
return selected;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the string specified for this key or null
|
||||
/// </summary>
|
||||
/// <param name="i">The name of the parameter</param>
|
||||
/// <returns>The value or null</returns>
|
||||
public string? GetString(string i) => this[i];
|
||||
/// <summary>
|
||||
/// Gets a boolean value with the specified name. Either specified as --i or --i:true
|
||||
/// </summary>
|
||||
/// <param name="i">The name of the parameter</param>
|
||||
/// <returns>The value</returns>
|
||||
public bool GetBool(string i) => _args.Any(s => s.ToLower().TrimStart('-', '/') == i.ToLower()) || bool.TryParse(this[i], out bool res) && res;
|
||||
/// <summary>
|
||||
/// Gets an arg using a transformer specified by you. The value passed will be the same as this[i]
|
||||
/// </summary>
|
||||
/// <param name="i">The name of the parameter</param>
|
||||
/// <param name="func">A null-safe function to convert a string to the expected type</param>
|
||||
/// <typeparam name="T">The type to convert to</typeparam>
|
||||
/// <returns>The converted value</returns>
|
||||
public T Get<T>(string i, Func<string?, T> func) => func(this[i]);
|
||||
/// <summary>
|
||||
/// Uses reflection to call the Parse method on types providing it. Use Get() with a func param for other types
|
||||
/// This will return null if the type is not found
|
||||
/// </summary>
|
||||
/// <param name="i">The name of the parameter</param>
|
||||
/// <typeparam name="T">The type to convert to</typeparam>
|
||||
/// <returns>The converted value</returns>
|
||||
public T Get<T>(string i)
|
||||
{
|
||||
MethodInfo[] parse = typeof(T).GetMethods().Where(s => s.Name.ToLower() == "parse"
|
||||
&& s.GetParameters().Length == 1
|
||||
&& s.GetParameters()[0].ParameterType == typeof(string)
|
||||
&& s.ReturnType == typeof(T)
|
||||
&& !s.IsAbstract && !s.IsPrivate && s.IsStatic).ToArray();
|
||||
if (parse.Length == 0)
|
||||
throw new InvalidOperationException("Could not find a valid parse method");
|
||||
string? v = this[i];
|
||||
if (v == null)
|
||||
return default;
|
||||
return (T) parse[0].Invoke(null, new object[] {v});
|
||||
}
|
||||
}
|
||||
}
|
@ -9,17 +9,16 @@
|
||||
<Deterministic>false</Deterministic>
|
||||
<PackageId>CC-Functions.Commandline</PackageId>
|
||||
<Title>CC-Functions.Commandline</Title>
|
||||
<Authors>JFronny</Authors>
|
||||
<Authors>CC24</Authors>
|
||||
<Description>Random pieces of code used across my projects. CLI/TUI extensions</Description>
|
||||
<Copyright>Copyright 2020</Copyright>
|
||||
<PackageProjectUrl>https://gitlab.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||
<RepositoryUrl>https://gitlab.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||
<PackageProjectUrl>https://github.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<AssemblyVersion>1.1.*</AssemblyVersion>
|
||||
<FileVersion>1.0.0.0</FileVersion>
|
||||
<VersionSuffix>0.0</VersionSuffix>
|
||||
<PackageVersion>1.1.$(VersionSuffix)</PackageVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
@ -31,6 +30,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Core\Core.csproj" />
|
||||
<ProjectReference Include="..\Misc\Misc.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using CC_Functions.Core;
|
||||
using CC_Functions.Misc;
|
||||
|
||||
namespace CC_Functions.Commandline.TUI
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using CC_Functions.Core;
|
||||
using CC_Functions.Misc;
|
||||
|
||||
namespace CC_Functions.Commandline.TUI
|
||||
{
|
||||
@ -10,14 +10,22 @@ namespace CC_Functions.Commandline.TUI
|
||||
public class CenteredScreen : Screen
|
||||
{
|
||||
private bool _resizing;
|
||||
private Size _actualSize;
|
||||
|
||||
/// <summary>
|
||||
/// The actual size of this control. The "Size" property is assigned automatically
|
||||
/// </summary>
|
||||
public Size ActualSize;
|
||||
|
||||
/// <summary>
|
||||
/// The panel used for storing and rendering the actual controls
|
||||
/// </summary>
|
||||
public Panel ContentPanel;
|
||||
|
||||
private string _title = "CC-Functions.CommandLine app";
|
||||
/// <summary>
|
||||
/// The title to display at the top of the console
|
||||
/// </summary>
|
||||
public string Title = "CC-Functions.CommandLine app";
|
||||
|
||||
private readonly Label _titleLabel;
|
||||
|
||||
/// <summary>
|
||||
@ -29,9 +37,9 @@ namespace CC_Functions.Commandline.TUI
|
||||
/// <param name="color">Whether to use color when drawing</param>
|
||||
public CenteredScreen(int width, int height, ConsoleColor contentBack, bool color = true) : base(width, height, color)
|
||||
{
|
||||
_titleLabel = new Label(Title);
|
||||
ContentPanel = new Panel {BackColor = contentBack};
|
||||
ActualSize = new Size(width, height);
|
||||
_titleLabel = new Label(Title);
|
||||
Controls.Add(ContentPanel);
|
||||
Controls.Add(_titleLabel);
|
||||
WindowResize += (screen, args) => CalculatePosition();
|
||||
@ -39,38 +47,6 @@ namespace CC_Functions.Commandline.TUI
|
||||
CalculatePosition(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The title to display at the top of the console
|
||||
/// </summary>
|
||||
public string Title
|
||||
{
|
||||
get => _title;
|
||||
set
|
||||
{
|
||||
if (_title != value && !string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
_title = value;
|
||||
CalculatePosition(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The actual size of this control. The "Size" property is assigned automatically
|
||||
/// </summary>
|
||||
public Size ActualSize
|
||||
{
|
||||
get => _actualSize;
|
||||
set
|
||||
{
|
||||
if (_actualSize != value)
|
||||
{
|
||||
_actualSize = value;
|
||||
CalculatePosition(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the Size variable, Title and ContentPanel position/size
|
||||
/// </summary>
|
||||
@ -88,7 +64,7 @@ namespace CC_Functions.Commandline.TUI
|
||||
if (!initial)
|
||||
{
|
||||
Console.Clear();
|
||||
DiffDraw.Draw(Color, true);
|
||||
DiffDraw.FullDraw(Color);
|
||||
}
|
||||
_resizing = false;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using CC_Functions.Core;
|
||||
using CC_Functions.Misc;
|
||||
|
||||
namespace CC_Functions.Commandline.TUI
|
||||
{
|
||||
|
@ -1,9 +1,8 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using CC_Functions.Commandline.TUI;
|
||||
using CC_Functions.Core;
|
||||
using CC_Functions.Misc;
|
||||
|
||||
namespace CC_Functions.Commandline
|
||||
namespace CC_Functions.Commandline.TUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides differential drawing of a char[,] Do not use in combination with System.Console
|
||||
@ -27,14 +26,12 @@ namespace CC_Functions.Commandline
|
||||
/// Draws to the console
|
||||
/// </summary>
|
||||
/// <param name="color">Whether to use color</param>
|
||||
/// <param name="full">Whether to redraw the entire screen (should be done from time to time to prevent corruption)</param>
|
||||
public static void Draw(bool color, bool full = false)
|
||||
public static void Draw(bool color)
|
||||
{
|
||||
Console.CursorTop = 0;
|
||||
Console.CursorLeft = 0;
|
||||
ConsoleColor fCol = Console.ForegroundColor;
|
||||
ConsoleColor bCol = Console.BackgroundColor;
|
||||
if (full) Console.Clear();
|
||||
ConsoleColor fcol = Console.ForegroundColor;
|
||||
ConsoleColor bcol = Console.BackgroundColor;
|
||||
int width = Width;
|
||||
int height = Height;
|
||||
for (int y = 0; y < height; y++)
|
||||
@ -42,8 +39,8 @@ namespace CC_Functions.Commandline
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
Pixel tmp1 = Screen[y, x];
|
||||
if (!full && tmp1 == _last[y, x]) continue;
|
||||
if (!ReferenceEquals(tmp1, null) && color)
|
||||
if (tmp1 == _last[y, x]) continue;
|
||||
if (color)
|
||||
{
|
||||
if (Console.ForegroundColor != tmp1.ForeColor)
|
||||
Console.ForegroundColor = tmp1.ForeColor;
|
||||
@ -51,13 +48,49 @@ namespace CC_Functions.Commandline
|
||||
Console.BackgroundColor = tmp1.BackColor;
|
||||
}
|
||||
Console.CursorLeft = x;
|
||||
Console.Write(tmp1 ?? Pixel.Empty);
|
||||
Console.Write(tmp1);
|
||||
}
|
||||
Console.WriteLine();
|
||||
Console.CursorLeft = 0;
|
||||
}
|
||||
Console.ForegroundColor = fCol;
|
||||
Console.BackgroundColor = bCol;
|
||||
Console.ForegroundColor = fcol;
|
||||
Console.BackgroundColor = bcol;
|
||||
_last = Screen;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redraws the entire screen (should be done from time to time to prevent corruption)
|
||||
/// </summary>
|
||||
/// <param name="color">Whether to use color</param>
|
||||
public static void FullDraw(bool color)
|
||||
{
|
||||
Console.CursorTop = 0;
|
||||
Console.CursorLeft = 0;
|
||||
ConsoleColor fcol = Console.ForegroundColor;
|
||||
ConsoleColor bcol = Console.BackgroundColor;
|
||||
Console.Clear();
|
||||
int width = Width;
|
||||
int height = Height;
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
Pixel tmp1 = Screen[y, x];
|
||||
if (color)
|
||||
{
|
||||
if (Console.ForegroundColor != tmp1.ForeColor)
|
||||
Console.ForegroundColor = tmp1.ForeColor;
|
||||
if (Console.BackgroundColor != tmp1.BackColor)
|
||||
Console.BackgroundColor = tmp1.BackColor;
|
||||
}
|
||||
Console.CursorLeft = x;
|
||||
Console.Write(tmp1);
|
||||
}
|
||||
Console.WriteLine();
|
||||
Console.CursorLeft = 0;
|
||||
}
|
||||
Console.ForegroundColor = fcol;
|
||||
Console.BackgroundColor = bcol;
|
||||
_last = Screen;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
using System.Drawing;
|
||||
using CC_Functions.Core;
|
||||
using CC_Functions.Misc;
|
||||
|
||||
namespace CC_Functions.Commandline.TUI
|
||||
{
|
||||
@ -8,40 +8,20 @@ namespace CC_Functions.Commandline.TUI
|
||||
/// </summary>
|
||||
public class Label : Control
|
||||
{
|
||||
private string _content;
|
||||
/// <summary>
|
||||
/// The text inside this label
|
||||
/// </summary>
|
||||
public string Content;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new label
|
||||
/// </summary>
|
||||
/// <param name="content">The text inside this label</param>
|
||||
public Label(string content)
|
||||
{
|
||||
_content = "";
|
||||
Content = content;
|
||||
}
|
||||
public Label(string content) => Content = content;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Selectable { get; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// The text inside this label
|
||||
/// </summary>
|
||||
public string Content
|
||||
{
|
||||
get => _content;
|
||||
set
|
||||
{
|
||||
if (_content != value)
|
||||
{
|
||||
_content = value;
|
||||
char[,] inp = Content.ToNdArray2D();
|
||||
int w = inp.GetLength(1);
|
||||
int h = inp.GetLength(0);
|
||||
Size = new Size(w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Pixel[,] Render()
|
||||
{
|
||||
@ -52,6 +32,7 @@ namespace CC_Functions.Commandline.TUI
|
||||
for (int x = 0; x < w; x++)
|
||||
for (int y = 0; y < h; y++)
|
||||
output[x, y] = new Pixel(BackColor, ForeColor, inp[x, y]);
|
||||
Size = new Size(w, h);
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using CC_Functions.Core;
|
||||
using CC_Functions.Misc;
|
||||
|
||||
namespace CC_Functions.Commandline.TUI
|
||||
{
|
||||
|
@ -8,8 +8,6 @@ namespace CC_Functions.Commandline.TUI
|
||||
/// </summary>
|
||||
public class Pixel
|
||||
{
|
||||
public static readonly Pixel Empty = new Pixel();
|
||||
|
||||
/// <summary>
|
||||
/// This pixels background color
|
||||
/// </summary>
|
||||
@ -90,7 +88,7 @@ namespace CC_Functions.Commandline.TUI
|
||||
/// <param name="a">First pixel to compare</param>
|
||||
/// <param name="b">Second pixel to compare</param>
|
||||
/// <returns>Whether they are equal</returns>
|
||||
public static bool operator ==(Pixel a, Pixel b) => !ReferenceEquals(a, null) && a.Equals(b);
|
||||
public static bool operator ==(Pixel a, Pixel b) => a.Equals(b);
|
||||
|
||||
/// <summary>
|
||||
/// Whether to pixels are not equal
|
||||
@ -98,7 +96,7 @@ namespace CC_Functions.Commandline.TUI
|
||||
/// <param name="a">First pixel to compare</param>
|
||||
/// <param name="b">Second pixel to compare</param>
|
||||
/// <returns>Whether they are not equal</returns>
|
||||
public static bool operator !=(Pixel a, Pixel b) => !(a == b);
|
||||
public static bool operator !=(Pixel a, Pixel b) => !a.Equals(b);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the content of this pixel
|
||||
|
@ -30,44 +30,18 @@ namespace CC_Functions.Commandline.TUI
|
||||
/// <param name="e">Args</param>
|
||||
public delegate void OnWindowResize(Screen screen, EventArgs e);
|
||||
|
||||
private bool _color;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to output in color. Recommended for most terminals, might cause slowdowns in others
|
||||
/// </summary>
|
||||
public bool Color
|
||||
{
|
||||
get => _color;
|
||||
set
|
||||
{
|
||||
if (_color != value)
|
||||
{
|
||||
_color = value;
|
||||
DiffDraw.Draw(_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current index of the tab-selected control in an array of selectable controls
|
||||
/// </summary>
|
||||
public int TabPoint
|
||||
{
|
||||
get => _tabPoint;
|
||||
set
|
||||
{
|
||||
if (_tabPoint != value)
|
||||
{
|
||||
_tabPoint = value;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public readonly bool Color;
|
||||
|
||||
private int _wndHeight = Console.WindowHeight;
|
||||
private int _wndWidth = Console.WindowWidth;
|
||||
|
||||
private int _tabPoint;
|
||||
/// <summary>
|
||||
/// The current index of the tab-selected control in an array of selectable controls
|
||||
/// </summary>
|
||||
public int TabPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a screen object. Multiple can be instantiated but drawing one overrides others. Use panels for that
|
||||
@ -100,7 +74,6 @@ namespace CC_Functions.Commandline.TUI
|
||||
/// <returns>The new state of the screen</returns>
|
||||
public new Pixel[,] Render()
|
||||
{
|
||||
FixSelection();
|
||||
Pixel[,] tmp = base.Render();
|
||||
DiffDraw.Clear(tmp);
|
||||
DiffDraw.Draw(Color);
|
||||
@ -129,18 +102,23 @@ namespace CC_Functions.Commandline.TUI
|
||||
break;
|
||||
case ConsoleKey.Enter:
|
||||
if (selectable.Any() && selectable.Length >= TabPoint && selectable[TabPoint].Enabled)
|
||||
{
|
||||
selectable[TabPoint].InvokeClick(this);
|
||||
render = true;
|
||||
}
|
||||
break;
|
||||
case ConsoleKey.Escape:
|
||||
Close?.Invoke(this, new EventArgs());
|
||||
break;
|
||||
default:
|
||||
if (selectable.Any() && selectable.Length >= TabPoint && selectable[TabPoint].Enabled)
|
||||
{
|
||||
InvokeInput(this, input);
|
||||
selectable[TabPoint].InvokeInput(this, input);
|
||||
InvokeInput(this, input);
|
||||
render = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
render = true;
|
||||
}
|
||||
if (_wndWidth != Console.WindowWidth || _wndHeight != Console.WindowHeight)
|
||||
{
|
||||
@ -151,8 +129,6 @@ namespace CC_Functions.Commandline.TUI
|
||||
}
|
||||
if (canRedraw && render)
|
||||
Render();
|
||||
else
|
||||
FixSelection();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -185,21 +161,10 @@ namespace CC_Functions.Commandline.TUI
|
||||
TabPoint--;
|
||||
if (TabPoint < 0) TabPoint = selectable.Length - 1;
|
||||
}
|
||||
FixSelection(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void FixSelection(bool draw = false)
|
||||
{
|
||||
Control[] controls = EnumerateRecursive();
|
||||
Control[] selectable = controls.Where(s => s.Selectable).ToArray();
|
||||
if (selectable.Any())
|
||||
{
|
||||
foreach (Control control in selectable) control.Selected = false;
|
||||
selectable[TabPoint].Selected = true;
|
||||
TabChanged?.Invoke(this, new EventArgs());
|
||||
if (draw)
|
||||
Render();
|
||||
Render();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using CC_Functions.Core;
|
||||
using CC_Functions.Misc;
|
||||
|
||||
namespace CC_Functions.Commandline.TUI
|
||||
{
|
||||
@ -31,14 +31,12 @@ namespace CC_Functions.Commandline.TUI
|
||||
if (_value < MinValue)
|
||||
_value = MinValue;
|
||||
Value = _value;
|
||||
ValueChanged?.Invoke(screen, new EventArgs());
|
||||
break;
|
||||
case ConsoleKey.RightArrow:
|
||||
_value += StepSize;
|
||||
if (_value > MaxValue)
|
||||
_value = MaxValue;
|
||||
Value = _value;
|
||||
ValueChanged?.Invoke(screen, new EventArgs());
|
||||
break;
|
||||
}
|
||||
};
|
||||
@ -53,7 +51,7 @@ namespace CC_Functions.Commandline.TUI
|
||||
get => _maxValue;
|
||||
set
|
||||
{
|
||||
if (value >= MinValue && value >= Value)
|
||||
if (value > MinValue && value >= Value)
|
||||
_maxValue = value;
|
||||
else
|
||||
throw new ArgumentOutOfRangeException(
|
||||
@ -70,7 +68,7 @@ namespace CC_Functions.Commandline.TUI
|
||||
get => _minValue;
|
||||
set
|
||||
{
|
||||
if (value <= MaxValue && value <= Value)
|
||||
if (value < MaxValue && value <= Value)
|
||||
_minValue = value;
|
||||
else
|
||||
throw new ArgumentOutOfRangeException(
|
||||
@ -102,7 +100,7 @@ namespace CC_Functions.Commandline.TUI
|
||||
{
|
||||
int delta = MaxValue - MinValue;
|
||||
int litValLen = Math.Max(MaxValue.ToString().Length, MinValue.ToString().Length);
|
||||
int prevpts = Math.Max((Value - MinValue) * Size.Width / Math.Max(delta, 1) - litValLen - 2, 0);
|
||||
int prevpts = Math.Max((Value - MinValue) * Size.Width / delta - litValLen - 2, 0);
|
||||
int postpts = Math.Max(Size.Width - prevpts - litValLen - 2, 0);
|
||||
char[,] rend = $"{new string('=', prevpts)}[{Value.ToString($"D{(Value < 0 ? litValLen - 1 : litValLen)}")}]{new string('=', postpts)}"
|
||||
.ToNdArray2D();
|
||||
@ -116,10 +114,5 @@ namespace CC_Functions.Commandline.TUI
|
||||
rend[i, j]);
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called if the selected value of the slider changes
|
||||
/// </summary>
|
||||
public event OnClick ValueChanged;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using CC_Functions.Core;
|
||||
using CC_Functions.Misc;
|
||||
|
||||
namespace CC_Functions.Commandline.TUI
|
||||
{
|
||||
@ -135,6 +135,7 @@ namespace CC_Functions.Commandline.TUI
|
||||
case ConsoleKey.Enter:
|
||||
if (lines.Length < Size.Height)
|
||||
{
|
||||
tmp = lines.ToList();
|
||||
lines[Cursor.Y] = lines[Cursor.Y].Insert(Math.Max(Cursor.X, 0), "\n");
|
||||
Cursor.Y++;
|
||||
Cursor.X = 0;
|
||||
|
@ -1,28 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>CC_Functions.Core</RootNamespace>
|
||||
<AssemblyName>CC_Functions.Core</AssemblyName>
|
||||
<Deterministic>false</Deterministic>
|
||||
<PackageId>CC-Functions.Core</PackageId>
|
||||
<Title>CC-Functions.Core</Title>
|
||||
<Authors>JFronny</Authors>
|
||||
<Description>Random pieces of code without external dependencies. Used in other CC_Functions packages</Description>
|
||||
<Copyright>Copyright 2020</Copyright>
|
||||
<PackageProjectUrl>https://gitlab.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||
<RepositoryUrl>https://gitlab.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<AssemblyVersion>1.1.*</AssemblyVersion>
|
||||
<FileVersion>1.0.0.0</FileVersion>
|
||||
<VersionSuffix>0.0</VersionSuffix>
|
||||
<PackageVersion>1.1.$(VersionSuffix)</PackageVersion>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DocumentationFile>bin\Debug\Core.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DocumentationFile>bin\Release\Core.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -1,255 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
|
||||
namespace CC_Functions.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for various types
|
||||
/// </summary>
|
||||
public static class GenericExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an element from the dictionary or adds the default
|
||||
/// </summary>
|
||||
/// <param name="dict">The dictionary to get from</param>
|
||||
/// <param name="key">The key to check</param>
|
||||
/// <param name="def">The default value to place</param>
|
||||
/// <typeparam name="TKey">The key type</typeparam>
|
||||
/// <typeparam name="TValue">The value type</typeparam>
|
||||
/// <returns>The element at the key</returns>
|
||||
public static TValue Get<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, TValue def = default)
|
||||
{
|
||||
if (!dict.ContainsKey(key))
|
||||
dict[key] = def;
|
||||
return dict[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets an element and returns it
|
||||
/// </summary>
|
||||
/// <param name="dict">The dictionary to set in</param>
|
||||
/// <param name="key">The key to set at</param>
|
||||
/// <param name="val">The value to place</param>
|
||||
/// <typeparam name="TKey">The key type</typeparam>
|
||||
/// <typeparam name="TValue">The value type</typeparam>
|
||||
/// <returns>The value that was placed</returns>
|
||||
public static TValue Set<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, TValue val = default)
|
||||
{
|
||||
dict[key] = val;
|
||||
return dict[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to cast an object
|
||||
/// </summary>
|
||||
/// <param name="o">The object to try to parse</param>
|
||||
/// <param name="parsed">The parsed object (if successful) or the default (usually null)</param>
|
||||
/// <typeparam name="T">The type to cast to</typeparam>
|
||||
/// <returns>Whether the cast was successful</returns>
|
||||
public static bool TryCast<T>(this object o, out T parsed)
|
||||
{
|
||||
try
|
||||
{
|
||||
parsed = (T) o;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
parsed = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a function that transforms an object in-line
|
||||
/// </summary>
|
||||
/// <param name="self">The object to run on</param>
|
||||
/// <param name="func">The function to run</param>
|
||||
/// <typeparam name="TIn">The input type</typeparam>
|
||||
/// <typeparam name="TOut">The output type</typeparam>
|
||||
/// <returns></returns>
|
||||
public static TOut SelectO<TIn, TOut>(this TIn self, Func<TIn, TOut> func) => func.Invoke(self);
|
||||
|
||||
/// <summary>
|
||||
/// Runs a function under a condition in-line (equal to if)
|
||||
/// </summary>
|
||||
/// <param name="condition">The condition to check</param>
|
||||
/// <param name="func">The function to run</param>
|
||||
public static void RunIf(bool condition, Action func)
|
||||
{
|
||||
if (condition)
|
||||
func();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a string to a value of an enum
|
||||
/// </summary>
|
||||
/// <param name="value">The string to parse</param>
|
||||
/// <typeparam name="TEnum">The enum type (MUST be an enum)</typeparam>
|
||||
/// <returns>The element</returns>
|
||||
public static TEnum ParseToEnum<TEnum>(string value) => (TEnum) Enum.Parse(typeof(TEnum),
|
||||
Enum.GetNames(typeof(TEnum)).First(s => s.ToLower() == value.ToLower()));
|
||||
|
||||
/// <summary>
|
||||
/// Parses a string to a nullable bool (defaults to null if parse fails)
|
||||
/// </summary>
|
||||
/// <param name="value">The st string to parse</param>
|
||||
/// <returns>The output nullable bool</returns>
|
||||
public static bool? ParseBool(string value) =>
|
||||
bool.TryParse(value, out bool tmp) ? (bool?) tmp : null;
|
||||
|
||||
/// <summary>
|
||||
/// AND operation for nullable bools (uses <see cref="True">True</see>)
|
||||
/// </summary>
|
||||
/// <param name="left">First bool to check</param>
|
||||
/// <param name="right">Second bool to check</param>
|
||||
/// <returns>The operation result</returns>
|
||||
public static bool And(this bool? left, bool? right) => left.True() && right.True();
|
||||
|
||||
/// <summary>
|
||||
/// OR operation for nullable bools (uses <see cref="True">True</see>)
|
||||
/// </summary>
|
||||
/// <param name="left">First bool to check</param>
|
||||
/// <param name="right">Second bool to check</param>
|
||||
/// <returns>The operation result</returns>
|
||||
public static bool Or(this bool? left, bool? right) => left.True() || right.True();
|
||||
|
||||
/// <summary>
|
||||
/// XOR operation for nullable bools (uses <see cref="True">True</see>)
|
||||
/// </summary>
|
||||
/// <param name="left">First bool to check</param>
|
||||
/// <param name="right">Second bool to check</param>
|
||||
/// <returns>The operation result</returns>
|
||||
public static bool Xor(this bool? left, bool? right) => left.Or(right) && !left.And(right);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the nullable bool is true (null->false)
|
||||
/// </summary>
|
||||
/// <param name="self">Value to check</param>
|
||||
/// <returns>Whether it is true</returns>
|
||||
public static bool True(this bool? self) => self == true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the nullable bool is false (null->false)
|
||||
/// </summary>
|
||||
/// <param name="self">Value to check</param>
|
||||
/// <returns>Whether it is false</returns>
|
||||
public static bool False(this bool? self) => self == false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the nullable bool is null
|
||||
/// </summary>
|
||||
/// <param name="self">Value to check</param>
|
||||
/// <returns>Whether it is null</returns>
|
||||
public static bool Null(this bool? self) => self == null;
|
||||
|
||||
/// <summary>
|
||||
/// Removes an element from a dictionary by its index (not key)
|
||||
/// </summary>
|
||||
/// <param name="dict">The dictionary to remove from</param>
|
||||
/// <param name="index">The index of the value</param>
|
||||
/// <typeparam name="TKey">The key type</typeparam>
|
||||
/// <typeparam name="TValue">The value type</typeparam>
|
||||
public static void RemoveAt<TKey, TValue>(this Dictionary<TKey, TValue> dict, int index) =>
|
||||
dict.Remove(dict.Keys.ToArray()[index]);
|
||||
|
||||
/// <summary>
|
||||
/// "Unshorten" (follow) an URL
|
||||
/// </summary>
|
||||
/// <param name="self">The URL to unshorten</param>
|
||||
/// <returns>The unshortened URL</returns>
|
||||
public static Uri Unshorten(this Uri self)
|
||||
{
|
||||
HttpWebRequest req = (HttpWebRequest) WebRequest.Create(self);
|
||||
req.AllowAutoRedirect = true;
|
||||
req.MaximumAutomaticRedirections = 100;
|
||||
WebResponse resp = req.GetResponse();
|
||||
return resp.ResponseUri;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds a RectangleF to a Rectangle instead of flooring
|
||||
/// </summary>
|
||||
/// <param name="self">The RectangleF to round</param>
|
||||
/// <returns>The rounded Rectangle</returns>
|
||||
public static Rectangle Round(this RectangleF self) => Rectangle.Round(self);
|
||||
|
||||
/// <summary>
|
||||
/// Ceilings a RectangleF to a Rectangle instead of flooring
|
||||
/// </summary>
|
||||
/// <param name="self">The RectangleF to ceil (?)</param>
|
||||
/// <returns>The ceiled (?) Rectangle</returns>
|
||||
public static Rectangle Ceiling(this RectangleF self) => Rectangle.Ceiling(self);
|
||||
|
||||
/// <summary>
|
||||
/// Pings an URL to check for availability
|
||||
/// </summary>
|
||||
/// <param name="self">The URL to check</param>
|
||||
/// <returns>Whether the service is online</returns>
|
||||
public static bool Ping(this Uri self)
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(self);
|
||||
request.Timeout = 3000;
|
||||
request.AllowAutoRedirect = true;
|
||||
using WebResponse response = request.GetResponse();
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of a dictionary
|
||||
/// </summary>
|
||||
/// <param name="directory">The dictionary to check</param>
|
||||
/// <returns>The size of the dictionary</returns>
|
||||
public static long GetSize(this DirectoryInfo directory) => IO.GetDirectorySize(directory.FullName);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a directory to an archive recursively
|
||||
/// </summary>
|
||||
/// <param name="archive">The archive to add to</param>
|
||||
/// <param name="folderPath">The directory to add</param>
|
||||
/// <param name="entryName">The name of the directory in-archive</param>
|
||||
/// <param name="ignoredExtensions">Extensions for files to ignore</param>
|
||||
/// <param name="ignoredPaths">Paths to exclude from adding</param>
|
||||
/// <returns>The new entry</returns>
|
||||
public static ZipArchiveEntry AddDirectory(this ZipArchive archive, string folderPath, string entryName,
|
||||
string[] ignoredExtensions, string[] ignoredPaths)
|
||||
{
|
||||
entryName = entryName.TrimEnd('/');
|
||||
ZipArchiveEntry result = archive.CreateEntry($"{entryName}/");
|
||||
string[] files = Directory.GetFiles(folderPath);
|
||||
foreach (string t in files)
|
||||
if (!ignoredExtensions.Contains(Path.GetExtension(t)) &&
|
||||
!ignoredPaths.Any(s => IO.CheckPathEqual(s, t)))
|
||||
archive.CreateEntryFromFile(t, $"{entryName}/{Path.GetFileName(t)}");
|
||||
string[] dirs = Directory.GetDirectories(folderPath);
|
||||
foreach (string t in dirs)
|
||||
if (!ignoredPaths.Any(s => IO.CheckPathEqual(s, t)))
|
||||
archive.AddDirectory(t, $"{entryName}/{Path.GetFileName(t)}", ignoredExtensions,
|
||||
ignoredPaths);
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the threads cultureInfo properties to InvariantCulture. For testing
|
||||
/// </summary>
|
||||
/// <param name="thread">The thread to modify</param>
|
||||
public static void ForceInvariantCulture(this Thread thread)
|
||||
{
|
||||
thread.CurrentCulture = CultureInfo.InvariantCulture;
|
||||
thread.CurrentUICulture = CultureInfo.InvariantCulture;
|
||||
}
|
||||
}
|
||||
}
|
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 J. Fronny
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -2,7 +2,7 @@
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
||||
namespace CC_Functions.Core
|
||||
namespace CC_Functions.Misc
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension functions to work with 1D and 2D arrays
|
@ -1,9 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using CC_Functions.Core;
|
||||
|
||||
namespace CC_Functions.Misc
|
||||
{
|
||||
@ -12,6 +13,234 @@ namespace CC_Functions.Misc
|
||||
/// </summary>
|
||||
public static class GenericExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an element from the dictionary or adds the default
|
||||
/// </summary>
|
||||
/// <param name="dict">The dictionary to get from</param>
|
||||
/// <param name="key">The key to check</param>
|
||||
/// <param name="def">The default value to place</param>
|
||||
/// <typeparam name="TKey">The key type</typeparam>
|
||||
/// <typeparam name="TValue">The value type</typeparam>
|
||||
/// <returns>The element at the key</returns>
|
||||
public static TValue Get<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, TValue def = default)
|
||||
{
|
||||
if (!dict.ContainsKey(key))
|
||||
dict[key] = def;
|
||||
return dict[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets an element and returns it
|
||||
/// </summary>
|
||||
/// <param name="dict">The dictionary to set in</param>
|
||||
/// <param name="key">The key to set at</param>
|
||||
/// <param name="val">The value to place</param>
|
||||
/// <typeparam name="TKey">The key type</typeparam>
|
||||
/// <typeparam name="TValue">The value type</typeparam>
|
||||
/// <returns>The value that was placed</returns>
|
||||
public static TValue Set<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, TValue val = default)
|
||||
{
|
||||
dict[key] = val;
|
||||
return dict[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to cast an object
|
||||
/// </summary>
|
||||
/// <param name="o">The object to try to parse</param>
|
||||
/// <param name="parsed">The parsed object (if successful) or the default (usually null)</param>
|
||||
/// <typeparam name="T">The type to cast to</typeparam>
|
||||
/// <returns>Whether the cast was successful</returns>
|
||||
public static bool TryCast<T>(this object o, out T parsed)
|
||||
{
|
||||
try
|
||||
{
|
||||
parsed = (T) o;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
parsed = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a function that transforms an object in-line
|
||||
/// </summary>
|
||||
/// <param name="self">The object to run on</param>
|
||||
/// <param name="func">The function to run</param>
|
||||
/// <typeparam name="TIn">The input type</typeparam>
|
||||
/// <typeparam name="TOut">The output type</typeparam>
|
||||
/// <returns></returns>
|
||||
public static TOut SelectO<TIn, TOut>(this TIn self, Func<TIn, TOut> func) => func.Invoke(self);
|
||||
|
||||
/// <summary>
|
||||
/// Runs a function under a condition in-line (equal to if)
|
||||
/// </summary>
|
||||
/// <param name="condition">The condition to check</param>
|
||||
/// <param name="func">The function to run</param>
|
||||
public static void RunIf(bool condition, Action func)
|
||||
{
|
||||
if (condition)
|
||||
func();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a string to a value of an enum
|
||||
/// </summary>
|
||||
/// <param name="value">The string to parse</param>
|
||||
/// <typeparam name="TEnum">The enum type (MUST be an enum)</typeparam>
|
||||
/// <returns>The element</returns>
|
||||
public static TEnum ParseToEnum<TEnum>(string value) => (TEnum) Enum.Parse(typeof(TEnum),
|
||||
Enum.GetNames(typeof(TEnum)).First(s => s.ToLower() == value.ToLower()));
|
||||
|
||||
/// <summary>
|
||||
/// Parses a string to a nullable bool (defaults to null if parse fails)
|
||||
/// </summary>
|
||||
/// <param name="value">The st string to parse</param>
|
||||
/// <returns>The output nullable bool</returns>
|
||||
public static bool? ParseBool(string value) =>
|
||||
bool.TryParse(value, out bool tmp) ? (bool?) tmp : null;
|
||||
|
||||
/// <summary>
|
||||
/// AND operation for nullable bools (uses <see cref="True">True</see>)
|
||||
/// </summary>
|
||||
/// <param name="left">First bool to check</param>
|
||||
/// <param name="right">Second bool to check</param>
|
||||
/// <returns>The operation result</returns>
|
||||
public static bool And(this bool? left, bool? right) => left.True() && right.True();
|
||||
|
||||
/// <summary>
|
||||
/// OR operation for nullable bools (uses <see cref="True">True</see>)
|
||||
/// </summary>
|
||||
/// <param name="left">First bool to check</param>
|
||||
/// <param name="right">Second bool to check</param>
|
||||
/// <returns>The operation result</returns>
|
||||
public static bool Or(this bool? left, bool? right) => left.True() || right.True();
|
||||
|
||||
/// <summary>
|
||||
/// XOR operation for nullable bools (uses <see cref="True">True</see>)
|
||||
/// </summary>
|
||||
/// <param name="left">First bool to check</param>
|
||||
/// <param name="right">Second bool to check</param>
|
||||
/// <returns>The operation result</returns>
|
||||
public static bool Xor(this bool? left, bool? right) => left.Or(right) && !left.And(right);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the nullable bool is true (null->false)
|
||||
/// </summary>
|
||||
/// <param name="self">Value to check</param>
|
||||
/// <returns>Whether it is true</returns>
|
||||
public static bool True(this bool? self) => self == true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the nullable bool is false (null->false)
|
||||
/// </summary>
|
||||
/// <param name="self">Value to check</param>
|
||||
/// <returns>Whether it is false</returns>
|
||||
public static bool False(this bool? self) => self == false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the nullable bool is null
|
||||
/// </summary>
|
||||
/// <param name="self">Value to check</param>
|
||||
/// <returns>Whether it is null</returns>
|
||||
public static bool Null(this bool? self) => self == null;
|
||||
|
||||
/// <summary>
|
||||
/// Removes an element from a dictionary by its index (not key)
|
||||
/// </summary>
|
||||
/// <param name="dict">The dictionary to remove from</param>
|
||||
/// <param name="index">The index of the value</param>
|
||||
/// <typeparam name="TKey">The key type</typeparam>
|
||||
/// <typeparam name="TValue">The value type</typeparam>
|
||||
public static void RemoveAt<TKey, TValue>(this Dictionary<TKey, TValue> dict, int index) =>
|
||||
dict.Remove(dict.Keys.ToArray()[index]);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of a dictionary
|
||||
/// </summary>
|
||||
/// <param name="directory">The dictionary to check</param>
|
||||
/// <returns>The size of the dictionary</returns>
|
||||
public static long GetSize(this DirectoryInfo directory) => IO.GetDirectorySize(directory.FullName);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a directory to an archive recursively
|
||||
/// </summary>
|
||||
/// <param name="archive">The archive to add to</param>
|
||||
/// <param name="folderPath">The directory to add</param>
|
||||
/// <param name="entryName">The name of the directory in-archive</param>
|
||||
/// <param name="ignoredExtensions">Extensions for files to ignore</param>
|
||||
/// <param name="ignoredPaths">Paths to exclude from adding</param>
|
||||
/// <returns>The new entry</returns>
|
||||
public static ZipArchiveEntry AddDirectory(this ZipArchive archive, string folderPath, string entryName,
|
||||
string[] ignoredExtensions, string[] ignoredPaths)
|
||||
{
|
||||
entryName = entryName.TrimEnd('/');
|
||||
ZipArchiveEntry result = archive.CreateEntry($"{entryName}/");
|
||||
string[] files = Directory.GetFiles(folderPath);
|
||||
foreach (string t in files)
|
||||
if (!ignoredExtensions.Contains(Path.GetExtension(t)) &&
|
||||
!ignoredPaths.Any(s => IO.CheckPathEqual(s, t)))
|
||||
archive.CreateEntryFromFile(t, $"{entryName}/{Path.GetFileName(t)}");
|
||||
string[] dirs = Directory.GetDirectories(folderPath);
|
||||
foreach (string t in dirs)
|
||||
if (!ignoredPaths.Any(s => IO.CheckPathEqual(s, t)))
|
||||
archive.AddDirectory(t, $"{entryName}/{Path.GetFileName(t)}", ignoredExtensions,
|
||||
ignoredPaths);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// "Unshorten" (follow) an URL
|
||||
/// </summary>
|
||||
/// <param name="self">The URL to unshorten</param>
|
||||
/// <returns>The unshortened URL</returns>
|
||||
public static Uri Unshorten(this Uri self)
|
||||
{
|
||||
HttpWebRequest req = (HttpWebRequest) WebRequest.Create(self);
|
||||
req.AllowAutoRedirect = true;
|
||||
req.MaximumAutomaticRedirections = 100;
|
||||
WebResponse resp = req.GetResponse();
|
||||
return resp.ResponseUri;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings an URL to check for availability
|
||||
/// </summary>
|
||||
/// <param name="self">The URL to check</param>
|
||||
/// <returns>Whether the service is online</returns>
|
||||
public static bool Ping(this Uri self)
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(self);
|
||||
request.Timeout = 3000;
|
||||
request.AllowAutoRedirect = true;
|
||||
using WebResponse response = request.GetResponse();
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds a RectangleF to a Rectangle instead of flooring
|
||||
/// </summary>
|
||||
/// <param name="self">The RectangleF to round</param>
|
||||
/// <returns>The rounded Rectangle</returns>
|
||||
public static Rectangle Round(this RectangleF self) => Rectangle.Round(self);
|
||||
|
||||
/// <summary>
|
||||
/// Ceilings a RectangleF to a Rectangle instead of flooring
|
||||
/// </summary>
|
||||
/// <param name="self">The RectangleF to ceil (?)</param>
|
||||
/// <returns>The ceiled (?) Rectangle</returns>
|
||||
public static Rectangle Ceiling(this RectangleF self) => Rectangle.Ceiling(self);
|
||||
|
||||
/// <summary>
|
||||
/// Extension method for <see cref="Crypto">Crypto's</see> Encrypt
|
||||
/// </summary>
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace CC_Functions.Core
|
||||
namespace CC_Functions.Misc
|
||||
{
|
||||
/// <summary>
|
||||
/// IO functions
|
@ -7,17 +7,17 @@
|
||||
<Deterministic>false</Deterministic>
|
||||
<PackageId>CC-Functions.Misc</PackageId>
|
||||
<Title>CC-Functions.Misc</Title>
|
||||
<Authors>JFronny</Authors>
|
||||
<Authors>CC24</Authors>
|
||||
<Description>Random pieces of code used across my projects. I do NOT recommend using this in your own project!</Description>
|
||||
<Copyright>Copyright 2020</Copyright>
|
||||
<PackageProjectUrl>https://gitlab.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||
<RepositoryUrl>https://gitlab.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||
<PackageProjectUrl>https://github.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<AssemblyVersion>1.1.*</AssemblyVersion>
|
||||
<FileVersion>1.0.0.0</FileVersion>
|
||||
<VersionSuffix>0.0</VersionSuffix>
|
||||
<PackageVersion>1.1.$(VersionSuffix)</PackageVersion>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DocumentationFile>bin\Debug\Misc.xml</DocumentationFile>
|
||||
@ -29,14 +29,11 @@
|
||||
<EmbeddedResource Include="HIDClasses.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Management" Version="5.0.0" />
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="5.0.0" />
|
||||
<PackageReference Include="System.Management" Version="4.7.0" />
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.IO.Compression" Condition="'$(TargetFramework)' == 'net461'" />
|
||||
<Reference Include="System.IO.Compression.FileSystem" Condition="'$(TargetFramework)' == 'net461'" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Core\Core.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -1,4 +1,4 @@
|
||||
namespace CC_Functions.Core
|
||||
namespace CC_Functions.Misc
|
||||
{
|
||||
/// <summary>
|
||||
/// Characters for use in CC-Functions.CommandLine
|
@ -1,6 +1,2 @@
|
||||
# CC-Functions
|
||||
[![UpTool2](https://img.shields.io/badge/Get%20it-on%20UpTool2-blue)](https://jfronny.gitlab.io/home/uptool)
|
||||
[![Nuget](https://img.shields.io/nuget/v/CC-Functions.Core?label=CC-Functions.Core)](https://www.nuget.org/packages/CC-Functions.Core/)
|
||||
[![Nuget](https://img.shields.io/nuget/v/CC-Functions.Misc?label=CC-Functions.Misc)](https://www.nuget.org/packages/CC-Functions.Misc/)
|
||||
[![Nuget](https://img.shields.io/nuget/v/CC-Functions.W32?label=CC-Functions.W32)](https://www.nuget.org/packages/CC-Functions.W32/)
|
||||
[![Nuget](https://img.shields.io/nuget/v/CC-Functions.W32?label=CC-Functions.Commandline)](https://www.nuget.org/packages/CC-Functions.Commandline/)
|
||||
# CC-Functions
|
||||
[![UpTool2](https://img.shields.io/github/v/tag/JFronny/CC-Functions?color=informational&label=UpTool2)](https://jfronny.github.io/home/uptool) [![Nuget](https://img.shields.io/nuget/v/CC-Functions.Misc?label=CC-Functions.Misc)](https://www.nuget.org/packages/CC-Functions.Misc/) [![Nuget](https://img.shields.io/nuget/v/CC-Functions.W32?label=CC-Functions.W32)](https://www.nuget.org/packages/CC-Functions.W32/)
|
||||
|
@ -5,13 +5,13 @@
|
||||
<AssemblyName>CC-Functions.W32</AssemblyName>
|
||||
<LangVersion>8</LangVersion>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFrameworks>net461;netcoreapp3.1</TargetFrameworks>
|
||||
<Deterministic>false</Deterministic>
|
||||
<Authors>JFronny</Authors>
|
||||
<Authors>CC24</Authors>
|
||||
<Description>W32 Additions for CC-Functions</Description>
|
||||
<Copyright>Copyright 2020</Copyright>
|
||||
<PackageProjectUrl>https://gitlab.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||
<RepositoryUrl>https://gitlab.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||
<PackageProjectUrl>https://github.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<AssemblyVersion>1.1.*</AssemblyVersion>
|
||||
<FileVersion>1.0.0.0</FileVersion>
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user