Compare commits
No commits in common. "master" and "1.1.7468.32091" have entirely different histories.
master
...
1.1.7468.3
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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CLITest", "CLITest\CLITest.csproj", "{3FAB0713-3021-4C6A-BF4A-ABBD542634A6}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CLITest", "CLITest\CLITest.csproj", "{3FAB0713-3021-4C6A-BF4A-ABBD542634A6}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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}.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.ActiveCfg = Release|Any CPU
|
||||||
{3FAB0713-3021-4C6A-BF4A-ABBD542634A6}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -1,32 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using CC_Functions.Commandline;
|
|
||||||
using CC_Functions.Commandline.TUI;
|
using CC_Functions.Commandline.TUI;
|
||||||
using CC_Functions.Core;
|
|
||||||
|
|
||||||
namespace CLITest
|
namespace CLITest
|
||||||
{
|
{
|
||||||
internal class Program
|
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.BackgroundColor = ConsoleColor.Black;
|
||||||
Console.ForegroundColor = ConsoleColor.White;
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
Console.Clear();
|
Console.Clear();
|
||||||
|
@ -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,11 +9,11 @@
|
|||||||
<Deterministic>false</Deterministic>
|
<Deterministic>false</Deterministic>
|
||||||
<PackageId>CC-Functions.Commandline</PackageId>
|
<PackageId>CC-Functions.Commandline</PackageId>
|
||||||
<Title>CC-Functions.Commandline</Title>
|
<Title>CC-Functions.Commandline</Title>
|
||||||
<Authors>JFronny</Authors>
|
<Authors>CC24</Authors>
|
||||||
<Description>Random pieces of code used across my projects. CLI/TUI extensions</Description>
|
<Description>Random pieces of code used across my projects. CLI/TUI extensions</Description>
|
||||||
<Copyright>Copyright 2020</Copyright>
|
<Copyright>Copyright 2020</Copyright>
|
||||||
<PackageProjectUrl>https://gitlab.com/JFronny/CC-Functions</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://gitlab.com/JFronny/CC-Functions.git</RepositoryUrl>
|
<RepositoryUrl>https://github.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
<AssemblyVersion>1.1.*</AssemblyVersion>
|
<AssemblyVersion>1.1.*</AssemblyVersion>
|
||||||
<FileVersion>1.0.0.0</FileVersion>
|
<FileVersion>1.0.0.0</FileVersion>
|
||||||
@ -31,6 +31,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Core\Core.csproj" />
|
<ProjectReference Include="..\Misc\Misc.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using CC_Functions.Core;
|
using CC_Functions.Misc;
|
||||||
|
|
||||||
namespace CC_Functions.Commandline.TUI
|
namespace CC_Functions.Commandline.TUI
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using CC_Functions.Core;
|
using CC_Functions.Misc;
|
||||||
|
|
||||||
namespace CC_Functions.Commandline.TUI
|
namespace CC_Functions.Commandline.TUI
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using CC_Functions.Core;
|
using CC_Functions.Misc;
|
||||||
|
|
||||||
namespace CC_Functions.Commandline.TUI
|
namespace CC_Functions.Commandline.TUI
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using CC_Functions.Commandline.TUI;
|
using CC_Functions.Misc;
|
||||||
using CC_Functions.Core;
|
|
||||||
|
|
||||||
namespace CC_Functions.Commandline
|
namespace CC_Functions.Commandline.TUI
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides differential drawing of a char[,] Do not use in combination with System.Console
|
/// Provides differential drawing of a char[,] Do not use in combination with System.Console
|
@ -1,5 +1,5 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using CC_Functions.Core;
|
using CC_Functions.Misc;
|
||||||
|
|
||||||
namespace CC_Functions.Commandline.TUI
|
namespace CC_Functions.Commandline.TUI
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using CC_Functions.Core;
|
using CC_Functions.Misc;
|
||||||
|
|
||||||
namespace CC_Functions.Commandline.TUI
|
namespace CC_Functions.Commandline.TUI
|
||||||
{
|
{
|
||||||
|
@ -129,17 +129,18 @@ namespace CC_Functions.Commandline.TUI
|
|||||||
break;
|
break;
|
||||||
case ConsoleKey.Enter:
|
case ConsoleKey.Enter:
|
||||||
if (selectable.Any() && selectable.Length >= TabPoint && selectable[TabPoint].Enabled)
|
if (selectable.Any() && selectable.Length >= TabPoint && selectable[TabPoint].Enabled)
|
||||||
|
{
|
||||||
selectable[TabPoint].InvokeClick(this);
|
selectable[TabPoint].InvokeClick(this);
|
||||||
|
render = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.Escape:
|
case ConsoleKey.Escape:
|
||||||
Close?.Invoke(this, new EventArgs());
|
Close?.Invoke(this, new EventArgs());
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
if (selectable.Any() && selectable.Length >= TabPoint && selectable[TabPoint].Enabled)
|
|
||||||
selectable[TabPoint].InvokeInput(this, input);
|
|
||||||
InvokeInput(this, input);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (selectable.Any() && selectable.Length >= TabPoint && selectable[TabPoint].Enabled)
|
||||||
|
selectable[TabPoint].InvokeInput(this, input);
|
||||||
|
InvokeInput(this, input);
|
||||||
render = true;
|
render = true;
|
||||||
}
|
}
|
||||||
if (_wndWidth != Console.WindowWidth || _wndHeight != Console.WindowHeight)
|
if (_wndWidth != Console.WindowWidth || _wndHeight != Console.WindowHeight)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using CC_Functions.Core;
|
using CC_Functions.Misc;
|
||||||
|
|
||||||
namespace CC_Functions.Commandline.TUI
|
namespace CC_Functions.Commandline.TUI
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using CC_Functions.Core;
|
using CC_Functions.Misc;
|
||||||
|
|
||||||
namespace CC_Functions.Commandline.TUI
|
namespace CC_Functions.Commandline.TUI
|
||||||
{
|
{
|
||||||
@ -135,6 +135,7 @@ namespace CC_Functions.Commandline.TUI
|
|||||||
case ConsoleKey.Enter:
|
case ConsoleKey.Enter:
|
||||||
if (lines.Length < Size.Height)
|
if (lines.Length < Size.Height)
|
||||||
{
|
{
|
||||||
|
tmp = lines.ToList();
|
||||||
lines[Cursor.Y] = lines[Cursor.Y].Insert(Math.Max(Cursor.X, 0), "\n");
|
lines[Cursor.Y] = lines[Cursor.Y].Insert(Math.Max(Cursor.X, 0), "\n");
|
||||||
Cursor.Y++;
|
Cursor.Y++;
|
||||||
Cursor.X = 0;
|
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.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace CC_Functions.Core
|
namespace CC_Functions.Misc
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains extension functions to work with 1D and 2D arrays
|
/// Contains extension functions to work with 1D and 2D arrays
|
@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using CC_Functions.Core;
|
|
||||||
|
|
||||||
namespace CC_Functions.Misc
|
namespace CC_Functions.Misc
|
||||||
{
|
{
|
||||||
@ -12,6 +13,234 @@ namespace CC_Functions.Misc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class GenericExtensions
|
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>
|
/// <summary>
|
||||||
/// Extension method for <see cref="Crypto">Crypto's</see> Encrypt
|
/// Extension method for <see cref="Crypto">Crypto's</see> Encrypt
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace CC_Functions.Core
|
namespace CC_Functions.Misc
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IO functions
|
/// IO functions
|
@ -7,17 +7,17 @@
|
|||||||
<Deterministic>false</Deterministic>
|
<Deterministic>false</Deterministic>
|
||||||
<PackageId>CC-Functions.Misc</PackageId>
|
<PackageId>CC-Functions.Misc</PackageId>
|
||||||
<Title>CC-Functions.Misc</Title>
|
<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>
|
<Description>Random pieces of code used across my projects. I do NOT recommend using this in your own project!</Description>
|
||||||
<Copyright>Copyright 2020</Copyright>
|
<Copyright>Copyright 2020</Copyright>
|
||||||
<PackageProjectUrl>https://gitlab.com/JFronny/CC-Functions</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://gitlab.com/JFronny/CC-Functions.git</RepositoryUrl>
|
<RepositoryUrl>https://github.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
<AssemblyVersion>1.1.*</AssemblyVersion>
|
<AssemblyVersion>1.1.*</AssemblyVersion>
|
||||||
<FileVersion>1.0.0.0</FileVersion>
|
<FileVersion>1.0.0.0</FileVersion>
|
||||||
<VersionSuffix>0.0</VersionSuffix>
|
<VersionSuffix>0.0</VersionSuffix>
|
||||||
<PackageVersion>1.1.$(VersionSuffix)</PackageVersion>
|
<PackageVersion>1.1.$(VersionSuffix)</PackageVersion>
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DocumentationFile>bin\Debug\Misc.xml</DocumentationFile>
|
<DocumentationFile>bin\Debug\Misc.xml</DocumentationFile>
|
||||||
@ -29,14 +29,11 @@
|
|||||||
<EmbeddedResource Include="HIDClasses.txt" />
|
<EmbeddedResource Include="HIDClasses.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Management" Version="5.0.0" />
|
<PackageReference Include="System.Management" Version="4.7.0" />
|
||||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="5.0.0" />
|
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.7.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System.IO.Compression" Condition="'$(TargetFramework)' == 'net461'" />
|
<Reference Include="System.IO.Compression" Condition="'$(TargetFramework)' == 'net461'" />
|
||||||
<Reference Include="System.IO.Compression.FileSystem" Condition="'$(TargetFramework)' == 'net461'" />
|
<Reference Include="System.IO.Compression.FileSystem" Condition="'$(TargetFramework)' == 'net461'" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Core\Core.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
@ -1,4 +1,4 @@
|
|||||||
namespace CC_Functions.Core
|
namespace CC_Functions.Misc
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Characters for use in CC-Functions.CommandLine
|
/// Characters for use in CC-Functions.CommandLine
|
@ -1,6 +1,2 @@
|
|||||||
# CC-Functions
|
# CC-Functions
|
||||||
[![UpTool2](https://img.shields.io/badge/Get%20it-on%20UpTool2-blue)](https://jfronny.gitlab.io/home/uptool)
|
[![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/)
|
||||||
[![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/)
|
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
<AssemblyName>CC-Functions.W32</AssemblyName>
|
<AssemblyName>CC-Functions.W32</AssemblyName>
|
||||||
<LangVersion>8</LangVersion>
|
<LangVersion>8</LangVersion>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFrameworks>net461;netcoreapp3.1</TargetFrameworks>
|
||||||
<Deterministic>false</Deterministic>
|
<Deterministic>false</Deterministic>
|
||||||
<Authors>JFronny</Authors>
|
<Authors>CC24</Authors>
|
||||||
<Description>W32 Additions for CC-Functions</Description>
|
<Description>W32 Additions for CC-Functions</Description>
|
||||||
<Copyright>Copyright 2020</Copyright>
|
<Copyright>Copyright 2020</Copyright>
|
||||||
<PackageProjectUrl>https://gitlab.com/JFronny/CC-Functions</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/JFronny/CC-Functions</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://gitlab.com/JFronny/CC-Functions.git</RepositoryUrl>
|
<RepositoryUrl>https://github.com/JFronny/CC-Functions.git</RepositoryUrl>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
<AssemblyVersion>1.1.*</AssemblyVersion>
|
<AssemblyVersion>1.1.*</AssemblyVersion>
|
||||||
<FileVersion>1.0.0.0</FileVersion>
|
<FileVersion>1.0.0.0</FileVersion>
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": [
|
|
||||||
"config:base"
|
|
||||||
]
|
|
||||||
}
|
|
Reference in New Issue
Block a user