[
  {
    "path": ".appveyor.yml",
    "content": "version: 7.0.{build}\n\nbranches:\n  only:\n    - master\n\nskip_tags: true\nskip_commits:\n  files:\n    - .github/*\n    - README.md\n\nmax_jobs: 1\n\nimage: Visual Studio 2019\n\nclone_folder: c:\\projects\\SAM\n\ncache:\n  - packages -> **\\packages.config\n  - '%LocalAppData%\\NuGet\\Cache'\n  - '%LocalAppData%\\NuGet\\v3-cache'\n\ninstall:\n  - git submodule update --init --recursive\n\nconfiguration:\n  - Release\n\ndotnet_csproj:\n  patch: true\n  file: '**\\*.csproj'\n  version: '{version}'\n  assembly_version: '{version}'\n  file_version: '{version}'\n  informational_version: '{version}'\n\nbuild:\n  project: SAM.sln\n  parallel: true\n  verbosity: minimal\n\nbefore_build:\n  - nuget restore\n  \nafter_build:\n  - set TZ=GMT\n  - git log . > git-log.txt\n  - 7z a -r -tzip -mx=9 -x!*/LICENSE.txt SteamAchievementManager-%APPVEYOR_BUILD_VERSION%.zip ./LICENSE.txt ./git-log.txt ./upload/*.exe ./upload/*.dll\n\nartifacts:\n  - path: '*-*.zip'\n"
  },
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore\n\n# User-specific files\n*.rsuser\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n**/Properties/launchSettings.json\nprivate/\nupload/\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Mono auto generated files\nmono_crash.*\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\n[Ww][Ii][Nn]32/\n[Aa][Rr][Mm]/\n[Aa][Rr][Mm]64/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n[Ll]ogs/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# Visual Studio 2017 auto generated files\nGenerated\\ Files/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUnit\n*.VisualState.xml\nTestResult.xml\nnunit-*.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# Benchmark Results\nBenchmarkDotNet.Artifacts/\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n# ASP.NET Scaffolding\nScaffoldingReadMe.txt\n\n# StyleCop\nStyleCopReport.xml\n\n# Files built by Visual Studio\n*_i.c\n*_p.c\n*_h.h\n*.ilk\n*.meta\n*.obj\n*.iobj\n*.pch\n*.pdb\n*.ipdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*_wpftmp.csproj\n*.log\n*.tlog\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# Visual Studio Trace Files\n*.e2e\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# AxoCover is a Code Coverage Tool\n.axoCover/*\n!.axoCover/settings.json\n\n# Coverlet is a free, cross platform Code Coverage Tool\ncoverage*.json\ncoverage*.xml\ncoverage*.info\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# Note: Comment the next line if you want to checkin your web deploy settings,\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# NuGet Symbol Packages\n*.snupkg\n# The packages folder can be ignored because of Package Restore\n**/[Pp]ackages/*\n# except build/, which is used as an MSBuild target.\n!**/[Pp]ackages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/[Pp]ackages/repositories.config\n# NuGet v3's project.json files produces more ignorable files\n*.nuget.props\n*.nuget.targets\n\n# Nuget personal access tokens and Credentials\nnuget.config\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n*.appx\n*.appxbundle\n*.appxupload\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!?*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# Including strong name files can present a security risk\n# (https://github.com/github/gitignore/pull/2483#issue-259490424)\n#*.snk\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\nServiceFabricBackup/\n*.rptproj.bak\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n*.rptproj.rsuser\n*- [Bb]ackup.rdl\n*- [Bb]ackup ([0-9]).rdl\n*- [Bb]ackup ([0-9][0-9]).rdl\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\nnode_modules/\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# CodeRush personal settings\n.cr/personal\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# Tabs Studio\n*.tss\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n\n# OpenCover UI analysis results\nOpenCover/\n\n# Azure Stream Analytics local run output\nASALocalRun/\n\n# MSBuild Binary and Structured Log\n*.binlog\n\n# NVidia Nsight GPU debugger configuration file\n*.nvuser\n\n# MFractors (Xamarin productivity tool) working folder\n.mfractor/\n\n# Local History for Visual Studio\n.localhistory/\n\n# BeatPulse healthcheck temp database\nhealthchecksdb\n\n# Backup folder for Package Reference Convert tool in Visual Studio 2017\nMigrationBackup/\n\n# Ionide (cross platform F# VS Code tools) working folder\n.ionide/\n\n# Fody - auto-generated XML schema\nFodyWeavers.xsd\n\n# VS Code files for those working on multiple tools\n.vscode/*\n!.vscode/settings.json\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n*.code-workspace\n\n# Local History for Visual Studio Code\n.history/\n\n# Windows Installer files from build outputs\n*.cab\n*.msi\n*.msix\n*.msm\n*.msp\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "zlib License\n\nCopyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgment in the product documentation would\n   be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and must not\n   be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source\n   distribution."
  },
  {
    "path": "README.md",
    "content": "# Steam Achievement Manager\n\nSteam Achievement Manager (SAM) is a lightweight, portable application used to manage achievements and statistics in the popular PC gaming platform Steam. This application requires the [Steam client](https://store.steampowered.com/about/), a Steam account and network access. Steam must be running and the user must be logged in.\n\nThis is the code for SAM. The closed-source version originally released in 2008, last major release in 2011, and last updated in 2013 (a hotfix).\n\nThe code is being made available so that those interested can do as they like with it.\n\nThere are some changes to the code since the last closed-source release:\n- General code maintenance to bring it into a more modern state.\n- Icons have been replaced with ones from the Fugue Icons set.\n- Version has been bumped to 7.0.x.x to indicate the open-source release.\n\n[Download latest release](https://github.com/gibbed/SteamAchievementManager/releases/latest).\n\n[![Build status](https://ci.appveyor.com/api/projects/status/00vic6jliar6j0ol/branch/master?svg=true)](https://ci.appveyor.com/project/gibbed/steamachievementmanager/branch/master)\n\n## Attribution\n\nMost (if not all) icons are from the [Fugue Icons](https://p.yusukekamiyamane.com/) set.\n"
  },
  {
    "path": "SAM.API/CallHandle.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.API\n{\n    public enum CallHandle : ulong\n    {\n        Invalid = 0,\n    }\n}\n"
  },
  {
    "path": "SAM.API/Callback.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API\n{\n    public abstract class Callback : ICallback\n    {\n        public delegate void CallbackFunction(IntPtr param);\n\n        public event CallbackFunction OnRun;\n\n        public abstract int Id { get; }\n        public abstract bool IsServer { get; }\n\n        public void Run(IntPtr param)\n        {\n            this.OnRun(param);\n        }\n    }\n\n    public abstract class Callback<TParameter> : ICallback\n        where TParameter : struct\n    {\n        public delegate void CallbackFunction(TParameter arg);\n\n        public event CallbackFunction OnRun;\n\n        public abstract int Id { get; }\n        public abstract bool IsServer { get; }\n\n        public void Run(IntPtr pvParam)\n        {\n            var data = (TParameter)Marshal.PtrToStructure(pvParam, typeof(TParameter));\n            this.OnRun(data);\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.API/Callbacks/AppDataChanged.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.API.Callbacks\n{\n    public class AppDataChanged : Callback<Types.AppDataChanged>\n    {\n        public override int Id => 1001;\n        public override bool IsServer => false;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Callbacks/UserStatsReceived.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.API.Callbacks\n{\n    public class UserStatsReceived : Callback<Types.UserStatsReceived>\n    {\n        public override int Id => 1101;\n        public override bool IsServer => false;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Client.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\n\nnamespace SAM.API\n{\n    public class Client : IDisposable\n    {\n        public Wrappers.SteamClient018 SteamClient;\n        public Wrappers.SteamUser012 SteamUser;\n        public Wrappers.SteamUserStats013 SteamUserStats;\n        public Wrappers.SteamUtils005 SteamUtils;\n        public Wrappers.SteamApps001 SteamApps001;\n        public Wrappers.SteamApps008 SteamApps008;\n\n        private bool _IsDisposed = false;\n        private int _Pipe;\n        private int _User;\n\n        private readonly List<ICallback> _Callbacks = new();\n\n        public void Initialize(long appId)\n        {\n            if (string.IsNullOrEmpty(Steam.GetInstallPath()) == true)\n            {\n                throw new ClientInitializeException(ClientInitializeFailure.GetInstallPath, \"failed to get Steam install path\");\n            }\n\n            if (appId != 0)\n            {\n                Environment.SetEnvironmentVariable(\"SteamAppId\", appId.ToString(CultureInfo.InvariantCulture));\n            }\n\n            if (Steam.Load() == false)\n            {\n                throw new ClientInitializeException(ClientInitializeFailure.Load, \"failed to load SteamClient\");\n            }\n\n            this.SteamClient = Steam.CreateInterface<Wrappers.SteamClient018>(\"SteamClient018\");\n            if (this.SteamClient == null)\n            {\n                throw new ClientInitializeException(ClientInitializeFailure.CreateSteamClient, \"failed to create ISteamClient018\");\n            }\n\n            this._Pipe = this.SteamClient.CreateSteamPipe();\n            if (this._Pipe == 0)\n            {\n                throw new ClientInitializeException(ClientInitializeFailure.CreateSteamPipe, \"failed to create pipe\");\n            }\n\n            this._User = this.SteamClient.ConnectToGlobalUser(this._Pipe);\n            if (this._User == 0)\n            {\n                throw new ClientInitializeException(ClientInitializeFailure.ConnectToGlobalUser, \"failed to connect to global user\");\n            }\n\n            this.SteamUtils = this.SteamClient.GetSteamUtils004(this._Pipe);\n            if (appId > 0 && this.SteamUtils.GetAppId() != (uint)appId)\n            {\n                throw new ClientInitializeException(ClientInitializeFailure.AppIdMismatch, \"appID mismatch\");\n            }\n\n            this.SteamUser = this.SteamClient.GetSteamUser012(this._User, this._Pipe);\n            this.SteamUserStats = this.SteamClient.GetSteamUserStats013(this._User, this._Pipe);\n            this.SteamApps001 = this.SteamClient.GetSteamApps001(this._User, this._Pipe);\n            this.SteamApps008 = this.SteamClient.GetSteamApps008(this._User, this._Pipe);\n        }\n\n        ~Client()\n        {\n            this.Dispose(false);\n        }\n\n        protected virtual void Dispose(bool disposing)\n        {\n            if (this._IsDisposed == true)\n            {\n                return;\n            }\n\n            if (this.SteamClient != null && this._Pipe > 0)\n            {\n                if (this._User > 0)\n                {\n                    this.SteamClient.ReleaseUser(this._Pipe, this._User);\n                    this._User = 0;\n                }\n\n                this.SteamClient.ReleaseSteamPipe(this._Pipe);\n                this._Pipe = 0;\n            }\n\n            this._IsDisposed = true;\n        }\n\n        public void Dispose()\n        {\n            Dispose(true);\n            GC.SuppressFinalize(this);\n        }\n\n        public TCallback CreateAndRegisterCallback<TCallback>()\n            where TCallback : ICallback, new()\n        {\n            TCallback callback = new();\n            this._Callbacks.Add(callback);\n            return callback;\n        }\n\n        private bool _RunningCallbacks;\n\n        public void RunCallbacks(bool server)\n        {\n            if (this._RunningCallbacks == true)\n            {\n                return;\n            }\n\n            this._RunningCallbacks = true;\n\n            Types.CallbackMessage message;\n            while (Steam.GetCallback(this._Pipe, out message, out _) == true)\n            {\n                var callbackId = message.Id;\n                foreach (ICallback callback in this._Callbacks.Where(\n                    candidate => candidate.Id == callbackId &&\n                                 candidate.IsServer == server))\n                {\n                    callback.Run(message.ParamPointer);\n                }\n                Steam.FreeLastCallback(this._Pipe);\n            }\n\n            this._RunningCallbacks = false;\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.API/ClientInitializeException.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\nusing System;\n\nnamespace SAM.API\n{\n    public class ClientInitializeException : Exception\n    {\n        public readonly ClientInitializeFailure Failure;\n\n        public ClientInitializeException(ClientInitializeFailure failure)\n        {\n            this.Failure = failure;\n        }\n\n        public ClientInitializeException(ClientInitializeFailure failure, string message)\n            : base(message)\n        {\n            this.Failure = failure;\n        }\n\n        public ClientInitializeException(ClientInitializeFailure failure, string message, Exception innerException)\n            : base(message, innerException)\n        {\n            this.Failure = failure;\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.API/ClientInitializeFailure.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\nnamespace SAM.API\n{\n    public enum ClientInitializeFailure : byte\n    {\n        Unknown = 0,\n        GetInstallPath,\n        Load,\n        CreateSteamClient,\n        CreateSteamPipe,\n        ConnectToGlobalUser,\n        AppIdMismatch,\n    }\n}\n"
  },
  {
    "path": "SAM.API/GlobalSuppressions.cs",
    "content": "[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1004:GenericMethodsShouldProvideTypeParameter\", Scope = \"member\", Target = \"SAM.API.NativeWrapper`1.#Call`1(System.IntPtr,System.Object[])\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1004:GenericMethodsShouldProvideTypeParameter\", Scope = \"member\", Target = \"SAM.API.NativeWrapper`1.#Call`2(System.IntPtr,System.Object[])\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1004:GenericMethodsShouldProvideTypeParameter\", Scope = \"member\", Target = \"SAM.API.NativeWrapper`1.#GetDelegate`1(System.IntPtr)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1009:DeclareEventHandlersCorrectly\", Scope = \"member\", Target = \"SAM.API.Callback.#OnRun\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1009:DeclareEventHandlersCorrectly\", Scope = \"member\", Target = \"SAM.API.Callback`1.#OnRun\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1020:AvoidNamespacesWithFewTypes\", Scope = \"namespace\", Target = \"SAM.API.Callbacks\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1021:AvoidOutParameters\", MessageId = \"1#\", Scope = \"member\", Target = \"SAM.API.Steam.#GetCallback(System.Int32,SAM.API.Types.CallbackMessage&,System.Int32&)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1021:AvoidOutParameters\", MessageId = \"1#\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamUserStats007.#GetAchievementState(System.String,System.Boolean&)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1021:AvoidOutParameters\", MessageId = \"1#\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamUserStats007.#GetStatValue(System.String,System.Int32&)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1021:AvoidOutParameters\", MessageId = \"1#\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamUserStats007.#GetStatValue(System.String,System.Single&)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1021:AvoidOutParameters\", MessageId = \"1#\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamUtils005.#GetImageSize(System.Int32,System.Int32&,System.Int32&)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1021:AvoidOutParameters\", MessageId = \"2#\", Scope = \"member\", Target = \"SAM.API.Steam.#GetCallback(System.Int32,SAM.API.Types.CallbackMessage&,System.Int32&)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1021:AvoidOutParameters\", MessageId = \"2#\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamUtils005.#GetImageSize(System.Int32,System.Int32&,System.Int32&)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1024:UsePropertiesWhereAppropriate\", Scope = \"member\", Target = \"SAM.API.Steam.#GetInstallPath()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1024:UsePropertiesWhereAppropriate\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamApps003.#GetCurrentGameLanguage()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1024:UsePropertiesWhereAppropriate\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamUser012.#GetSteamId()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1024:UsePropertiesWhereAppropriate\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamUtils005.#GetAppId()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1024:UsePropertiesWhereAppropriate\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamUtils005.#GetConnectedUniverse()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1024:UsePropertiesWhereAppropriate\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamUtils005.#GetIPCountry()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1034:NestedTypesShouldNotBeVisible\", Scope = \"type\", Target = \"SAM.API.Callback`1+CallbackFunction\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1034:NestedTypesShouldNotBeVisible\", Scope = \"type\", Target = \"SAM.API.Callback+CallbackFunction\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1045:DoNotPassTypesByReference\", MessageId = \"0#\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamClient009.#CreateLocalUser(System.Int32&,SAM.API.Types.AccountType)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Client.#SteamApps001\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Client.#SteamApps003\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Client.#SteamClient\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Client.#SteamUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Client.#SteamUserStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Client.#SteamUtils\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps001.#GetAppData\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#GetAvailableGameLanguages\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#GetCurrentGameLanguage\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsCybercafe\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsDlcInstalled\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsLowViolence\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsSubscribed\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsSubscribedApp\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsVACBanned\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#ConnectToGlobalUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#CreateLocalUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#CreateSteamPipe\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetIPCCallCount\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamApps\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamFriends\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamGameServer\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamGameServerStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamGenericInterface\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamMasterServerUpdater\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamMatchmaking\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamMatchmakingServers\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamNetworking\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamRemoteStorage\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamUserStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamUtils\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#ReleaseSteamPipe\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#ReleaseUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#RunFrame\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#SetLocalIPBinding\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#SetWarningMessageHook\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#BeginAuthSession\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#CancelAuthTicket\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#DecompressVoice\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#EndAuthSession\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetAuthSessionTicket\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetCompressedVoice\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetHSteamUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetSteamID\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetUserDataFolder\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#InitiateGameConnection\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#LoggedOn\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#StartVoiceRecording\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#StopVoiceRecording\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#TerminateGameConnection\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#TrackAppUsageEvent\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#UserHasLicenseForApp\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#ClearAchievement\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#DownloadLeaderboardEntries\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#FindLeaderboard\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#FindOrCreateLeaderboard\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetAchievement\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetAchievementAndUnlockTime\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetAchievementDisplayAttribute\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetAchievementIcon\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetDownloadedLeaderboardEntry\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetLeaderboardDisplayType\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetLeaderboardEntryCount\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetLeaderboardName\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetLeaderboardSortMethod\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetNumberOfCurrentPlayers\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetStatFloat\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetStatInteger\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetUserAchievement\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetUserAchievementAndUnlockTime\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetUserStatFloat\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetUserStatInt\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#IndicateAchievementProgress\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#RequestCurrentStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#RequestUserStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#ResetAllStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#SetAchievement\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#SetStatFloat\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#SetStatInteger\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#StoreStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#UpdateAvgRateStat\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#UploadLeaderboardScore\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetAPICallFailureReason\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetAPICallResult\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetAppID\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetConnectedUniverse\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetCSERIPPort\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetCurrentBatteryPower\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetImageRGBA\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetImageSize\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetIPCCallCount\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetIPCountry\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetSecondsSinceAppActive\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetSecondsSinceComputerActive\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetServerRealTime\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#IsAPICallCompleted\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#IsOverlayEnabled\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#OverlayNeedsPresent\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#RunFrame\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#SetOverlayNotificationPosition\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#SetWarningMessageHook\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.NativeWrapper`1.#Functions\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.NativeWrapper`1.#ObjectAddress\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.AppDataChanged.#Id\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.AppDataChanged.#Result\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.CallbackMessage.#Id\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.CallbackMessage.#ParamPointer\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.CallbackMessage.#ParamSize\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.CallbackMessage.#User\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.UserItemsReceived.#GameId\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.UserItemsReceived.#ItemCount\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.UserItemsReceived.#Unknown\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.UserStatsReceived.#GameId\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.UserStatsReceived.#Result\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.UserStatsStored.#GameId\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1051:DoNotDeclareVisibleInstanceFields\", Scope = \"member\", Target = \"SAM.API.Types.UserStatsStored.#Result\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1060:MovePInvokesToNativeMethodsClass\", Scope = \"member\", Target = \"SAM.API.Steam+Native.#GetProcAddress(System.IntPtr,System.String)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1060:MovePInvokesToNativeMethodsClass\", Scope = \"member\", Target = \"SAM.API.Steam+Native.#LoadLibraryEx(System.String,System.IntPtr,System.UInt32)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1060:MovePInvokesToNativeMethodsClass\", Scope = \"member\", Target = \"SAM.API.Steam+Native.#SetDllDirectory(System.String)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA2210:AssembliesShouldHaveValidStrongNames\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Auth\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#BeginAuthSession\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Auth\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#CancelAuthTicket\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Auth\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#EndAuthSession\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Auth\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetAuthSessionTicket\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Avg\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#UpdateAvgRateStat\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Cybercafe\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsCybercafe\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Dlc\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsDlcInstalled\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Multiset\", Scope = \"member\", Target = \"SAM.API.Types.AccountType.#Multiset\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"param\", Scope = \"member\", Target = \"SAM.API.ICallback.#Run(System.IntPtr)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Param\", Scope = \"member\", Target = \"SAM.API.Types.CallbackMessage.#ParamPointer\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Param\", Scope = \"member\", Target = \"SAM.API.Types.CallbackMessage.#ParamSize\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"param\", Scope = \"type\", Target = \"SAM.API.Callback+CallbackFunction\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Utils\", Scope = \"member\", Target = \"SAM.API.Client.#SteamUtils\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Utils\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamUtils\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Utils\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamClient009.#GetISteamUtils`1(System.Int32,System.String)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Utils\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamClient009.#GetSteamUtils004(System.Int32)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Utils\", Scope = \"type\", Target = \"SAM.API.Interfaces.ISteamUtils005\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Utils\", Scope = \"type\", Target = \"SAM.API.Wrappers.SteamUtils005\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"API\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"API\", Scope = \"namespace\", Target = \"SAM.API\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"API\", Scope = \"namespace\", Target = \"SAM.API.Callbacks\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"API\", Scope = \"namespace\", Target = \"SAM.API.Interfaces\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"API\", Scope = \"namespace\", Target = \"SAM.API.Types\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"API\", Scope = \"namespace\", Target = \"SAM.API.Wrappers\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"OK\", Scope = \"member\", Target = \"SAM.API.Types.ItemRequestResult.#OK\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"RGBA\", Scope = \"member\", Target = \"SAM.API.Wrappers.SteamUtils005.#GetImageRGBA(System.Int32,System.Byte[])\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"SAM\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"SAM\", Scope = \"namespace\", Target = \"SAM.API\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"SAM\", Scope = \"namespace\", Target = \"SAM.API.Callbacks\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"SAM\", Scope = \"namespace\", Target = \"SAM.API.Interfaces\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"SAM\", Scope = \"namespace\", Target = \"SAM.API.Types\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"SAM\", Scope = \"namespace\", Target = \"SAM.API.Wrappers\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1710:IdentifiersShouldHaveCorrectSuffix\", Scope = \"member\", Target = \"SAM.API.Callback.#OnRun\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1710:IdentifiersShouldHaveCorrectSuffix\", Scope = \"member\", Target = \"SAM.API.Callback`1.#OnRun\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1720:IdentifiersShouldNotContainTypeNames\", MessageId = \"int\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetUserStatInt\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1720:IdentifiersShouldNotContainTypeNames\", MessageId = \"integer\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetStatInteger\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1720:IdentifiersShouldNotContainTypeNames\", MessageId = \"integer\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#SetStatInteger\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1720:IdentifiersShouldNotContainTypeNames\", MessageId = \"pointer\", Scope = \"member\", Target = \"SAM.API.NativeWrapper`1.#Call`1(System.IntPtr,System.Object[])\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1720:IdentifiersShouldNotContainTypeNames\", MessageId = \"pointer\", Scope = \"member\", Target = \"SAM.API.NativeWrapper`1.#Call`2(System.IntPtr,System.Object[])\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1720:IdentifiersShouldNotContainTypeNames\", MessageId = \"pointer\", Scope = \"member\", Target = \"SAM.API.NativeWrapper`1.#GetDelegate`1(System.IntPtr)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1720:IdentifiersShouldNotContainTypeNames\", MessageId = \"pointer\", Scope = \"member\", Target = \"SAM.API.NativeWrapper`1.#GetFunction`1(System.IntPtr)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1725:ParameterNamesShouldMatchBaseDeclaration\", MessageId = \"0#\", Scope = \"member\", Target = \"SAM.API.Callback`1.#Run(System.IntPtr)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\", Scope = \"member\", Target = \"SAM.API.NativeStrings.#PointerToString(System.Byte*)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\", Scope = \"member\", Target = \"SAM.API.NativeStrings.#PointerToString(System.Byte*,System.Int32)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\", Scope = \"type\", Target = \"SAM.API.Interfaces.ISteamApps001\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\", Scope = \"type\", Target = \"SAM.API.Interfaces.ISteamApps003\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\", Scope = \"type\", Target = \"SAM.API.Interfaces.ISteamClient009\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\", Scope = \"type\", Target = \"SAM.API.Interfaces.ISteamUser012\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\", Scope = \"type\", Target = \"SAM.API.Interfaces.ISteamUtils005\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\", Scope = \"type\", Target = \"SAM.API.Types.AppDataChanged\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\", Scope = \"type\", Target = \"SAM.API.Types.CallbackMessage\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\", Scope = \"type\", Target = \"SAM.API.Types.UserItemsReceived\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\", Scope = \"type\", Target = \"SAM.API.Types.UserStatsReceived\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\", Scope = \"type\", Target = \"SAM.API.Types.UserStatsStored\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps001.#GetAppData\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#GetAvailableGameLanguages\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#GetCurrentGameLanguage\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsCybercafe\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsDlcInstalled\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsLowViolence\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsSubscribed\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsSubscribedApp\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamApps003.#IsVACBanned\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#ConnectToGlobalUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#CreateLocalUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#CreateSteamPipe\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetIPCCallCount\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamApps\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamFriends\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamGameServer\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamGameServerStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamGenericInterface\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamMasterServerUpdater\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamMatchmaking\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamMatchmakingServers\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamNetworking\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamRemoteStorage\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamUserStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#GetISteamUtils\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#ReleaseSteamPipe\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#ReleaseUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#RunFrame\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#SetLocalIPBinding\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamClient009.#SetWarningMessageHook\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#BeginAuthSession\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#CancelAuthTicket\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#DecompressVoice\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#EndAuthSession\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetAuthSessionTicket\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetCompressedVoice\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetHSteamUser\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetSteamID\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#GetUserDataFolder\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#InitiateGameConnection\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#LoggedOn\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#StartVoiceRecording\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#StopVoiceRecording\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#TerminateGameConnection\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#TrackAppUsageEvent\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUser012.#UserHasLicenseForApp\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#ClearAchievement\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#DownloadLeaderboardEntries\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#FindLeaderboard\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#FindOrCreateLeaderboard\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetAchievement\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetAchievementAndUnlockTime\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetAchievementDisplayAttribute\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetAchievementIcon\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetDownloadedLeaderboardEntry\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetLeaderboardDisplayType\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetLeaderboardEntryCount\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetLeaderboardName\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetLeaderboardSortMethod\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetNumberOfCurrentPlayers\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetStatFloat\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetStatInteger\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetUserAchievement\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetUserAchievementAndUnlockTime\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetUserStatFloat\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#GetUserStatInt\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#IndicateAchievementProgress\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#RequestCurrentStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#RequestUserStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#ResetAllStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#SetAchievement\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#SetStatFloat\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#SetStatInteger\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#StoreStats\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#UpdateAvgRateStat\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUserStats007.#UploadLeaderboardScore\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetAPICallFailureReason\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetAPICallResult\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetAppID\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetConnectedUniverse\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetCSERIPPort\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetCurrentBatteryPower\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetImageRGBA\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetImageSize\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetIPCCallCount\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetIPCountry\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetSecondsSinceAppActive\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetSecondsSinceComputerActive\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#GetServerRealTime\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#IsAPICallCompleted\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#IsOverlayEnabled\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#OverlayNeedsPresent\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#RunFrame\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#SetOverlayNotificationPosition\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Interfaces.ISteamUtils005.#SetWarningMessageHook\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.NativeWrapper`1.#ObjectAddress\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Security\", \"CA2111:PointersShouldNotBeVisible\", Scope = \"member\", Target = \"SAM.API.Types.CallbackMessage.#ParamPointer\")]\n"
  },
  {
    "path": "SAM.API/ICallback.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\n\nnamespace SAM.API\n{\n    public interface ICallback\n    {\n        int Id { get; }\n        bool IsServer { get; }\n        void Run(IntPtr param);\n    }\n}\n"
  },
  {
    "path": "SAM.API/INativeWrapper.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\n\nnamespace SAM.API\n{\n    public interface INativeWrapper\n    {\n        void SetupFunctions(IntPtr objectAddress);\n    }\n}\n"
  },
  {
    "path": "SAM.API/Interfaces/ISteamApps001.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Interfaces\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public struct ISteamApps001\n    {\n        public IntPtr GetAppData;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Interfaces/ISteamApps008.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Interfaces\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public struct ISteamApps008\n    {\n        public IntPtr IsSubscribed;\n        public IntPtr IsLowViolence;\n        public IntPtr IsCybercafe;\n        public IntPtr IsVACBanned;\n        public IntPtr GetCurrentGameLanguage;\n        public IntPtr GetAvailableGameLanguages;\n        public IntPtr IsSubscribedApp;\n        public IntPtr IsDlcInstalled;\n        public IntPtr GetEarliestPurchaseUnixTime;\n        public IntPtr IsSubscribedFromFreeWeekend;\n        public IntPtr GetDLCCount;\n        public IntPtr GetDLCDataByIndex;\n        public IntPtr InstallDLC;\n        public IntPtr UninstallDLC;\n        public IntPtr RequestAppProofOfPurchaseKey;\n        public IntPtr GetCurrentBetaName;\n        public IntPtr MarkContentCorrupt;\n        public IntPtr GetInstalledDepots;\n        public IntPtr GetAppInstallDir;\n        public IntPtr IsAppInstalled;\n        public IntPtr GetAppOwner;\n        public IntPtr GetLaunchQueryParam;\n        public IntPtr GetDlcDownloadProgress;\n        public IntPtr GetAppBuildId;\n        public IntPtr RequestAllProofOfPurchaseKeys;\n        public IntPtr GetFileDetails;\n        public IntPtr GetLaunchCommandLine;\n        public IntPtr IsSubscribedFromFamilySharing;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Interfaces/ISteamClient018.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Interfaces\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public struct ISteamClient018\n    {\n        public IntPtr CreateSteamPipe;\n        public IntPtr ReleaseSteamPipe;\n        public IntPtr ConnectToGlobalUser;\n        public IntPtr CreateLocalUser;\n        public IntPtr ReleaseUser;\n        public IntPtr GetISteamUser;\n        public IntPtr GetISteamGameServer;\n        public IntPtr SetLocalIPBinding;\n        public IntPtr GetISteamFriends;\n        public IntPtr GetISteamUtils;\n        public IntPtr GetISteamMatchmaking;\n        public IntPtr GetISteamMatchmakingServers;\n        public IntPtr GetISteamGenericInterface;\n        public IntPtr GetISteamUserStats;\n        public IntPtr GetISteamGameServerStats;\n        public IntPtr GetISteamApps;\n        public IntPtr GetISteamNetworking;\n        public IntPtr GetISteamRemoteStorage;\n        public IntPtr GetISteamScreenshots;\n        public IntPtr GetISteamGameSearch;\n        public IntPtr RunFrame;\n        public IntPtr GetIPCCallCount;\n        public IntPtr SetWarningMessageHook;\n        public IntPtr ShutdownIfAllPipesClosed;\n        public IntPtr GetISteamHTTP;\n        public IntPtr DEPRECATED_GetISteamUnifiedMessages;\n        public IntPtr GetISteamController;\n        public IntPtr GetISteamUGC;\n        public IntPtr GetISteamAppList;\n        public IntPtr GetISteamMusic;\n        public IntPtr GetISteamMusicRemote;\n        public IntPtr GetISteamHTMLSurface;\n        public IntPtr DEPRECATED_Set_SteamAPI_CPostAPIResultInProcess;\n        public IntPtr DEPRECATED_Remove_SteamAPI_CPostAPIResultInProcess;\n        public IntPtr Set_SteamAPI_CCheckCallbackRegisteredInProcess;\n        public IntPtr GetISteamInventory;\n        public IntPtr GetISteamVideo;\n        public IntPtr GetISteamParentalSettings;\n        public IntPtr GetISteamInput;\n        public IntPtr GetISteamParties;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Interfaces/ISteamUser012.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Interfaces\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public struct ISteamUser012\n    {\n        public IntPtr GetHSteamUser;\n        public IntPtr LoggedOn;\n        public IntPtr GetSteamID;\n        public IntPtr InitiateGameConnection;\n        public IntPtr TerminateGameConnection;\n        public IntPtr TrackAppUsageEvent;\n        public IntPtr GetUserDataFolder;\n        public IntPtr StartVoiceRecording;\n        public IntPtr StopVoiceRecording;\n        public IntPtr GetCompressedVoice;\n        public IntPtr DecompressVoice;\n        public IntPtr GetAuthSessionTicket;\n        public IntPtr BeginAuthSession;\n        public IntPtr EndAuthSession;\n        public IntPtr CancelAuthTicket;\n        public IntPtr UserHasLicenseForApp;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Interfaces/ISteamUserStats013.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Interfaces\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public class ISteamUserStats013\n    {\n        public IntPtr GetStatFloat;\n        public IntPtr GetStatInteger;\n        public IntPtr SetStatFloat;\n        public IntPtr SetStatInteger;\n        public IntPtr UpdateAvgRateStat;\n        public IntPtr GetAchievement;\n        public IntPtr SetAchievement;\n        public IntPtr ClearAchievement;\n        public IntPtr GetAchievementAndUnlockTime;\n        public IntPtr StoreStats;\n        public IntPtr GetAchievementIcon;\n        public IntPtr GetAchievementDisplayAttribute;\n        public IntPtr IndicateAchievementProgress;\n        public IntPtr GetNumAchievements;\n        public IntPtr GetAchievementName;\n        public IntPtr RequestUserStats;\n        public IntPtr GetUserStatFloat;\n        public IntPtr GetUserStatInt;\n        public IntPtr GetUserAchievement;\n        public IntPtr GetUserAchievementAndUnlockTime;\n        public IntPtr ResetAllStats;\n        public IntPtr FindOrCreateLeaderboard;\n        public IntPtr FindLeaderboard;\n        public IntPtr GetLeaderboardName;\n        public IntPtr GetLeaderboardEntryCount;\n        public IntPtr GetLeaderboardSortMethod;\n        public IntPtr GetLeaderboardDisplayType;\n        public IntPtr DownloadLeaderboardEntries;\n        public IntPtr DownloadLeaderboardEntriesForUsers;\n        public IntPtr GetDownloadedLeaderboardEntry;\n        public IntPtr UploadLeaderboardScore;\n        public IntPtr AttachLeaderboardUGC;\n        public IntPtr GetNumberOfCurrentPlayers;\n        public IntPtr RequestGlobalAchievementPercentages;\n        public IntPtr GetMostAchievedAchievementInfo;\n        public IntPtr GetNextMostAchievedAchievementInfo;\n        public IntPtr GetAchievementAchievedPercent;\n        public IntPtr RequestGlobalStats;\n        public IntPtr GetGlobalStatFloat;\n        public IntPtr GetGlobalStatInteger;\n        public IntPtr GetGlobalStatHistoryFloat;\n        public IntPtr GetGlobalStatHistoryInteger;\n        public IntPtr GetAchievementProgressLimitsFloat;\n        public IntPtr GetAchievementProgressLimitsInteger;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Interfaces/ISteamUtils005.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Interfaces\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public struct ISteamUtils005\n    {\n        public IntPtr GetSecondsSinceAppActive;\n        public IntPtr GetSecondsSinceComputerActive;\n        public IntPtr GetConnectedUniverse;\n        public IntPtr GetServerRealTime;\n        public IntPtr GetIPCountry;\n        public IntPtr GetImageSize;\n        public IntPtr GetImageRGBA;\n        public IntPtr GetCSERIPPort;\n        public IntPtr GetCurrentBatteryPower;\n        public IntPtr GetAppID;\n        public IntPtr SetOverlayNotificationPosition;\n        public IntPtr IsAPICallCompleted;\n        public IntPtr GetAPICallFailureReason;\n        public IntPtr GetAPICallResult;\n        public IntPtr RunFrame;\n        public IntPtr GetIPCCallCount;\n        public IntPtr SetWarningMessageHook;\n        public IntPtr IsOverlayEnabled;\n        public IntPtr OverlayNeedsPresent;\n    }\n}\n"
  },
  {
    "path": "SAM.API/LICENSE.txt",
    "content": "zlib License\n\nCopyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgment in the product documentation would\n   be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and must not\n   be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source\n   distribution."
  },
  {
    "path": "SAM.API/NativeClass.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]\n    internal struct NativeClass\n    {\n        public IntPtr VirtualTable;\n    }\n}\n"
  },
  {
    "path": "SAM.API/NativeStrings.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing Microsoft.Win32.SafeHandles;\n\nnamespace SAM.API\n{\n    internal class NativeStrings\n    {\n        public sealed class StringHandle : SafeHandleZeroOrMinusOneIsInvalid\n        {\n            internal StringHandle(IntPtr preexistingHandle, bool ownsHandle)\n                : base(ownsHandle)\n            {\n                this.SetHandle(preexistingHandle);\n            }\n\n            public IntPtr Handle\n            {\n                get { return this.handle; }\n            }\n\n            protected override bool ReleaseHandle()\n            {\n                if (handle != IntPtr.Zero)\n                {\n                    Marshal.FreeHGlobal(handle);\n                    handle = IntPtr.Zero;\n                    return true;\n                }\n\n                return false;\n            }\n        }\n\n        public static unsafe StringHandle StringToStringHandle(string value)\n        {\n            if (value == null)\n            {\n                return new StringHandle(IntPtr.Zero, true);\n            }\n\n            var bytes = Encoding.UTF8.GetBytes(value);\n            var length = bytes.Length;\n\n            var p = Marshal.AllocHGlobal(length + 1);\n            Marshal.Copy(bytes, 0, p, bytes.Length);\n            ((byte*)p)[length] = 0;\n            return new StringHandle(p, true);\n        }\n\n        public static unsafe string PointerToString(sbyte* bytes)\n        {\n            if (bytes == null)\n            {\n                return null;\n            }\n\n            int running = 0;\n\n            var b = bytes;\n            if (*b == 0)\n            {\n                return string.Empty;\n            }\n\n            while ((*b++) != 0)\n            {\n                running++;\n            }\n\n            return new string(bytes, 0, running, Encoding.UTF8);\n        }\n\n        public static unsafe string PointerToString(byte* bytes)\n        {\n            return PointerToString((sbyte*)bytes);\n        }\n\n        public static unsafe string PointerToString(IntPtr nativeData)\n        {\n            return PointerToString((sbyte*)nativeData.ToPointer());\n        }\n\n        public static unsafe string PointerToString(sbyte* bytes, int length)\n        {\n            if (bytes == null)\n            {\n                return null;\n            }\n\n            int running = 0;\n\n            var b = bytes;\n            if (length == 0 || *b == 0)\n            {\n                return string.Empty;\n            }\n\n            while ((*b++) != 0 &&\n                   running < length)\n            {\n                running++;\n            }\n\n            return new string(bytes, 0, running, Encoding.UTF8);\n        }\n\n        public static unsafe string PointerToString(byte* bytes, int length)\n        {\n            return PointerToString((sbyte*)bytes, length);\n        }\n\n        public static unsafe string PointerToString(IntPtr nativeData, int length)\n        {\n            return PointerToString((sbyte*)nativeData.ToPointer(), length);\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.API/NativeWrapper.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API\n{\n    public abstract class NativeWrapper<TNativeFunctions> : INativeWrapper\n    {\n        protected IntPtr ObjectAddress;\n        protected TNativeFunctions Functions;\n\n        public override string ToString()\n        {\n            return $\"Steam Interface<{typeof(TNativeFunctions)}> #{this.ObjectAddress.ToInt32():X8}\";\n        }\n\n        public void SetupFunctions(IntPtr objectAddress)\n        {\n            this.ObjectAddress = objectAddress;\n\n            var iface = (NativeClass)Marshal.PtrToStructure(\n                this.ObjectAddress,\n                typeof(NativeClass));\n\n            this.Functions = (TNativeFunctions)Marshal.PtrToStructure(\n                iface.VirtualTable,\n                typeof(TNativeFunctions));\n        }\n\n        private readonly Dictionary<IntPtr, Delegate> _FunctionCache = new();\n\n        protected Delegate GetDelegate<TDelegate>(IntPtr pointer)\n        {\n            if (this._FunctionCache.TryGetValue(pointer, out var function) == false)\n            {\n                function = Marshal.GetDelegateForFunctionPointer(pointer, typeof(TDelegate));\n                this._FunctionCache[pointer] = function;\n            }\n            return function;\n        }\n\n        protected TDelegate GetFunction<TDelegate>(IntPtr pointer)\n            where TDelegate : class\n        {\n            return (TDelegate)((object)this.GetDelegate<TDelegate>(pointer));\n        }\n\n        protected void Call<TDelegate>(IntPtr pointer, params object[] args)\n        {\n            this.GetDelegate<TDelegate>(pointer).DynamicInvoke(args);\n        }\n\n        protected TReturn Call<TReturn, TDelegate>(IntPtr pointer, params object[] args)\n        {\n            return (TReturn)this.GetDelegate<TDelegate>(pointer).DynamicInvoke(args);\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.API/SAM.API.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <Company>Gibbed</Company>\n    <Authors>Gibbed</Authors>\n    <Description></Description>\n    <Copyright>Copyright © Gibbed 2019</Copyright>\n  </PropertyGroup>\n  <PropertyGroup>\n    <Version>7.0.0</Version>\n    <AssemblyVersion>7.0.0.0</AssemblyVersion>\n    <FileVersion>7.0.0.0</FileVersion>\n  </PropertyGroup>\n  <PropertyGroup>\n    <ApplicationIcon>Pink.ico</ApplicationIcon>\n  </PropertyGroup>\n  <PropertyGroup>\n    <RepositoryUrl>https://github.com/gibbed/SteamAchievementManager/</RepositoryUrl>\n    <RepositoryType>Git</RepositoryType>\n  </PropertyGroup>\n  <PropertyGroup>\n    <TargetFramework>net48</TargetFramework>\n    <LangVersion>9.0</LangVersion>\n    <Platforms>x86</Platforms>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x86'\">\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x86'\">\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "SAM.API/SAM.API.csproj.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:String x:Key=\"/Default/CodeEditing/Localization/Localizable/@EntryValue\">No</s:String></wpf:ResourceDictionary>"
  },
  {
    "path": "SAM.API/Steam.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing Microsoft.Win32;\n\nnamespace SAM.API\n{\n    public static class Steam\n    {\n        private struct Native\n        {\n            [DllImport(\"kernel32.dll\", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]\n            internal static extern IntPtr GetProcAddress(IntPtr module, string name);\n\n            [DllImport(\"kernel32.dll\", SetLastError = true, CharSet = CharSet.Unicode)]\n            internal static extern IntPtr LoadLibraryEx(string path, IntPtr file, uint flags);\n\n            [DllImport(\"kernel32.dll\", SetLastError = true, CharSet = CharSet.Unicode)]\n            [return: MarshalAs(UnmanagedType.Bool)]\n            internal static extern bool SetDllDirectory(string path);\n\n            internal const uint LoadWithAlteredSearchPath = 8;\n        }\n\n        private static Delegate GetExportDelegate<TDelegate>(IntPtr module, string name)\n        {\n            IntPtr address = Native.GetProcAddress(module, name);\n            return address == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(address, typeof(TDelegate));\n        }\n\n        private static TDelegate GetExportFunction<TDelegate>(IntPtr module, string name)\n            where TDelegate : class\n        {\n            return (TDelegate)((object)GetExportDelegate<TDelegate>(module, name));\n        }\n\n        private static IntPtr _Handle = IntPtr.Zero;\n\n        public static string GetInstallPath()\n        {\n            return (string)Registry.GetValue(@\"HKEY_LOCAL_MACHINE\\Software\\Valve\\Steam\", \"InstallPath\", null);\n        }\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]\n        private delegate IntPtr NativeCreateInterface(string version, IntPtr returnCode);\n\n        private static NativeCreateInterface _CallCreateInterface;\n\n        public static TClass CreateInterface<TClass>(string version)\n            where TClass : INativeWrapper, new()\n        {\n            IntPtr address = _CallCreateInterface(version, IntPtr.Zero);\n\n            if (address == IntPtr.Zero)\n            {\n                return default;\n            }\n\n            TClass instance = new();\n            instance.SetupFunctions(address);\n            return instance;\n        }\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeSteamGetCallback(int pipe, out Types.CallbackMessage message, out int call);\n\n        private static NativeSteamGetCallback _CallSteamBGetCallback;\n\n        public static bool GetCallback(int pipe, out Types.CallbackMessage message, out int call)\n        {\n            return _CallSteamBGetCallback(pipe, out message, out call);\n        }\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeSteamFreeLastCallback(int pipe);\n\n        private static NativeSteamFreeLastCallback _CallSteamFreeLastCallback;\n\n        public static bool FreeLastCallback(int pipe)\n        {\n            return _CallSteamFreeLastCallback(pipe);\n        }\n\n        public static bool Load()\n        {\n            if (_Handle != IntPtr.Zero)\n            {\n                return true;\n            }\n\n            string path = GetInstallPath();\n            if (path == null)\n            {\n                return false;\n            }\n\n            Native.SetDllDirectory(path + \";\" + Path.Combine(path, \"bin\"));\n\n            path = Path.Combine(path, \"steamclient.dll\");\n            IntPtr module = Native.LoadLibraryEx(path, IntPtr.Zero, Native.LoadWithAlteredSearchPath);\n            if (module == IntPtr.Zero)\n            {\n                return false;\n            }\n\n            _CallCreateInterface = GetExportFunction<NativeCreateInterface>(module, \"CreateInterface\");\n            if (_CallCreateInterface == null)\n            {\n                return false;\n            }\n\n            _CallSteamBGetCallback = GetExportFunction<NativeSteamGetCallback>(module, \"Steam_BGetCallback\");\n            if (_CallSteamBGetCallback == null)\n            {\n                return false;\n            }\n\n            _CallSteamFreeLastCallback = GetExportFunction<NativeSteamFreeLastCallback>(module, \"Steam_FreeLastCallback\");\n            if (_CallSteamFreeLastCallback == null)\n            {\n                return false;\n            }\n\n            _Handle = module;\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.API/Types/AccountType.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.API.Types\n{\n    public enum AccountType : int\n    {\n        Invalid = 0,\n        Individual = 1,\n        Multiset = 2,\n        GameServer = 3,\n        AnonGameServer = 4,\n        Pending = 5,\n        ContentServer = 6,\n        Clan = 7,\n        Chat = 8,\n        P2PSuperSeeder = 9,\n    }\n}\n"
  },
  {
    "path": "SAM.API/Types/AppDataChanged.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Types\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public struct AppDataChanged\n    {\n        public uint Id;\n        public bool Result;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Types/CallbackMessage.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Types\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public struct CallbackMessage\n    {\n        public int User;\n        public int Id;\n        public IntPtr ParamPointer;\n        public int ParamSize;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Types/ItemRequestResult.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.API.Types\n{\n    public enum ItemRequestResult : int\n    {\n        InvalidValue = -1,\n        OK = 0,\n        Denied = 1,\n        ServerError = 2,\n        Timeout = 3,\n        Invalid = 4,\n        NoMatch = 5,\n        UnknownError = 6,\n        NotLoggedOn = 7,\n    }\n}\n"
  },
  {
    "path": "SAM.API/Types/UserItemsReceived.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Types\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public struct UserItemsReceived\n    {\n        public ulong GameId;\n        public int Unknown;\n        public int ItemCount;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Types/UserStatType.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.API.Types\n{\n    public enum UserStatType\n    {\n        Invalid = 0,\n        Integer = 1,\n        Int = Integer,\n        Float = 2,\n        AverageRate = 3,\n        Achievements = 4,\n        GroupAchievements = 5,\n    }\n}\n"
  },
  {
    "path": "SAM.API/Types/UserStatsReceived.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Types\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public struct UserStatsReceived\n    {\n        public ulong GameId;\n        public int Result;\n        public ulong SteamIdUser;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Types/UserStatsStored.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System.Runtime.InteropServices;\n\nnamespace SAM.API.Types\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    public struct UserStatsStored\n    {\n        public ulong GameId;\n        public int Result;\n    }\n}\n"
  },
  {
    "path": "SAM.API/Wrappers/SteamApps001.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\nusing SAM.API.Interfaces;\n\nnamespace SAM.API.Wrappers\n{\n    public class SteamApps001 : NativeWrapper<ISteamApps001>\n    {\n        #region GetAppData\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate int NativeGetAppData(\n            IntPtr self,\n            uint appId,\n            IntPtr key,\n            IntPtr value,\n            int valueLength);\n\n        public string GetAppData(uint appId, string key)\n        {\n            using (var nativeHandle = NativeStrings.StringToStringHandle(key))\n            {\n                const int valueLength = 1024;\n                var valuePointer = Marshal.AllocHGlobal(valueLength);\n                int result = this.Call<int, NativeGetAppData>(\n                    this.Functions.GetAppData,\n                    this.ObjectAddress,\n                    appId,\n                    nativeHandle.Handle,\n                    valuePointer,\n                    valueLength);\n                var value = result == 0 ? null : NativeStrings.PointerToString(valuePointer, valueLength);\n                Marshal.FreeHGlobal(valuePointer);\n                return value;\n            }\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "SAM.API/Wrappers/SteamApps008.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\nusing SAM.API.Interfaces;\n\nnamespace SAM.API.Wrappers\n{\n    public class SteamApps008 : NativeWrapper<ISteamApps008>\n    {\n        #region IsSubscribed\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeIsSubscribedApp(IntPtr self, uint gameId);\n\n        public bool IsSubscribedApp(uint gameId)\n        {\n            return this.Call<bool, NativeIsSubscribedApp>(this.Functions.IsSubscribedApp, this.ObjectAddress, gameId);\n        }\n        #endregion\n\n        #region GetCurrentGameLanguage\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate IntPtr NativeGetCurrentGameLanguage(IntPtr self);\n\n        public string GetCurrentGameLanguage()\n        {\n            var languagePointer = this.Call<IntPtr, NativeGetCurrentGameLanguage>(\n                this.Functions.GetCurrentGameLanguage,\n                this.ObjectAddress);\n            return NativeStrings.PointerToString(languagePointer);\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "SAM.API/Wrappers/SteamClient018.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\nusing SAM.API.Interfaces;\n\nnamespace SAM.API.Wrappers\n{\n    public class SteamClient018 : NativeWrapper<ISteamClient018>\n    {\n        #region CreateSteamPipe\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate int NativeCreateSteamPipe(IntPtr self);\n\n        public int CreateSteamPipe()\n        {\n            return this.Call<int, NativeCreateSteamPipe>(this.Functions.CreateSteamPipe, this.ObjectAddress);\n        }\n        #endregion\n\n        #region ReleaseSteamPipe\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeReleaseSteamPipe(IntPtr self, int pipe);\n\n        public bool ReleaseSteamPipe(int pipe)\n        {\n            return this.Call<bool, NativeReleaseSteamPipe>(this.Functions.ReleaseSteamPipe, this.ObjectAddress, pipe);\n        }\n        #endregion\n\n        #region CreateLocalUser\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate int NativeCreateLocalUser(IntPtr self, ref int pipe, Types.AccountType type);\n\n        public int CreateLocalUser(ref int pipe, Types.AccountType type)\n        {\n            var call = this.GetFunction<NativeCreateLocalUser>(this.Functions.CreateLocalUser);\n            return call(this.ObjectAddress, ref pipe, type);\n        }\n        #endregion\n\n        #region ConnectToGlobalUser\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate int NativeConnectToGlobalUser(IntPtr self, int pipe);\n\n        public int ConnectToGlobalUser(int pipe)\n        {\n            return this.Call<int, NativeConnectToGlobalUser>(\n                this.Functions.ConnectToGlobalUser,\n                this.ObjectAddress,\n                pipe);\n        }\n        #endregion\n\n        #region ReleaseUser\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate void NativeReleaseUser(IntPtr self, int pipe, int user);\n\n        public void ReleaseUser(int pipe, int user)\n        {\n            this.Call<NativeReleaseUser>(this.Functions.ReleaseUser, this.ObjectAddress, pipe, user);\n        }\n        #endregion\n\n        #region SetLocalIPBinding\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate void NativeSetLocalIPBinding(IntPtr self, uint host, ushort port);\n\n        public void SetLocalIPBinding(uint host, ushort port)\n        {\n            this.Call<NativeSetLocalIPBinding>(this.Functions.SetLocalIPBinding, this.ObjectAddress, host, port);\n        }\n        #endregion\n\n        #region GetISteamUser\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate IntPtr NativeGetISteamUser(IntPtr self, int user, int pipe, IntPtr version);\n\n        private TClass GetISteamUser<TClass>(int user, int pipe, string version)\n            where TClass : INativeWrapper, new()\n        {\n            using (var nativeVersion = NativeStrings.StringToStringHandle(version))\n            {\n                IntPtr address = this.Call<IntPtr, NativeGetISteamUser>(\n                    this.Functions.GetISteamUser,\n                    this.ObjectAddress,\n                    user,\n                    pipe,\n                    nativeVersion.Handle);\n                TClass result = new();\n                result.SetupFunctions(address);\n                return result;\n            }\n        }\n        #endregion\n\n        #region GetSteamUser012\n        public SteamUser012 GetSteamUser012(int user, int pipe)\n        {\n            return this.GetISteamUser<SteamUser012>(user, pipe, \"SteamUser012\");\n        }\n        #endregion\n\n        #region GetISteamUserStats\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate IntPtr NativeGetISteamUserStats(IntPtr self, int user, int pipe, IntPtr version);\n\n        private TClass GetISteamUserStats<TClass>(int user, int pipe, string version)\n            where TClass : INativeWrapper, new()\n        {\n            using (var nativeVersion = NativeStrings.StringToStringHandle(version))\n            {\n                IntPtr address = this.Call<IntPtr, NativeGetISteamUserStats>(\n                    this.Functions.GetISteamUserStats,\n                    this.ObjectAddress,\n                    user,\n                    pipe,\n                    nativeVersion.Handle);\n                TClass result = new();\n                result.SetupFunctions(address);\n                return result;\n            }\n        }\n        #endregion\n\n        #region GetSteamUserStats013\n        public SteamUserStats013 GetSteamUserStats013(int user, int pipe)\n        {\n            return this.GetISteamUserStats<SteamUserStats013>(user, pipe, \"STEAMUSERSTATS_INTERFACE_VERSION013\");\n        }\n        #endregion\n\n        #region GetISteamUtils\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate IntPtr NativeGetISteamUtils(IntPtr self, int pipe, IntPtr version);\n\n        public TClass GetISteamUtils<TClass>(int pipe, string version)\n            where TClass : INativeWrapper, new()\n        {\n            using (var nativeVersion = NativeStrings.StringToStringHandle(version))\n            {\n                IntPtr address = this.Call<IntPtr, NativeGetISteamUtils>(\n                    this.Functions.GetISteamUtils,\n                    this.ObjectAddress,\n                    pipe,\n                    nativeVersion.Handle);\n                TClass result = new();\n                result.SetupFunctions(address);\n                return result;\n            }\n        }\n        #endregion\n\n        #region GetSteamUtils004\n        public SteamUtils005 GetSteamUtils004(int pipe)\n        {\n            return this.GetISteamUtils<SteamUtils005>(pipe, \"SteamUtils005\");\n        }\n        #endregion\n\n        #region GetISteamApps\n        private delegate IntPtr NativeGetISteamApps(int user, int pipe, IntPtr version);\n\n        private TClass GetISteamApps<TClass>(int user, int pipe, string version)\n            where TClass : INativeWrapper, new()\n        {\n            using (var nativeVersion = NativeStrings.StringToStringHandle(version))\n            {\n                IntPtr address = this.Call<IntPtr, NativeGetISteamApps>(\n                    this.Functions.GetISteamApps,\n                    user,\n                    pipe,\n                    nativeVersion.Handle);\n                TClass result = new();\n                result.SetupFunctions(address);\n                return result;\n            }\n        }\n        #endregion\n\n        #region GetSteamApps001\n        public SteamApps001 GetSteamApps001(int user, int pipe)\n        {\n            return this.GetISteamApps<SteamApps001>(user, pipe, \"STEAMAPPS_INTERFACE_VERSION001\");\n        }\n        #endregion\n\n        #region GetSteamApps008\n        public SteamApps008 GetSteamApps008(int user, int pipe)\n        {\n            return this.GetISteamApps<SteamApps008>(user, pipe, \"STEAMAPPS_INTERFACE_VERSION008\");\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "SAM.API/Wrappers/SteamUser012.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\nusing SAM.API.Interfaces;\n\nnamespace SAM.API.Wrappers\n{\n    public class SteamUser012 : NativeWrapper<ISteamUser012>\n    {\n        #region IsLoggedIn\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeLoggedOn(IntPtr self);\n\n        public bool IsLoggedIn()\n        {\n            return this.Call<bool, NativeLoggedOn>(this.Functions.LoggedOn, this.ObjectAddress);\n        }\n        #endregion\n\n        #region GetSteamID\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate void NativeGetSteamId(IntPtr self, out ulong steamId);\n\n        public ulong GetSteamId()\n        {\n            var call = this.GetFunction<NativeGetSteamId>(this.Functions.GetSteamID);\n            ulong steamId;\n            call(this.ObjectAddress, out steamId);\n            return steamId;\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "SAM.API/Wrappers/SteamUserStats013.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\nusing SAM.API.Interfaces;\n\nnamespace SAM.API.Wrappers\n{\n    public class SteamUserStats013 : NativeWrapper<ISteamUserStats013>\n    {\n        #region GetStatValue (int)\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeGetStatInt(IntPtr self, IntPtr name, out int data);\n\n        public bool GetStatValue(string name, out int value)\n        {\n            using (var nativeName = NativeStrings.StringToStringHandle(name))\n            {\n                var call = this.GetFunction<NativeGetStatInt>(this.Functions.GetStatInteger);\n                return call(this.ObjectAddress, nativeName.Handle, out value);\n            }\n        }\n        #endregion\n\n        #region GetStatValue (float)\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeGetStatFloat(IntPtr self, IntPtr name, out float data);\n\n        public bool GetStatValue(string name, out float value)\n        {\n            using (var nativeName = NativeStrings.StringToStringHandle(name))\n            {\n                var call = this.GetFunction<NativeGetStatFloat>(this.Functions.GetStatFloat);\n                return call(this.ObjectAddress, nativeName.Handle, out value);\n            }\n        }\n        #endregion\n\n        #region SetStatValue (int)\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeSetStatInt(IntPtr self, IntPtr name, int data);\n\n        public bool SetStatValue(string name, int value)\n        {\n            using (var nativeName = NativeStrings.StringToStringHandle(name))\n            {\n                return this.Call<bool, NativeSetStatInt>(\n                    this.Functions.SetStatInteger,\n                    this.ObjectAddress,\n                    nativeName.Handle,\n                    value);\n            }\n        }\n        #endregion\n\n        #region SetStatValue (float)\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeSetStatFloat(IntPtr self, IntPtr name, float data);\n\n        public bool SetStatValue(string name, float value)\n        {\n            using (var nativeName = NativeStrings.StringToStringHandle(name))\n            {\n                return this.Call<bool, NativeSetStatFloat>(\n                    this.Functions.SetStatFloat,\n                    this.ObjectAddress,\n                    nativeName.Handle,\n                    value);\n            }\n        }\n        #endregion\n\n        #region GetAchievement\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeGetAchievement(\n            IntPtr self,\n            IntPtr name,\n            [MarshalAs(UnmanagedType.I1)] out bool isAchieved);\n\n        public bool GetAchievement(string name, out bool isAchieved)\n        {\n            using (var nativeName = NativeStrings.StringToStringHandle(name))\n            {\n                var call = this.GetFunction<NativeGetAchievement>(this.Functions.GetAchievement);\n                return call(this.ObjectAddress, nativeName.Handle, out isAchieved);\n            }\n        }\n        #endregion\n\n        #region SetAchievement\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeSetAchievement(IntPtr self, IntPtr name);\n\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeClearAchievement(IntPtr self, IntPtr name);\n\n        public bool SetAchievement(string name, bool state)\n        {\n            using (var nativeName = NativeStrings.StringToStringHandle(name))\n            {\n                if (state == false)\n                {\n                    return this.Call<bool, NativeClearAchievement>(\n                        this.Functions.ClearAchievement,\n                        this.ObjectAddress,\n                        nativeName.Handle);\n                }\n\n                return this.Call<bool, NativeSetAchievement>(\n                    this.Functions.SetAchievement,\n                    this.ObjectAddress,\n                    nativeName.Handle);\n            }\n        }\n        #endregion\n\n        #region GetAchievementAndUnlockTime\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeGetAchievementAndUnlockTime(\n            IntPtr self,\n            IntPtr name,\n            [MarshalAs(UnmanagedType.I1)] out bool isAchieved,\n            out uint unlockTime);\n\n        public bool GetAchievementAndUnlockTime(string name, out bool isAchieved, out uint unlockTime)\n        {\n            using (var nativeName = NativeStrings.StringToStringHandle(name))\n            {\n                var call = this.GetFunction<NativeGetAchievementAndUnlockTime>(this.Functions.GetAchievementAndUnlockTime);\n                return call(this.ObjectAddress, nativeName.Handle, out isAchieved, out unlockTime);\n            }\n        }\n        #endregion\n\n        #region StoreStats\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeStoreStats(IntPtr self);\n\n        public bool StoreStats()\n        {\n            return this.Call<bool, NativeStoreStats>(this.Functions.StoreStats, this.ObjectAddress);\n        }\n        #endregion\n\n        #region GetAchievementIcon\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate int NativeGetAchievementIcon(IntPtr self, IntPtr name);\n\n        public int GetAchievementIcon(string name)\n        {\n            using (var nativeName = NativeStrings.StringToStringHandle(name))\n            {\n                return this.Call<int, NativeGetAchievementIcon>(\n                    this.Functions.GetAchievementIcon,\n                    this.ObjectAddress,\n                    nativeName.Handle);\n            }\n        }\n        #endregion\n\n        #region GetAchievementDisplayAttribute\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate IntPtr NativeGetAchievementDisplayAttribute(IntPtr self, IntPtr name, IntPtr key);\n\n        public string GetAchievementDisplayAttribute(string name, string key)\n        {\n            using (var nativeName = NativeStrings.StringToStringHandle(name))\n            using (var nativeKey = NativeStrings.StringToStringHandle(key))\n            {\n                var result = this.Call<IntPtr, NativeGetAchievementDisplayAttribute>(\n                    this.Functions.GetAchievementDisplayAttribute,\n                    this.ObjectAddress,\n                    nativeName.Handle,\n                    nativeKey.Handle);\n                return NativeStrings.PointerToString(result);\n            }\n        }\n        #endregion\n\n        #region RequestUserStats\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate CallHandle NativeRequestUserStats(IntPtr self, ulong steamIdUser);\n\n        public CallHandle RequestUserStats(ulong steamIdUser)\n        {\n            return this.Call<CallHandle, NativeRequestUserStats>(this.Functions.RequestUserStats, this.ObjectAddress, steamIdUser);\n        }\n        #endregion\n\n        #region ResetAllStats\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeResetAllStats(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool achievementsToo);\n\n        public bool ResetAllStats(bool achievementsToo)\n        {\n            return this.Call<bool, NativeResetAllStats>(\n                this.Functions.ResetAllStats,\n                this.ObjectAddress,\n                achievementsToo);\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "SAM.API/Wrappers/SteamUtils005.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\nusing SAM.API.Interfaces;\n\nnamespace SAM.API.Wrappers\n{\n    public class SteamUtils005 : NativeWrapper<ISteamUtils005>\n    {\n        #region GetConnectedUniverse\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate int NativeGetConnectedUniverse(IntPtr self);\n\n        public int GetConnectedUniverse()\n        {\n            return this.Call<int, NativeGetConnectedUniverse>(this.Functions.GetConnectedUniverse, this.ObjectAddress);\n        }\n        #endregion\n\n        #region GetIPCountry\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate IntPtr NativeGetIPCountry(IntPtr self);\n\n        public string GetIPCountry()\n        {\n            var result = this.Call<IntPtr, NativeGetIPCountry>(this.Functions.GetIPCountry, this.ObjectAddress);\n            return NativeStrings.PointerToString(result);\n        }\n        #endregion\n\n        #region GetImageSize\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeGetImageSize(IntPtr self, int index, out int width, out int height);\n\n        public bool GetImageSize(int index, out int width, out int height)\n        {\n            var call = this.GetFunction<NativeGetImageSize>(this.Functions.GetImageSize);\n            return call(this.ObjectAddress, index, out width, out height);\n        }\n        #endregion\n\n        #region GetImageRGBA\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        [return: MarshalAs(UnmanagedType.I1)]\n        private delegate bool NativeGetImageRGBA(IntPtr self, int index, byte[] buffer, int length);\n\n        public bool GetImageRGBA(int index, byte[] data)\n        {\n            if (data == null)\n            {\n                throw new ArgumentNullException(\"data\");\n            }\n            var call = this.GetFunction<NativeGetImageRGBA>(this.Functions.GetImageRGBA);\n            return call(this.ObjectAddress, index, data, data.Length);\n        }\n        #endregion\n\n        #region GetAppID\n        [UnmanagedFunctionPointer(CallingConvention.ThisCall)]\n        private delegate uint NativeGetAppId(IntPtr self);\n\n        public uint GetAppId()\n        {\n            return this.Call<uint, NativeGetAppId>(this.Functions.GetAppID, this.ObjectAddress);\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "SAM.Game/DoubleBufferedListView.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System.Windows.Forms;\n\nnamespace SAM.Game\n{\n\tinternal class DoubleBufferedListView : ListView\n\t{\n\t\tpublic DoubleBufferedListView()\n\t\t{\n\t\t\tbase.DoubleBuffered = true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "SAM.Game/GlobalSuppressions.cs",
    "content": "[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"SAM.Game.KeyValue.#LoadAsBinary(System.String)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"SAM.Game.KeyValue.#ReadAsBinary(System.IO.Stream)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"SAM.Game.Manager.#LoadUserGameStatsSchema()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"SAM.Game.Manager.#OnIconDownload(System.Object,System.Net.DownloadDataCompletedEventArgs)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"SAM.Game.Manager.#OnUserStatsReceived(SAM.API.Types.UserStatsReceived)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1064:ExceptionsShouldBePublic\", Scope = \"type\", Target = \"SAM.Game.Stats.StatIsProtectedException\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA2210:AssembliesShouldHaveValidStrongNames\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.ColumnHeader.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Game.Manager.#InitializeComponent()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.Control.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Game.Manager.#InitializeComponent()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.Form.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Game.Manager.#.ctor(System.Int64,SAM.API.Client)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Game.Manager.#OnResetAllStats(System.Object,System.EventArgs)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Game.Manager.#OnUserStatsReceived(SAM.API.Types.UserStatsReceived)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Game.Program.#Main(System.String[])\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.Windows.Forms.IWin32Window,System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Game.Manager.#OnCheckAchievement(System.Object,System.Windows.Forms.ItemCheckEventArgs)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.Windows.Forms.IWin32Window,System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Game.Manager.#OnResetAllStats(System.Object,System.EventArgs)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.Windows.Forms.IWin32Window,System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Game.Manager.#OnStore(System.Object,System.EventArgs)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.Windows.Forms.IWin32Window,System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Game.Manager.#RefreshStats()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.Windows.Forms.IWin32Window,System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Game.Manager.#Store()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.Windows.Forms.IWin32Window,System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Game.Manager.#StoreAchievements()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.Windows.Forms.IWin32Window,System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Game.Manager.#StoreStatistics()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.ToolStripItem.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Game.Manager.#DownloadNextIcon()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.ToolStripItem.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Game.Manager.#InitializeComponent()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.ToolStripItem.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Game.Manager.#OnUserStatsReceived(SAM.API.Types.UserStatsReceived)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.ToolStripItem.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Game.Manager.#RefreshStats()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.ToolStripItem.set_ToolTipText(System.String)\", Scope = \"member\", Target = \"SAM.Game.Manager.#InitializeComponent()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1309:UseOrdinalStringComparison\", MessageId = \"System.String.StartsWith(System.String,System.StringComparison)\", Scope = \"member\", Target = \"SAM.Game.Manager.#GetAchievements()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA2204:Literals should be spelled correctly\", MessageId = \"wstring\", Scope = \"member\", Target = \"SAM.Game.KeyValue.#ReadAsBinary(System.IO.Stream)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1800:DoNotCastUnnecessarily\", Scope = \"member\", Target = \"SAM.Game.Manager.#GetStatistics()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1800:DoNotCastUnnecessarily\", Scope = \"member\", Target = \"SAM.Game.Manager.#StoreStatistics()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\", Scope = \"member\", Target = \"SAM.Game.Stats.AchievementInfo.#ImageIndex\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\", Scope = \"member\", Target = \"SAM.Game.Stats.StatInfo.#DisplayName\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\", Scope = \"member\", Target = \"SAM.Game.Stats.StatInfo.#Extra\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\", Scope = \"member\", Target = \"SAM.Game.Stats.StatInfo.#IsIncrementOnly\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\", Scope = \"member\", Target = \"SAM.Game.Stats.StatIsProtectedException.#.ctor(System.String)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\", Scope = \"member\", Target = \"SAM.Game.Stats.StatIsProtectedException.#.ctor(System.String,System.Exception)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\", Scope = \"member\", Target = \"SAM.Game.StreamHelpers.#ReadStringAscii(System.IO.Stream)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1823:AvoidUnusedPrivateFields\", Scope = \"member\", Target = \"SAM.Game.Stats.AchievementDefinition.#IsHidden\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1823:AvoidUnusedPrivateFields\", Scope = \"member\", Target = \"SAM.Game.Stats.FloatStatDefinition.#DefaultValue\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1823:AvoidUnusedPrivateFields\", Scope = \"member\", Target = \"SAM.Game.Stats.FloatStatDefinition.#MaxChange\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1823:AvoidUnusedPrivateFields\", Scope = \"member\", Target = \"SAM.Game.Stats.FloatStatDefinition.#MaxValue\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1823:AvoidUnusedPrivateFields\", Scope = \"member\", Target = \"SAM.Game.Stats.FloatStatDefinition.#MinValue\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1823:AvoidUnusedPrivateFields\", Scope = \"member\", Target = \"SAM.Game.Stats.IntegerStatDefinition.#DefaultValue\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1823:AvoidUnusedPrivateFields\", Scope = \"member\", Target = \"SAM.Game.Stats.IntegerStatDefinition.#MaxChange\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1823:AvoidUnusedPrivateFields\", Scope = \"member\", Target = \"SAM.Game.Stats.IntegerStatDefinition.#MaxValue\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1823:AvoidUnusedPrivateFields\", Scope = \"member\", Target = \"SAM.Game.Stats.IntegerStatDefinition.#MinValue\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Reliability\", \"CA2000:Dispose objects before losing scope\", Scope = \"member\", Target = \"SAM.Game.Manager.#.ctor(System.Int64,SAM.API.Client)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Reliability\", \"CA2000:Dispose objects before losing scope\", Scope = \"member\", Target = \"SAM.Game.Manager.#InitializeComponent()\")]\n"
  },
  {
    "path": "SAM.Game/InvariantShorthand.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\n\nnamespace SAM.Game\n{\n    public static class InvariantShorthand\n    {\n        public static string _(FormattableString formattable)\n        {\n            return FormattableString.Invariant(formattable);\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Game/KeyValue.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\n\nnamespace SAM.Game\n{\n    internal class KeyValue\n    {\n        private static readonly KeyValue _Invalid = new();\n        public string Name = \"<root>\";\n        public KeyValueType Type = KeyValueType.None;\n        public object Value;\n        public bool Valid;\n\n        public List<KeyValue> Children = null;\n\n        public KeyValue this[string key]\n        {\n            get\n            {\n                if (this.Children == null)\n                {\n                    return _Invalid;\n                }\n\n                var child = this.Children.SingleOrDefault(\n                    c => string.Compare(c.Name, key, StringComparison.InvariantCultureIgnoreCase) == 0);\n\n                if (child == null)\n                {\n                    return _Invalid;\n                }\n\n                return child;\n            }\n        }\n\n        public string AsString(string defaultValue)\n        {\n            if (this.Valid == false)\n            {\n                return defaultValue;\n            }\n\n            if (this.Value == null)\n            {\n                return defaultValue;\n            }\n\n            return this.Value.ToString();\n        }\n\n        public int AsInteger(int defaultValue)\n        {\n            if (this.Valid == false)\n            {\n                return defaultValue;\n            }\n\n            switch (this.Type)\n            {\n                case KeyValueType.String:\n                case KeyValueType.WideString:\n                {\n                    return int.TryParse((string)this.Value, out int value) == false\n                        ? defaultValue\n                        : value;\n                }\n\n                case KeyValueType.Int32:\n                {\n                    return (int)this.Value;\n                }\n\n                case KeyValueType.Float32:\n                {\n                    return (int)((float)this.Value);\n                }\n\n                case KeyValueType.UInt64:\n                {\n                    return (int)((ulong)this.Value & 0xFFFFFFFF);\n                }\n            }\n\n            return defaultValue;\n        }\n\n        public float AsFloat(float defaultValue)\n        {\n            if (this.Valid == false)\n            {\n                return defaultValue;\n            }\n\n            switch (this.Type)\n            {\n                case KeyValueType.String:\n                case KeyValueType.WideString:\n                {\n                    return float.TryParse((string)this.Value, out float value) == false\n                        ? defaultValue\n                        : value;\n                }\n\n                case KeyValueType.Int32:\n                {\n                    return (int)this.Value;\n                }\n\n                case KeyValueType.Float32:\n                {\n                    return (float)this.Value;\n                }\n\n                case KeyValueType.UInt64:\n                {\n                    return (ulong)this.Value & 0xFFFFFFFF;\n                }\n            }\n\n            return defaultValue;\n        }\n\n        public bool AsBoolean(bool defaultValue)\n        {\n            if (this.Valid == false)\n            {\n                return defaultValue;\n            }\n\n            switch (this.Type)\n            {\n                case KeyValueType.String:\n                case KeyValueType.WideString:\n                {\n                    return int.TryParse((string)this.Value, out int value) == false\n                        ? defaultValue\n                        : value != 0;\n                }\n\n                case KeyValueType.Int32:\n                {\n                    return ((int)this.Value) != 0;\n                }\n\n                case KeyValueType.Float32:\n                {\n                    return ((int)((float)this.Value)) != 0;\n                }\n\n                case KeyValueType.UInt64:\n                {\n                    return ((ulong)this.Value) != 0;\n                }\n            }\n\n            return defaultValue;\n        }\n\n        public override string ToString()\n        {\n            if (this.Valid == false)\n            {\n                return \"<invalid>\";\n            }\n\n            if (this.Type == KeyValueType.None)\n            {\n                return this.Name;\n            }\n\n            return $\"{this.Name} = {this.Value}\";\n        }\n\n        public static KeyValue LoadAsBinary(string path)\n        {\n            if (File.Exists(path) == false)\n            {\n                return null;\n            }\n\n            try\n            {\n                using (var input = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))\n                {\n                    KeyValue kv = new();\n                    if (kv.ReadAsBinary(input) == false)\n                    {\n                        return null;\n                    }\n                    return kv;\n                }\n            }\n            catch (Exception)\n            {\n                return null;\n            }\n        }\n\n        public bool ReadAsBinary(Stream input)\n        {\n            this.Children = new();\n            try\n            {\n                while (true)\n                {\n                    var type = (KeyValueType)input.ReadValueU8();\n\n                    if (type == KeyValueType.End)\n                    {\n                        break;\n                    }\n\n                    KeyValue current = new()\n                    {\n                        Type = type,\n                        Name = input.ReadStringUnicode(),\n                    };\n\n                    switch (type)\n                    {\n                        case KeyValueType.None:\n                        {\n                            current.ReadAsBinary(input);\n                            break;\n                        }\n\n                        case KeyValueType.String:\n                        {\n                            current.Valid = true;\n                            current.Value = input.ReadStringUnicode();\n                            break;\n                        }\n\n                        case KeyValueType.WideString:\n                        {\n                            throw new FormatException(\"wstring is unsupported\");\n                        }\n\n                        case KeyValueType.Int32:\n                        {\n                            current.Valid = true;\n                            current.Value = input.ReadValueS32();\n                            break;\n                        }\n\n                        case KeyValueType.UInt64:\n                        {\n                            current.Valid = true;\n                            current.Value = input.ReadValueU64();\n                            break;\n                        }\n\n                        case KeyValueType.Float32:\n                        {\n                            current.Valid = true;\n                            current.Value = input.ReadValueF32();\n                            break;\n                        }\n\n                        case KeyValueType.Color:\n                        {\n                            current.Valid = true;\n                            current.Value = input.ReadValueU32();\n                            break;\n                        }\n\n                        case KeyValueType.Pointer:\n                        {\n                            current.Valid = true;\n                            current.Value = input.ReadValueU32();\n                            break;\n                        }\n\n                        default:\n                        {\n                            throw new FormatException();\n                        }\n                    }\n\n                    if (input.Position >= input.Length)\n                    {\n                        throw new FormatException();\n                    }\n\n                    this.Children.Add(current);\n                }\n\n                this.Valid = true;\n                return input.Position == input.Length;\n            }\n            catch (Exception)\n            {\n                return false;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Game/KeyValueType.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.Game\n{\n    internal enum KeyValueType : byte\n    {\n        None = 0,\n        String = 1,\n        Int32 = 2,\n        Float32 = 3,\n        Pointer = 4,\n        WideString = 5,\n        Color = 6,\n        UInt64 = 7,\n        End = 8,\n    }\n}\n"
  },
  {
    "path": "SAM.Game/LICENSE.txt",
    "content": "zlib License\n\nCopyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgment in the product documentation would\n   be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and must not\n   be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source\n   distribution."
  },
  {
    "path": "SAM.Game/Manager.Designer.cs",
    "content": "﻿namespace SAM.Game\n{\n    partial class Manager\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            System.Windows.Forms.ToolStripSeparator _ToolStripSeparator1;\n            System.Windows.Forms.ToolStripSeparator _ToolStripSeparator2;\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Manager));\n            this._MainToolStrip = new System.Windows.Forms.ToolStrip();\n            this._StoreButton = new System.Windows.Forms.ToolStripButton();\n            this._ReloadButton = new System.Windows.Forms.ToolStripButton();\n            this._ResetButton = new System.Windows.Forms.ToolStripButton();\n            this._AchievementImageList = new System.Windows.Forms.ImageList(this.components);\n            this._MainStatusStrip = new System.Windows.Forms.StatusStrip();\n            this._CountryStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();\n            this._GameStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();\n            this._DownloadStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();\n            this._CallbackTimer = new System.Windows.Forms.Timer(this.components);\n            this._MainTabControl = new System.Windows.Forms.TabControl();\n            this._AchievementsTabPage = new System.Windows.Forms.TabPage();\n            this._AchievementListView = new SAM.Game.DoubleBufferedListView();\n            this._AchievementNameColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\n            this._AchievementDescriptionColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\n            this._AchievementUnlockTimeColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\n            this._AchievementsToolStrip = new System.Windows.Forms.ToolStrip();\n            this._LockAllButton = new System.Windows.Forms.ToolStripButton();\n            this._InvertAllButton = new System.Windows.Forms.ToolStripButton();\n            this._UnlockAllButton = new System.Windows.Forms.ToolStripButton();\n            this._DisplayLabel = new System.Windows.Forms.ToolStripLabel();\n            this._DisplayLockedOnlyButton = new System.Windows.Forms.ToolStripButton();\n            this._DisplayUnlockedOnlyButton = new System.Windows.Forms.ToolStripButton();\n            this._MatchingStringLabel = new System.Windows.Forms.ToolStripLabel();\n            this._MatchingStringTextBox = new System.Windows.Forms.ToolStripTextBox();\n            this._StatisticsTabPage = new System.Windows.Forms.TabPage();\n            this._EnableStatsEditingCheckBox = new System.Windows.Forms.CheckBox();\n            this._StatisticsDataGridView = new System.Windows.Forms.DataGridView();\n            _ToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();\n            _ToolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();\n            this._MainToolStrip.SuspendLayout();\n            this._MainStatusStrip.SuspendLayout();\n            this._MainTabControl.SuspendLayout();\n            this._AchievementsTabPage.SuspendLayout();\n            this._AchievementsToolStrip.SuspendLayout();\n            this._StatisticsTabPage.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this._StatisticsDataGridView)).BeginInit();\n            this.SuspendLayout();\n            // \n            // _ToolStripSeparator1\n            // \n            _ToolStripSeparator1.Name = \"_ToolStripSeparator1\";\n            _ToolStripSeparator1.Size = new System.Drawing.Size(6, 25);\n            // \n            // _ToolStripSeparator2\n            // \n            _ToolStripSeparator2.Name = \"_ToolStripSeparator2\";\n            _ToolStripSeparator2.Size = new System.Drawing.Size(6, 25);\n            // \n            // _MainToolStrip\n            // \n            this._MainToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this._StoreButton,\n            this._ReloadButton,\n            this._ResetButton});\n            this._MainToolStrip.Location = new System.Drawing.Point(0, 0);\n            this._MainToolStrip.Name = \"_MainToolStrip\";\n            this._MainToolStrip.Size = new System.Drawing.Size(712, 25);\n            this._MainToolStrip.TabIndex = 1;\n            // \n            // _StoreButton\n            // \n            this._StoreButton.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;\n            this._StoreButton.Enabled = false;\n            this._StoreButton.Image = global::SAM.Game.Resources.Save;\n            this._StoreButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._StoreButton.Name = \"_StoreButton\";\n            this._StoreButton.Size = new System.Drawing.Size(120, 22);\n            this._StoreButton.Text = \"Commit Changes\";\n            this._StoreButton.ToolTipText = \"Store achievements and statistics for active game.\";\n            this._StoreButton.Click += new System.EventHandler(this.OnStore);\n            // \n            // _ReloadButton\n            // \n            this._ReloadButton.Enabled = false;\n            this._ReloadButton.Image = global::SAM.Game.Resources.Refresh;\n            this._ReloadButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._ReloadButton.Name = \"_ReloadButton\";\n            this._ReloadButton.Size = new System.Drawing.Size(66, 22);\n            this._ReloadButton.Text = \"Refresh\";\n            this._ReloadButton.ToolTipText = \"Refresh achievements and statistics for active game.\";\n            this._ReloadButton.Click += new System.EventHandler(this.OnRefresh);\n            // \n            // _ResetButton\n            // \n            this._ResetButton.Image = global::SAM.Game.Resources.Reset;\n            this._ResetButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._ResetButton.Name = \"_ResetButton\";\n            this._ResetButton.Size = new System.Drawing.Size(55, 22);\n            this._ResetButton.Text = \"Reset\";\n            this._ResetButton.ToolTipText = \"Reset achievements and/or statistics for active game.\";\n            this._ResetButton.Click += new System.EventHandler(this.OnResetAllStats);\n            // \n            // _AchievementImageList\n            // \n            this._AchievementImageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth24Bit;\n            this._AchievementImageList.ImageSize = new System.Drawing.Size(64, 64);\n            this._AchievementImageList.TransparentColor = System.Drawing.Color.Transparent;\n            // \n            // _MainStatusStrip\n            // \n            this._MainStatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this._CountryStatusLabel,\n            this._GameStatusLabel,\n            this._DownloadStatusLabel});\n            this._MainStatusStrip.Location = new System.Drawing.Point(0, 370);\n            this._MainStatusStrip.Name = \"_MainStatusStrip\";\n            this._MainStatusStrip.Size = new System.Drawing.Size(712, 22);\n            this._MainStatusStrip.TabIndex = 4;\n            // \n            // _CountryStatusLabel\n            // \n            this._CountryStatusLabel.Name = \"_CountryStatusLabel\";\n            this._CountryStatusLabel.Size = new System.Drawing.Size(0, 17);\n            // \n            // _GameStatusLabel\n            // \n            this._GameStatusLabel.Name = \"_GameStatusLabel\";\n            this._GameStatusLabel.Size = new System.Drawing.Size(555, 17);\n            this._GameStatusLabel.Spring = true;\n            this._GameStatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;\n            // \n            // _DownloadStatusLabel\n            // \n            this._DownloadStatusLabel.Image = global::SAM.Game.Resources.Download;\n            this._DownloadStatusLabel.Name = \"_DownloadStatusLabel\";\n            this._DownloadStatusLabel.Size = new System.Drawing.Size(111, 17);\n            this._DownloadStatusLabel.Text = \"Download status\";\n            this._DownloadStatusLabel.Visible = false;\n            // \n            // _CallbackTimer\n            // \n            this._CallbackTimer.Enabled = true;\n            this._CallbackTimer.Tick += new System.EventHandler(this.OnTimer);\n            // \n            // _MainTabControl\n            // \n            this._MainTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this._MainTabControl.Controls.Add(this._AchievementsTabPage);\n            this._MainTabControl.Controls.Add(this._StatisticsTabPage);\n            this._MainTabControl.Location = new System.Drawing.Point(8, 33);\n            this._MainTabControl.Name = \"_MainTabControl\";\n            this._MainTabControl.SelectedIndex = 0;\n            this._MainTabControl.Size = new System.Drawing.Size(696, 334);\n            this._MainTabControl.TabIndex = 5;\n            // \n            // _AchievementsTabPage\n            // \n            this._AchievementsTabPage.Controls.Add(this._AchievementListView);\n            this._AchievementsTabPage.Controls.Add(this._AchievementsToolStrip);\n            this._AchievementsTabPage.Location = new System.Drawing.Point(4, 22);\n            this._AchievementsTabPage.Name = \"_AchievementsTabPage\";\n            this._AchievementsTabPage.Padding = new System.Windows.Forms.Padding(3);\n            this._AchievementsTabPage.Size = new System.Drawing.Size(688, 308);\n            this._AchievementsTabPage.TabIndex = 0;\n            this._AchievementsTabPage.Text = \"Achievements\";\n            this._AchievementsTabPage.UseVisualStyleBackColor = true;\n            // \n            // _AchievementListView\n            // \n            this._AchievementListView.Activation = System.Windows.Forms.ItemActivation.OneClick;\n            this._AchievementListView.BackColor = System.Drawing.Color.Black;\n            this._AchievementListView.BackgroundImageTiled = true;\n            this._AchievementListView.CheckBoxes = true;\n            this._AchievementListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {\n            this._AchievementNameColumnHeader,\n            this._AchievementDescriptionColumnHeader,\n            this._AchievementUnlockTimeColumnHeader});\n            this._AchievementListView.Dock = System.Windows.Forms.DockStyle.Fill;\n            this._AchievementListView.ForeColor = System.Drawing.Color.White;\n            this._AchievementListView.FullRowSelect = true;\n            this._AchievementListView.GridLines = true;\n            this._AchievementListView.HideSelection = false;\n            this._AchievementListView.LargeImageList = this._AchievementImageList;\n            this._AchievementListView.Location = new System.Drawing.Point(3, 28);\n            this._AchievementListView.Name = \"_AchievementListView\";\n            this._AchievementListView.Size = new System.Drawing.Size(682, 277);\n            this._AchievementListView.SmallImageList = this._AchievementImageList;\n            this._AchievementListView.Sorting = System.Windows.Forms.SortOrder.Ascending;\n            this._AchievementListView.TabIndex = 4;\n            this._AchievementListView.UseCompatibleStateImageBehavior = false;\n            this._AchievementListView.View = System.Windows.Forms.View.Details;\n            this._AchievementListView.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.OnCheckAchievement);\n            // \n            // _AchievementNameColumnHeader\n            // \n            this._AchievementNameColumnHeader.Text = \"Name\";\n            this._AchievementNameColumnHeader.Width = 200;\n            // \n            // _AchievementDescriptionColumnHeader\n            // \n            this._AchievementDescriptionColumnHeader.Text = \"Description\";\n            this._AchievementDescriptionColumnHeader.Width = 300;\n            // \n            // _AchievementUnlockTimeColumnHeader\n            // \n            this._AchievementUnlockTimeColumnHeader.Text = \"Unlock Time\";\n            this._AchievementUnlockTimeColumnHeader.Width = 160;\n            // \n            // _AchievementsToolStrip\n            // \n            this._AchievementsToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this._LockAllButton,\n            this._InvertAllButton,\n            this._UnlockAllButton,\n            _ToolStripSeparator1,\n            this._DisplayLabel,\n            this._DisplayLockedOnlyButton,\n            this._DisplayUnlockedOnlyButton,\n            _ToolStripSeparator2,\n            this._MatchingStringLabel,\n            this._MatchingStringTextBox});\n            this._AchievementsToolStrip.Location = new System.Drawing.Point(3, 3);\n            this._AchievementsToolStrip.Name = \"_AchievementsToolStrip\";\n            this._AchievementsToolStrip.Size = new System.Drawing.Size(682, 25);\n            this._AchievementsToolStrip.TabIndex = 5;\n            // \n            // _LockAllButton\n            // \n            this._LockAllButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;\n            this._LockAllButton.Image = global::SAM.Game.Resources.Lock;\n            this._LockAllButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._LockAllButton.Name = \"_LockAllButton\";\n            this._LockAllButton.Size = new System.Drawing.Size(23, 22);\n            this._LockAllButton.Text = \"Lock All\";\n            this._LockAllButton.ToolTipText = \"Lock all achievements.\";\n            this._LockAllButton.Click += new System.EventHandler(this.OnLockAll);\n            // \n            // _InvertAllButton\n            // \n            this._InvertAllButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;\n            this._InvertAllButton.Image = global::SAM.Game.Resources.Invert;\n            this._InvertAllButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._InvertAllButton.Name = \"_InvertAllButton\";\n            this._InvertAllButton.Size = new System.Drawing.Size(23, 22);\n            this._InvertAllButton.Text = \"Invert All\";\n            this._InvertAllButton.ToolTipText = \"Invert all achievements.\";\n            this._InvertAllButton.Click += new System.EventHandler(this.OnInvertAll);\n            // \n            // _UnlockAllButton\n            // \n            this._UnlockAllButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;\n            this._UnlockAllButton.Image = global::SAM.Game.Resources.Unlock;\n            this._UnlockAllButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._UnlockAllButton.Name = \"_UnlockAllButton\";\n            this._UnlockAllButton.Size = new System.Drawing.Size(23, 22);\n            this._UnlockAllButton.Text = \"Unlock All\";\n            this._UnlockAllButton.ToolTipText = \"Unlock all achievements.\";\n            this._UnlockAllButton.Click += new System.EventHandler(this.OnUnlockAll);\n            // \n            // _DisplayLabel\n            // \n            this._DisplayLabel.Font = new System.Drawing.Font(\"Segoe UI\", 9F);\n            this._DisplayLabel.Name = \"_DisplayLabel\";\n            this._DisplayLabel.Size = new System.Drawing.Size(62, 22);\n            this._DisplayLabel.Text = \"Show only\";\n            // \n            // _DisplayLockedOnlyButton\n            // \n            this._DisplayLockedOnlyButton.CheckOnClick = true;\n            this._DisplayLockedOnlyButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;\n            this._DisplayLockedOnlyButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._DisplayLockedOnlyButton.Name = \"_DisplayLockedOnlyButton\";\n            this._DisplayLockedOnlyButton.Size = new System.Drawing.Size(46, 22);\n            this._DisplayLockedOnlyButton.Text = \"locked\";\n            this._DisplayLockedOnlyButton.Click += new System.EventHandler(this.OnDisplayCheckedOnly);\n            // \n            // _DisplayUnlockedOnlyButton\n            // \n            this._DisplayUnlockedOnlyButton.CheckOnClick = true;\n            this._DisplayUnlockedOnlyButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;\n            this._DisplayUnlockedOnlyButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._DisplayUnlockedOnlyButton.Name = \"_DisplayUnlockedOnlyButton\";\n            this._DisplayUnlockedOnlyButton.Size = new System.Drawing.Size(60, 22);\n            this._DisplayUnlockedOnlyButton.Text = \"unlocked\";\n            this._DisplayUnlockedOnlyButton.Click += new System.EventHandler(this.OnDisplayUncheckedOnly);\n            // \n            // _MatchingStringLabel\n            // \n            this._MatchingStringLabel.Font = new System.Drawing.Font(\"Segoe UI\", 9F);\n            this._MatchingStringLabel.Name = \"_MatchingStringLabel\";\n            this._MatchingStringLabel.Size = new System.Drawing.Size(33, 22);\n            this._MatchingStringLabel.Text = \"Filter\";\n            // \n            // _MatchingStringTextBox\n            // \n            this._MatchingStringTextBox.Font = new System.Drawing.Font(\"Segoe UI\", 9F);\n            this._MatchingStringTextBox.Name = \"_MatchingStringTextBox\";\n            this._MatchingStringTextBox.Size = new System.Drawing.Size(100, 25);\n            this._MatchingStringTextBox.ToolTipText = \"Type at least 3 characters that must appear in the name or description\";\n            this._MatchingStringTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnFilterUpdate);\n            // \n            // _StatisticsTabPage\n            // \n            this._StatisticsTabPage.Controls.Add(this._EnableStatsEditingCheckBox);\n            this._StatisticsTabPage.Controls.Add(this._StatisticsDataGridView);\n            this._StatisticsTabPage.Location = new System.Drawing.Point(4, 22);\n            this._StatisticsTabPage.Name = \"_StatisticsTabPage\";\n            this._StatisticsTabPage.Padding = new System.Windows.Forms.Padding(3);\n            this._StatisticsTabPage.Size = new System.Drawing.Size(688, 308);\n            this._StatisticsTabPage.TabIndex = 1;\n            this._StatisticsTabPage.Text = \"Statistics\";\n            this._StatisticsTabPage.UseVisualStyleBackColor = true;\n            // \n            // _EnableStatsEditingCheckBox\n            // \n            this._EnableStatsEditingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this._EnableStatsEditingCheckBox.AutoSize = true;\n            this._EnableStatsEditingCheckBox.Location = new System.Drawing.Point(6, 285);\n            this._EnableStatsEditingCheckBox.Name = \"_EnableStatsEditingCheckBox\";\n            this._EnableStatsEditingCheckBox.Size = new System.Drawing.Size(512, 17);\n            this._EnableStatsEditingCheckBox.TabIndex = 1;\n            this._EnableStatsEditingCheckBox.Text = \"I understand by modifying the values of stats, I may screw things up and can\\'t bl\" +\n    \"ame anyone but myself.\";\n            this._EnableStatsEditingCheckBox.UseVisualStyleBackColor = true;\n            this._EnableStatsEditingCheckBox.CheckedChanged += new System.EventHandler(this.OnStatAgreementChecked);\n            // \n            // _StatisticsDataGridView\n            // \n            this._StatisticsDataGridView.AllowUserToAddRows = false;\n            this._StatisticsDataGridView.AllowUserToDeleteRows = false;\n            this._StatisticsDataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this._StatisticsDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\n            this._StatisticsDataGridView.Location = new System.Drawing.Point(6, 6);\n            this._StatisticsDataGridView.Name = \"_StatisticsDataGridView\";\n            this._StatisticsDataGridView.Size = new System.Drawing.Size(596, 273);\n            this._StatisticsDataGridView.TabIndex = 0;\n            this._StatisticsDataGridView.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.OnStatCellEndEdit);\n            this._StatisticsDataGridView.DataError += new System.Windows.Forms.DataGridViewDataErrorEventHandler(this.OnStatDataError);\n            // \n            // Manager\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(712, 392);\n            this.Controls.Add(this._MainToolStrip);\n            this.Controls.Add(this._MainTabControl);\n            this.Controls.Add(this._MainStatusStrip);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.MinimumSize = new System.Drawing.Size(640, 50);\n            this.Name = \"Manager\";\n            this.Text = \"Steam Achievement Manager 7.0\";\n            this._MainToolStrip.ResumeLayout(false);\n            this._MainToolStrip.PerformLayout();\n            this._MainStatusStrip.ResumeLayout(false);\n            this._MainStatusStrip.PerformLayout();\n            this._MainTabControl.ResumeLayout(false);\n            this._AchievementsTabPage.ResumeLayout(false);\n            this._AchievementsTabPage.PerformLayout();\n            this._AchievementsToolStrip.ResumeLayout(false);\n            this._AchievementsToolStrip.PerformLayout();\n            this._StatisticsTabPage.ResumeLayout(false);\n            this._StatisticsTabPage.PerformLayout();\n            ((System.ComponentModel.ISupportInitialize)(this._StatisticsDataGridView)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.ToolStrip _MainToolStrip;\n        private System.Windows.Forms.ToolStripButton _StoreButton;\n        private System.Windows.Forms.ToolStripButton _ReloadButton;\n        private System.Windows.Forms.StatusStrip _MainStatusStrip;\n        private System.Windows.Forms.ToolStripStatusLabel _CountryStatusLabel;\n        private System.Windows.Forms.ToolStripStatusLabel _GameStatusLabel;\n        private System.Windows.Forms.ImageList _AchievementImageList;\n        private System.Windows.Forms.Timer _CallbackTimer;\n        private System.Windows.Forms.TabControl _MainTabControl;\n        private System.Windows.Forms.TabPage _AchievementsTabPage;\n        private System.Windows.Forms.TabPage _StatisticsTabPage;\n        private DoubleBufferedListView _AchievementListView;\n        private System.Windows.Forms.ColumnHeader _AchievementNameColumnHeader;\n        private System.Windows.Forms.ColumnHeader _AchievementDescriptionColumnHeader;\n        private System.Windows.Forms.ToolStrip _AchievementsToolStrip;\n        private System.Windows.Forms.ToolStripButton _LockAllButton;\n        private System.Windows.Forms.ToolStripButton _InvertAllButton;\n        private System.Windows.Forms.ToolStripButton _UnlockAllButton;\n        private System.Windows.Forms.DataGridView _StatisticsDataGridView;\n        private System.Windows.Forms.ToolStripButton _ResetButton;\n        private System.Windows.Forms.ToolStripStatusLabel _DownloadStatusLabel;\n        private System.Windows.Forms.ToolStripLabel _DisplayLabel;\n        private System.Windows.Forms.ToolStripButton _DisplayUnlockedOnlyButton;\n        private System.Windows.Forms.ToolStripButton _DisplayLockedOnlyButton;\n        private System.Windows.Forms.ToolStripLabel _MatchingStringLabel;\n        private System.Windows.Forms.ToolStripTextBox _MatchingStringTextBox;\n        private System.Windows.Forms.ColumnHeader _AchievementUnlockTimeColumnHeader;\n        private System.Windows.Forms.CheckBox _EnableStatsEditingCheckBox;\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Manager.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Net;\nusing System.Windows.Forms;\nusing static SAM.Game.InvariantShorthand;\nusing APITypes = SAM.API.Types;\n\nnamespace SAM.Game\n{\n    internal partial class Manager : Form\n    {\n        private readonly long _GameId;\n        private readonly API.Client _SteamClient;\n\n        private readonly WebClient _IconDownloader = new();\n\n        private readonly List<Stats.AchievementInfo> _IconQueue = new();\n        private readonly List<Stats.StatDefinition> _StatDefinitions = new();\n\n        private readonly List<Stats.AchievementDefinition> _AchievementDefinitions = new();\n\n        private readonly BindingList<Stats.StatInfo> _Statistics = new();\n\n        private readonly API.Callbacks.UserStatsReceived _UserStatsReceivedCallback;\n\n        //private API.Callback<APITypes.UserStatsStored> UserStatsStoredCallback;\n\n        public Manager(long gameId, API.Client client)\n        {\n            this.InitializeComponent();\n\n            this._MainTabControl.SelectedTab = this._AchievementsTabPage;\n            //this.statisticsList.Enabled = this.checkBox1.Checked;\n\n            this._AchievementImageList.Images.Add(\"Blank\", new Bitmap(64, 64));\n\n            this._StatisticsDataGridView.AutoGenerateColumns = false;\n\n            this._StatisticsDataGridView.Columns.Add(\"name\", \"Name\");\n            this._StatisticsDataGridView.Columns[0].ReadOnly = true;\n            this._StatisticsDataGridView.Columns[0].Width = 200;\n            this._StatisticsDataGridView.Columns[0].DataPropertyName = \"DisplayName\";\n\n            this._StatisticsDataGridView.Columns.Add(\"value\", \"Value\");\n            this._StatisticsDataGridView.Columns[1].ReadOnly = this._EnableStatsEditingCheckBox.Checked == false;\n            this._StatisticsDataGridView.Columns[1].Width = 90;\n            this._StatisticsDataGridView.Columns[1].DataPropertyName = \"Value\";\n\n            this._StatisticsDataGridView.Columns.Add(\"extra\", \"Extra\");\n            this._StatisticsDataGridView.Columns[2].ReadOnly = true;\n            this._StatisticsDataGridView.Columns[2].Width = 200;\n            this._StatisticsDataGridView.Columns[2].DataPropertyName = \"Extra\";\n\n            this._StatisticsDataGridView.DataSource = new BindingSource()\n            {\n                DataSource = this._Statistics,\n            };\n\n            this._GameId = gameId;\n            this._SteamClient = client;\n\n            this._IconDownloader.DownloadDataCompleted += this.OnIconDownload;\n\n            string name = this._SteamClient.SteamApps001.GetAppData((uint)this._GameId, \"name\");\n            if (name != null)\n            {\n                base.Text += \" | \" + name;\n            }\n            else\n            {\n                base.Text += \" | \" + this._GameId.ToString(CultureInfo.InvariantCulture);\n            }\n\n            this._UserStatsReceivedCallback = client.CreateAndRegisterCallback<API.Callbacks.UserStatsReceived>();\n            this._UserStatsReceivedCallback.OnRun += this.OnUserStatsReceived;\n\n            //this.UserStatsStoredCallback = new API.Callback(1102, new API.Callback.CallbackFunction(this.OnUserStatsStored));\n\n            this.RefreshStats();\n        }\n\n        private void AddAchievementIcon(Stats.AchievementInfo info, Image icon)\n        {\n            if (icon == null)\n            {\n                info.ImageIndex = 0;\n            }\n            else\n            {\n                info.ImageIndex = this._AchievementImageList.Images.Count;\n                this._AchievementImageList.Images.Add(info.IsAchieved == true ? info.IconNormal : info.IconLocked, icon);\n            }\n        }\n\n        private void OnIconDownload(object sender, DownloadDataCompletedEventArgs e)\n        {\n            if (e.Error == null && e.Cancelled == false)\n            {\n                var info = (Stats.AchievementInfo)e.UserState;\n\n                Bitmap bitmap;\n                try\n                {\n                    using (MemoryStream stream = new())\n                    {\n                        stream.Write(e.Result, 0, e.Result.Length);\n                        bitmap = new(stream);\n                    }\n                }\n                catch (Exception)\n                {\n                    bitmap = null;\n                }\n\n                this.AddAchievementIcon(info, bitmap);\n                this._AchievementListView.Update();\n            }\n\n            this.DownloadNextIcon();\n        }\n\n        private void DownloadNextIcon()\n        {\n            if (this._IconQueue.Count == 0)\n            {\n                this._DownloadStatusLabel.Visible = false;\n                return;\n            }\n\n            if (this._IconDownloader.IsBusy == true)\n            {\n                return;\n            }\n\n            this._DownloadStatusLabel.Text = $\"Downloading {this._IconQueue.Count} icons...\";\n            this._DownloadStatusLabel.Visible = true;\n\n            var info = this._IconQueue[0];\n            this._IconQueue.RemoveAt(0);\n\n\n            this._IconDownloader.DownloadDataAsync(\n                new Uri(_($\"https://cdn.steamstatic.com/steamcommunity/public/images/apps/{this._GameId}/{(info.IsAchieved == true ? info.IconNormal : info.IconLocked)}\")),\n                info);\n        }\n\n        private static string TranslateError(int id) => id switch\n        {\n            2 => \"generic error -- this usually means you don't own the game\",\n            _ => _($\"{id}\"),\n        };\n\n        private static string GetLocalizedString(KeyValue kv, string language, string defaultValue)\n        {\n            var name = kv[language].AsString(\"\");\n            if (string.IsNullOrEmpty(name) == false)\n            {\n                return name;\n            }\n\n            if (language != \"english\")\n            {\n                name = kv[\"english\"].AsString(\"\");\n                if (string.IsNullOrEmpty(name) == false)\n                {\n                    return name;\n                }\n            }\n\n            name = kv.AsString(\"\");\n            if (string.IsNullOrEmpty(name) == false)\n            {\n                return name;\n            }\n\n            return defaultValue;\n        }\n\n        private bool LoadUserGameStatsSchema()\n        {\n            string path;\n            try\n            {\n                string fileName = _($\"UserGameStatsSchema_{this._GameId}.bin\");\n                path = API.Steam.GetInstallPath();\n                path = Path.Combine(path, \"appcache\", \"stats\", fileName);\n                if (File.Exists(path) == false)\n                {\n                    return false;\n                }\n            }\n            catch (Exception e)\n            {\n                return false;\n            }\n\n            var kv = KeyValue.LoadAsBinary(path);\n            if (kv == null)\n            {\n                return false;\n            }\n\n            var currentLanguage = this._SteamClient.SteamApps008.GetCurrentGameLanguage();\n\n            this._AchievementDefinitions.Clear();\n            this._StatDefinitions.Clear();\n\n            var stats = kv[this._GameId.ToString(CultureInfo.InvariantCulture)][\"stats\"];\n            if (stats.Valid == false || stats.Children == null)\n            {\n                return false;\n            }\n\n            foreach (var stat in stats.Children)\n            {\n                if (stat.Valid == false)\n                {\n                    continue;\n                }\n\n                APITypes.UserStatType type;\n\n                // schema in the new format?\n                var typeNode = stat[\"type\"];\n                if (typeNode.Valid == true && typeNode.Type == KeyValueType.String)\n                {\n                    if (Enum.TryParse((string)typeNode.Value, true, out type) == false)\n                    {\n                        type = APITypes.UserStatType.Invalid;\n                    }\n                }\n                else\n                {\n                    type = APITypes.UserStatType.Invalid;\n                }\n\n                // schema in the old format?\n                if (type == APITypes.UserStatType.Invalid)\n                {\n                    var typeIntNode = stat[\"type_int\"];\n                    var rawType = typeIntNode.Valid == true\n                        ? typeIntNode.AsInteger(0)\n                        : typeNode.AsInteger(0);\n                    type = (APITypes.UserStatType)rawType;\n                }\n\n                switch (type)\n                {\n                    case APITypes.UserStatType.Invalid:\n                    {\n                        break;\n                    }\n\n                    case APITypes.UserStatType.Integer:\n                    {\n                        var id = stat[\"name\"].AsString(\"\");\n                        string name = GetLocalizedString(stat[\"display\"][\"name\"], currentLanguage, id);\n\n                        this._StatDefinitions.Add(new Stats.IntegerStatDefinition()\n                        {\n                            Id = stat[\"name\"].AsString(\"\"),\n                            DisplayName = name,\n                            MinValue = stat[\"min\"].AsInteger(int.MinValue),\n                            MaxValue = stat[\"max\"].AsInteger(int.MaxValue),\n                            MaxChange = stat[\"maxchange\"].AsInteger(0),\n                            IncrementOnly = stat[\"incrementonly\"].AsBoolean(false),\n                            SetByTrustedGameServer = stat[\"bSetByTrustedGS\"].AsBoolean(false),\n                            DefaultValue = stat[\"default\"].AsInteger(0),\n                            Permission = stat[\"permission\"].AsInteger(0),\n                        });\n                        break;\n                    }\n\n                    case APITypes.UserStatType.Float:\n                    case APITypes.UserStatType.AverageRate:\n                    {\n                        var id = stat[\"name\"].AsString(\"\");\n                        string name = GetLocalizedString(stat[\"display\"][\"name\"], currentLanguage, id);\n\n                        this._StatDefinitions.Add(new Stats.FloatStatDefinition()\n                        {\n                            Id = stat[\"name\"].AsString(\"\"),\n                            DisplayName = name,\n                            MinValue = stat[\"min\"].AsFloat(float.MinValue),\n                            MaxValue = stat[\"max\"].AsFloat(float.MaxValue),\n                            MaxChange = stat[\"maxchange\"].AsFloat(0.0f),\n                            IncrementOnly = stat[\"incrementonly\"].AsBoolean(false),\n                            DefaultValue = stat[\"default\"].AsFloat(0.0f),\n                            Permission = stat[\"permission\"].AsInteger(0),\n                        });\n                        break;\n                    }\n\n                    case APITypes.UserStatType.Achievements:\n                    case APITypes.UserStatType.GroupAchievements:\n                    {\n                        if (stat.Children != null)\n                        {\n                            foreach (var bits in stat.Children.Where(\n                                b => string.Compare(b.Name, \"bits\", StringComparison.InvariantCultureIgnoreCase) == 0))\n                            {\n                                if (bits.Valid == false || bits.Children == null)\n                                {\n                                    continue;\n                                }\n\n                                foreach (var bit in bits.Children)\n                                {\n                                    string id = bit[\"name\"].AsString(\"\");\n                                    string name = GetLocalizedString(bit[\"display\"][\"name\"], currentLanguage, id);\n                                    string desc = GetLocalizedString(bit[\"display\"][\"desc\"], currentLanguage, \"\");\n\n                                    this._AchievementDefinitions.Add(new()\n                                    {\n                                        Id = id,\n                                        Name = name,\n                                        Description = desc,\n                                        IconNormal = bit[\"display\"][\"icon\"].AsString(\"\"),\n                                        IconLocked = bit[\"display\"][\"icon_gray\"].AsString(\"\"),\n                                        IsHidden = bit[\"display\"][\"hidden\"].AsBoolean(false),\n                                        Permission = bit[\"permission\"].AsInteger(0),\n                                    });\n                                }\n                            }\n                        }\n\n                        break;\n                    }\n\n                    default:\n                    {\n                        throw new InvalidOperationException(\"invalid stat type\");\n                    }\n                }\n            }\n\n            return true;\n        }\n\n        private void OnUserStatsReceived(APITypes.UserStatsReceived param)\n        {\n            if (param.Result != 1)\n            {\n                this._GameStatusLabel.Text = $\"Error while retrieving stats: {TranslateError(param.Result)}\";\n                this.EnableInput();\n                return;\n            }\n\n            if (this.LoadUserGameStatsSchema() == false)\n            {\n                this._GameStatusLabel.Text = \"Failed to load schema.\";\n                this.EnableInput();\n                return;\n            }\n\n            try\n            {\n                this.GetAchievements();\n            }\n            catch (Exception e)\n            {\n                this._GameStatusLabel.Text = \"Error when handling achievements retrieval.\";\n                this.EnableInput();\n                MessageBox.Show(\n                    \"Error when handling achievements retrieval:\\n\" + e,\n                    \"Error\",\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Error);\n                return;\n            }\n\n            try\n            {\n                this.GetStatistics();\n            }\n            catch (Exception e)\n            {\n                this._GameStatusLabel.Text = \"Error when handling stats retrieval.\";\n                this.EnableInput();\n                MessageBox.Show(\n                    \"Error when handling stats retrieval:\\n\" + e,\n                    \"Error\",\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Error);\n                return;\n            }\n\n            this._GameStatusLabel.Text = $\"Retrieved {this._AchievementListView.Items.Count} achievements and {this._StatisticsDataGridView.Rows.Count} statistics.\";\n            this.EnableInput();\n        }\n\n        private void RefreshStats()\n        {\n            this._AchievementListView.Items.Clear();\n            this._StatisticsDataGridView.Rows.Clear();\n\n            var steamId = this._SteamClient.SteamUser.GetSteamId();\n\n            // This still triggers the UserStatsReceived callback, in addition to the callresult.\n            // No need to implement callresults for the time being.\n            var callHandle = this._SteamClient.SteamUserStats.RequestUserStats(steamId);\n            if (callHandle == API.CallHandle.Invalid)\n            {\n                MessageBox.Show(this, \"Failed.\", \"Error\", MessageBoxButtons.OK, MessageBoxIcon.Error);\n                return;\n            }\n\n            this._GameStatusLabel.Text = \"Retrieving stat information...\";\n            this.DisableInput();\n        }\n\n        private bool _IsUpdatingAchievementList;\n\n        private void GetAchievements()\n        {\n            var textSearch = this._MatchingStringTextBox.Text.Length > 0\n                ? this._MatchingStringTextBox.Text\n                : null;\n\n            this._IsUpdatingAchievementList = true;\n\n            this._AchievementListView.Items.Clear();\n            this._AchievementListView.BeginUpdate();\n            //this.Achievements.Clear();\n\n            bool wantLocked = this._DisplayLockedOnlyButton.Checked == true;\n            bool wantUnlocked = this._DisplayUnlockedOnlyButton.Checked == true;\n\n            foreach (var def in this._AchievementDefinitions)\n            {\n                if (string.IsNullOrEmpty(def.Id) == true)\n                {\n                    continue;\n                }\n\n                if (this._SteamClient.SteamUserStats.GetAchievementAndUnlockTime(\n                    def.Id,\n                    out bool isAchieved,\n                    out var unlockTime) == false)\n                {\n                    continue;\n                }\n\n                bool wanted = (wantLocked == false && wantUnlocked == false) || isAchieved switch\n                {\n                    true => wantUnlocked,\n                    false => wantLocked,\n                };\n                if (wanted == false)\n                {\n                    continue;\n                }\n\n                if (textSearch != null)\n                {\n                    if (def.Name.IndexOf(textSearch, StringComparison.OrdinalIgnoreCase) < 0 &&\n                        def.Description.IndexOf(textSearch, StringComparison.OrdinalIgnoreCase) < 0)\n                    {\n                        continue;\n                    }\n                }\n\n                Stats.AchievementInfo info = new()\n                {\n                    Id = def.Id,\n                    IsAchieved = isAchieved,\n                    UnlockTime = isAchieved == true && unlockTime > 0\n                        ? DateTimeOffset.FromUnixTimeSeconds(unlockTime).LocalDateTime\n                        : null,\n                    IconNormal = string.IsNullOrEmpty(def.IconNormal) ? null : def.IconNormal,\n                    IconLocked = string.IsNullOrEmpty(def.IconLocked) ? def.IconNormal : def.IconLocked,\n                    Permission = def.Permission,\n                    Name = def.Name,\n                    Description = def.Description,\n                };\n\n                ListViewItem item = new()\n                {\n                    Checked = isAchieved,\n                    Tag = info,\n                    Text = info.Name,\n                    BackColor = (def.Permission & 3) == 0 ? Color.Black : Color.FromArgb(64, 0, 0),\n                };\n\n                info.Item = item;\n\n                if (item.Text.StartsWith(\"#\", StringComparison.InvariantCulture) == true)\n                {\n                    item.Text = info.Id;\n                    item.SubItems.Add(\"\");\n                }\n                else\n                {\n                    item.SubItems.Add(info.Description);\n                }\n\n                item.SubItems.Add(info.UnlockTime.HasValue == true\n                    ? info.UnlockTime.Value.ToString()\n                    : \"\");\n\n                info.ImageIndex = 0;\n\n                this.AddAchievementToIconQueue(info, false);\n                this._AchievementListView.Items.Add(item);\n            }\n\n            this._AchievementListView.EndUpdate();\n            this._IsUpdatingAchievementList = false;\n\n            this.DownloadNextIcon();\n        }\n\n        private void GetStatistics()\n        {\n            this._Statistics.Clear();\n            foreach (var stat in this._StatDefinitions)\n            {\n                if (string.IsNullOrEmpty(stat.Id) == true)\n                {\n                    continue;\n                }\n\n                if (stat is Stats.IntegerStatDefinition intStat)\n                {\n                    if (this._SteamClient.SteamUserStats.GetStatValue(intStat.Id, out int value) == false)\n                    {\n                        continue;\n                    }\n                    this._Statistics.Add(new Stats.IntStatInfo()\n                    {\n                        Id = intStat.Id,\n                        DisplayName = intStat.DisplayName,\n                        IntValue = value,\n                        OriginalValue = value,\n                        IsIncrementOnly = intStat.IncrementOnly,\n                        Permission = intStat.Permission,\n                    });\n                }\n                else if (stat is Stats.FloatStatDefinition floatStat)\n                {\n                    if (this._SteamClient.SteamUserStats.GetStatValue(floatStat.Id, out float value) == false)\n                    {\n                        continue;\n                    }\n                    this._Statistics.Add(new Stats.FloatStatInfo()\n                    {\n                        Id = floatStat.Id,\n                        DisplayName = floatStat.DisplayName,\n                        FloatValue = value,\n                        OriginalValue = value,\n                        IsIncrementOnly = floatStat.IncrementOnly,\n                        Permission = floatStat.Permission,\n                    });\n                }\n            }\n        }\n\n        private void AddAchievementToIconQueue(Stats.AchievementInfo info, bool startDownload)\n        {\n            int imageIndex = this._AchievementImageList.Images.IndexOfKey(\n                info.IsAchieved == true ? info.IconNormal : info.IconLocked);\n\n            if (imageIndex >= 0)\n            {\n                info.ImageIndex = imageIndex;\n            }\n            else\n            {\n                this._IconQueue.Add(info);\n\n                if (startDownload == true)\n                {\n                    this.DownloadNextIcon();\n                }\n            }\n        }\n\n        private int StoreAchievements()\n        {\n            if (this._AchievementListView.Items.Count == 0)\n            {\n                return 0;\n            }\n\n            List<Stats.AchievementInfo> achievements = new();\n            foreach (ListViewItem item in this._AchievementListView.Items)\n            {\n                if (item.Tag is not Stats.AchievementInfo achievementInfo ||\n                    achievementInfo.IsAchieved == item.Checked)\n                {\n                    continue;\n                }\n\n                achievementInfo.IsAchieved = item.Checked;\n                achievements.Add(achievementInfo);\n            }\n\n            if (achievements.Count == 0)\n            {\n                return 0;\n            }\n\n            foreach (var info in achievements)\n            {\n                if (this._SteamClient.SteamUserStats.SetAchievement(info.Id, info.IsAchieved) == false)\n                {\n                    MessageBox.Show(\n                        this,\n                        $\"An error occurred while setting the state for {info.Id}, aborting store.\",\n                        \"Error\",\n                        MessageBoxButtons.OK,\n                        MessageBoxIcon.Error);\n                    return -1;\n                }\n            }\n\n            return achievements.Count;\n        }\n\n        private int StoreStatistics()\n        {\n            if (this._Statistics.Count == 0)\n            {\n                return 0;\n            }\n\n            var statistics = this._Statistics.Where(stat => stat.IsModified == true).ToList();\n            if (statistics.Count == 0)\n            {\n                return 0;\n            }\n\n            foreach (var stat in statistics)\n            {\n                if (stat is Stats.IntStatInfo intStat)\n                {\n                    if (this._SteamClient.SteamUserStats.SetStatValue(\n                        intStat.Id,\n                        intStat.IntValue) == false)\n                    {\n                        MessageBox.Show(\n                            this,\n                            $\"An error occurred while setting the value for {stat.Id}, aborting store.\",\n                            \"Error\",\n                            MessageBoxButtons.OK,\n                            MessageBoxIcon.Error);\n                        return -1;\n                    }\n                }\n                else if (stat is Stats.FloatStatInfo floatStat)\n                {\n                    if (this._SteamClient.SteamUserStats.SetStatValue(\n                        floatStat.Id,\n                        floatStat.FloatValue) == false)\n                    {\n                        MessageBox.Show(\n                            this,\n                            $\"An error occurred while setting the value for {stat.Id}, aborting store.\",\n                            \"Error\",\n                            MessageBoxButtons.OK,\n                            MessageBoxIcon.Error);\n                        return -1;\n                    }\n                }\n                else\n                {\n                    throw new InvalidOperationException(\"unsupported stat type\");\n                }\n            }\n\n            return statistics.Count;\n        }\n\n        private void DisableInput()\n        {\n            this._ReloadButton.Enabled = false;\n            this._StoreButton.Enabled = false;\n        }\n\n        private void EnableInput()\n        {\n            this._ReloadButton.Enabled = true;\n            this._StoreButton.Enabled = true;\n        }\n\n        private void OnTimer(object sender, EventArgs e)\n        {\n            this._CallbackTimer.Enabled = false;\n            this._SteamClient.RunCallbacks(false);\n            this._CallbackTimer.Enabled = true;\n        }\n\n        private void OnRefresh(object sender, EventArgs e)\n        {\n            this.RefreshStats();\n        }\n\n        private void OnLockAll(object sender, EventArgs e)\n        {\n            foreach (ListViewItem item in this._AchievementListView.Items)\n            {\n                item.Checked = false;\n            }\n        }\n\n        private void OnInvertAll(object sender, EventArgs e)\n        {\n            foreach (ListViewItem item in this._AchievementListView.Items)\n            {\n                item.Checked = !item.Checked;\n            }\n        }\n\n        private void OnUnlockAll(object sender, EventArgs e)\n        {\n            foreach (ListViewItem item in this._AchievementListView.Items)\n            {\n                item.Checked = true;\n            }\n        }\n\n        private bool Store()\n        {\n            if (this._SteamClient.SteamUserStats.StoreStats() == false)\n            {\n                MessageBox.Show(\n                    this,\n                    \"An error occurred while storing, aborting.\",\n                    \"Error\",\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Error);\n                return false;\n            }\n\n            return true;\n        }\n\n        private void OnStore(object sender, EventArgs e)\n        {\n            int achievements = this.StoreAchievements();\n            if (achievements < 0)\n            {\n                this.RefreshStats();\n                return;\n            }\n\n            int stats = this.StoreStatistics();\n            if (stats < 0)\n            {\n                this.RefreshStats();\n                return;\n            }\n\n            if (this.Store() == false)\n            {\n                this.RefreshStats();\n                return;\n            }\n\n            MessageBox.Show(\n                this,\n                $\"Stored {achievements} achievements and {stats} statistics.\",\n                \"Information\",\n                MessageBoxButtons.OK,\n                MessageBoxIcon.Information);\n            this.RefreshStats();\n        }\n\n        private void OnStatDataError(object sender, DataGridViewDataErrorEventArgs e)\n        {\n            if (e.Context != DataGridViewDataErrorContexts.Commit)\n            {\n                return;\n            }\n\n            var view = (DataGridView)sender;\n            if (e.Exception is Stats.StatIsProtectedException)\n            {\n                e.ThrowException = false;\n                e.Cancel = true;\n                view.Rows[e.RowIndex].ErrorText = \"Stat is protected! -- you can't modify it\";\n            }\n            else\n            {\n                e.ThrowException = false;\n                e.Cancel = true;\n                view.Rows[e.RowIndex].ErrorText = \"Invalid value\";\n            }\n        }\n\n        private void OnStatAgreementChecked(object sender, EventArgs e)\n        {\n            this._StatisticsDataGridView.Columns[1].ReadOnly = this._EnableStatsEditingCheckBox.Checked == false;\n        }\n\n        private void OnStatCellEndEdit(object sender, DataGridViewCellEventArgs e)\n        {\n            var view = (DataGridView)sender;\n            view.Rows[e.RowIndex].ErrorText = \"\";\n        }\n\n        private void OnResetAllStats(object sender, EventArgs e)\n        {\n            if (MessageBox.Show(\n                \"Are you absolutely sure you want to reset stats?\",\n                \"Warning\",\n                MessageBoxButtons.YesNo,\n                MessageBoxIcon.Warning) == DialogResult.No)\n            {\n                return;\n            }\n\n            bool achievementsToo = DialogResult.Yes == MessageBox.Show(\n                \"Do you want to reset achievements too?\",\n                \"Question\",\n                MessageBoxButtons.YesNo,\n                MessageBoxIcon.Question);\n\n            if (MessageBox.Show(\n                \"Really really sure?\",\n                \"Warning\",\n                MessageBoxButtons.YesNo,\n                MessageBoxIcon.Error) == DialogResult.No)\n            {\n                return;\n            }\n\n            if (this._SteamClient.SteamUserStats.ResetAllStats(achievementsToo) == false)\n            {\n                MessageBox.Show(this, \"Failed.\", \"Error\", MessageBoxButtons.OK, MessageBoxIcon.Error);\n                return;\n            }\n\n            this.RefreshStats();\n        }\n\n        private void OnCheckAchievement(object sender, ItemCheckEventArgs e)\n        {\n            if (sender != this._AchievementListView)\n            {\n                return;\n            }\n\n            if (this._IsUpdatingAchievementList == true)\n            {\n                return;\n            }\n\n            if (this._AchievementListView.Items[e.Index].Tag is not Stats.AchievementInfo info)\n            {\n                return;\n            }\n\n            if ((info.Permission & 3) != 0)\n            {\n                MessageBox.Show(\n                    this,\n                    \"Sorry, but this is a protected achievement and cannot be managed with Steam Achievement Manager.\",\n                    \"Error\",\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Error);\n                e.NewValue = e.CurrentValue;\n            }\n        }\n\n        private void OnDisplayUncheckedOnly(object sender, EventArgs e)\n        {\n            if ((sender as ToolStripButton).Checked == true)\n            {\n                this._DisplayLockedOnlyButton.Checked = false;\n            }\n\n            this.GetAchievements();\n        }\n\n        private void OnDisplayCheckedOnly(object sender, EventArgs e)\n        {\n            if ((sender as ToolStripButton).Checked == true)\n            {\n                this._DisplayUnlockedOnlyButton.Checked = false;\n            }\n\n            this.GetAchievements();\n        }\n\n        private void OnFilterUpdate(object sender, KeyEventArgs e)\n        {\n            this.GetAchievements();\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Manager.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"_ToolStripSeparator1.GenerateMember\" type=\"System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>False</value>\n  </metadata>\n  <metadata name=\"_ToolStripSeparator2.GenerateMember\" type=\"System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>False</value>\n  </metadata>\n  <metadata name=\"_MainToolStrip.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <metadata name=\"_AchievementImageList.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>352, 20</value>\n  </metadata>\n  <metadata name=\"_MainStatusStrip.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>230, 17</value>\n  </metadata>\n  <metadata name=\"_CallbackTimer.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>502, 20</value>\n  </metadata>\n  <metadata name=\"_AchievementsToolStrip.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>628, 20</value>\n  </metadata>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AADAgP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAA\n</value>\n  </data>\n</root>"
  },
  {
    "path": "SAM.Game/Program.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Diagnostics;\nusing System.Windows.Forms;\n\nnamespace SAM.Game\n{\n    internal static class Program\n    {\n        [STAThread]\n        public static void Main(string[] args)\n        {\n            long appId;\n\n            if (args.Length == 0)\n            {\n                Process.Start(\"SAM.Picker.exe\");\n                return;\n            }\n\n            if (long.TryParse(args[0], out appId) == false)\n            {\n                MessageBox.Show(\n                    \"Could not parse application ID from command line argument.\",\n                    \"Error\",\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Error);\n                return;\n            }\n\n            if (API.Steam.GetInstallPath() == Application.StartupPath)\n            {\n                MessageBox.Show(\n                    \"This tool declines to being run from the Steam directory.\",\n                    \"Error\",\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Error);\n                return;\n            }\n\n            using (API.Client client = new())\n            {\n                try\n                {\n                    client.Initialize(appId);\n                }\n                catch (API.ClientInitializeException e)\n                {\n                    if (e.Failure == API.ClientInitializeFailure.ConnectToGlobalUser)\n                    {\n                        MessageBox.Show(\n                            \"Steam is not running. Please start Steam then run this tool again.\\n\\n\" +\n                            \"If you have the game through Family Share, the game may be locked due to\\n\" +\n                            \"the Family Share account actively playing a game.\\n\\n\" +\n                            \"(\" + e.Message + \")\",\n                            \"Error\",\n                            MessageBoxButtons.OK,\n                            MessageBoxIcon.Error);\n                    }\n                    else if (string.IsNullOrEmpty(e.Message) == false)\n                    {\n                        MessageBox.Show(\n                            \"Steam is not running. Please start Steam then run this tool again.\\n\\n\" +\n                            \"(\" + e.Message + \")\",\n                            \"Error\",\n                            MessageBoxButtons.OK,\n                            MessageBoxIcon.Error);\n                    }\n                    else\n                    {\n                        MessageBox.Show(\n                            \"Steam is not running. Please start Steam then run this tool again.\",\n                            \"Error\",\n                            MessageBoxButtons.OK,\n                            MessageBoxIcon.Error);\n                    }\n                    return;\n                }\n                catch (DllNotFoundException)\n                {\n                    MessageBox.Show(\n                        \"You've caused an exceptional error!\",\n                        \"Error\",\n                        MessageBoxButtons.OK,\n                        MessageBoxIcon.Error);\n                    return;\n                }\n\n                Application.EnableVisualStyles();\n                Application.SetCompatibleTextRenderingDefault(false);\n                Application.Run(new Manager(appId, client));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace SAM.Game {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"SAM.Game.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Download {\n            get {\n                object obj = ResourceManager.GetObject(\"Download\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Invert {\n            get {\n                object obj = ResourceManager.GetObject(\"Invert\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Lock {\n            get {\n                object obj = ResourceManager.GetObject(\"Lock\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Refresh {\n            get {\n                object obj = ResourceManager.GetObject(\"Refresh\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Reset {\n            get {\n                object obj = ResourceManager.GetObject(\"Reset\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Sad {\n            get {\n                object obj = ResourceManager.GetObject(\"Sad\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Save {\n            get {\n                object obj = ResourceManager.GetObject(\"Save\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Unlock {\n            get {\n                object obj = ResourceManager.GetObject(\"Unlock\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"Lock\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\lock.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Refresh\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\arrow-circle-double.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Unlock\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\lock-unlock.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Reset\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\bomb.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Invert\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\lock--pencil.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Save\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\transmitter.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Sad\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\poop-smiley-sad-enlarged.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Download\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\download-cloud.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n</root>"
  },
  {
    "path": "SAM.Game/SAM.Game.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <AssemblyTitle>Steam Achievement Manager</AssemblyTitle>\n    <Company>Gibbed</Company>\n    <Authors>Gibbed</Authors>\n    <Description>A manager for game achievements in Steam.</Description>\n    <Copyright>Copyright © Gibbed 2019</Copyright>\n  </PropertyGroup>\n  <PropertyGroup>\n    <Version>7.0.0</Version>\n    <AssemblyVersion>7.0.0.0</AssemblyVersion>\n    <FileVersion>7.0.0.0</FileVersion>\n  </PropertyGroup>\n  <PropertyGroup>\n    <ApplicationIcon>Blank.ico</ApplicationIcon>\n    <ApplicationManifest>app.manifest</ApplicationManifest>\n  </PropertyGroup>\n  <PropertyGroup>\n    <RepositoryUrl>https://github.com/gibbed/SteamAchievementManager/</RepositoryUrl>\n    <RepositoryType>Git</RepositoryType>\n  </PropertyGroup>\n  <PropertyGroup>\n    <OutputType>WinExe</OutputType>\n    <TargetFramework>net48</TargetFramework>\n    <LangVersion>9.0</LangVersion>\n    <Platforms>x86</Platforms>\n    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|x86' \">\n    <OutputPath>..\\bin\\</OutputPath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|x86' \">\n    <OutputPath>..\\upload\\</OutputPath>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System.Windows.Forms\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Update=\"DoubleBufferedListView.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Update=\"Manager.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Update=\"Resources.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Resources.resx</DependentUpon>\n      <DesignTime>True</DesignTime>\n    </Compile>\n    <EmbeddedResource Update=\"Resources.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\n    </EmbeddedResource>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\SAM.API\\SAM.API.csproj\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "SAM.Game/SAM.Game.csproj.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:String x:Key=\"/Default/CodeEditing/Localization/Localizable/@EntryValue\">No</s:String></wpf:ResourceDictionary>"
  },
  {
    "path": "SAM.Game/Stats/AchievementDefinition.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.Game.Stats\n{\n    internal class AchievementDefinition\n    {\n        public string Id;\n        public string Name;\n        public string Description;\n        public string IconNormal;\n        public string IconLocked;\n        public bool IsHidden;\n        public int Permission;\n\n        public override string ToString()\n        {\n            return $\"{this.Name ?? this.Id ?? base.ToString()}: {this.Permission}\";\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Stats/AchievementInfo.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Windows.Forms;\n\nnamespace SAM.Game.Stats\n{\n    internal class AchievementInfo\n    {\n        public string Id;\n        public bool IsAchieved;\n        public DateTime? UnlockTime;\n        public int Permission;\n        public string IconNormal;\n        public string IconLocked;\n        public string Name;\n        public string Description;\n        public ListViewItem Item;\n\n        #region public int ImageIndex;\n        public int ImageIndex\n        {\n            get => this.Item.ImageIndex;\n            set => this.Item.ImageIndex = value;\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Stats/FloatStatDefinition.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.Game.Stats\n{\n    internal class FloatStatDefinition : StatDefinition\n    {\n        public float MinValue;\n        public float MaxValue;\n        public float MaxChange;\n        public bool IncrementOnly;\n        public float DefaultValue;\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Stats/FloatStatInfo.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.Game.Stats\n{\n    internal class FloatStatInfo : StatInfo\n    {\n        public float OriginalValue;\n        public float FloatValue;\n\n        public override object Value\n        {\n            get => this.FloatValue;\n            set\n            {\n                var f = float.Parse((string)value, System.Globalization.CultureInfo.CurrentCulture);\n                if ((this.Permission & 2) != 0 &&\n                    this.FloatValue.Equals(f) == false)\n                {\n                    throw new StatIsProtectedException();\n                }\n                this.FloatValue = f;\n            }\n        }\n\n        public override bool IsModified => this.FloatValue.Equals(this.OriginalValue) == false;\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Stats/IntStatInfo.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.Game.Stats\n{\n    internal class IntStatInfo : StatInfo\n    {\n        public int OriginalValue;\n        public int IntValue;\n\n        public override object Value\n        {\n            get => this.IntValue;\n            set\n            {\n                var i = int.Parse((string)value, System.Globalization.CultureInfo.CurrentCulture);\n                if ((this.Permission & 2) != 0 &&\n                    this.IntValue != i)\n                {\n                    throw new StatIsProtectedException();\n                }\n                this.IntValue = i;\n            }\n        }\n\n        public override bool IsModified => this.IntValue != this.OriginalValue;\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Stats/IntegerStatDefinition.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.Game.Stats\n{\n    internal class IntegerStatDefinition : StatDefinition\n    {\n        public int MinValue;\n        public int MaxValue;\n        public int MaxChange;\n        public bool IncrementOnly;\n        public bool SetByTrustedGameServer;\n        public int DefaultValue;\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Stats/StatDefinition.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.Game.Stats\n{\n    internal abstract class StatDefinition\n    {\n        public string Id;\n        public string DisplayName;\n        public int Permission;\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Stats/StatFlags.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\n\nnamespace SAM.Game.Stats\n{\n    [Flags]\n    internal enum StatFlags\n    {\n        None = 0,\n        IncrementOnly = 1 << 0,\n        Protected = 1 << 1,\n        UnknownPermission = 1 << 2,\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Stats/StatInfo.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nnamespace SAM.Game.Stats\n{\n    internal abstract class StatInfo\n    {\n        public abstract bool IsModified { get; }\n        public string Id { get; set; }\n        public string DisplayName { get; set; }\n        public abstract object Value { get; set; }\n        public bool IsIncrementOnly { get; set; }\n        public int Permission { get; set; }\n\n        public string Extra\n        {\n            get\n            {\n                var flags = StatFlags.None;\n                flags |= this.IsIncrementOnly == false ? 0 : StatFlags.IncrementOnly;\n                flags |= ((this.Permission & 2) != 0) == false ? 0 : StatFlags.Protected;\n                flags |= ((this.Permission & ~2) != 0) == false ? 0 : StatFlags.UnknownPermission;\n                return flags.ToString();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Game/Stats/StatIsProtectedException.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.Serialization;\n\nnamespace SAM.Game.Stats\n{\n    [Serializable]\n    internal class StatIsProtectedException : Exception\n    {\n        public StatIsProtectedException()\n        {\n        }\n\n        public StatIsProtectedException(string message)\n            : base(message)\n        {\n        }\n\n        public StatIsProtectedException(string message, Exception innerException)\n            : base(message, innerException)\n        {\n        }\n\n        protected StatIsProtectedException(SerializationInfo info, StreamingContext context)\n            : base(info, context)\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Game/StreamHelpers.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.IO;\nusing System.Text;\n\nnamespace SAM.Game\n{\n    internal static class StreamHelpers\n    {\n        public static byte ReadValueU8(this Stream stream)\n        {\n            return (byte)stream.ReadByte();\n        }\n\n        public static int ReadValueS32(this Stream stream)\n        {\n            var data = new byte[4];\n            int read = stream.Read(data, 0, 4);\n            Debug.Assert(read == 4);\n            return BitConverter.ToInt32(data, 0);\n        }\n\n        public static uint ReadValueU32(this Stream stream)\n        {\n            var data = new byte[4];\n            int read = stream.Read(data, 0, 4);\n            Debug.Assert(read == 4);\n            return BitConverter.ToUInt32(data, 0);\n        }\n\n        public static ulong ReadValueU64(this Stream stream)\n        {\n            var data = new byte[8];\n            int read = stream.Read(data, 0, 8);\n            Debug.Assert(read == 8);\n            return BitConverter.ToUInt64(data, 0);\n        }\n\n        public static float ReadValueF32(this Stream stream)\n        {\n            var data = new byte[4];\n            int read = stream.Read(data, 0, 4);\n            Debug.Assert(read == 4);\n            return BitConverter.ToSingle(data, 0);\n        }\n\n        internal static string ReadStringInternalDynamic(this Stream stream, Encoding encoding, char end)\n        {\n            int characterSize = encoding.GetByteCount(\"e\");\n            Debug.Assert(characterSize == 1 || characterSize == 2 || characterSize == 4);\n            string characterEnd = end.ToString(CultureInfo.InvariantCulture);\n\n            int i = 0;\n            var data = new byte[128 * characterSize];\n\n            while (true)\n            {\n                if (i + characterSize > data.Length)\n                {\n                    Array.Resize(ref data, data.Length + (128 * characterSize));\n                }\n\n                int read = stream.Read(data, i, characterSize);\n                Debug.Assert(read == characterSize);\n\n                if (encoding.GetString(data, i, characterSize) == characterEnd)\n                {\n                    break;\n                }\n\n                i += characterSize;\n            }\n\n            if (i == 0)\n            {\n                return \"\";\n            }\n\n            return encoding.GetString(data, 0, i);\n        }\n\n        public static string ReadStringAscii(this Stream stream)\n        {\n            return stream.ReadStringInternalDynamic(Encoding.ASCII, '\\0');\n        }\n\n        public static string ReadStringUnicode(this Stream stream)\n        {\n            return stream.ReadStringInternalDynamic(Encoding.UTF8, '\\0');\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Game/app.config",
    "content": "<?xml version=\"1.0\"?>\n<configuration>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.0\"/></startup></configuration>\n"
  },
  {
    "path": "SAM.Game/app.manifest",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n  <assemblyIdentity version=\"1.0.0.0\" name=\"MyApplication.app\"/>\n  <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v2\">\n    <security>\n      <requestedPrivileges xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n        <requestedExecutionLevel  level=\"asInvoker\" uiAccess=\"false\" />\n      </requestedPrivileges>\n    </security>\n  </trustInfo>\n\n  <compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">\n    <application>\n\n      <!-- Windows 7 -->\n      <supportedOS Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\" />\n      <!-- Windows 8 -->\n      <supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\" />\n      <!-- Windows 8.1 -->\n      <supportedOS Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\" />\n      <!-- Windows 10 -->\n      <supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\" />\n\n    </application>\n  </compatibility>\n\n  <application xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n    <windowsSettings>\n      <dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true</dpiAware>\n    </windowsSettings>\n  </application>\n</assembly>\n"
  },
  {
    "path": "SAM.Picker/GameInfo.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System.Globalization;\nusing System.Windows.Forms;\n\nnamespace SAM.Picker\n{\n    internal class GameInfo\n    {\n        private string _Name;\n\n        public uint Id;\n        public string Type;\n        public int ImageIndex;\n\n        public string Name\n        {\n            get => this._Name;\n            set => this._Name = value ?? \"App \" + this.Id.ToString(CultureInfo.InvariantCulture);\n        }\n\n        public string ImageUrl;\n\n        public ListViewItem Item;\n\n        public GameInfo(uint id, string type)\n        {\n            this.Id = id;\n            this.Type = type;\n            this.Name = null;\n            this.ImageIndex = 0;\n            this.ImageUrl = null;\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Picker/GamePicker.Designer.cs",
    "content": "﻿namespace SAM.Picker\n{\n    partial class GamePicker\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            System.Windows.Forms.ToolStripSeparator _ToolStripSeparator1;\n            System.Windows.Forms.ToolStripSeparator _ToolStripSeparator2;\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GamePicker));\n            this._LogoImageList = new System.Windows.Forms.ImageList(this.components);\n            this._CallbackTimer = new System.Windows.Forms.Timer(this.components);\n            this._PickerToolStrip = new System.Windows.Forms.ToolStrip();\n            this._RefreshGamesButton = new System.Windows.Forms.ToolStripButton();\n            this._AddGameTextBox = new System.Windows.Forms.ToolStripTextBox();\n            this._AddGameButton = new System.Windows.Forms.ToolStripButton();\n            this._FindGamesLabel = new System.Windows.Forms.ToolStripLabel();\n            this._SearchGameTextBox = new System.Windows.Forms.ToolStripTextBox();\n            this._FilterDropDownButton = new System.Windows.Forms.ToolStripDropDownButton();\n            this._FilterGamesMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this._FilterDemosMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this._FilterModsMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this._FilterJunkMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this._GameListView = new SAM.Picker.MyListView();\n            this._PickerStatusStrip = new System.Windows.Forms.StatusStrip();\n            this._PickerStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();\n            this._DownloadStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();\n            this._LogoWorker = new System.ComponentModel.BackgroundWorker();\n            this._ListWorker = new System.ComponentModel.BackgroundWorker();\n            _ToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();\n            _ToolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();\n            this._PickerToolStrip.SuspendLayout();\n            this._PickerStatusStrip.SuspendLayout();\n            this.SuspendLayout();\n            //\n            // _ToolStripSeparator1\n            //\n            _ToolStripSeparator1.Name = \"_ToolStripSeparator1\";\n            _ToolStripSeparator1.Size = new System.Drawing.Size(6, 25);\n            //\n            // _ToolStripSeparator2\n            //\n            _ToolStripSeparator2.Name = \"_ToolStripSeparator2\";\n            _ToolStripSeparator2.Size = new System.Drawing.Size(6, 25);\n            //\n            // _LogoImageList\n            //\n            this._LogoImageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth24Bit;\n            this._LogoImageList.ImageSize = new System.Drawing.Size(184, 69);\n            this._LogoImageList.TransparentColor = System.Drawing.Color.Transparent;\n            //\n            // _CallbackTimer\n            //\n            this._CallbackTimer.Enabled = true;\n            this._CallbackTimer.Tick += new System.EventHandler(this.OnTimer);\n            //\n            // _PickerToolStrip\n            //\n            this._PickerToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this._RefreshGamesButton,\n            _ToolStripSeparator1,\n            this._AddGameTextBox,\n            this._AddGameButton,\n            _ToolStripSeparator2,\n            this._FindGamesLabel,\n            this._SearchGameTextBox,\n            this._FilterDropDownButton});\n            this._PickerToolStrip.Location = new System.Drawing.Point(0, 0);\n            this._PickerToolStrip.Name = \"_PickerToolStrip\";\n            this._PickerToolStrip.Size = new System.Drawing.Size(742, 25);\n            this._PickerToolStrip.TabIndex = 1;\n            this._PickerToolStrip.Text = \"toolStrip1\";\n            //\n            // _RefreshGamesButton\n            //\n            this._RefreshGamesButton.Image = global::SAM.Picker.Resources.Refresh;\n            this._RefreshGamesButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._RefreshGamesButton.Name = \"_RefreshGamesButton\";\n            this._RefreshGamesButton.Size = new System.Drawing.Size(105, 22);\n            this._RefreshGamesButton.Text = \"Refresh Games\";\n            this._RefreshGamesButton.Click += new System.EventHandler(this.OnRefresh);\n            //\n            // _AddGameTextBox\n            //\n            this._AddGameTextBox.Font = new System.Drawing.Font(\"Segoe UI\", 9F);\n            this._AddGameTextBox.Name = \"_AddGameTextBox\";\n            this._AddGameTextBox.Size = new System.Drawing.Size(100, 25);\n            //\n            // _AddGameButton\n            //\n            this._AddGameButton.Image = global::SAM.Picker.Resources.Search;\n            this._AddGameButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._AddGameButton.Name = \"_AddGameButton\";\n            this._AddGameButton.Size = new System.Drawing.Size(83, 22);\n            this._AddGameButton.Text = \"Add Game\";\n            this._AddGameButton.Click += new System.EventHandler(this.OnAddGame);\n            //\n            // _FindGamesLabel\n            //\n            this._FindGamesLabel.Name = \"_FindGamesLabel\";\n            this._FindGamesLabel.Size = new System.Drawing.Size(33, 22);\n            this._FindGamesLabel.Text = \"Filter\";\n            //\n            // _SearchGameTextBox\n            //\n            this._SearchGameTextBox.Font = new System.Drawing.Font(\"Segoe UI\", 9F);\n            this._SearchGameTextBox.Name = \"_SearchGameTextBox\";\n            this._SearchGameTextBox.Size = new System.Drawing.Size(100, 25);\n            this._SearchGameTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OnFilterUpdate);\n            //\n            // _FilterDropDownButton\n            //\n            this._FilterDropDownButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;\n            this._FilterDropDownButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this._FilterGamesMenuItem,\n            this._FilterDemosMenuItem,\n            this._FilterModsMenuItem,\n            this._FilterJunkMenuItem});\n            this._FilterDropDownButton.Image = global::SAM.Picker.Resources.Filter;\n            this._FilterDropDownButton.ImageTransparentColor = System.Drawing.Color.Magenta;\n            this._FilterDropDownButton.Name = \"_FilterDropDownButton\";\n            this._FilterDropDownButton.Size = new System.Drawing.Size(29, 22);\n            this._FilterDropDownButton.Text = \"Game filtering\";\n            //\n            // _FilterGamesMenuItem\n            //\n            this._FilterGamesMenuItem.Checked = true;\n            this._FilterGamesMenuItem.CheckOnClick = true;\n            this._FilterGamesMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;\n            this._FilterGamesMenuItem.Name = \"_FilterGamesMenuItem\";\n            this._FilterGamesMenuItem.Size = new System.Drawing.Size(180, 22);\n            this._FilterGamesMenuItem.Text = \"Show &games\";\n            this._FilterGamesMenuItem.CheckedChanged += new System.EventHandler(this.OnFilterUpdate);\n            //\n            // _FilterDemosMenuItem\n            //\n            this._FilterDemosMenuItem.CheckOnClick = true;\n            this._FilterDemosMenuItem.Name = \"_FilterDemosMenuItem\";\n            this._FilterDemosMenuItem.Size = new System.Drawing.Size(180, 22);\n            this._FilterDemosMenuItem.Text = \"Show &demos\";\n            this._FilterDemosMenuItem.CheckedChanged += new System.EventHandler(this.OnFilterUpdate);\n            //\n            // _FilterModsMenuItem\n            //\n            this._FilterModsMenuItem.CheckOnClick = true;\n            this._FilterModsMenuItem.Name = \"_FilterModsMenuItem\";\n            this._FilterModsMenuItem.Size = new System.Drawing.Size(180, 22);\n            this._FilterModsMenuItem.Text = \"Show &mods\";\n            this._FilterModsMenuItem.CheckedChanged += new System.EventHandler(this.OnFilterUpdate);\n            //\n            // _FilterJunkMenuItem\n            //\n            this._FilterJunkMenuItem.CheckOnClick = true;\n            this._FilterJunkMenuItem.Name = \"_FilterJunkMenuItem\";\n            this._FilterJunkMenuItem.Size = new System.Drawing.Size(180, 22);\n            this._FilterJunkMenuItem.Text = \"Show &junk\";\n            this._FilterJunkMenuItem.CheckedChanged += new System.EventHandler(this.OnFilterUpdate);\n            //\n            // _GameListView\n            //\n            this._GameListView.BackColor = System.Drawing.Color.Black;\n            this._GameListView.Dock = System.Windows.Forms.DockStyle.Fill;\n            this._GameListView.ForeColor = System.Drawing.Color.White;\n            this._GameListView.HideSelection = false;\n            this._GameListView.LargeImageList = this._LogoImageList;\n            this._GameListView.Location = new System.Drawing.Point(0, 25);\n            this._GameListView.MultiSelect = false;\n            this._GameListView.Name = \"_GameListView\";\n            this._GameListView.OwnerDraw = true;\n            this._GameListView.Size = new System.Drawing.Size(742, 245);\n            this._GameListView.SmallImageList = this._LogoImageList;\n            this._GameListView.Sorting = System.Windows.Forms.SortOrder.Ascending;\n            this._GameListView.TabIndex = 0;\n            this._GameListView.TileSize = new System.Drawing.Size(184, 69);\n            this._GameListView.UseCompatibleStateImageBehavior = false;\n            this._GameListView.VirtualMode = true;\n            this._GameListView.DrawItem += new System.Windows.Forms.DrawListViewItemEventHandler(this.OnGameListViewDrawItem);\n            this._GameListView.ItemActivate += new System.EventHandler(this.OnActivateGame);\n            this._GameListView.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.OnGameListViewRetrieveVirtualItem);\n            this._GameListView.SearchForVirtualItem += new System.Windows.Forms.SearchForVirtualItemEventHandler(this.OnGameListViewSearchForVirtualItem);\n            //\n            // _PickerStatusStrip\n            //\n            this._PickerStatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this._PickerStatusLabel,\n            this._DownloadStatusLabel});\n            this._PickerStatusStrip.Location = new System.Drawing.Point(0, 270);\n            this._PickerStatusStrip.Name = \"_PickerStatusStrip\";\n            this._PickerStatusStrip.Size = new System.Drawing.Size(742, 22);\n            this._PickerStatusStrip.TabIndex = 2;\n            this._PickerStatusStrip.Text = \"statusStrip\";\n            //\n            // _PickerStatusLabel\n            //\n            this._PickerStatusLabel.Name = \"_PickerStatusLabel\";\n            this._PickerStatusLabel.Size = new System.Drawing.Size(727, 17);\n            this._PickerStatusLabel.Spring = true;\n            this._PickerStatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;\n            //\n            // _DownloadStatusLabel\n            //\n            this._DownloadStatusLabel.Image = global::SAM.Picker.Resources.Download;\n            this._DownloadStatusLabel.Name = \"_DownloadStatusLabel\";\n            this._DownloadStatusLabel.Size = new System.Drawing.Size(111, 17);\n            this._DownloadStatusLabel.Text = \"Download status\";\n            this._DownloadStatusLabel.Visible = false;\n            //\n            // _LogoWorker\n            //\n            this._LogoWorker.WorkerSupportsCancellation = true;\n            this._LogoWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.DoDownloadLogo);\n            this._LogoWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.OnDownloadLogo);\n            //\n            // _ListWorker\n            //\n            this._ListWorker.WorkerSupportsCancellation = true;\n            this._ListWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.DoDownloadList);\n            this._ListWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.OnDownloadList);\n            //\n            // GamePicker\n            //\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(742, 292);\n            this.Controls.Add(this._GameListView);\n            this.Controls.Add(this._PickerStatusStrip);\n            this.Controls.Add(this._PickerToolStrip);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.Name = \"GamePicker\";\n            this.Text = \"Steam Achievement Manager 7.0 | Pick a game... Any game...\";\n            this._PickerToolStrip.ResumeLayout(false);\n            this._PickerToolStrip.PerformLayout();\n            this._PickerStatusStrip.ResumeLayout(false);\n            this._PickerStatusStrip.PerformLayout();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n        }\n\n        private MyListView _GameListView;\n        private System.Windows.Forms.ImageList _LogoImageList;\n        private System.Windows.Forms.Timer _CallbackTimer;\n        private System.Windows.Forms.ToolStrip _PickerToolStrip;\n        private System.Windows.Forms.ToolStripButton _RefreshGamesButton;\n        private System.Windows.Forms.ToolStripTextBox _AddGameTextBox;\n        private System.Windows.Forms.ToolStripButton _AddGameButton;\n        private System.Windows.Forms.ToolStripDropDownButton _FilterDropDownButton;\n        private System.Windows.Forms.ToolStripMenuItem _FilterGamesMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem _FilterJunkMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem _FilterDemosMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem _FilterModsMenuItem;\n        private System.Windows.Forms.StatusStrip _PickerStatusStrip;\n        private System.Windows.Forms.ToolStripStatusLabel _DownloadStatusLabel;\n        private System.Windows.Forms.ToolStripStatusLabel _PickerStatusLabel;\n        private System.ComponentModel.BackgroundWorker _LogoWorker;\n        private System.ComponentModel.BackgroundWorker _ListWorker;\n        private System.Windows.Forms.ToolStripTextBox _SearchGameTextBox;\n        private System.Windows.Forms.ToolStripLabel _FindGamesLabel;\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "SAM.Picker/GamePicker.cs",
    "content": "/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Net;\nusing System.Windows.Forms;\nusing System.Xml.XPath;\nusing static SAM.Picker.InvariantShorthand;\nusing APITypes = SAM.API.Types;\n\nnamespace SAM.Picker\n{\n    internal partial class GamePicker : Form\n    {\n        private readonly API.Client _SteamClient;\n\n        private readonly Dictionary<uint, GameInfo> _Games;\n        private readonly List<GameInfo> _FilteredGames;\n\n        private readonly object _LogoLock;\n        private readonly HashSet<string> _LogosAttempting;\n        private readonly HashSet<string> _LogosAttempted;\n        private readonly ConcurrentQueue<GameInfo> _LogoQueue;\n\n        private readonly API.Callbacks.AppDataChanged _AppDataChangedCallback;\n\n        public GamePicker(API.Client client)\n        {\n            this._Games = new();\n            this._FilteredGames = new();\n            this._LogoLock = new();\n            this._LogosAttempting = new();\n            this._LogosAttempted = new();\n            this._LogoQueue = new();\n\n            this.InitializeComponent();\n\n            Bitmap blank = new(this._LogoImageList.ImageSize.Width, this._LogoImageList.ImageSize.Height);\n            using (var g = Graphics.FromImage(blank))\n            {\n                g.Clear(Color.DimGray);\n            }\n\n            this._LogoImageList.Images.Add(\"Blank\", blank);\n\n            this._SteamClient = client;\n\n            this._AppDataChangedCallback = client.CreateAndRegisterCallback<API.Callbacks.AppDataChanged>();\n            this._AppDataChangedCallback.OnRun += this.OnAppDataChanged;\n\n            this.AddGames();\n        }\n\n        private void OnAppDataChanged(APITypes.AppDataChanged param)\n        {\n            if (param.Result == false)\n            {\n                return;\n            }\n\n            if (this._Games.TryGetValue(param.Id, out var game) == false)\n            {\n                return;\n            }\n\n            game.Name = this._SteamClient.SteamApps001.GetAppData(game.Id, \"name\");\n\n            this.AddGameToLogoQueue(game);\n            this.DownloadNextLogo();\n        }\n\n        private void DoDownloadList(object sender, DoWorkEventArgs e)\n        {\n            this._PickerStatusLabel.Text = \"Downloading game list...\";\n\n            byte[] bytes;\n            using (WebClient downloader = new())\n            {\n                bytes = downloader.DownloadData(new Uri(\"https://gib.me/sam/games.xml\"));\n            }\n\n            List<KeyValuePair<uint, string>> pairs = new();\n            using (MemoryStream stream = new(bytes, false))\n            {\n                XPathDocument document = new(stream);\n                var navigator = document.CreateNavigator();\n                var nodes = navigator.Select(\"/games/game\");\n                while (nodes.MoveNext() == true)\n                {\n                    string type = nodes.Current.GetAttribute(\"type\", \"\");\n                    if (string.IsNullOrEmpty(type) == true)\n                    {\n                        type = \"normal\";\n                    }\n                    pairs.Add(new((uint)nodes.Current.ValueAsLong, type));\n                }\n            }\n\n            this._PickerStatusLabel.Text = \"Checking game ownership...\";\n            foreach (var kv in pairs)\n            {\n                this.AddGame(kv.Key, kv.Value);\n            }\n        }\n\n        private void OnDownloadList(object sender, RunWorkerCompletedEventArgs e)\n        {\n            if (e.Error != null || e.Cancelled == true)\n            {\n                this.AddDefaultGames();\n                MessageBox.Show(e.Error.ToString(), \"Error\", MessageBoxButtons.OK, MessageBoxIcon.Error);\n            }\n\n            this.RefreshGames();\n            this._RefreshGamesButton.Enabled = true;\n            this.DownloadNextLogo();\n        }\n\n        private void RefreshGames()\n        {\n            var nameSearch = this._SearchGameTextBox.Text.Length > 0\n                ? this._SearchGameTextBox.Text\n                : null;\n\n            var wantNormals = this._FilterGamesMenuItem.Checked == true;\n            var wantDemos = this._FilterDemosMenuItem.Checked == true;\n            var wantMods = this._FilterModsMenuItem.Checked == true;\n            var wantJunk = this._FilterJunkMenuItem.Checked == true;\n\n            this._FilteredGames.Clear();\n            foreach (var info in this._Games.Values.OrderBy(gi => gi.Name))\n            {\n                if (nameSearch != null &&\n                    info.Name.IndexOf(nameSearch, StringComparison.OrdinalIgnoreCase) < 0)\n                {\n                    continue;\n                }\n\n                bool wanted = info.Type switch\n                {\n                    \"normal\" => wantNormals,\n                    \"demo\" => wantDemos,\n                    \"mod\" => wantMods,\n                    \"junk\" => wantJunk,\n                    _ => true,\n                };\n                if (wanted == false)\n                {\n                    continue;\n                }\n\n                this._FilteredGames.Add(info);\n            }\n\n            this._GameListView.VirtualListSize = this._FilteredGames.Count;\n            this._PickerStatusLabel.Text =\n                $\"Displaying {this._GameListView.Items.Count} games. Total {this._Games.Count} games.\";\n\n            if (this._GameListView.Items.Count > 0)\n            {\n                this._GameListView.Items[0].Selected = true;\n                this._GameListView.Select();\n            }\n        }\n\n        private void OnGameListViewRetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)\n        {\n            var info = this._FilteredGames[e.ItemIndex];\n            e.Item = info.Item = new()\n            {\n                Text = info.Name,\n                ImageIndex = info.ImageIndex,\n            };\n        }\n\n        private void OnGameListViewSearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e)\n        {\n            if (e.Direction != SearchDirectionHint.Down || e.IsTextSearch == false)\n            {\n                return;\n            }\n\n            var count = this._FilteredGames.Count;\n            if (count < 2)\n            {\n                return;\n            }\n\n            var text = e.Text;\n            int startIndex = e.StartIndex;\n\n            Predicate<GameInfo> predicate;\n            /*if (e.IsPrefixSearch == true)*/\n            {\n                predicate = gi => gi.Name != null && gi.Name.StartsWith(text, StringComparison.CurrentCultureIgnoreCase);\n            }\n            /*else\n            {\n                predicate = gi => gi.Name != null && string.Compare(gi.Name, text, StringComparison.CurrentCultureIgnoreCase) == 0;\n            }*/\n\n            int index;\n            if (e.StartIndex >= count)\n            {\n                // starting from the last item in the list\n                index = this._FilteredGames.FindIndex(0, startIndex - 1, predicate);\n            }\n            else if (startIndex <= 0)\n            {\n                // starting from the first item in the list\n                index = this._FilteredGames.FindIndex(0, count, predicate);\n            }\n            else\n            {\n                index = this._FilteredGames.FindIndex(startIndex, count - startIndex, predicate);\n                if (index < 0)\n                {\n                    index = this._FilteredGames.FindIndex(0, startIndex - 1, predicate);\n                }\n            }\n\n            e.Index = index < 0 ? -1 : index;\n        }\n\n        private void DoDownloadLogo(object sender, DoWorkEventArgs e)\n        {\n            var info = (GameInfo)e.Argument;\n\n            this._LogosAttempted.Add(info.ImageUrl);\n\n            using (WebClient downloader = new())\n            {\n                try\n                {\n                    var data = downloader.DownloadData(new Uri(info.ImageUrl));\n                    using (MemoryStream stream = new(data, false))\n                    {\n                        Bitmap bitmap = new(stream);\n                        e.Result = new LogoInfo(info.Id, bitmap);\n                    }\n                }\n                catch (Exception)\n                {\n                    e.Result = new LogoInfo(info.Id, null);\n                }\n            }\n        }\n\n        private void OnDownloadLogo(object sender, RunWorkerCompletedEventArgs e)\n        {\n            if (e.Error != null || e.Cancelled == true)\n            {\n                return;\n            }\n\n            if (e.Result is LogoInfo logoInfo &&\n                logoInfo.Bitmap != null &&\n                this._Games.TryGetValue(logoInfo.Id, out var gameInfo) == true)\n            {\n                this._GameListView.BeginUpdate();\n                var imageIndex = this._LogoImageList.Images.Count;\n                this._LogoImageList.Images.Add(gameInfo.ImageUrl, logoInfo.Bitmap);\n                gameInfo.ImageIndex = imageIndex;\n                this._GameListView.EndUpdate();\n            }\n\n            this.DownloadNextLogo();\n        }\n\n        private void DownloadNextLogo()\n        {\n            lock (this._LogoLock)\n            {\n\n                if (this._LogoWorker.IsBusy == true)\n                {\n                    return;\n                }\n\n                GameInfo info;\n                while (true)\n                {\n                    if (this._LogoQueue.TryDequeue(out info) == false)\n                    {\n                        this._DownloadStatusLabel.Visible = false;\n                        return;\n                    }\n\n                    if (info.Item == null)\n                    {\n                        continue;\n                    }\n\n                    if (this._FilteredGames.Contains(info) == false ||\n                        info.Item.Bounds.IntersectsWith(this._GameListView.ClientRectangle) == false)\n                    {\n                        this._LogosAttempting.Remove(info.ImageUrl);\n                        continue;\n                    }\n\n                    break;\n                }\n\n                this._DownloadStatusLabel.Text = $\"Downloading {1 + this._LogoQueue.Count} game icons...\";\n                this._DownloadStatusLabel.Visible = true;\n\n                this._LogoWorker.RunWorkerAsync(info);\n            }\n        }\n\n        private string GetGameImageUrl(uint id)\n        {\n            string candidate;\n\n            var currentLanguage = this._SteamClient.SteamApps008.GetCurrentGameLanguage();\n\n            candidate = this._SteamClient.SteamApps001.GetAppData(id, _($\"small_capsule/{currentLanguage}\"));\n            if (string.IsNullOrEmpty(candidate) == false)\n            {\n                return _($\"https://shared.cloudflare.steamstatic.com/store_item_assets/steam/apps/{id}/{candidate}\");\n            }\n\n            if (currentLanguage != \"english\")\n            {\n                candidate = this._SteamClient.SteamApps001.GetAppData(id, \"small_capsule/english\");\n                if (string.IsNullOrEmpty(candidate) == false)\n                {\n                    return _($\"https://shared.cloudflare.steamstatic.com/store_item_assets/steam/apps/{id}/{candidate}\");\n                }\n            }\n\n            candidate = this._SteamClient.SteamApps001.GetAppData(id, \"logo\");\n            if (string.IsNullOrEmpty(candidate) == false)\n            {\n                return _($\"https://cdn.steamstatic.com/steamcommunity/public/images/apps/{id}/{candidate}.jpg\");\n            }\n\n            return null;\n        }\n\n        private void AddGameToLogoQueue(GameInfo info)\n        {\n            if (info.ImageIndex > 0)\n            {\n                return;\n            }\n\n            var imageUrl = GetGameImageUrl(info.Id);\n            if (string.IsNullOrEmpty(imageUrl) == true)\n            {\n                return;\n            }\n\n            info.ImageUrl = imageUrl;\n\n            int imageIndex = this._LogoImageList.Images.IndexOfKey(imageUrl);\n            if (imageIndex >= 0)\n            {\n                info.ImageIndex = imageIndex;\n            }\n            else if (\n                this._LogosAttempting.Contains(imageUrl) == false &&\n                this._LogosAttempted.Contains(imageUrl) == false)\n            {\n                this._LogosAttempting.Add(imageUrl);\n                this._LogoQueue.Enqueue(info);\n            }\n        }\n\n        private bool OwnsGame(uint id)\n        {\n            return this._SteamClient.SteamApps008.IsSubscribedApp(id);\n        }\n\n        private void AddGame(uint id, string type)\n        {\n            if (this._Games.ContainsKey(id) == true)\n            {\n                return;\n            }\n\n            if (this.OwnsGame(id) == false)\n            {\n                return;\n            }\n\n            GameInfo info = new(id, type);\n            info.Name = this._SteamClient.SteamApps001.GetAppData(info.Id, \"name\");\n            this._Games.Add(id, info);\n        }\n\n        private void AddGames()\n        {\n            this._Games.Clear();\n            this._RefreshGamesButton.Enabled = false;\n            this._ListWorker.RunWorkerAsync();\n        }\n\n        private void AddDefaultGames()\n        {\n            this.AddGame(480, \"normal\"); // Spacewar\n        }\n\n        private void OnTimer(object sender, EventArgs e)\n        {\n            this._CallbackTimer.Enabled = false;\n            this._SteamClient.RunCallbacks(false);\n            this._CallbackTimer.Enabled = true;\n        }\n\n        private void OnActivateGame(object sender, EventArgs e)\n        {\n            var focusedItem = (sender as MyListView)?.FocusedItem;\n            var index = focusedItem != null ? focusedItem.Index : -1;\n            if (index < 0 || index >= this._FilteredGames.Count)\n            {\n                return;\n            }\n\n            var info = this._FilteredGames[index];\n            if (info == null)\n            {\n                return;\n            }\n\n            try\n            {\n                Process.Start(\"SAM.Game.exe\", info.Id.ToString(CultureInfo.InvariantCulture));\n            }\n            catch (Win32Exception)\n            {\n                MessageBox.Show(\n                    this,\n                    \"Failed to start SAM.Game.exe.\",\n                    \"Error\",\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Error);\n            }\n        }\n\n        private void OnRefresh(object sender, EventArgs e)\n        {\n            this._AddGameTextBox.Text = \"\";\n            this.AddGames();\n        }\n\n        private void OnAddGame(object sender, EventArgs e)\n        {\n            uint id;\n\n            if (uint.TryParse(this._AddGameTextBox.Text, out id) == false)\n            {\n                MessageBox.Show(\n                    this,\n                    \"Please enter a valid game ID.\",\n                    \"Error\",\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Error);\n                return;\n            }\n\n            if (this.OwnsGame(id) == false)\n            {\n                MessageBox.Show(this, \"You don't own that game.\", \"Error\", MessageBoxButtons.OK, MessageBoxIcon.Error);\n                return;\n            }\n\n            while (this._LogoQueue.TryDequeue(out var logo) == true)\n            {\n                // clear the download queue because we will be showing only one app\n                this._LogosAttempted.Remove(logo.ImageUrl);\n            }\n\n            this._AddGameTextBox.Text = \"\";\n            this._Games.Clear();\n            this.AddGame(id, \"normal\");\n            this._FilterGamesMenuItem.Checked = true;\n            this.RefreshGames();\n            this.DownloadNextLogo();\n        }\n\n        private void OnFilterUpdate(object sender, EventArgs e)\n        {\n            this.RefreshGames();\n\n            // Compatibility with _GameListView SearchForVirtualItemEventHandler (otherwise _SearchGameTextBox loose focus on KeyUp)\n            this._SearchGameTextBox.Focus();\n        }\n\n        private void OnGameListViewDrawItem(object sender, DrawListViewItemEventArgs e)\n        {\n            e.DrawDefault = true;\n\n            if (e.Item.Bounds.IntersectsWith(this._GameListView.ClientRectangle) == false)\n            {\n                return;\n            }\n\n            var info = this._FilteredGames[e.ItemIndex];\n            if (info.ImageIndex <= 0)\n            {\n                this.AddGameToLogoQueue(info);\n                this.DownloadNextLogo();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Picker/GamePicker.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"_ToolStripSeparator1.GenerateMember\" type=\"System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>False</value>\n  </metadata>\n  <metadata name=\"_ToolStripSeparator2.GenerateMember\" type=\"System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>False</value>\n  </metadata>\n  <metadata name=\"_LogoImageList.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>542, 17</value>\n  </metadata>\n  <metadata name=\"_CallbackTimer.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>678, 17</value>\n  </metadata>\n  <metadata name=\"_PickerToolStrip.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <metadata name=\"_PickerStatusStrip.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>155, 17</value>\n  </metadata>\n  <metadata name=\"_LogoWorker.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>418, 17</value>\n  </metadata>\n  <metadata name=\"_ListWorker.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>303, 17</value>\n  </metadata>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAMAEBAAAAEACABoBQAANgAAACAgAAABAAgAqAgAAJ4FAAAwMAAAAQAYAKgcAABGDgAAKAAAABAA\n        AAAgAAAAAQAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgP8A////AMXKxwD///8ADQkMAJus\n        oQBeW10AwNXIAIyMjAC2trYAa29tAHVzdAC5v7wAj5aRAHx8fACRjI8AstnBAGGCbgAlNisAPFFGAHCX\n        gACbq6EAgX+AAHp4egDA1cgAR2FSADApLgChsKcAj5aRAGtvbQBih3EAX15fAIODgwCTj5IApcKyABwb\n        GwC0vbcAYIJtAGmJdgBjZ2UAoLKmADJEOQCGhIUAd3Z2ALa2tgB2nYYAXltdAIafjwBnhXQAcY9+ADFE\n        OACzyrwALD0zAHZ0dQCFgYMArsW4AGeHcwBHSEgAhpqNAG6PfABtjnoAJiUlALDGuQAWIBsAhIODAHh3\n        eADFyscAbY96AGmGdQBshncAio+MAEVFRABDP0IAqbauAGOEcAAdGhwAioqKALm/vACLh4kAdXJ0AIWC\n        hAC5xr8Ah6yWAGSAcABrh3cAaod2AGyMeQCbr6MAjaqZAEVdTwAJBgcAi4uLAF5/awCfuKkArcO1AJus\n        oQBGYFEAX3tqAGuIeABphnQACw8NAC4sLgBMSksAjo6OAGWDcgBif20AYX9tAJWyoQBrdW8Abo56AHiY\n        hgBMYlUADQkMAIOCgwCMjIwAhYWFAGyLeQBqh3cAaYd1AEZTSwCmxbQAGCMcAC8qLACQkJAAgYGBAFhb\n        WQBvjHsAX3hpAHGRfwB9oIoAHCYfAKS/sAAvKi4AkpKSAK6wrwBlgXAAUVZTACIkIgCChIMAL0U3AHRy\n        cwB9fH0AdXR1AGmCcwBwinsAMUc5AEVARACEg4QAdnN1AGJgYQB8enwAh4eHAAAAAAD///8AAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEAAQEBAQIC\n        AQEBAQEBAQEBAQEBAQIBAQIBAQEBAQEBAQEBAQIBAgIBAgEBAQEBAQEBAgICAgICAQIBAQEBAQEBAQIC\n        AgICAgECAgEBAQEBAQECAgICAgECAgICAQEBAQEBAgIBAQICAgICAgICAgEBAQEBAQEBAQICAgICAgIC\n        AQEBAQEBAQECAgICAQEBAQIBAQEBAQEBAQICAQICAgECAQEBAQEBAQEBAgECAgIBAgEBAQEBAQEBAQIB\n        AgICAQIBAQEBAQEBAQECAgEBAQICAQEBAQEBAQEBAQICAgICAQEAAQEBAQEBAQEBAQEBAQEAgAEAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAEAACgA\n        AAAgAAAAQAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwID/AP///wCAgAAAAIAAAACA\n        gAAAAIAAwMDAAMDcwADwyqYAgICAAP8A/wD/AAAA//8AAAD/AAAA//8AAAD/AP///wDw+/8ApKCgANTw\n        /wCx4v8AjtT/AGvG/wBIuP8AJar/AACq/wAAktwAAHq5AABilgAASnMAADJQANTj/wCxx/8Ajqv/AGuP\n        /wBIc/8AJVf/AABV/wAASdwAAD25AAAxlgAAJXMAABlQANTU/wCxsf8Ajo7/AGtr/wBISP8AJSX/AAAA\n        /wAAANwAAAC5AAAAlgAAAHMAAABQAOPU/wDHsf8Aq47/AI9r/wBzSP8AVyX/AFUA/wBJANwAPQC5ADEA\n        lgAlAHMAGQBQAPDU/wDisf8A1I7/AMZr/wC4SP8AqiX/AKoA/wCSANwAegC5AGIAlgBKAHMAMgBQAP/U\n        /wD/sf8A/47/AP9r/wD/SP8A/yX/AP8A/wDcANwAuQC5AJYAlgBzAHMAUABQAP/U8AD/seIA/47UAP9r\n        xgD/SLgA/yWqAP8AqgDcAJIAuQB6AJYAYgBzAEoAUAAyAP/U4wD/sccA/46rAP9rjwD/SHMA/yVXAP8A\n        VQDcAEkAuQA9AJYAMQBzACUAUAAZAP/U1AD/sbEA/46OAP9rawD/SEgA/yUlAP8AAADcAAAAuQAAAJYA\n        AABzAAAAUAAAAP/j1AD/x7EA/6uOAP+PawD/c0gA/1clAP9VAADcSQAAuT0AAJYxAABzJQAAUBkAAP/w\n        1AD/4rEA/9SOAP/GawD/uEgA/6olAP+qAADckgAAuXoAAJZiAABzSgAAUDIAAP//1AD//7EA//+OAP//\n        awD//0gA//8lAP//AADc3AAAubkAAJaWAABzcwAAUFAAAPD/1ADi/7EA1P+OAMb/awC4/0gAqv8lAKr/\n        AACS3AAAerkAAGKWAABKcwAAMlAAAOP/1ADH/7EAq/+OAI//awBz/0gAV/8lAFX/AABJ3AAAPbkAADGW\n        AAAlcwAAGVAAANT/1ACx/7EAjv+OAGv/awBI/0gAJf8lAAD/AAAA3AAAALkAAACWAAAAcwAAAFAAANT/\n        4wCx/8cAjv+rAGv/jwBI/3MAJf9XAAD/VQAA3EkAALk9AACWMQAAcyUAAFAZANT/8ACx/+IAjv/UAGv/\n        xgBI/7gAJf+qAAD/qgAA3JIAALl6AACWYgAAc0oAAFAyANT//wCx//8Ajv//AGv//wBI//8AJf//AAD/\n        /wAA3NwAALm5AACWlgAAc3MAAFBQAPLy8gDm5uYA2traAM7OzgDCwsIAtra2AKqqqgCenp4AkpKSAIaG\n        hgB6enoAbm5uAGJiYgBWVlYASkpKAD4+PgAyMjIAJiYmABoaGgAODg4AAAABAQEBAQEBAQEBAQEBAQEB\n        AQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEB\n        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAgICAQEBAQEBAQEB\n        AQEBAQEBAQEBAQEBAQEBAQEBAQIBAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAQICAgECAQEB\n        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAgICAgICAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgIB\n        AgIBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAQICAgIBAQEBAQEBAQEBAQEBAQEBAQICAgICAgIB\n        AQICAgICAgICAgEBAQEBAQECAgIBAgICAgICAgIBAQEBAQECAgICAgICAgEBAQEBAgIBAQICAgICAgIC\n        AQEBAQEBAQICAgIBAQEBAgEBAQECAQICAgICAgIBAQEBAQEBAQEBAQICAQICAgECAQEBAQIBAgICAgIB\n        AQEBAQEBAQEBAQEBAQIBAgICAQIBAQEBAgIBAQICAQEBAQEBAQEBAQEBAQEBAgECAgIBAgEBAQEBAgIC\n        AgEBAQEBAQEBAQEBAQEBAQECAgEBAQICAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAgICAgEBAQEB\n        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEB\n        AQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAMAAAAOAAAABAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAHAAAADKAAAADAA\n        AABgAAAAAQAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/wAAAAAAAAAA\n        AMCA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/wAAAMCA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/////////////////////8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/////8CA\n        /8CA/8CA/8CA/8CA/////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/////////////////////////8CA/8CA/////8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA////////////////////////////////\n        /8CA/////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA////////////\n        /////////////////////////////////8CA/////////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/////////////////////////////////////////////////8CA/8CA////////////\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA////////////////////////////////////////////////\n        /////8CA/8CA/8CA/////////////////////////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA////////////////////////\n        /////////////////////////////////////////////////////////////////////////////8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA////\n        /////////////////////////////////////////////////////8CA/8CA/8CA/8CA/8CA////////\n        /////////////////////////////////////////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /////////////8CA/8CA/////////////////////////////////////////////////////8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA////////////////////////////////////////////////////\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/////8CA/8CA////////////////////////////////////////\n        /////////////////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA////////////////////\n        /////8CA/8CA/8CA/8CA/8CA/////////8CA/8CA/8CA/8CA/8CA/8CA/////8CA/8CA////////////\n        /////////////////////////////////////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/////////////////8CA/8CA/////////////8CA/8CA/////////8CA/8CA/8CA\n        /8CA/////8CA/8CA/////////////////////////////////////////////8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/////////////8CA////////////\n        /////////8CA/////////8CA/8CA/8CA/8CA/////8CA/8CA////////////////////////////////\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/////////8CA/8CA/////////////////////8CA/8CA/////8CA/8CA/8CA/8CA/////8CA/8CA\n        /////////////////////////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/////////8CA/8CA/////////////////////8CA////\n        /////8CA/8CA/8CA/8CA/8CA/////8CA/8CA/////////8CA/////////8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA////////\n        /8CA/////////////////8CA/8CA/////////8CA/8CA/8CA/8CA/8CA/8CA/////8CA/8CA/8CA////\n        /////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/////////////8CA/8CA/8CA/8CA/8CA/////////////8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/////////////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/////////////8CA/8CA\n        /8CA/////////////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/////////////////////////////8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/////8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/wAA\n        AMCA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/wAAAAAAAAAAAMCA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA\n        /8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/8CA/wAAAAAAAMAAAAAAAwAAgAAAAAAB\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAB\n        AADAAAAAAAMAAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "SAM.Picker/GlobalSuppressions.cs",
    "content": "[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"SAM.Picker.GamePicker.#DoDownloadLogo(System.Object,System.ComponentModel.DoWorkEventArgs)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA2210:AssembliesShouldHaveValidStrongNames\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.Control.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Picker.GamePicker.#InitializeComponent()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Picker.Program.#Main()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.Windows.Forms.IWin32Window,System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Picker.GamePicker.#OnActivateGame(System.Object,System.EventArgs)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.MessageBox.Show(System.Windows.Forms.IWin32Window,System.String,System.String,System.Windows.Forms.MessageBoxButtons,System.Windows.Forms.MessageBoxIcon)\", Scope = \"member\", Target = \"SAM.Picker.GamePicker.#OnAddGame(System.Object,System.EventArgs)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.ToolStripItem.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Picker.GamePicker.#DownloadNextLogo()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.ToolStripItem.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Picker.GamePicker.#InitializeComponent()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Globalization\", \"CA1303:Do not pass literals as localized parameters\", MessageId = \"System.Windows.Forms.ToolStripItem.set_Text(System.String)\", Scope = \"member\", Target = \"SAM.Picker.GamePicker.#RefreshGames()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA2204:Literals should be spelled correctly\", MessageId = \"statusStrip\", Scope = \"member\", Target = \"SAM.Picker.GamePicker.#InitializeComponent()\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Reliability\", \"CA2000:Dispose objects before losing scope\", Scope = \"member\", Target = \"SAM.Picker.GamePicker.#.ctor(SAM.API.Client)\")]\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Reliability\", \"CA2000:Dispose objects before losing scope\", Scope = \"member\", Target = \"SAM.Picker.GamePicker.#InitializeComponent()\")]\n"
  },
  {
    "path": "SAM.Picker/InvariantShorthand.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\n\nnamespace SAM.Picker\n{\n    internal static class InvariantShorthand\n    {\n        public static string _(FormattableString formattable)\n        {\n            return FormattableString.Invariant(formattable);\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Picker/LICENSE.txt",
    "content": "zlib License\n\nCopyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgment in the product documentation would\n   be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and must not\n   be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source\n   distribution."
  },
  {
    "path": "SAM.Picker/LogoInfo.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System.Drawing;\n\nnamespace SAM.Picker\n{\n    internal class LogoInfo\n    {\n        public readonly uint Id;\n        public readonly Bitmap Bitmap;\n\n        public LogoInfo(uint id, Bitmap bitmap)\n        {\n            this.Id = id;\n            this.Bitmap = bitmap;\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Picker/MyListView.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Windows.Forms;\n\nnamespace SAM.Picker\n{\n    internal class MyListView : ListView\n    {\n        public event ScrollEventHandler Scroll;\n\n        public MyListView()\n        {\n            base.DoubleBuffered = true;\n        }\n\n        protected virtual void OnScroll(ScrollEventArgs e)\n        {\n            this.Scroll?.Invoke(this, e);\n        }\n\n        protected override void WndProc(ref Message m)\n        {\n            base.WndProc(ref m);\n\n            switch (m.Msg)\n            {\n                case 0x0100: // WM_KEYDOWN\n                {\n                    ScrollEventType type;\n                    if (TranslateKeyScrollEvent((Keys)m.WParam.ToInt32(), out type) == true)\n                    {\n                        this.OnScroll(new(type, Win32.GetScrollPos(this.Handle, 1 /*SB_VERT*/)));\n                    }\n                    break;\n                }\n\n                case 0x0115: // WM_VSCROLL\n                case 0x020A: // WM_MOUSEWHEEL\n                {\n                    this.OnScroll(new(ScrollEventType.EndScroll, Win32.GetScrollPos(this.Handle, 1 /*SB_VERT*/)));\n                    break;\n                }\n            }\n        }\n\n        private static bool TranslateKeyScrollEvent(Keys keys, out ScrollEventType type)\n        {\n            switch (keys)\n            {\n                case Keys.Down:\n                {\n                    type = ScrollEventType.SmallIncrement;\n                    return true;\n                }\n\n                case Keys.Up:\n                {\n                    type = ScrollEventType.SmallDecrement;\n                    return true;\n                }\n\n                case Keys.PageDown:\n                {\n                    type = ScrollEventType.LargeIncrement;\n                    return true;\n                }\n\n                case Keys.PageUp:\n                {\n                    type = ScrollEventType.SmallDecrement;\n                    return true;\n                }\n\n                case Keys.Home:\n                {\n                    type = ScrollEventType.First;\n                    return true;\n                }\n\n                case Keys.End:\n                {\n                    type = ScrollEventType.Last;\n                    return true;\n                }\n            }\n\n            type = default;\n            return false;\n        }\n\n        private static class Win32\n        {\n            [DllImport(\"user32.dll\", SetLastError = true)]\n            public static extern int GetScrollPos(IntPtr hWnd, int nBar);\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Picker/Program.cs",
    "content": "﻿/* Copyright (c) 2024 Rick (rick 'at' gibbed 'dot' us)\n *\n * This software is provided 'as-is', without any express or implied\n * warranty. In no event will the authors be held liable for any damages\n * arising from the use of this software.\n *\n * Permission is granted to anyone to use this software for any purpose,\n * including commercial applications, and to alter it and redistribute it\n * freely, subject to the following restrictions:\n *\n * 1. The origin of this software must not be misrepresented; you must not\n *    claim that you wrote the original software. If you use this software\n *    in a product, an acknowledgment in the product documentation would\n *    be appreciated but is not required.\n *\n * 2. Altered source versions must be plainly marked as such, and must not\n *    be misrepresented as being the original software.\n *\n * 3. This notice may not be removed or altered from any source\n *    distribution.\n */\n\nusing System;\nusing System.Windows.Forms;\n\nnamespace SAM.Picker\n{\n    internal static class Program\n    {\n        [STAThread]\n        private static void Main()\n        {\n            if (API.Steam.GetInstallPath() == Application.StartupPath)\n            {\n                MessageBox.Show(\n                    \"This tool declines to being run from the Steam directory.\",\n                    \"Error\",\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Error);\n                return;\n            }\n\n            using (API.Client client = new())\n            {\n                try\n                {\n                    client.Initialize(0);\n                }\n                catch (API.ClientInitializeException e)\n                {\n                    if (string.IsNullOrEmpty(e.Message) == false)\n                    {\n                        MessageBox.Show(\n                            \"Steam is not running. Please start Steam then run this tool again.\\n\\n\" +\n                            \"(\" + e.Message + \")\",\n                            \"Error\",\n                            MessageBoxButtons.OK,\n                            MessageBoxIcon.Error);\n                    }\n                    else\n                    {\n                        MessageBox.Show(\n                            \"Steam is not running. Please start Steam then run this tool again.\",\n                            \"Error\",\n                            MessageBoxButtons.OK,\n                            MessageBoxIcon.Error);\n                    }\n                    return;\n                }\n                catch (DllNotFoundException)\n                {\n                    MessageBox.Show(\n                        \"You've caused an exceptional error!\",\n                        \"Error\",\n                        MessageBoxButtons.OK,\n                        MessageBoxIcon.Error);\n                    return;\n                }\n\n                Application.EnableVisualStyles();\n                Application.SetCompatibleTextRenderingDefault(false);\n                Application.Run(new GamePicker(client));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Picker/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace SAM.Picker {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"SAM.Picker.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Download {\n            get {\n                object obj = ResourceManager.GetObject(\"Download\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Filter {\n            get {\n                object obj = ResourceManager.GetObject(\"Filter\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Refresh {\n            get {\n                object obj = ResourceManager.GetObject(\"Refresh\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap Search {\n            get {\n                object obj = ResourceManager.GetObject(\"Search\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "SAM.Picker/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"Refresh\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\arrow-circle-double.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Filter\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\television-test.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Search\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\magnifier.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Download\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\download-cloud.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n</root>"
  },
  {
    "path": "SAM.Picker/SAM.Picker.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <AssemblyTitle>Steam Achievement Manager Picker</AssemblyTitle>\n    <Company>Gibbed</Company>\n    <Authors>Gibbed</Authors>\n    <Description>A game picker for the Steam Achievement Manager.</Description>\n    <Copyright>Copyright © Gibbed 2019</Copyright>\n  </PropertyGroup>\n  <PropertyGroup>\n    <Version>7.0.0</Version>\n    <AssemblyVersion>7.0.0.0</AssemblyVersion>\n    <FileVersion>7.0.0.0</FileVersion>\n  </PropertyGroup>\n  <PropertyGroup>\n    <ApplicationIcon>SAM.ico</ApplicationIcon>\n    <ApplicationManifest>app.manifest</ApplicationManifest>\n  </PropertyGroup>\n  <PropertyGroup>\n    <RepositoryUrl>https://github.com/gibbed/SteamAchievementManager/</RepositoryUrl>\n    <RepositoryType>Git</RepositoryType>\n  </PropertyGroup>\n  <PropertyGroup>\n    <OutputType>WinExe</OutputType>\n    <TargetFramework>net48</TargetFramework>\n    <LangVersion>9.0</LangVersion>\n    <Platforms>x86</Platforms>\n    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|x86' \">\n    <OutputPath>..\\bin\\</OutputPath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|x86' \">\n    <OutputPath>..\\upload\\</OutputPath>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System.Windows.Forms\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Update=\"MyListView.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Update=\"GamePicker.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <EmbeddedResource Update=\"Resources.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\n    </EmbeddedResource>\n    <Compile Update=\"Resources.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Resources.resx</DependentUpon>\n      <DesignTime>True</DesignTime>\n    </Compile>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\SAM.API\\SAM.API.csproj\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "SAM.Picker/app.manifest",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n  <assemblyIdentity version=\"1.0.0.0\" name=\"MyApplication.app\"/>\n  <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v2\">\n    <security>\n      <requestedPrivileges xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n        <requestedExecutionLevel  level=\"asInvoker\" uiAccess=\"false\" />\n      </requestedPrivileges>\n    </security>\n  </trustInfo>\n\n  <compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">\n    <application>\n\n      <!-- Windows 7 -->\n      <supportedOS Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\" />\n      <!-- Windows 8 -->\n      <supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\" />\n      <!-- Windows 8.1 -->\n      <supportedOS Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\" />\n      <!-- Windows 10 -->\n      <supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\" />\n\n    </application>\n  </compatibility>\n\n  <application xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n    <windowsSettings>\n      <dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true</dpiAware>\n    </windowsSettings>\n  </application>\n</assembly>\n"
  },
  {
    "path": "SAM.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.28803.156\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"SAM.Picker\", \"SAM.Picker\\SAM.Picker.csproj\", \"{E89E57BB-0F09-47F3-98A0-2026E2E65FBA}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"SAM.API\", \"SAM.API\\SAM.API.csproj\", \"{DF9102D5-048A-4D21-8CE3-3544CBDF0ED1}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"SAM.Game\", \"SAM.Game\\SAM.Game.csproj\", \"{7640DE31-E54E-45F9-9CF0-8DF3A3EA30FC}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{E89E57BB-0F09-47F3-98A0-2026E2E65FBA}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{E89E57BB-0F09-47F3-98A0-2026E2E65FBA}.Debug|x86.Build.0 = Debug|x86\n\t\t{E89E57BB-0F09-47F3-98A0-2026E2E65FBA}.Release|x86.ActiveCfg = Release|x86\n\t\t{E89E57BB-0F09-47F3-98A0-2026E2E65FBA}.Release|x86.Build.0 = Release|x86\n\t\t{DF9102D5-048A-4D21-8CE3-3544CBDF0ED1}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{DF9102D5-048A-4D21-8CE3-3544CBDF0ED1}.Debug|x86.Build.0 = Debug|x86\n\t\t{DF9102D5-048A-4D21-8CE3-3544CBDF0ED1}.Release|x86.ActiveCfg = Release|x86\n\t\t{DF9102D5-048A-4D21-8CE3-3544CBDF0ED1}.Release|x86.Build.0 = Release|x86\n\t\t{7640DE31-E54E-45F9-9CF0-8DF3A3EA30FC}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{7640DE31-E54E-45F9-9CF0-8DF3A3EA30FC}.Debug|x86.Build.0 = Debug|x86\n\t\t{7640DE31-E54E-45F9-9CF0-8DF3A3EA30FC}.Release|x86.ActiveCfg = Release|x86\n\t\t{7640DE31-E54E-45F9-9CF0-8DF3A3EA30FC}.Release|x86.Build.0 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {FB343317-9FA7-49C3-A55C-D95A69E836EC}\n\tEndGlobalSection\nEndGlobal\n"
  }
]