Skip to content

Commit 291a41f

Browse files
authored
Implement detecting and hiding modded planets if preferred (#974)
Closes #968
2 parents e0273e5 + 3049667 commit 291a41f

File tree

18 files changed

+543
-46
lines changed

18 files changed

+543
-46
lines changed

Refresh.Core/Extensions/GameAssetExtensions.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,6 @@ namespace Refresh.Core.Extensions;
1515

1616
public static class GameAssetExtensions
1717
{
18-
public static void TraverseDependenciesRecursively(this GameAsset asset, GameDatabaseContext database, Action<string, GameAsset?> callback)
19-
{
20-
callback(asset.AssetHash, asset);
21-
foreach (string internalAssetHash in database.GetAssetDependencies(asset).ToArray())
22-
{
23-
GameAsset? internalAsset = database.GetAssetFromHash(internalAssetHash);
24-
25-
// Only run this if this is null, since the next recursion will trigger its own callback
26-
if(internalAsset == null)
27-
callback(internalAssetHash, internalAsset);
28-
29-
internalAsset?.TraverseDependenciesRecursively(database, callback);
30-
}
31-
}
32-
3318
/// <summary>
3419
/// Automatically crops and resizes an image into its corresponding icon form.
3520
/// </summary>

Refresh.Core/Services/CommandService.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,20 @@ public void HandleCommand(CommandInvocation command, GameDatabaseContext databas
100100
database.SetUnescapeXmlSequences(user, false);
101101
break;
102102
}
103+
case "showmodp":
104+
case "showmoddedplanet":
105+
case "showmoddedplanets":
106+
{
107+
database.SetShowModdedPlanets(user, true);
108+
break;
109+
}
110+
case "hidemodp":
111+
case "hidemoddedplanet":
112+
case "hidemoddedplanets":
113+
{
114+
database.SetShowModdedPlanets(user, false);
115+
break;
116+
}
103117
case "showmods":
104118
{
105119
database.SetShowModdedContent(user, true);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Refresh.Database.Models.Assets;
2+
3+
namespace Refresh.Database.Extensions;
4+
5+
public static class GameAssetExtensions
6+
{
7+
public static void TraverseDependenciesRecursively(this GameAsset asset, GameDatabaseContext database, Action<string, GameAsset?> callback)
8+
{
9+
callback(asset.AssetHash, asset);
10+
foreach (string internalAssetHash in database.GetAssetDependencies(asset).ToArray())
11+
{
12+
GameAsset? internalAsset = database.GetAssetFromHash(internalAssetHash);
13+
14+
// Only run this if this is null, since the next recursion will trigger its own callback
15+
if(internalAsset == null)
16+
callback(internalAssetHash, internalAsset);
17+
18+
internalAsset?.TraverseDependenciesRecursively(database, callback);
19+
}
20+
}
21+
}

Refresh.Database/GameDatabaseContext.Users.cs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Refresh.Database.Models.Levels.Scores;
99
using Refresh.Database.Models.Levels;
1010
using Refresh.Database.Models.Photos;
11+
using Refresh.Database.Models.Assets;
1112

1213
namespace Refresh.Database;
1314

@@ -111,24 +112,26 @@ public void UpdateUserData(GameUser user, ISerializedEditUser data, TokenGame ga
111112
{
112113
case TokenGame.LittleBigPlanet2:
113114
user.Lbp2PlanetsHash = data.PlanetsHash;
114-
user.Lbp3PlanetsHash = data.PlanetsHash;
115+
user.AreLbp2PlanetsModded = this.GetPlanetModdedStatus(data.PlanetsHash);
115116
break;
116117
case TokenGame.LittleBigPlanet3:
117118
user.Lbp3PlanetsHash = data.PlanetsHash;
119+
user.AreLbp3PlanetsModded = this.GetPlanetModdedStatus(data.PlanetsHash);
118120
break;
119121
case TokenGame.LittleBigPlanetVita:
120122
user.VitaPlanetsHash = data.PlanetsHash;
123+
user.AreVitaPlanetsModded = this.GetPlanetModdedStatus(data.PlanetsHash);
121124
break;
122125
case TokenGame.BetaBuild:
123126
user.BetaPlanetsHash = data.PlanetsHash;
127+
user.AreBetaPlanetsModded = this.GetPlanetModdedStatus(data.PlanetsHash);
124128
break;
125129
}
126130

127131
// ReSharper disable once InvertIf
128132
if (data.IconHash != null)
129133
switch (game)
130134
{
131-
132135
case TokenGame.LittleBigPlanet1:
133136
case TokenGame.LittleBigPlanet2:
134137
case TokenGame.LittleBigPlanet3:
@@ -214,6 +217,9 @@ public void UpdateUserData(GameUser user, IApiEditUserRequest data)
214217

215218
if (data.ProfileVisibility != null)
216219
user.ProfileVisibility = data.ProfileVisibility.Value;
220+
221+
if (data.ShowModdedPlanets != null)
222+
user.ShowModdedPlanets = data.ShowModdedPlanets.Value;
217223

218224
if (data.ShowModdedContent != null)
219225
user.ShowModdedContent = data.ShowModdedContent.Value;
@@ -226,6 +232,28 @@ public void UpdateUserData(GameUser user, IApiEditUserRequest data)
226232
});
227233
}
228234

235+
public void UpdatePlanetModdedStatus(GameUser user)
236+
{
237+
user.AreLbp2PlanetsModded = this.GetPlanetModdedStatus(user.Lbp2PlanetsHash);
238+
user.AreLbp3PlanetsModded = this.GetPlanetModdedStatus(user.Lbp3PlanetsHash);
239+
user.AreVitaPlanetsModded = this.GetPlanetModdedStatus(user.VitaPlanetsHash);
240+
user.AreBetaPlanetsModded = this.GetPlanetModdedStatus(user.BetaPlanetsHash);
241+
}
242+
243+
private bool GetPlanetModdedStatus(string rootAssetHash)
244+
{
245+
bool modded = false;
246+
247+
GameAsset? rootAsset = this.GetAssetFromHash(rootAssetHash);
248+
rootAsset?.TraverseDependenciesRecursively(this, (_, asset) =>
249+
{
250+
if (asset != null && (asset.AssetFlags & (AssetFlags.Modded | AssetFlags.ModdedOnPlanets)) != 0)
251+
modded = true;
252+
});
253+
254+
return modded;
255+
}
256+
229257
[Pure]
230258
public int GetTotalUserCount() => this.GameUsers.Count();
231259

@@ -370,12 +398,15 @@ public void FullyDeleteUser(GameUser user)
370398

371399
public void ResetUserPlanets(GameUser user)
372400
{
373-
this.Write(() =>
374-
{
375-
user.Lbp2PlanetsHash = "0";
376-
user.Lbp3PlanetsHash = "0";
377-
user.VitaPlanetsHash = "0";
378-
});
401+
user.Lbp2PlanetsHash = "0";
402+
user.Lbp3PlanetsHash = "0";
403+
user.VitaPlanetsHash = "0";
404+
user.BetaPlanetsHash = "0";
405+
user.AreLbp2PlanetsModded = false;
406+
user.AreLbp3PlanetsModded = false;
407+
user.AreVitaPlanetsModded = false;
408+
user.AreBetaPlanetsModded = false;
409+
this.SaveChanges();
379410
}
380411

381412
public void SetUnescapeXmlSequences(GameUser user, bool value)
@@ -386,6 +417,12 @@ public void SetUnescapeXmlSequences(GameUser user, bool value)
386417
});
387418
}
388419

