new build pipeline

This commit is contained in:
Genteure 2021-02-26 21:57:10 +08:00
parent 534adfba1b
commit 48155e28e0
36 changed files with 288 additions and 4218 deletions

69
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,69 @@
name: Build and Test
on:
push:
pull_request:
jobs:
test:
strategy:
matrix:
os: [windows-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Restore Packages
run: dotnet restore -v m
- name: Run Tests
run: dotnet test -v m
build_wpf:
needs: test
strategy:
matrix:
build_configuration: [Debug, Release]
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Restore Packages
run: nuget restore -Verbosity quiet
- name: Build WPF
run: msbuild /nologo /v:m /p:Configuration="${{ matrix.build_configuration }}"
- name: Upload Artifacts
uses: actions/upload-artifact@v2
with:
name: WPF-${{ matrix.build_configuration }}
path: BililiveRecorder.WPF/bin/${{ matrix.build_configuration }}
build_cli:
needs: test
strategy:
matrix:
rid: [any, linux-arm, linux-arm64, linux-x64, osx-x64, win-x64]
build_configuration: [Debug, Release]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Restore Packages
run: dotnet restore -v m
- name: Build CLI
if: ${{ matrix.rid == 'any' }}
run: dotnet publish -c ${{ matrix.build_configuration }} BililiveRecorder.Cli\BililiveRecorder.Cli.csproj
- name: Build CLI
if: ${{ matrix.rid != 'any' }}
run: dotnet publish -c ${{ matrix.build_configuration }} -r ${{ matrix.rid }} BililiveRecorder.Cli\BililiveRecorder.Cli.csproj
- name: Upload Artifacts
uses: actions/upload-artifact@v2
with:
name: CLI-${{ matrix.rid }}-${{ matrix.build_configuration }}
path: BililiveRecorder.Cli/publish/${{ matrix.build_configuration }}

102
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,102 @@
name: Release
on:
release:
types: [published]
jobs:
test:
strategy:
matrix:
os: [windows-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Restore Packages
run: dotnet restore -v m
- name: Run Tests
run: dotnet test -v m
release_wpf:
needs: test
strategy:
matrix:
build_configuration: [Release]
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Restore Packages
run: nuget restore -Verbosity quiet
- name: Build WPF
run: msbuild /nologo /v:m /p:Configuration="${{ matrix.build_configuration }}"
- name: Upload Artifacts
uses: actions/upload-artifact@v2
with:
name: WPF-${{ matrix.build_configuration }}
path: BililiveRecorder.WPF/bin/${{ matrix.build_configuration }}
- name: Pack Release Asset
run: 7z a BililiveRecorder-WPF-Portable.zip BililiveRecorder.WPF/bin/${{ matrix.build_configuration }}
- name: Upload Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: BililiveRecorder-WPF-Portable.zip
asset_name: BililiveRecorder-WPF-Portable.zip
asset_content_type: application/zip
- name: Upload Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: BililiveRecorder.WPF\bin\SquirrelReleases\Setup.exe
asset_name: BililiveRecorder-WPF-Setup.exe
asset_content_type: application/vnd.microsoft.portable-executable
release_cli:
needs: test
strategy:
matrix:
rid: [any, linux-arm, linux-arm64, linux-x64, osx-x64, win-x64]
build_configuration: [Release]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Restore Packages
run: dotnet restore -v m
- name: Build CLI
if: ${{ matrix.rid == 'any' }}
run: dotnet publish -c ${{ matrix.build_configuration }} BililiveRecorder.Cli\BililiveRecorder.Cli.csproj
- name: Build CLI
if: ${{ matrix.rid != 'any' }}
run: dotnet publish -c ${{ matrix.build_configuration }} -r ${{ matrix.rid }} BililiveRecorder.Cli\BililiveRecorder.Cli.csproj
- name: Upload Artifacts
uses: actions/upload-artifact@v2
with:
name: CLI-${{ matrix.rid }}-${{ matrix.build_configuration }}
path: BililiveRecorder.Cli/publish/${{ matrix.build_configuration }}
- name: Pack Release Asset
run: |
cd BililiveRecorder.Cli/publish
zip -r CLI-${{ matrix.rid }}-${{ matrix.build_configuration }}.zip ./${{ matrix.build_configuration }}
- name: Upload Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: BililiveRecorder.Cli/publish/CLI-${{ matrix.rid }}-${{ matrix.build_configuration }}.zip
asset_name: BililiveRecorder-CLI-${{ matrix.rid }}.zip
asset_content_type: application/zip

2
.gitignore vendored
View File

@ -261,6 +261,4 @@ paket-files/
__pycache__/
*.pyc
TempBuildInfo/*.cs
BililiveRecorder.WPF/Nlog.config
BililiveRecorder.Cli/Properties/launchSettings.json

View File

@ -1,32 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>9.0</LangVersion>
<TargetFramework>net5.0</TargetFramework>
<StartupObject>BililiveRecorder.Cli.Program</StartupObject>
<RuntimeIdentifiers>win-x64;osx-x64;osx.10.11-x64;linux-arm64;linux-arm;linux-x64</RuntimeIdentifiers>
<RuntimeIdentifier Condition=" '$(RuntimeIdentifier)' == 'any' "></RuntimeIdentifier>
<PublishDir Condition=" '$(RuntimeIdentifier)' == '' ">publish\any</PublishDir>
<PublishDir Condition=" '$(RuntimeIdentifier)' != '' ">publish\$(RuntimeIdentifier)</PublishDir>
<SelfContained Condition=" '$(RuntimeIdentifier)' == '' ">false</SelfContained>
<SelfContained Condition=" '$(SelfContained)' == '' ">true</SelfContained>
</PropertyGroup>
<ItemGroup>
<Compile Remove="publish\**" />
<EmbeddedResource Remove="publish\**" />
<None Remove="publish\**" />
</ItemGroup>
<ItemGroup>
<None Remove="NLog.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\TempBuildInfo\BuildInfo.Cli.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="NLog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
@ -39,10 +30,9 @@
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20574.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BililiveRecorder.Core\BililiveRecorder.Core.csproj" />
</ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="cd $(SolutionDir)&#xD;&#xA;powershell -ExecutionPolicy Bypass -File .\CI\patch_buildinfo.ps1 Cli" />
</Target>
</Project>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd ../CI/NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"
>
<targets>
<target name="console" xsi:type="Console" encoding="utf-8"
layout="${longdate} ${level:upperCase=true} ${processid} ${logger} ${event-properties:item=roomid} ${message} ${exception:format=Type} ${exception:format=Message} ${exception:format=ToString}"
/>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="console"/>
</rules>
</nlog>

View File

@ -1,24 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>9.0</LangVersion>
<Version>0.0.0.0</Version>
<Authors>Genteure</Authors>
<Company>Genteure</Company>
<Copyright>Copyright © 2018 - 2021 Genteure</Copyright>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
<FileVersion>0.0.0.0</FileVersion>
<OldToolsVersion>2.0</OldToolsVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<DebugType>portable</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\TempBuildInfo\BuildInfo.Core.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="JsonSubTypes" Version="1.8.0" />
<PackageReference Include="HierarchicalPropertyDefault" Version="0.1.1-beta-g721d36b97c" />
@ -30,13 +18,9 @@
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="System.IO.Pipelines" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BililiveRecorder.Flv\BililiveRecorder.Flv.csproj" />
</ItemGroup>
<PropertyGroup>
<PreBuildEvent>
cd $(SolutionDir)
powershell -ExecutionPolicy Bypass -File .\CI\patch_buildinfo.ps1 Core
</PreBuildEvent>
</PropertyGroup>
</Project>

View File

@ -181,7 +181,7 @@ namespace BililiveRecorder.Core.Danmaku
writer.WriteStartDocument();
writer.WriteProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"#s\"");
writer.WriteStartElement("i");
writer.WriteComment("\nB站录播姬 " + BuildInfo.Version + " " + BuildInfo.HeadSha1 + "\n本文件的弹幕信息兼容B站主站视频弹幕XML格式\n本XML自带样式可以在浏览器里打开推荐使用Chrome\n\nsc 为SuperChat\ngift为礼物\nguard为上船\n\nattribute \"raw\" 为原始数据\n");
writer.WriteComment("\nB站录播姬 " + GitVersionInformation.FullSemVer + "\n本文件的弹幕信息兼容B站主站视频弹幕XML格式\n本XML自带样式可以在浏览器里打开推荐使用Chrome\n\nsc 为SuperChat\ngift为礼物\nguard为上船\n\nattribute \"raw\" 为原始数据\n");
writer.WriteElementString("chatserver", "chat.bilibili.com");
writer.WriteElementString("chatid", "0");
writer.WriteElementString("mission", "0");
@ -190,7 +190,7 @@ namespace BililiveRecorder.Core.Danmaku
writer.WriteElementString("real_name", "0");
writer.WriteElementString("source", "0");
writer.WriteStartElement("BililiveRecorder");
writer.WriteAttributeString("version", BuildInfo.Version + "-" + BuildInfo.HeadShaShort);
writer.WriteAttributeString("version", GitVersionInformation.FullSemVer);
writer.WriteEndElement();
writer.WriteStartElement("BililiveRecorderRecordInfo");
writer.WriteAttributeString("roomid", room.RoomConfig.RoomId.ToString());

View File

@ -224,7 +224,6 @@ namespace BililiveRecorder.Core.Recording
if (scriptTagBody.Values.Count == 2 && scriptTagBody.Values[1] is ScriptDataEcmaArray value)
{
var now = DateTimeOffset.Now;
const string version = "TODO-dev-1.3.x";
value["Title"] = (ScriptDataString)this.room.Title;
value["Artist"] = (ScriptDataString)$"{this.room.Name} ({this.room.RoomConfig.RoomId})";
value["Comment"] = (ScriptDataString)
@ -233,12 +232,13 @@ namespace BililiveRecorder.Core.Recording
$"直播标题: {this.room.Title}\n" +
$"直播分区: {this.room.AreaNameParent}·{this.room.AreaNameChild}\n" +
$"录制时间: {now:O}\n" +
$"\n使用 B站录播姬 录制 https://rec.danmuji.org\n" +
$"录播姬版本: {version}");
$"\n" +
$"使用 B站录播姬 录制 https://rec.danmuji.org\n" +
$"录播姬版本: {GitVersionInformation.FullSemVer}");
value["BililiveRecorder"] = new ScriptDataEcmaArray
{
["RecordedBy"] = (ScriptDataString)"BililiveRecorder B站录播姬",
["RecorderVersion"] = (ScriptDataString)version, // TODO fix version
["RecorderVersion"] = (ScriptDataString)GitVersionInformation.FullSemVer,
["StartTime"] = (ScriptDataDate)now,
["RoomId"] = (ScriptDataString)this.room.RoomConfig.RoomId.ToString(),
["ShortId"] = (ScriptDataString)this.room.ShortId.ToString(),

View File

@ -325,7 +325,7 @@ namespace BililiveRecorder.Core
this.logger.Verbose("Recording stats: {@stats}", e);
var diff = DateTimeOffset.UtcNow - this.recordTaskStartTime;
this.Stats.SessionDuration = diff.Subtract(TimeSpan.FromMilliseconds(diff.Milliseconds));
this.Stats.SessionDuration = TimeSpan.FromSeconds(Math.Round(diff.TotalSeconds));
this.Stats.FileMaxTimestamp = TimeSpan.FromMilliseconds(e.FileMaxTimestamp);
this.Stats.SessionMaxTimestamp = TimeSpan.FromMilliseconds(e.SessionMaxTimestamp);
this.Stats.DuraionRatio = e.DuraionRatio;

View File

@ -19,7 +19,7 @@ namespace BililiveRecorder.Core.SimpleWebhook
static BasicWebhookV1()
{
client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", $"BililiveRecorder/{typeof(BasicWebhookV1).Assembly.GetName().Version}-{BuildInfo.HeadShaShort}");
client.DefaultRequestHeaders.Add("User-Agent", $"BililiveRecorder/{GitVersionInformation.FullSemVer}");
}
public BasicWebhookV1(ConfigV2 config)

View File

@ -22,7 +22,7 @@ namespace BililiveRecorder.Core.SimpleWebhook
this.config = config ?? throw new ArgumentNullException(nameof(config));
this.client = new HttpClient();
this.client.DefaultRequestHeaders.Add("User-Agent", $"BililiveRecorder/{typeof(BasicWebhookV1).Assembly.GetName().Version}-{BuildInfo.HeadShaShort}");
this.client.DefaultRequestHeaders.Add("User-Agent", $"BililiveRecorder/{GitVersionInformation.FullSemVer}");
}
public Task SendSessionStartedAsync(RecordSessionStartedEventArgs args) =>

View File

@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>portable</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>

View File

@ -20,7 +20,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
public Task RunAsync(FlvProcessingContext context, Func<Task> next)
{
if (!(context.OriginalInput is PipelineHeaderAction header))
if (context.OriginalInput is not PipelineHeaderAction header)
return next();
else
{

View File

@ -21,7 +21,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
public Task RunAsync(FlvProcessingContext context, Func<Task> next)
{
if (!(context.OriginalInput is PipelineDataAction data))
if (context.OriginalInput is not PipelineDataAction data)
return next();
else
{

View File

@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
</configuration>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -12,8 +13,6 @@
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<LangVersion>9.0</LangVersion>
<Nullable>enable</Nullable>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -82,7 +81,6 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="..\TempBuildInfo\BuildInfo.WPF.cs" />
<Compile Include="Controls\AddRoomCard.xaml.cs">
<DependentUpon>AddRoomCard.xaml</DependentUpon>
</Compile>
@ -238,8 +236,6 @@
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="MockData\MockRecordedRoom.cs" />
<Compile Include="MockData\MockRecorder.cs" />
<Compile Include="NewMainWindow.xaml.cs">
<DependentUpon>NewMainWindow.xaml</DependentUpon>
</Compile>
@ -276,11 +272,6 @@
<EmbeddedResource Include="Properties\Strings.zh-Hant.resx" />
<None Include="Properties\app.manifest" />
<Resource Include="ico.ico" />
<Content Include="NLog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="NLog.Release.config" />
<None Include="NLog.Debug.config" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
@ -296,6 +287,10 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.6.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Hardcodet.NotifyIcon.Wpf">
<Version>1.0.8</Version>
</PackageReference>
@ -311,16 +306,11 @@
<PackageReference Include="Newtonsoft.Json">
<Version>12.0.3</Version>
</PackageReference>
<PackageReference Include="NuGet.CommandLine">
<Version>4.7.1</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Sentry">
<Version>3.0.6</Version>
<Version>3.0.7</Version>
</PackageReference>
<PackageReference Include="Sentry.Serilog">
<Version>3.0.6</Version>
<Version>3.0.7</Version>
</PackageReference>
<PackageReference Include="Serilog.Enrichers.Process">
<Version>2.0.1</Version>
@ -359,18 +349,16 @@
<Version>3.8.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>cd $(SolutionDir)
powershell -ExecutionPolicy Bypass -File .\CI\patch_buildinfo.ps1 WPF
copy /y .\BililiveRecorder.WPF\NLog.$(ConfigurationName).config .\BililiveRecorder.WPF\NLog.config</PreBuildEvent>
</PropertyGroup>
<PropertyGroup>
<SquirrelBuildTarget Condition=" '$(SquirrelBuildTarget)' == '' ">.\SquirrelRelease</SquirrelBuildTarget>
</PropertyGroup>
<Target Name="AfterBuild" Condition=" '$(Configuration)' == 'Release'">
<Exec Command="..\packages\NuGet.CommandLine.4.7.1\tools\NuGet.exe pack BililiveRecorder.nuspec -Version $([System.IO.File]::ReadAllText('../VERSION')) -Properties Configuration=Release -OutputDirectory $(OutDir) -BasePath $(OutDir)" />
<Exec Command="..\packages\squirrel.windows.1.9.0\tools\Squirrel.exe --releasify $(OutDir)BililiveRecorder.$([System.IO.File]::ReadAllText('../VERSION')).nupkg -r $(SquirrelBuildTarget) --framework-version net462 --no-msi" />
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="myAssemblyInfo" />
</GetAssemblyIdentity>
<PropertyGroup>
<NupkgReleaseDir>bin\NupkgReleases\</NupkgReleaseDir>
<SquirrelReleaseDir>bin\SquirrelReleases\</SquirrelReleaseDir>
</PropertyGroup>
<Exec Command="nuget pack BililiveRecorder.nuspec -Version %(myAssemblyInfo.Version) -Properties Configuration=Release -OutputDirectory $(NupkgReleaseDir) -BasePath $(OutDir)" />
<Exec Command="$(SquirrelToolsPath)\squirrel --releasify $(NupkgReleaseDir)\BililiveRecorder.$([System.Version]::Parse(%(myAssemblyInfo.Version)).ToString(3)).nupkg --releaseDir=$(SquirrelReleaseDir) --framework-version net472 --no-msi" />
</Target>
</Project>

View File

@ -12,6 +12,6 @@
<language>zh-CN</language>
</metadata>
<files>
<file src="**" target="lib\net45\" exclude="*.nupkg;*.vshost.*;*.log;*.txt"/>
<file src="**" target="lib\net45\" exclude="*.nupkg;*.vshost.*;*.log;*.txt;NuGet.Squirrel.pdb;*\Microsoft.VisualStudio.Threading.resources.dll;*\Microsoft.VisualStudio.Validation.resources.dll"/>
</files>
</package>

View File

@ -13,21 +13,10 @@ namespace BililiveRecorder.WPF.Converters
public object TrueValue { get => this.GetValue(TrueValueProperty); set => this.SetValue(TrueValueProperty, value); }
public object FalseValue { get => this.GetValue(FalseValueProperty); set => this.SetValue(FalseValueProperty, value); }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return this.FalseValue;
}
else
{
return (bool)value ? this.TrueValue : this.FalseValue;
}
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value == null ? this.FalseValue : (bool)value ? this.TrueValue : this.FalseValue;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value != null ? value.Equals(this.TrueValue) : false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
value != null && value.Equals(this.TrueValue);
}
}

View File

@ -1,127 +0,0 @@
using System;
using System.ComponentModel;
using BililiveRecorder.Core;
using BililiveRecorder.Core.Config.V2;
#nullable enable
namespace BililiveRecorder.WPF.MockData
{
#if false && DEBUG
internal class MockRecordedRoom : IRecordedRoom
{
private bool disposedValue;
public MockRecordedRoom()
{
this.RoomId = 123456789;
this.ShortRoomId = 1234;
this.StreamerName = "Mock主播名Mock主播名Mock主播名Mock主播名";
this.IsMonitoring = false;
this.IsRecording = true;
this.IsStreaming = true;
this.DownloadSpeedPersentage = 100d;
this.DownloadSpeedMegaBitps = 2.45d;
}
public int ShortRoomId { get; set; }
public int RoomId { get; set; }
public string StreamerName { get; set; }
public string Title { get; set; } = string.Empty;
public IStreamMonitor StreamMonitor { get; set; } = null!;
public IFlvStreamProcessor? Processor { get; set; }
public bool IsMonitoring { get; set; }
public bool IsRecording { get; set; }
public bool IsDanmakuConnected { get; set; }
public bool IsStreaming { get; set; }
public double DownloadSpeedPersentage { get; set; }
public double DownloadSpeedMegaBitps { get; set; }
public DateTime LastUpdateDateTime { get; set; }
public Guid Guid { get; } = Guid.NewGuid();
public RoomConfig RoomConfig => new RoomConfig();
public event PropertyChangedEventHandler? PropertyChanged;
public event EventHandler<RecordEndData>? RecordEnded;
public void Clip()
{
}
public void RefreshRoomInfo()
{
}
public void Shutdown()
{
}
public bool Start()
{
this.IsMonitoring = true;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.IsMonitoring)));
return true;
}
public void StartRecord()
{
this.IsRecording = true;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.IsRecording)));
}
public void Stop()
{
this.IsMonitoring = false;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.IsMonitoring)));
}
public void StopRecord()
{
this.IsRecording = false;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.IsRecording)));
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects)
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
this.disposedValue = true;
}
}
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
// ~MockRecordedRoom()
// {
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
// Dispose(disposing: false);
// }
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
this.Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
#endif
}

View File

@ -1,164 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using BililiveRecorder.Core;
using BililiveRecorder.Core.Config.V2;
namespace BililiveRecorder.WPF.MockData
{
#if false && DEBUG
internal class MockRecorder : IRecorder
{
private bool disposedValue;
public MockRecorder()
{
this.Rooms.Add(new MockRecordedRoom
{
IsMonitoring = false,
IsRecording = false
});
this.Rooms.Add(new MockRecordedRoom
{
IsMonitoring = true,
IsRecording = false
});
this.Rooms.Add(new MockRecordedRoom
{
DownloadSpeedPersentage = 100,
DownloadSpeedMegaBitps = 12.45
});
this.Rooms.Add(new MockRecordedRoom
{
DownloadSpeedPersentage = 95,
DownloadSpeedMegaBitps = 789.45
});
this.Rooms.Add(new MockRecordedRoom
{
DownloadSpeedPersentage = 90
});
this.Rooms.Add(new MockRecordedRoom
{
DownloadSpeedPersentage = 85
});
this.Rooms.Add(new MockRecordedRoom
{
DownloadSpeedPersentage = 80
});
this.Rooms.Add(new MockRecordedRoom
{
DownloadSpeedPersentage = 75
});
this.Rooms.Add(new MockRecordedRoom
{
DownloadSpeedPersentage = 70
});
this.Rooms.Add(new MockRecordedRoom
{
DownloadSpeedPersentage = 109
});
}
private ObservableCollection<IRecordedRoom> Rooms { get; } = new ObservableCollection<IRecordedRoom>();
public ConfigV2 Config { get; } = new ConfigV2();
public int Count => this.Rooms.Count;
public bool IsReadOnly => true;
int ICollection<IRecordedRoom>.Count => this.Rooms.Count;
bool ICollection<IRecordedRoom>.IsReadOnly => true;
public IRecordedRoom this[int index] => this.Rooms[index];
public event PropertyChangedEventHandler PropertyChanged
{
add => (this.Rooms as INotifyPropertyChanged).PropertyChanged += value;
remove => (this.Rooms as INotifyPropertyChanged).PropertyChanged -= value;
}
public event NotifyCollectionChangedEventHandler CollectionChanged
{
add => (this.Rooms as INotifyCollectionChanged).CollectionChanged += value;
remove => (this.Rooms as INotifyCollectionChanged).CollectionChanged -= value;
}
void ICollection<IRecordedRoom>.Add(IRecordedRoom item) => throw new NotSupportedException("Collection is readonly");
void ICollection<IRecordedRoom>.Clear() => throw new NotSupportedException("Collection is readonly");
bool ICollection<IRecordedRoom>.Remove(IRecordedRoom item) => throw new NotSupportedException("Collection is readonly");
bool ICollection<IRecordedRoom>.Contains(IRecordedRoom item) => this.Rooms.Contains(item);
void ICollection<IRecordedRoom>.CopyTo(IRecordedRoom[] array, int arrayIndex) => this.Rooms.CopyTo(array, arrayIndex);
public IEnumerator<IRecordedRoom> GetEnumerator() => this.Rooms.GetEnumerator();
IEnumerator<IRecordedRoom> IEnumerable<IRecordedRoom>.GetEnumerator() => this.Rooms.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => this.Rooms.GetEnumerator();
public bool Initialize(string workdir)
{
this.Config.Global.WorkDirectory = workdir;
return true;
}
public void AddRoom(int roomid)
{
this.AddRoom(roomid, false);
}
public void AddRoom(int roomid, bool enabled)
{
this.Rooms.Add(new MockRecordedRoom { RoomId = roomid, IsMonitoring = enabled });
}
public void RemoveRoom(IRecordedRoom rr)
{
this.Rooms.Remove(rr);
}
public void SaveConfigToFile()
{
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
// dispose managed state (managed objects)
this.Rooms.Clear();
}
// free unmanaged resources (unmanaged objects) and override finalizer
// set large fields to null
this.disposedValue = true;
}
}
// override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
// ~MockRecorder()
// {
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
// Dispose(disposing: false);
// }
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
this.Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
#endif
}

View File

@ -1,43 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd ../CI/NLog.xsd"
autoReload="true" throwExceptions="false" throwConfigExceptions="true" internalLogLevel="Off">
<extensions>
<add assembly="Sentry.NLog"/>
</extensions>
<targets>
<target name="WPFLogger" xsi:type="MethodCall" className="BililiveRecorder.WPF.Models.LogModel, BililiveRecorder.WPF" methodName="AddLog">
<parameter layout="[${date:format=HH\:mm\:ss}] ${level:upperCase=true} ${event-properties:item=roomid} ${message} ${exception:format=Message}" />
</target>
<target name="file" xsi:type="File" encoding="utf-8" lineEnding="CRLF" fileName="${basedir}/logs/log.current.txt"
maxArchiveFiles="15" archiveFileName="${basedir}/logs/log.{#}.txt" archiveNumbering="Date"
archiveEvery="Day" archiveDateFormat="yyyyMMdd">
<layout xsi:type="JsonLayout">
<attribute name='time' layout='${longdate}'/>
<attribute name='level' layout='${level:upperCase=true}'/>
<attribute name='pid' layout='${processid}'/>
<attribute name='logger' layout='${logger}'/>
<attribute name='roomid' layout='${event-properties:item=roomid}'/>
<attribute name='message' escapeUnicode="false" layout='${message}'/>
<attribute name='exception' escapeUnicode="false" encode='false'>
<layout xsi:type='JsonLayout'>
<attribute name='type' escapeUnicode="false" layout='${exception:format=Type}'/>
<attribute name='message' escapeUnicode="false" layout='${exception:format=Message}'/>
<attribute name='tostring' escapeUnicode="false" layout='${exception:format=ToString}'/>
</layout>
</attribute>
</layout>
</target>
<target xsi:type="Sentry" name="sentry" layout="${message}"
breadcrumbLayout="${event-properties:item=roomid} ${message}"
minimumBreadcrumbLevel="Debug" minimumEventLevel="Error">
<options initializeSdk="false"/>
<tag name="logger" layout="${logger}" />
</target>
</targets>
<rules>
<logger name="*" writeTo="sentry"/>
<logger name="*" minlevel="Trace" writeTo="WPFLogger"/>
<logger name="*" minlevel="Trace" writeTo="file"/>
</rules>
</nlog>

View File

@ -20,7 +20,7 @@ namespace BililiveRecorder.WPF
public NewMainWindow()
{
this.SoftwareVersion = BuildInfo.Version + " " + BuildInfo.HeadShaShort;
this.SoftwareVersion = GitVersionInformation.FullSemVer;
Pages.AnnouncementPage.CultureInfo = CultureInfo.CurrentUICulture;
LocalizeDictionary.Instance.Culture = CultureInfo.CurrentUICulture;

View File

@ -1,43 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd ../CI/NLog.xsd"
autoReload="true" throwExceptions="false" throwConfigExceptions="true" internalLogLevel="Off">
<extensions>
<add assembly="Sentry.NLog"/>
</extensions>
<targets>
<target name="WPFLogger" xsi:type="MethodCall" className="BililiveRecorder.WPF.Models.LogModel, BililiveRecorder.WPF" methodName="AddLog">
<parameter layout="[${date:format=HH\:mm\:ss}] ${level:upperCase=true} ${event-properties:item=roomid} ${message} ${exception:format=Message}" />
</target>
<target name="file" xsi:type="File" encoding="utf-8" lineEnding="CRLF" fileName="${basedir}/logs/log.current.txt"
maxArchiveFiles="15" archiveFileName="${basedir}/logs/log.{#}.txt" archiveNumbering="Date"
archiveEvery="Day" archiveDateFormat="yyyyMMdd">
<layout xsi:type="JsonLayout">
<attribute name='time' layout='${longdate}'/>
<attribute name='level' layout='${level:upperCase=true}'/>
<attribute name='pid' layout='${processid}'/>
<attribute name='logger' layout='${logger}'/>
<attribute name='roomid' layout='${event-properties:item=roomid}'/>
<attribute name='message' escapeUnicode="false" layout='${message}'/>
<attribute name='exception' escapeUnicode="false" encode='false'>
<layout xsi:type='JsonLayout'>
<attribute name='type' escapeUnicode="false" layout='${exception:format=Type}'/>
<attribute name='message' escapeUnicode="false" layout='${exception:format=Message}'/>
<attribute name='tostring' escapeUnicode="false" layout='${exception:format=ToString}'/>
</layout>
</attribute>
</layout>
</target>
<target xsi:type="Sentry" name="sentry" layout="${message}"
breadcrumbLayout="${event-properties:item=roomid} ${message}"
minimumBreadcrumbLevel="Debug" minimumEventLevel="Error">
<options initializeSdk="false"/>
<tag name="logger" layout="${logger}" />
</target>
</targets>
<rules>
<logger name="*" writeTo="sentry"/>
<logger name="*" minlevel="Info" writeTo="WPFLogger"/>
<logger name="*" minlevel="Debug" writeTo="file"/>
</rules>
</nlog>

View File

@ -26,7 +26,7 @@ namespace BililiveRecorder.WPF.Pages
static AnnouncementPage()
{
client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", $"BililiveRecorder/{typeof(AnnouncementPage).Assembly.GetName().Version}-{BuildInfo.HeadShaShort}");
client.DefaultRequestHeaders.Add("User-Agent", $"BililiveRecorder/{GitVersionInformation.FullSemVer}");
}
public AnnouncementPage()

View File

@ -8,7 +8,8 @@ namespace BililiveRecorder.WPF.Pages
public LogPage()
{
this.InitializeComponent();
this.VersionTextBlock.Text = " " + BuildInfo.Version + " " + BuildInfo.HeadShaShort;
this.VersionTextBlock.Text = " " + GitVersionInformation.FullSemVer;
this.VersionTextBlock.ToolTip = GitVersionInformation.InformationalVersion;
}
}
}

View File

@ -1,4 +1,4 @@
using System.Reflection;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
@ -6,7 +6,7 @@ using System.Windows;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("B站录播姬")]
[assembly: AssemblyDescription("B站录播姬")]
[assembly: AssemblyDescription("B站录播姬 by genteure")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Genteure")]
[assembly: AssemblyProduct("B站录播姬")]
@ -37,17 +37,3 @@ using System.Windows;
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: AssemblyFileVersion("0.0.0.0")]

View File

@ -1,10 +0,0 @@
namespace BililiveRecorder.[PROJECT_NAME]
{
internal class BuildInfo
{
internal const bool Appveyor = [APPVEYOR];
internal const string Version = @"[VERSION]";
internal const string HeadSha1 = @"[GIT_HASH]";
internal const string HeadShaShort = @"[GIT_HASH_S]";
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
Write-Host "Current build configuration is $env:CONFIGURATION"
if ($env:APPVEYOR -and (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) -and $env:CONFIGURATION -eq "Release") {
if ($false -and $env:APPVEYOR -and (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) -and $env:CONFIGURATION -eq "Release") {
git config --global credential.helper store
Add-Content "$env:USERPROFILE\.git-credentials" "https://$($env:github_access_token):x-oauth-basic@github.com`n"
git config --global user.email "appveyor@genteure.com"

View File

@ -1,9 +0,0 @@
# called by msbuild
$isAppveyor = if ($env:APPVEYOR -eq $null) { "false" } else { $env:APPVEYOR }
$buildversion = if ($env:APPVEYOR_BUILD_VERSION -eq $null) { "本地编译" } else { $env:APPVEYOR_BUILD_VERSION }
$githash = git rev-parse --verify HEAD
(Get-Content .\BuildInfo.txt).Replace('[PROJECT_NAME]', $args).Replace('[APPVEYOR]', $isAppveyor.ToLower()).Replace('[VERSION]', $buildversion).Replace('[GIT_HASH]', $githash).Replace('[GIT_HASH_S]', $githash.Substring(0, 8)) | Set-Content ".\TempBuildInfo\BuildInfo.$args.cs"
Write-Output "BuildInfo for $args patched"

15
Directory.Build.props Normal file
View File

@ -0,0 +1,15 @@
<Project>
<PropertyGroup>
<Copyright>Copyright © 2018 - 2021 Genteure</Copyright>
<Authors>Genteure</Authors>
<Company>$(Authors)</Company>
<LangVersion>9.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.6.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

5
GitVersion.yml Normal file
View File

@ -0,0 +1,5 @@
mode: ContinuousDelivery
branches: {}
ignore:
sha: []
merge-message-formats: {}

View File

View File

@ -4,13 +4,13 @@ platform: Any CPU
skip_tags: true
assembly_info:
patch: true
patch: false
file: '**\AssemblyInfo.*'
assembly_version: $(APPVEYOR_BUILD_VERSION)
assembly_file_version: $(APPVEYOR_BUILD_VERSION)
assembly_informational_version: $(APPVEYOR_BUILD_VERSION)
dotnet_csproj:
patch: true
patch: false
file: '**\*.csproj'
version: $(APPVEYOR_BUILD_VERSION)
package_version: $(APPVEYOR_BUILD_VERSION)
@ -19,18 +19,14 @@ dotnet_csproj:
informational_version: $(APPVEYOR_BUILD_VERSION)
environment:
github_access_token:
secure: 3n2WMbrqWb0nmy2LBmu7w6dJltiHHC4LCoNuIKBh7fKV0xfxCwVGOxbTpunLI2pe
codesignaes:
secure: 9f78dD9jN5vlVZ0zv15kdD4Mj+/+uacfu29bbGC+cBVFs834aFVf5Ci+n3NP3Bl7
codesignpasswd:
secure: iKv14aGuHUDEfb5fSIBMuSsu1JnisWXL8wJ7x/2DCNtggWKevjhOFBOrI7c95xBY
# github_access_token:
# secure: 3n2WMbrqWb0nmy2LBmu7w6dJltiHHC4LCoNuIKBh7fKV0xfxCwVGOxbTpunLI2pe
cache:
- packages
install:
- ps: ./CI/appveyor_install.ps1
# - ps: ./CI/appveyor_install.ps1
before_build:
- nuget restore -Verbosity quiet
@ -47,21 +43,21 @@ build_script:
- ps: msbuild /nologo /v:m /t:BililiveRecorder_Cli:Publish /p:Configuration="$env:CONFIGURATION" /p:RuntimeIdentifier="win-x64" /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
for:
-
branches:
only:
- master # including pull requests target at master
configuration: Release
before_deploy: # wont run on pull request
- ps: ./CI/appveyor_deploy.ps1
deploy: # wont run on pull request
provider: GitHub
release: v$(APPVEYOR_BUILD_VERSION)
description: '# ◁☆Fill out this before publish☆▷'
auth_token:
secure: 3n2WMbrqWb0nmy2LBmu7w6dJltiHHC4LCoNuIKBh7fKV0xfxCwVGOxbTpunLI2pe
artifact: github
draft: true
#-
# branches:
# only:
# - master # including pull requests target at master
# configuration: Release
# before_deploy: # wont run on pull request
# - ps: ./CI/appveyor_deploy.ps1
# deploy: # wont run on pull request
# provider: GitHub
# release: v$(APPVEYOR_BUILD_VERSION)
# description: '# ◁☆Fill out this before publish☆▷'
# auth_token:
# secure: 3n2WMbrqWb0nmy2LBmu7w6dJltiHHC4LCoNuIKBh7fKV0xfxCwVGOxbTpunLI2pe
# artifact: github
# draft: true
-
configuration: Debug
artifacts:

View File

@ -1,6 +1,6 @@
{
"sdk": {
"version": "3.1.102",
"version": "5.0.100",
"rollForward": "latestFeature"
}
}

View File

@ -12,7 +12,7 @@ namespace BililiveRecorder.Core.UnitTests.Danmaku
{
public class ManualTests
{
[Fact]
[Fact(Skip = "skip")]
public async Task TestAsync()
{
var client = new DanmakuClient(new HttpApiClient(null!), null);