GenerateBuildStamp read BuildCounter.txt, added 1 and wrote it back on every CoreCompile, so the number tracked BUILDS: a day of iteration reached #1122 against 563 commits. It now uses git rev-list count of HEAD, which is what the comment always claimed (and why the file existed in .gitignore). No counter file, no drift; a missing git still falls back to the start. Also moves the MIC and lip-sync volume bars up one line: both were pinned to the floor of their bay by a star row plus VerticalAlignment=Bottom. They now sit directly under their headers, with the auto rows sized to content.
183 lines
11 KiB
XML
183 lines
11 KiB
XML
<Project Sdk="Microsoft.NET.Sdk">
|
||
|
||
<PropertyGroup>
|
||
<OutputType>WinExe</OutputType>
|
||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||
<Nullable>enable</Nullable>
|
||
<ImplicitUsings>enable</ImplicitUsings>
|
||
<UseWPF>true</UseWPF>
|
||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||
<ApplicationIcon>Assets\llamacasty-icon.ico</ApplicationIcon>
|
||
<!-- The shipped exe is LlamaCasty.exe (renamed 2026-11-01, before the first Steam depot so
|
||
the store never sees the legacy name). RootNamespace stays `ytLive` — the C# namespaces
|
||
are not user-visible and renaming them would churn every file for no benefit. -->
|
||
<AssemblyName>LlamaCasty</AssemblyName>
|
||
<RootNamespace>ytLive</RootNamespace>
|
||
<!-- 64-bit Windows only (creator ruling 2026-10-09). The bundled ffmpeg is the win64 build
|
||
and ONNX Runtime ships no win-x86 native, so a 32-bit process could never stream; a
|
||
32-bit address space (2–4 GB) would also choke on 1080p frame buffers. x64 makes the
|
||
exe refuse to start on 32-bit Windows instead of failing at Go Live. -->
|
||
<PlatformTarget>x64</PlatformTarget>
|
||
</PropertyGroup>
|
||
|
||
<ItemGroup>
|
||
<Compile Remove="ytLive.Tests\**" />
|
||
<EmbeddedResource Remove="ytLive.Tests\**" />
|
||
<None Remove="ytLive.Tests\**" />
|
||
<Page Remove="ytLive.Tests\**" />
|
||
</ItemGroup>
|
||
|
||
<!-- Per-build identity stamp (2026-09-04): takes 1–6 could not be attributed to an
|
||
exact binary — render perf "fixes" were being judged against builds we could not
|
||
prove were running. A fresh GUID per build makes an incremental compile impossible
|
||
(that is the point: every exe you launch was compiled NOW), the wordmark shows the
|
||
id, and startup.log records id + build time. -->
|
||
<Target Name="GenerateBuildStamp" BeforeTargets="CoreCompile">
|
||
<PropertyGroup>
|
||
<BuildStampFile>$(IntermediateOutputPath)BuildStamp.g.cs</BuildStampFile>
|
||
<BuildStampId>$([System.Guid]::NewGuid().ToString('N').Substring(0,8))</BuildStampId>
|
||
<BuildStampTime>$([System.DateTime]::Now.ToString('yyyy-MM-dd HH:mm:ss'))</BuildStampTime>
|
||
<!-- RELEASE COUNTER (creator ruling 2026-09-04): the UI shows a sequential number that
|
||
ticks +1 per COMMIT — a per-BUILD GUID changed on every launch and read as noise
|
||
(rightly). It is git rev-list count of HEAD, evaluated below.
|
||
⛔ It used to read BuildCounter.txt, add 1 and write it back on EVERY CoreCompile, so it
|
||
counted BUILDS: one day of iteration reached #1122 against 563 commits (2026-11-01).
|
||
No counter file now: the commit count cannot drift. Missing git falls back to the
|
||
start, so the build never breaks. GUID + compile time stay in startup.log. -->
|
||
<BuildNumberBaseline>17</BuildNumberBaseline>
|
||
<BuildNumberStart>13</BuildNumberStart>
|
||
</PropertyGroup>
|
||
<Exec Command=""C:\Program Files\Git\cmd\git.exe" rev-list --count HEAD"
|
||
WorkingDirectory="$(ProjectDir)" ConsoleToMSBuild="true" IgnoreExitCode="true">
|
||
<Output TaskParameter="ConsoleOutput" PropertyName="CommitCountRaw" />
|
||
</Exec>
|
||
<PropertyGroup>
|
||
<!-- First integer in git's output: the Exec can echo the count twice, and a multi-line value
|
||
would fail the numeric check below and silently pin the stamp. -->
|
||
<CommitCount>$([System.Text.RegularExpressions.Regex]::Match('$(CommitCountRaw)', '[0-9]+').Value)</CommitCount>
|
||
<BuildNumber Condition="'$(CommitCount)' != ''">$(CommitCount)</BuildNumber>
|
||
<BuildNumber Condition="! $([System.Text.RegularExpressions.Regex]::IsMatch('$(BuildNumber)', '^[0-9]+$'))">$(BuildNumberStart)</BuildNumber>
|
||
</PropertyGroup>
|
||
<ItemGroup>
|
||
<BuildStampLines Include="// <auto-generated> Per-build identity (ytLive.csproj GenerateBuildStamp)."/>
|
||
<BuildStampLines Include="// Release/Label = the sequential UI stamp (+1 per commit, started at 13)."/>
|
||
<BuildStampLines Include="// Id/BuiltLocal = per-build forensic identity, logged to startup.log only. Never edit by hand."/>
|
||
<BuildStampLines Include="namespace ytLive.Helpers%3B"/>
|
||
<BuildStampLines Include="public static class BuildStamp { public const int Release = $(BuildNumber)%3B public const string Label = "#$(BuildNumber)"%3B public const string Id = "$(BuildStampId)"%3B public const string BuiltLocal = "$(BuildStampTime)"%3B }"/>
|
||
</ItemGroup>
|
||
<WriteLinesToFile File="$(BuildStampFile)" Lines="@(BuildStampLines)" Overwrite="true" WriteOnlyWhenDifferent="false" />
|
||
<ItemGroup>
|
||
<Compile Include="$(BuildStampFile)" />
|
||
</ItemGroup>
|
||
</Target>
|
||
|
||
<ItemGroup>
|
||
<Resource Include="Assets\llamacasty-icon.png" />
|
||
<Resource Include="Assets\llamacasty-logo.jpg" />
|
||
<Resource Include="Assets\starting-background.jpg" />
|
||
<Resource Include="Assets\brb-background.jpg" />
|
||
<Resource Include="Assets\live-background.jpg" />
|
||
<Resource Include="Assets\ending-background.jpg" />
|
||
<Resource Include="Assets\chat-background.jpg" />
|
||
<Resource Include="Assets\alert-default.mp4" />
|
||
<!-- Design-standard typefaces (DESIGN.md): Inter + JetBrains Mono, OFL-1.1. -->
|
||
<Resource Include="Assets\Fonts\Inter-Regular.ttf" />
|
||
<Resource Include="Assets\Fonts\Inter-Medium.ttf" />
|
||
<Resource Include="Assets\Fonts\Inter-SemiBold.ttf" />
|
||
<Resource Include="Assets\Fonts\Inter-Bold.ttf" />
|
||
<Resource Include="Assets\Fonts\JetBrainsMono-Medium.ttf" />
|
||
<Resource Include="Assets\Fonts\JetBrainsMono-SemiBold.ttf" />
|
||
</ItemGroup>
|
||
|
||
<ItemGroup Condition="'$(Configuration)' != 'Debug'">
|
||
<!-- ⛔ Development-only UI never ships: no BAML, no code-behind, nothing to reveal.
|
||
OverlayHost adds the panel at runtime inside #if DEBUG, so a Release build has no
|
||
reference to it and compiles cleanly. -->
|
||
<Page Remove="Controls\DeveloperPanel.xaml" />
|
||
<Compile Remove="Controls\DeveloperPanel.xaml.cs" />
|
||
</ItemGroup>
|
||
|
||
<!-- Steamworks runtime (scripts/steam-sdk.sh extracts it; steam/ is gitignored).
|
||
⛔ Link puts it BESIDE the exe rather than under steam/, because the loader looks there.
|
||
⛔ ExcludeFromSingleFile matters for the same reason as ffmpeg: a native DLL otherwise
|
||
gets swallowed into the single-file bundle and the app cannot load it at runtime. -->
|
||
<ItemGroup>
|
||
<None Remove="steam\**" />
|
||
<None Include="steam\steam_api64.dll" Link="steam_api64.dll"
|
||
CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="Always"
|
||
ExcludeFromSingleFile="true" />
|
||
<!-- Local-only: lets SteamAPI.Init() resolve an app id outside the Steam client (480 =
|
||
Valve's Spacewar test app). Never published — Valve's guidance is to omit it. -->
|
||
<None Include="steam\steam_appid.txt" Link="steam_appid.txt" Condition="'$(Configuration)' == 'Debug'"
|
||
CopyToOutputDirectory="PreserveNewest" />
|
||
</ItemGroup>
|
||
|
||
<ItemGroup>
|
||
<None Include="THIRD-PARTY-NOTICES.txt" CopyToOutputDirectory="PreserveNewest" />
|
||
<!-- The EULA and privacy policy travel with every copy: they are what the About screen and
|
||
any store listing are checked against. -->
|
||
<None Include="LICENSE" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="Always" />
|
||
<None Include="PRIVACY.md" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="Always" />
|
||
</ItemGroup>
|
||
|
||
<!-- Webcam background effects (TASK 51): Google's MediaPipe Selfie Segmenter (landscape,
|
||
Apache-2.0), converted to ONNX by tools/selfie-seg/ and embedded in the assembly —
|
||
~430 KB, so it lives in git, ships inside the exe, and is never downloaded at runtime
|
||
(Store policy 10.2.2, same posture as the bundled ffmpeg). -->
|
||
<ItemGroup>
|
||
<EmbeddedResource Include="Assets\Models\selfie_segmenter_landscape.onnx" LogicalName="ytLive.Assets.Models.selfie_segmenter_landscape.onnx" />
|
||
</ItemGroup>
|
||
|
||
<!-- Bundled FFmpeg (TASK 48 item 1, Store policy 10.2.2 dynamic code inclusion).
|
||
The app used to DOWNLOAD an unsigned ffmpeg from GitHub at first run and execute
|
||
it; that 404'd on the creator's first real recording (2026-09-01) and is the one
|
||
hard certification gate. ffmpeg.exe + ffprobe.exe + the libav*.dll family now ship
|
||
in the output under a single ffmpeg/ folder — the shared build resolves its DLLs
|
||
from the exe's own directory, so they must stay siblings.
|
||
|
||
The binaries are NOT in git (135 MB). scripts/fetch-ffmpeg.sh populates ./ffmpeg
|
||
from a pinned URL, verifying SHA-256 first. CopyToPublishDirectory=Always is the
|
||
one that matters for the MSIX package. -->
|
||
<ItemGroup>
|
||
<!-- `Remove` first: the SDK's default None glob already matched ffmpeg\**, so an Include
|
||
without removing it produced DUPLICATE items — one carrying the copy metadata and one
|
||
with none. Harmless until PublishSingleFile + IncludeNativeLibrariesForSelfExtract came
|
||
along, where the bundler collapses the duplicate and the folder silently stops being
|
||
published (found 2026-11-01: a 9-file publish with no ffmpeg in it). -->
|
||
<!-- ⛔ ExcludeFromSingleFile is load-bearing. With PublishSingleFile +
|
||
IncludeNativeLibrariesForSelfExtract the bundler treats the libav*.dll family as native
|
||
libs and swallows them INTO the exe — a 182 MB exe with no ffmpeg\ folder beside it, so
|
||
the locator finds nothing and every stream fails at runtime. The metadata keeps the
|
||
folder a folder. (Found 2026-11-01 by diffing the publish output against a control
|
||
publish without the single-file flags.) -->
|
||
<None Remove="ffmpeg\**" />
|
||
<None Include="ffmpeg\**" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="Always" ExcludeFromSingleFile="true" />
|
||
</ItemGroup>
|
||
|
||
<Target Name="GuardBundledFfmpeg" BeforeTargets="CoreCompile">
|
||
<Error Condition="!Exists('$(MSBuildProjectDirectory)\ffmpeg\ffmpeg.exe')"
|
||
Text="Bundled FFmpeg is missing from ffmpeg\. Run scripts/fetch-ffmpeg.sh once before building (it pins the URL and verifies SHA-256). FFmpeg must be bundled, never downloaded at runtime — that is Windows Store policy 10.2.2, and the previous download path 404'd on 2026-09-01." />
|
||
</Target>
|
||
|
||
<ItemGroup>
|
||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||
<_Parameter1>ytLive.Tests</_Parameter1>
|
||
</AssemblyAttribute>
|
||
</ItemGroup>
|
||
|
||
<ItemGroup>
|
||
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.10" />
|
||
<PackageReference Include="Microsoft.ML.OnnxRuntime" Version="1.31.0" />
|
||
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
|
||
<PackageReference Include="NAudio.WinMM" Version="2.2.1" />
|
||
<PackageReference Include="Notification.Wpf" Version="11.0.0" />
|
||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.12" />
|
||
<!-- Steam's managed wrapper. The native steam_api64.dll comes from the SDK via
|
||
scripts/steam-sdk.sh; this package only provides the C# surface (SteamAPI, SteamApps). -->
|
||
<PackageReference Include="Steamworks.NET" Version="2024.8.0" />
|
||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="8.0.0" />
|
||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2903.40" />
|
||
</ItemGroup>
|
||
|
||
</Project>
|