420+
public void SetShowModdedPlanets(GameUser user, bool value)
421+
{
422+
user.ShowModdedPlanets = value;
423+
this.SaveChanges();
424+
}
425+
389426
public void SetShowModdedContent(GameUser user, bool value)
390427
{
391428
this.Write(() =>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using Microsoft.EntityFrameworkCore.Infrastructure;
2+
using Microsoft.EntityFrameworkCore.Migrations;
3+
4+
#nullable disable
5+
6+
namespace Refresh.Database.Migrations
7+
{
8+
/// <inheritdoc />
9+
[DbContext(typeof(GameDatabaseContext))]
10+
[Migration("20251020102449_TrackModdedPlanets")]
11+
public partial class TrackModdedPlanets : Migration
12+
{
13+
/// <inheritdoc />
14+
protected override void Up(MigrationBuilder migrationBuilder)
15+
{
16+
migrationBuilder.AddColumn<bool>(
17+
name: "AreBetaPlanetsModded",
18+
table: "GameUsers",
19+
type: "boolean",
20+
nullable: false,
21+
defaultValue: false);
22+
23+
migrationBuilder.AddColumn<bool>(
24+
name: "AreLbp2PlanetsModded",
25+
table: "GameUsers",
26+
type: "boolean",
27+
nullable: false,
28+
defaultValue: false);
29+
30+
migrationBuilder.AddColumn<bool>(
31+
name: "AreLbp3PlanetsModded",
32+
table: "GameUsers",
33+
type: "boolean",
34+
nullable: false,
35+
defaultValue: false);
36+
37+
migrationBuilder.AddColumn<bool>(
38+
name: "AreVitaPlanetsModded",
39+
table: "GameUsers",
40+
type: "boolean",
41+
nullable: false,
42+
defaultValue: false);
43+
44+
migrationBuilder.AddColumn<bool>(
45+
name: "ShowModdedPlanets",
46+
table: "GameUsers",
47+
type: "boolean",
48+
nullable: false,
49+
defaultValue: true);
50+
}
51+
52+
/// <inheritdoc />
53+
protected override void Down(MigrationBuilder migrationBuilder)
54+
{
55+
migrationBuilder.DropColumn(
56+
name: "AreBetaPlanetsModded",
57+
table: "GameUsers");
58+
59+
migrationBuilder.DropColumn(
60+
name: "AreLbp2PlanetsModded",
61+
table: "GameUsers");
62+
63+
migrationBuilder.DropColumn(
64+
name: "AreLbp3PlanetsModded",
65+
table: "GameUsers");
66+
67+
migrationBuilder.DropColumn(
68+
name: "AreVitaPlanetsModded",
69+
table: "GameUsers");
70+
71+
migrationBuilder.DropColumn(
72+
name: "ShowModdedPlanets",
73+
table: "GameUsers");
74+
}
75+
}
76+
}

Refresh.Database/Migrations/GameDatabaseContextModelSnapshot.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,18 @@ protected override void BuildModel(ModelBuilder modelBuilder)
14881488
b.Property<bool>("AllowIpAuthentication")
14891489
.HasColumnType("boolean");
14901490

1491+
b.Property<bool>("AreBetaPlanetsModded")
1492+
.HasColumnType("boolean");
1493+
1494+
b.Property<bool>("AreLbp2PlanetsModded")
1495+
.HasColumnType("boolean");
1496+
1497+
b.Property<bool>("AreLbp3PlanetsModded")
1498+
.HasColumnType("boolean");
1499+
1500+
b.Property<bool>("AreVitaPlanetsModded")
1501+
.HasColumnType("boolean");
1502+
14911503
b.Property<DateTimeOffset?>("BanExpiryDate")
14921504
.HasColumnType("timestamp with time zone");
14931505

@@ -1584,6 +1596,9 @@ protected override void BuildModel(ModelBuilder modelBuilder)
15841596
b.Property<bool>("ShowModdedContent")
15851597
.HasColumnType("boolean");
15861598

1599+
b.Property<bool>("ShowModdedPlanets")
1600+
.HasColumnType("boolean");
1601+
15871602
b.Property<bool>("ShowReuploadedContent")
15881603
.HasColumnType("boolean");
15891604

Refresh.Database/Models/Assets/AssetFlags.cs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ public enum AssetFlags
1616
/// This asset will only ever be created by mods.
1717
/// </summary>
1818
Modded = 1 << 2,
19+
/// <summary>
20+
/// A planet is considered modded if it depends on this asset, or if the asset already has the Modded flag above.
21+
/// </summary>
22+
ModdedOnPlanets = 1 << 3,
1923
}
2024

2125
public static class AssetSafetyLevelExtensions
@@ -26,29 +30,30 @@ public static AssetFlags FromAssetType(GameAssetType type, GameAssetFormat? meth
2630
{
2731
// Common asset types created by the game
2832
GameAssetType.Level => AssetFlags.None,
29-
GameAssetType.StreamingLevelChunk => AssetFlags.None,
33+
GameAssetType.StreamingLevelChunk => AssetFlags.None | AssetFlags.ModdedOnPlanets,
3034
GameAssetType.Plan => AssetFlags.None,
31-
GameAssetType.ThingRecording => AssetFlags.None,
32-
GameAssetType.SyncedProfile => AssetFlags.None,
33-
GameAssetType.GriefSongState => AssetFlags.None,
34-
GameAssetType.Quest => AssetFlags.None,
35-
GameAssetType.AdventureSharedData => AssetFlags.None,
36-
GameAssetType.AdventureCreateProfile => AssetFlags.None,
37-
GameAssetType.ChallengeGhost => AssetFlags.None,
35+
GameAssetType.ThingRecording => AssetFlags.None | AssetFlags.ModdedOnPlanets,
36+
GameAssetType.SyncedProfile => AssetFlags.None | AssetFlags.ModdedOnPlanets,
37+
GameAssetType.GriefSongState => AssetFlags.None | AssetFlags.ModdedOnPlanets,
38+
GameAssetType.Quest => AssetFlags.None | AssetFlags.ModdedOnPlanets,
39+
GameAssetType.AdventureSharedData => AssetFlags.None | AssetFlags.ModdedOnPlanets,
40+
GameAssetType.AdventureCreateProfile => AssetFlags.None | AssetFlags.ModdedOnPlanets,
41+
GameAssetType.ChallengeGhost => AssetFlags.None | AssetFlags.ModdedOnPlanets,
3842

3943
// Common media types created by the game
40-
GameAssetType.VoiceRecording => AssetFlags.Media,
44+
GameAssetType.VoiceRecording => AssetFlags.Media | AssetFlags.ModdedOnPlanets,
4145
GameAssetType.Painting => AssetFlags.Media,
4246
GameAssetType.Texture => AssetFlags.Media,
4347
GameAssetType.Jpeg => AssetFlags.Media,
4448
GameAssetType.Png => AssetFlags.Media,
45-
GameAssetType.Tga => AssetFlags.Media,
46-
GameAssetType.Mip => AssetFlags.Media,
49+
GameAssetType.Tga => AssetFlags.Media | AssetFlags.ModdedOnPlanets,
50+
GameAssetType.Mip => AssetFlags.Media | AssetFlags.ModdedOnPlanets,
4751

48-
// Uncommon, but still vanilla assets created by the game in niche scenarios
49-
GameAssetType.GfxMaterial => AssetFlags.Media, // while not image/audio data like the other media types, this is marked as media because this file can contain full PS3 shaders
50-
GameAssetType.Material => AssetFlags.None,
51-
GameAssetType.Bevel => AssetFlags.None,
52+
// Uncommon, but still vanilla assets created by the game in niche scenarios.
53+
// While not image/audio data like the other media types, GfxMaterial is marked as media because this file can contain full PS3 shaders.
54+
GameAssetType.GfxMaterial => AssetFlags.Media | AssetFlags.ModdedOnPlanets,
55+
GameAssetType.Material => AssetFlags.None | AssetFlags.ModdedOnPlanets,
56+
GameAssetType.Bevel => AssetFlags.None | AssetFlags.ModdedOnPlanets,
5257

5358
// Modded media types
5459
GameAssetType.GameDataTexture => AssetFlags.Media | AssetFlags.Modded,

Refresh.Database/Models/Users/GameUser.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ public partial class GameUser : IRateLimitUser
7878
public string Lbp3PlanetsHash { get; set; } = "0";
7979
public string VitaPlanetsHash { get; set; } = "0";
8080

81+
public bool AreBetaPlanetsModded { get; set; }
82+
public bool AreLbp2PlanetsModded { get; set; }
83+
public bool AreLbp3PlanetsModded { get; set; }
84+
public bool AreVitaPlanetsModded { get; set; }
85+
8186
public string YayFaceHash { get; set; } = "0";
8287
public string BooFaceHash { get; set; } = "0";
8388
public string MehFaceHash { get; set; } = "0";
@@ -119,6 +124,11 @@ public partial class GameUser : IRateLimitUser
119124

120125
public GameUserRole Role { get; set; }
121126

127+
/// <summary>
128+
/// Whether planets containing mods or VoiceRecordings should be shown in-game
129+
/// </summary>
130+
public bool ShowModdedPlanets { get; set; } = true;
131+
122132
/// <summary>
123133
/// Whether modded content should be shown in level listings
124134
/// </summary>

Refresh.Database/Query/IApiEditUserRequest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public interface IApiEditUserRequest
1414
bool? RedirectGriefReportsToPhotos { get; set; }
1515
bool? UnescapeXmlSequences { get; set; }
1616
string? EmailAddress { get; set; }
17+
bool? ShowModdedPlanets { get; set; }
1718
bool? ShowModdedContent { get; set; }
1819
bool? ShowReuploadedContent { get; set; }
1920
Visibility? LevelVisibility { get; set; }

Refresh.Interfaces.APIv3/Endpoints/Admin/AdminUserApiEndpoints.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ public ApiResponse<ApiAdminUserPlanetsResponse> GetUserPlanetsByUuid(RequestCont
107107
Lbp2PlanetsHash = user.Lbp2PlanetsHash,
108108
Lbp3PlanetsHash = user.Lbp3PlanetsHash,
109109
VitaPlanetsHash = user.VitaPlanetsHash,
110+
BetaPlanetsHash = user.BetaPlanetsHash,
111+
AreLbp2PlanetsModded = user.AreLbp2PlanetsModded,
112+
AreLbp3PlanetsModded = user.AreLbp3PlanetsModded,
113+
AreVitaPlanetsModded = user.AreVitaPlanetsModded,
114+
AreBetaPlanetsModded = user.AreBetaPlanetsModded,
110115
};
111116
}
112117

@@ -123,6 +128,11 @@ public ApiResponse<ApiAdminUserPlanetsResponse> GetUserPlanetsByUsername(Request
123128
Lbp2PlanetsHash = user.Lbp2PlanetsHash,
124129
Lbp3PlanetsHash = user.Lbp3PlanetsHash,
125130
VitaPlanetsHash = user.VitaPlanetsHash,
131+
BetaPlanetsHash = user.BetaPlanetsHash,
132+
AreLbp2PlanetsModded = user.AreLbp2PlanetsModded,
133+
AreLbp3PlanetsModded = user.AreLbp3PlanetsModded,
134+
AreVitaPlanetsModded = user.AreVitaPlanetsModded,
135+
AreBetaPlanetsModded = user.AreBetaPlanetsModded,
126136
};
127137
}
128138

0 commit comments

Comments
 (0)