Skip to content

Commit

Permalink
Filter out demos by default
Browse files Browse the repository at this point in the history
  • Loading branch information
Citrinate committed Jul 21, 2024
1 parent a05f6f8 commit f183c7e
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 7 deletions.
23 changes: 23 additions & 0 deletions FreePackages.Tests/Filters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public void CanFilterAppAppByParentTag() {
var demo = new FilterableApp(KeyValue.LoadAsText("demo_with_fewer_tags_than_parent.txt"));
var demoParent = KeyValue.LoadAsText("demo_with_fewer_tags_than_parent_parent.txt");

Filter.Types.Add("Demo");
Filter.Tags.Add(1742);

Assert.IsFalse(PackageFilter.IsAppWantedByFilter(demo, Filter));
Expand Down Expand Up @@ -431,4 +432,26 @@ public void CanFilterByReleaseDate() {

Assert.IsTrue(PackageFilter.IsAppWantedByFilter(app, Filter));
}

[TestMethod]
public void CanFilterDemos() {
var app = new FilterableApp(KeyValue.LoadAsText("demo_which_will_be_removed.txt"));

Assert.IsFalse(PackageFilter.IsWantedApp(app));
Assert.IsFalse(PackageFilter.IsAppWantedByFilter(app, Filter));

Filter.Types.Add("Demo");
var packageFilterWhichAllowsDemos = new PackageFilter(new BotCache(), new List<FilterConfig>() { Filter });
packageFilterWhichAllowsDemos.UpdateUserData(File.ReadAllText("userdata_empty.json").ToJsonObject<UserData>());

Assert.IsTrue(packageFilterWhichAllowsDemos.IsWantedApp(app));
Assert.IsTrue(PackageFilter.IsAppWantedByFilter(app, Filter));

var package = new FilterablePackage(KeyValue.LoadAsText("package_with_demo_which_will_be_removed.txt"));
var package_app_1 = KeyValue.LoadAsText("demo_which_will_be_removed.txt");
package.AddPackageContents(new List<KeyValue>() { package_app_1 });

Assert.IsTrue(packageFilterWhichAllowsDemos.IsWantedPackage(package));
Assert.IsFalse(PackageFilter.IsWantedPackage(package));
}
}
118 changes: 118 additions & 0 deletions FreePackages.Tests/TestData/demo_which_will_be_removed.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
"appinfo"
{
"appid" "2390760"
"common"
{
"name" "Headlong Hunt Demo"
"type" "Demo"
"parent" "2323660"
"icon" "4d5a7385e6b89cd637710621077ff5b78d6c97d0"
"clienticon" "0b952c17ef430b1024660c6744ea2a7ed8a1acbf"
"clienttga" "27711ecff9b45a6ba3208f56ff8632560e379a97"
"oslist" "windows"
"osarch" ""
"osextended" ""
"releasestate" "released"
"controller_support" "full"
"small_capsule"
{
"english" "capsule_231x87.jpg"
}
"header_image"
{
"english" "header.jpg"
}
"store_asset_mtime" "1694580774"
"associations"
{
"0"
{
"type" "developer"
"name" "Toombler Games"
}
"1"
{
"type" "publisher"
"name" "Toombler Games"
}
}
"primary_genre" "0"
"category"
{
"category_2" "1"
"category_28" "1"
"category_62" "1"
}
"supported_languages"
{
"english"
{
"supported" "true"
"full_audio" "true"
"subtitles" "true"
}
}
"steam_release_date" "1682337932"
"gameid" "2390760"
"exfgls" "6"
}
"extended"
{
"demoofappid" "2323660"
"developer" "Toombler Games"
"publisher" "Toombler Games"
}
"config"
{
"installdir" "Headlong Hunt Demo"
"launch"
{
"0"
{
"executable" "Headlong Hunt Demo.exe"
"config"
{
"oslist" "windows"
}
}
}
}
"depots"
{
"2390761"
{
"manifests"
{
"public"
{
"gid" "4197211795039899891"
"size" "227173403"
"download" "73094016"
}
}
"encryptedmanifests"
{
"developer"
{
"gid" "7804171D02872B87E66931369B0CB771"
"size" "158735D7CADF0FA8A8123611B609B5ED"
"download" "DF1C5DD4990E11ADCB42C8B55716E897"
}
}
}
"branches"
{
"public"
{
"buildid" "12253280"
"timeupdated" "1695358167"
}
"developer"
{
"buildid" "12253422"
"pwdrequired" "1"
"timeupdated" "1695359406"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"860092"
{
"packageid" "860092"
"billingtype" "12"
"licensetype" "1"
"status" "0"
"extended"
{
}
"appids"
{
"0" "2390760"
}
"depotids"
{
"0" "2390761"
}
"appitems"
{
}
}
3 changes: 3 additions & 0 deletions FreePackages.Tests/generate_test_data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ get_app 1086940 "package_with_single_app_app_1"

get_sub 44911 "package_which_is_no_cost"

get_app 2390760 "demo_which_will_be_removed"
get_sub 860092 "package_with_demo_which_will_be_removed"

# For app testing

get_app 440 "app_which_is_free"
Expand Down
2 changes: 1 addition & 1 deletion FreePackages/FreePackages.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<Authors>Citrinate</Authors>
<AssemblyVersion>1.5.0.2</AssemblyVersion>
<AssemblyVersion>1.5.1.0</AssemblyVersion>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<TargetFramework>net8.0</TargetFramework>
Expand Down
41 changes: 38 additions & 3 deletions FreePackages/Handlers/PackageFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ internal bool IsAppWantedByFilter(FilterableApp app, FilterConfig filter) {
return false;
}

if (app.Type == EAppType.Demo && !app.HasType(filter.Types)) {
// Demos are unwanted by default unless the filter explicitly applies to them
return false;
}

if (filter.Categories.Count > 0 && !app.HasCategory(filter.Categories, filter.RequireAllCategories)) {
// Unwanted due to missing categories
return false;
Expand Down Expand Up @@ -388,8 +393,38 @@ internal bool FilterOnlyAllowsPackages(FilterConfig filter) {
return false;
}

internal bool IsWantedApp(FilterableApp app) => FilterConfigs.Count == 0 || FilterConfigs.Any(filter => !FilterOnlyAllowsPackages(filter) && IsAppWantedByFilter(app, filter) && !IsAppIgnoredByFilter(app, filter));
internal bool IsWantedPackage(FilterablePackage package) => FilterConfigs.Count == 0 || FilterConfigs.Any(filter => IsPackageWantedByFilter(package, filter) && !IsPackageIgnoredByFilter(package, filter));
internal bool IsWantedPlaytest(FilterableApp app) => FilterConfigs.Count > 0 && FilterConfigs.Any(filter => !FilterOnlyAllowsPackages(filter) && IsPlaytestWantedByFilter(app, filter) && !IsAppIgnoredByFilter(app, filter));
internal bool IsWantedApp(FilterableApp app) {
if (FilterConfigs.Count == 0) {
if (app.Type == EAppType.Demo) {
// Demos are unwanted by default
return false;
}

return true;
}

return FilterConfigs.Any(filter => !FilterOnlyAllowsPackages(filter) && IsAppWantedByFilter(app, filter) && !IsAppIgnoredByFilter(app, filter));
}

internal bool IsWantedPackage(FilterablePackage package) {
if (FilterConfigs.Count == 0) {
if (package.PackageContents.All(app => app.Type == EAppType.Demo)) {
// Demos are unwanted by default
return false;
}

return true;
}

return FilterConfigs.Any(filter => IsPackageWantedByFilter(package, filter) && !IsPackageIgnoredByFilter(package, filter));
}

internal bool IsWantedPlaytest(FilterableApp app) {
if (FilterConfigs.Count == 0) {
return false;
}

return FilterConfigs.Any(filter => !FilterOnlyAllowsPackages(filter) && IsPlaytestWantedByFilter(app, filter) && !IsAppIgnoredByFilter(app, filter));
}
}
}
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ Under certain conditions, activating a free package while playing a game on Stea

### Changing the package limit

A maximum of 30 packages can be activated per 1.5 hours. By default, this plugin will use at most 25 of those activations and will resume where it left off if it's ever interrupted. You can control this limit by adding `FreePackagesPerHour` to your individual bot's config files of `uint` type:
A maximum of 30 packages can be activated per 1.5 hours. By default, this plugin will use at most 25 of those activations and will resume where it left off if it's ever interrupted. You can control this limit by adding `FreePackagesLimit` to your individual bot's config files of `uint` type:

```json
"FreePackagesPerHour": 25,
"FreePackagesLimit": 25,
```

> [!NOTE]
Expand All @@ -57,7 +57,7 @@ A maximum of 30 packages can be activated per 1.5 hours. By default, this plugi

### Enabling package filters

By default, the plugin will attempt to activate all free non-playtest packages. You can control what kinds of packages are activated by adding `FreePackagesFilters` to your individual bot's config files with the following structure:
By default, the plugin will attempt to activate all free non-demo and non-playtest packages. You can control what kinds of packages are activated by adding `FreePackagesFilters` to your individual bot's config files with the following structure:

```json
"FreePackagesFilters": [{
Expand Down Expand Up @@ -91,6 +91,9 @@ All filter options are explained below:

`HashSet<string>` type with default value of `[]`. Packages must contain an app with one of the `TypeNames` specified here or they will not be added to your account. You can leave this empty to allow for all types. The available `TypeNames` for filtering are: `"Game"`, `"Application"`, `"Tool"`, `"Demo"`, `"DLC"`, `"Music"`, `"Video"`

> [!NOTE]
> Demos are filtered out by default. This is because Steam will automatically remove all demos from your account eventually. However if you specify in your `Types` that you do want demos, then they will be included for that filter.
---

#### Tags
Expand Down

0 comments on commit f183c7e

Please sign in to comment.