From 96f9b207b6a9106d269dc724a2c95b7018f52d4c Mon Sep 17 00:00:00 2001 From: UncraftedName Date: Tue, 19 Sep 2023 16:36:00 -0700 Subject: [PATCH] Downgrade to net4.8 --- .github/workflows/CI.yml | 4 +- ConsoleApp/ConsoleApp.csproj | 80 ++++---- .../publish-single-file.pubxml | 18 -- .../DemoArgProcessing/DemoParserSubCommand.cs | 4 + ConsoleApp/src/PathExt.cs | 177 ++++++++++++++++++ DemoParser/DemoParser.csproj | 30 +-- .../Components/Messages/SvcPacketEntities.cs | 2 +- DemoParser/src/Utils/System/Index.cs | 18 ++ DemoParser/src/Utils/System/Range.cs | 14 ++ README.md | 2 +- Tests/Tests.csproj | 4 +- UncraftedDemoParser.sln | 34 ++-- publish-linux.sh | 1 - 13 files changed, 287 insertions(+), 101 deletions(-) delete mode 100644 ConsoleApp/Properties/PublishProfiles/publish-single-file.pubxml create mode 100644 ConsoleApp/src/PathExt.cs create mode 100644 DemoParser/src/Utils/System/Index.cs create mode 100644 DemoParser/src/Utils/System/Range.cs delete mode 100644 publish-linux.sh diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c2dc9ae..ad6896f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -14,8 +14,8 @@ jobs: fail-fast: false matrix: platform: - - {os: windows-latest, framework: net7.0-windows, runtime: win-x64} - - {os: ubuntu-latest, framework: net7.0, runtime: linux-x64} + - {os: windows-latest, framework: net481, runtime: win-x64} + # - {os: ubuntu-latest, framework: net7.0, runtime: linux-x64} build_type: - { name: 'Build', diff --git a/ConsoleApp/ConsoleApp.csproj b/ConsoleApp/ConsoleApp.csproj index 66205fb..a037abc 100644 --- a/ConsoleApp/ConsoleApp.csproj +++ b/ConsoleApp/ConsoleApp.csproj @@ -2,74 +2,72 @@ Exe + net481 ../github-resources/investigation.ico - AnyCPU;x64 + AnyCPU Debug;Release;Debug_ProcessEnts 10 true UntitledParser enable - 9999 - net7.0;net7.0-windows - - TRACE;DEBUG - - - - full + + UntitledParser.Unmerged - - embedded - - - - embedded + + TRACE;DEBUG - - full + + full - - full - + + + - + - - <_Parameter1>$([System.DateTime]::UtcNow.ToString("yyyyMMddHHmmss")) - + + <_Parameter1>$([System.DateTime]::UtcNow.ToString("yyyyMMddHHmmss")) + - - True - True - Resources.resx - + + True + True + Resources.resx + - - ResXFileCodeGenerator - Resources.Designer.cs - - - - Always - + + ResXFileCodeGenerator + Resources.Designer.cs + + + + Always + + + + $(MSBuildThisFileDirectory)bin\$(Configuration)\$(TargetFramework) + + + + - - - - + + + + diff --git a/ConsoleApp/Properties/PublishProfiles/publish-single-file.pubxml b/ConsoleApp/Properties/PublishProfiles/publish-single-file.pubxml deleted file mode 100644 index 85cd6da..0000000 --- a/ConsoleApp/Properties/PublishProfiles/publish-single-file.pubxml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Release - Any CPU - bin\Release\net7.0-windows\win-x64\publish\ - FileSystem - <_TargetId>Folder - net7.0-windows - win-x64 - false - true - false - - \ No newline at end of file diff --git a/ConsoleApp/src/DemoArgProcessing/DemoParserSubCommand.cs b/ConsoleApp/src/DemoArgProcessing/DemoParserSubCommand.cs index 49b88fa..bf22bbe 100644 --- a/ConsoleApp/src/DemoArgProcessing/DemoParserSubCommand.cs +++ b/ConsoleApp/src/DemoArgProcessing/DemoParserSubCommand.cs @@ -123,7 +123,11 @@ private void FlattenDirectories(DemoParsingSetupInfo setupInfo) { demoPath, commonParent == "" ? demoPath.FullName +#if NET5_0_OR_GREATER : Path.GetRelativePath(commonParent, demoPath.FullName) +#else + : PathExt.GetRelativePath(commonParent, demoPath.FullName) +#endif )); } diff --git a/ConsoleApp/src/PathExt.cs b/ConsoleApp/src/PathExt.cs new file mode 100644 index 0000000..7376be3 --- /dev/null +++ b/ConsoleApp/src/PathExt.cs @@ -0,0 +1,177 @@ +/* + * More-or-less ripped straight from .NET Core runtime, with some ws/comments stripped out + * + * Licensed to the .NET Foundation under one or more agreements. + * The .NET Foundation licenses this file to you under the MIT license. + */ + +// FIXME: This is very Windows-specific! This will probably be one of the things +// that needs fixed up if/when doing a Linux/Mono port. + +using System; +using System.IO; +using System.Text; + +namespace ConsoleApp { + + internal static class PathExt { + + private static bool IsDirectorySeparator(char c) => c == '\\' || c == '/'; + private static bool EndsInDirectorySeparator(string path) + => path.Length > 0 && IsDirectorySeparator(path[^1]); + + private static unsafe int EqualStartingCharacterCount(string? first, string? second, bool ignoreCase) { + if (string.IsNullOrEmpty(first) || string.IsNullOrEmpty(second)) return 0; + + int commonChars = 0; + fixed (char* f = first) + fixed (char* s = second) { + char* l = f; + char* r = s; + char* leftEnd = l + first!.Length; + char* rightEnd = r + second!.Length; + + while (l != leftEnd && r != rightEnd + && (*l == *r || (ignoreCase && char.ToUpperInvariant(*l) == char.ToUpperInvariant(*r)))) { + commonChars++; + l++; + r++; + } + } + + return commonChars; + } + + private static int GetCommonPathLength(string first, string second, bool ignoreCase) { + int commonChars = EqualStartingCharacterCount(first, second, ignoreCase); + if (commonChars == 0) return commonChars; + if (commonChars == first.Length && (commonChars == second.Length || + IsDirectorySeparator(second[commonChars]))) + return commonChars; + if (commonChars == second.Length && IsDirectorySeparator(first[commonChars])) + return commonChars; + while (commonChars > 0 && !IsDirectorySeparator(first[commonChars - 1])) + commonChars--; + return commonChars; + } + + private static bool AreRootsEqual(string first, string second, StringComparison comparisonType) { + int firstRootLength = GetRootLength(first); + int secondRootLength = GetRootLength(second); + + return firstRootLength == secondRootLength + && string.Compare( + strA: first, + indexA: 0, + strB: second, + indexB: 0, + length: firstRootLength, + comparisonType: comparisonType) == 0; + } + + private const int + DevicePrefixLength = 4, + UncPrefixLength = 2, + UncExtendedPrefixLength = 8; + + private static bool IsExtended(string path) { + return path.Length >= DevicePrefixLength + && path[0] == '\\' + && (path[1] == '\\' || path[1] == '?') + && path[2] == '?' + && path[3] == '\\'; + } + + private static bool IsDevice(string path) { + return IsExtended(path) + || + ( + path.Length >= DevicePrefixLength + && IsDirectorySeparator(path[0]) + && IsDirectorySeparator(path[1]) + && (path[2] == '.' || path[2] == '?') + && IsDirectorySeparator(path[3]) + ); + } + + private static bool IsDeviceUNC(string path) { + return path.Length >= UncExtendedPrefixLength + && IsDevice(path) + && IsDirectorySeparator(path[7]) + && path[4] == 'U' + && path[5] == 'N' + && path[6] == 'C'; + } + + private static bool IsValidDriveChar(char value) { + return (value >= 'A' && value <= 'Z') || (value >= 'a' && value <= 'z'); + } + + private static int GetRootLength(string path) { + int pathLength = path.Length; + int i = 0; + + bool deviceSyntax = IsDevice(path); + bool deviceUnc = deviceSyntax && IsDeviceUNC(path); + if ((!deviceSyntax || deviceUnc) && pathLength > 0 && IsDirectorySeparator(path[0])) { + if (deviceUnc || (pathLength > 1 && IsDirectorySeparator(path[1]))) { + i = deviceUnc ? UncExtendedPrefixLength : UncPrefixLength; + int n = 2; + while (i < pathLength && (!IsDirectorySeparator(path[i]) || --n > 0)) i++; + } else { + i = 1; + } + } else if (deviceSyntax) { + i = DevicePrefixLength; + while (i < pathLength && !IsDirectorySeparator(path[i])) i++; + if (i < pathLength && i > DevicePrefixLength && IsDirectorySeparator(path[i])) i++; + } + else if (pathLength >= 2 + && path[1] == ':' + && IsValidDriveChar(path[0])) { + i = 2; + if (pathLength > 2 && IsDirectorySeparator(path[2])) i++; + } + return i; + } + + public static string GetRelativePath(string relativeTo, string path, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) { + if (relativeTo == null) throw new ArgumentNullException(nameof(relativeTo)); + if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Empty path", nameof(relativeTo)); + if (path == null) throw new ArgumentNullException(nameof(path)); + if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Empty path", nameof(path)); + relativeTo = Path.GetFullPath(relativeTo); + path = Path.GetFullPath(path); + if (!AreRootsEqual(relativeTo, path, comparisonType)) return path; + int commonLength = GetCommonPathLength(relativeTo, path, ignoreCase: comparisonType == StringComparison.OrdinalIgnoreCase); + if (commonLength == 0) return path; + int relativeToLength = relativeTo.Length; + if (EndsInDirectorySeparator(relativeTo)) relativeToLength--; + bool pathEndsInSeparator = EndsInDirectorySeparator(path); + int pathLength = path.Length; + if (pathEndsInSeparator) pathLength--; + if (relativeToLength == pathLength && commonLength >= relativeToLength) return "."; + var sb = new StringBuilder(); + sb.EnsureCapacity(Math.Max(relativeTo.Length, path.Length)); + if (commonLength < relativeToLength) { + sb.Append(".."); + for (int i = commonLength + 1; i < relativeToLength; i++) { + if (IsDirectorySeparator(relativeTo[i])) { + sb.Append("\\.."); + } + } + } + else if (IsDirectorySeparator(path[commonLength])) { + commonLength++; + } + int differenceLength = pathLength - commonLength; + if (pathEndsInSeparator) differenceLength++; + if (differenceLength > 0) { + if (sb.Length > 0) sb.Append(Path.DirectorySeparatorChar); + sb.Append(path.AsSpan(commonLength, differenceLength).ToString()); + } + + return sb.ToString(); + } + } +} diff --git a/DemoParser/DemoParser.csproj b/DemoParser/DemoParser.csproj index 78ec453..9751ca1 100644 --- a/DemoParser/DemoParser.csproj +++ b/DemoParser/DemoParser.csproj @@ -1,7 +1,7 @@  - net7.0;net7.0-windows + net481 true UntitledDemoParser UncraftedName @@ -9,39 +9,39 @@ SourceEngine demo Valve Portal A parser for Source Engine demos. https://raw.githubusercontent.com/UncraftedName/UncraftedDemoParser/master/github-resources/investigation.ico - AnyCPU;x64 + AnyCPU Debug;Release;Debug_ProcessEnts 10 enable - TRACE - 1701;1702;8618;8602 + TRACE + 1701;1702;8618;8602 - TRACE;FORCE_PROCESS_ENTS;DEBUG - 1701;1702;8618;8602 + TRACE;FORCE_PROCESS_ENTS;DEBUG + 1701;1702;8618;8602 - 1701;1702;8618;8602 + 1701;1702;8618;8602 - - false + + false - false + false - - - - - + + + + + diff --git a/DemoParser/src/Parser/Components/Messages/SvcPacketEntities.cs b/DemoParser/src/Parser/Components/Messages/SvcPacketEntities.cs index e1e6c28..025a672 100644 --- a/DemoParser/src/Parser/Components/Messages/SvcPacketEntities.cs +++ b/DemoParser/src/Parser/Components/Messages/SvcPacketEntities.cs @@ -47,7 +47,7 @@ protected override void Parse(ref BitStreamReader bsr) { #endif // now, we do some setup for ent parsing ref EntitySnapshot? snapshot = ref GameState.EntitySnapshot; - snapshot ??= new EntitySnapshot(DemoRef); + snapshot ??= new EntitySnapshot(DemoRef!); if (IsDelta && snapshot.EngineTick < DeltaFrom) { // If the messages ever arrive in a different order I should queue them, diff --git a/DemoParser/src/Utils/System/Index.cs b/DemoParser/src/Utils/System/Index.cs new file mode 100644 index 0000000..2fe0c6b --- /dev/null +++ b/DemoParser/src/Utils/System/Index.cs @@ -0,0 +1,18 @@ +#if !NET5_0_OR_GREATER +namespace System { + /* Polyfill for System.Index from .NET Core, to allow C# 8.0 [^n] notation */ + public readonly struct Index { + private readonly int _val; + public Index(int val, bool fromend = false) { + _val = val; + if (fromend) _val = ~_val; + } + public int GetOffset(int len) { + if (_val < 0) return len + _val; + return _val; + } + + public static implicit operator Index(int i) => new Index(i); + } +} +#endif diff --git a/DemoParser/src/Utils/System/Range.cs b/DemoParser/src/Utils/System/Range.cs new file mode 100644 index 0000000..2c0bb75 --- /dev/null +++ b/DemoParser/src/Utils/System/Range.cs @@ -0,0 +1,14 @@ +#if !NET5_0_OR_GREATER +namespace System { + /* Polyfill for System.Index from .NET Core, to allow C# 8.0 [start..end] notation */ + public readonly struct Range { + public Index Start { get; } + public Index End { get; } + public Range(Index start, Index end) { Start = start; End = end; } + + public static Range StartAt(Index start) => new Range(start, new Index(-1)); + public static Range EndAt(Index end) => new Range(new Index(0), end); + public static Range All => new Range(new Index(0), new Index(-1)); + } +} +#endif diff --git a/README.md b/README.md index 66a7430..1dcf192 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Note that many of these more advanced features are only supported for some games ## Building and Coding -This project uses .NET 7.0. To build the project, just build the solution with Visual Studio or MSBuild. If you build a release build, all the assemblies get merged into one .exe which is easy to just send people or whatever (thanks mike). There is a pre-build step which runs some git commands to save the info used for the `--version` option, so as long as the repo has been cloned and you have a recent version of git that should work alright. +This project uses .NET 4.6.1. To build the project, just build the solution with Visual Studio or MSBuild. If you build a release build, all the assemblies get merged into one .exe which is easy to just send people or whatever (thanks mike). There is a pre-build step which runs some git commands to save the info used for the `--version` option, so as long as the repo has been cloned and you have a recent version of git that should work alright. There isn't an API or even any extensive documentation, and demos can be pretty darn complicated sometimes. If you want to get some information from them your best bet is to start digging through the code, or feel free to get in touch with me. The `--demo-dump` option will create a text file which contains a human readable representation of everything I know how to parse in the given demo, this is a good way to start digging for stuff. diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 7806084..6f96fcc 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -1,9 +1,9 @@  - net7.0;net7.0-windows + net481 false - AnyCPU;x64 + AnyCPU Debug;Release;Debug_ProcessEnts 10 diff --git a/UncraftedDemoParser.sln b/UncraftedDemoParser.sln index c9893f4..a7afc1d 100644 --- a/UncraftedDemoParser.sln +++ b/UncraftedDemoParser.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29806.167 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33829.357 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DemoParser", "DemoParser\DemoParser.csproj", "{C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}" EndProject @@ -21,40 +21,34 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Debug_ProcessEnts|Any CPU.ActiveCfg = Debug_ProcessEnts|Any CPU {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Debug_ProcessEnts|Any CPU.Build.0 = Debug_ProcessEnts|Any CPU - {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Debug_ProcessEnts|x64.ActiveCfg = Debug_ProcessEnts|x64 - {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Debug_ProcessEnts|x64.Build.0 = Debug_ProcessEnts|x64 + {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Debug_ProcessEnts|x64.ActiveCfg = Debug_ProcessEnts|Any CPU {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Debug|x64.ActiveCfg = Debug|x64 - {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Debug|x64.Build.0 = Debug|x64 + {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Debug|x64.ActiveCfg = Debug|Any CPU {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Release|Any CPU.ActiveCfg = Release|Any CPU {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Release|Any CPU.Build.0 = Release|Any CPU - {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Release|x64.ActiveCfg = Release|x64 - {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Release|x64.Build.0 = Release|x64 + {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Release|x64.ActiveCfg = Release|Any CPU + {C61D7FFB-7CD2-43CC-89DA-B9D8B3803385}.Release|x64.Build.0 = Release|Any CPU {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Debug_ProcessEnts|Any CPU.ActiveCfg = Debug_ProcessEnts|Any CPU {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Debug_ProcessEnts|Any CPU.Build.0 = Debug_ProcessEnts|Any CPU - {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Debug_ProcessEnts|x64.ActiveCfg = Debug_ProcessEnts|x64 - {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Debug_ProcessEnts|x64.Build.0 = Debug_ProcessEnts|x64 + {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Debug_ProcessEnts|x64.ActiveCfg = Debug_ProcessEnts|Any CPU {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Debug|x64.ActiveCfg = Debug|x64 - {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Debug|x64.Build.0 = Debug|x64 + {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Debug|x64.ActiveCfg = Debug|Any CPU {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Release|Any CPU.ActiveCfg = Release|Any CPU {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Release|Any CPU.Build.0 = Release|Any CPU - {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Release|x64.ActiveCfg = Release|x64 - {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Release|x64.Build.0 = Release|x64 + {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Release|x64.ActiveCfg = Release|Any CPU + {4B0F5468-9981-4E07-B2CD-DD62BFAF7D1F}.Release|x64.Build.0 = Release|Any CPU {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Debug_ProcessEnts|Any CPU.ActiveCfg = Debug_ProcessEnts|Any CPU {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Debug_ProcessEnts|Any CPU.Build.0 = Debug_ProcessEnts|Any CPU - {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Debug_ProcessEnts|x64.ActiveCfg = Debug_ProcessEnts|x64 - {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Debug_ProcessEnts|x64.Build.0 = Debug_ProcessEnts|x64 + {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Debug_ProcessEnts|x64.ActiveCfg = Debug_ProcessEnts|Any CPU {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Debug|x64.ActiveCfg = Debug|x64 - {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Debug|x64.Build.0 = Debug|x64 + {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Debug|x64.ActiveCfg = Debug|Any CPU {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Release|Any CPU.ActiveCfg = Release|Any CPU {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Release|Any CPU.Build.0 = Release|Any CPU - {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Release|x64.ActiveCfg = Release|x64 - {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Release|x64.Build.0 = Release|x64 + {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Release|x64.ActiveCfg = Release|Any CPU + {B6C5A577-C873-4E64-BC10-DE55BB3236A2}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/publish-linux.sh b/publish-linux.sh deleted file mode 100644 index 5b6be3f..0000000 --- a/publish-linux.sh +++ /dev/null @@ -1 +0,0 @@ -dotnet publish ConsoleApp --runtime=linux-x64 --framework=net7.0 -p:PublishSingleFile=true --self-contained=true --configuration=Release \ No newline at end of file