Skip to content
15 changes: 0 additions & 15 deletions Refresh.Core/Extensions/GameAssetExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,6 @@ namespace Refresh.Core.Extensions;

public static class GameAssetExtensions
{
public static void TraverseDependenciesRecursively(this GameAsset asset, GameDatabaseContext database, Action<string, GameAsset?> callback)
{
callback(asset.AssetHash, asset);
foreach (string internalAssetHash in database.GetAssetDependencies(asset).ToArray())
{
GameAsset? internalAsset = database.GetAssetFromHash(internalAssetHash);

// Only run this if this is null, since the next recursion will trigger its own callback
if(internalAsset == null)
callback(internalAssetHash, internalAsset);

internalAsset?.TraverseDependenciesRecursively(database, callback);
}
}

/// <summary>
/// Automatically crops and resizes an image into its corresponding icon form.
/// </summary>
Expand Down
14 changes: 14 additions & 0 deletions Refresh.Core/Services/CommandService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ public void HandleCommand(CommandInvocation command, GameDatabaseContext databas
database.SetUnescapeXmlSequences(user, false);
break;
}
case "showmodp":
case "showmoddedplanet":
case "showmoddedplanets":
{
database.SetShowModdedPlanets(user, true);
break;
}
case "hidemodp":
case "hidemoddedplanet":
case "hidemoddedplanets":
{
database.SetShowModdedPlanets(user, false);
break;
}
case "showmods":
{
database.SetShowModdedContent(user, true);
Expand Down
21 changes: 21 additions & 0 deletions Refresh.Database/Extensions/GameAssetExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Refresh.Database.Models.Assets;

namespace Refresh.Database.Extensions;

public static class GameAssetExtensions
{
public static void TraverseDependenciesRecursively(this GameAsset asset, GameDatabaseContext database, Action<string, GameAsset?> callback)
{
callback(asset.AssetHash, asset);
foreach (string internalAssetHash in database.GetAssetDependencies(asset).ToArray())
{
GameAsset? internalAsset = database.GetAssetFromHash(internalAssetHash);

// Only run this if this is null, since the next recursion will trigger its own callback
if(internalAsset == null)
callback(internalAssetHash, internalAsset);

internalAsset?.TraverseDependenciesRecursively(database, callback);
}
}
}
53 changes: 45 additions & 8 deletions Refresh.Database/GameDatabaseContext.Users.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Refresh.Database.Models.Levels.Scores;
using Refresh.Database.Models.Levels;
using Refresh.Database.Models.Photos;
using Refresh.Database.Models.Assets;

namespace Refresh.Database;

Expand Down Expand Up @@ -111,24 +112,26 @@ public void UpdateUserData(GameUser user, ISerializedEditUser data, TokenGame ga
{
case TokenGame.LittleBigPlanet2:
user.Lbp2PlanetsHash = data.PlanetsHash;
user.Lbp3PlanetsHash = data.PlanetsHash;
user.AreLbp2PlanetsModded = this.GetPlanetModdedStatus(data.PlanetsHash);
break;
case TokenGame.LittleBigPlanet3:
user.Lbp3PlanetsHash = data.PlanetsHash;
user.AreLbp3PlanetsModded = this.GetPlanetModdedStatus(data.PlanetsHash);
break;
case TokenGame.LittleBigPlanetVita:
user.VitaPlanetsHash = data.PlanetsHash;
user.AreVitaPlanetsModded = this.GetPlanetModdedStatus(data.PlanetsHash);
break;
case TokenGame.BetaBuild:
user.BetaPlanetsHash = data.PlanetsHash;
user.AreBetaPlanetsModded = this.GetPlanetModdedStatus(data.PlanetsHash);
break;
}

// ReSharper disable once InvertIf
if (data.IconHash != null)
switch (game)
{

case TokenGame.LittleBigPlanet1:
case TokenGame.LittleBigPlanet2:
case TokenGame.LittleBigPlanet3:
Expand Down Expand Up @@ -214,6 +217,9 @@ public void UpdateUserData(GameUser user, IApiEditUserRequest data)

if (data.ProfileVisibility != null)
user.ProfileVisibility = data.ProfileVisibility.Value;

if (data.ShowModdedPlanets != null)
user.ShowModdedPlanets = data.ShowModdedPlanets.Value;

if (data.ShowModdedContent != null)
user.ShowModdedContent = data.ShowModdedContent.Value;
Expand All @@ -226,6 +232,28 @@ public void UpdateUserData(GameUser user, IApiEditUserRequest data)
});
}

public void UpdatePlanetModdedStatus(GameUser user)
{
user.AreLbp2PlanetsModded = this.GetPlanetModdedStatus(user.Lbp2PlanetsHash);
user.AreLbp3PlanetsModded = this.GetPlanetModdedStatus(user.Lbp3PlanetsHash);
user.AreVitaPlanetsModded = this.GetPlanetModdedStatus(user.VitaPlanetsHash);
user.AreBetaPlanetsModded = this.GetPlanetModdedStatus(user.BetaPlanetsHash);
}

private bool GetPlanetModdedStatus(string rootAssetHash)
{
bool modded = false;

GameAsset? rootAsset = this.GetAssetFromHash(rootAssetHash);
rootAsset?.TraverseDependenciesRecursively(this, (_, asset) =>
{
if (asset != null && (asset.AssetFlags & (AssetFlags.Modded | AssetFlags.ModdedOnPlanets)) != 0)
modded = true;
});

return modded;
}

[Pure]
public int GetTotalUserCount() => this.GameUsers.Count();

Expand Down Expand Up @@ -370,12 +398,15 @@ public void FullyDeleteUser(GameUser user)

public void ResetUserPlanets(GameUser user)
{
this.Write(() =>
{
user.Lbp2PlanetsHash = "0";
user.Lbp3PlanetsHash = "0";
user.VitaPlanetsHash = "0";
});
user.Lbp2PlanetsHash = "0";
user.Lbp3PlanetsHash = "0";
user.VitaPlanetsHash = "0";
user.BetaPlanetsHash = "0";
user.AreLbp2PlanetsModded = false;
user.AreLbp3PlanetsModded = false;
user.AreVitaPlanetsModded = false;
user.AreBetaPlanetsModded = false;
this.SaveChanges();
}

public void SetUnescapeXmlSequences(GameUser user, bool value)
Expand All @@ -386,6 +417,12 @@ public void SetUnescapeXmlSequences(GameUser user, bool value)
});
}

public void SetShowModdedPlanets(GameUser user, bool value)
{
user.ShowModdedPlanets = value;
this.SaveChanges();
}

public void SetShowModdedContent(GameUser user, bool value)
{
this.Write(() =>
Expand Down
76 changes: 76 additions & 0 deletions Refresh.Database/Migrations/20251020102449_TrackModdedPlanets.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace Refresh.Database.Migrations
{
/// <inheritdoc />
[DbContext(typeof(GameDatabaseContext))]
[Migration("20251020102449_TrackModdedPlanets")]
public partial class TrackModdedPlanets : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "AreBetaPlanetsModded",
table: "GameUsers",
type: "boolean",
nullable: false,
defaultValue: false);

migrationBuilder.AddColumn<bool>(
name: "AreLbp2PlanetsModded",
table: "GameUsers",
type: "boolean",
nullable: false,
defaultValue: false);

migrationBuilder.AddColumn<bool>(
name: "AreLbp3PlanetsModded",
table: "GameUsers",
type: "boolean",
nullable: false,
defaultValue: false);

migrationBuilder.AddColumn<bool>(
name: "AreVitaPlanetsModded",
table: "GameUsers",
type: "boolean",
nullable: false,
defaultValue: false);

migrationBuilder.AddColumn<bool>(
name: "ShowModdedPlanets",
table: "GameUsers",
type: "boolean",
nullable: false,
defaultValue: true);
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "AreBetaPlanetsModded",
table: "GameUsers");

migrationBuilder.DropColumn(
name: "AreLbp2PlanetsModded",
table: "GameUsers");

migrationBuilder.DropColumn(
name: "AreLbp3PlanetsModded",
table: "GameUsers");

migrationBuilder.DropColumn(
name: "AreVitaPlanetsModded",
table: "GameUsers");

migrationBuilder.DropColumn(
name: "ShowModdedPlanets",
table: "GameUsers");
}
}
}
15 changes: 15 additions & 0 deletions Refresh.Database/Migrations/GameDatabaseContextModelSnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,18 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property<bool>("AllowIpAuthentication")
.HasColumnType("boolean");

b.Property<bool>("AreBetaPlanetsModded")
.HasColumnType("boolean");

b.Property<bool>("AreLbp2PlanetsModded")
.HasColumnType("boolean");

b.Property<bool>("AreLbp3PlanetsModded")
.HasColumnType("boolean");

b.Property<bool>("AreVitaPlanetsModded")
.HasColumnType("boolean");

b.Property<DateTimeOffset?>("BanExpiryDate")
.HasColumnType("timestamp with time zone");

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

b.Property<bool>("ShowModdedPlanets")
.HasColumnType("boolean");

b.Property<bool>("ShowReuploadedContent")
.HasColumnType("boolean");

Expand Down
35 changes: 20 additions & 15 deletions Refresh.Database/Models/Assets/AssetFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ public enum AssetFlags
/// This asset will only ever be created by mods.
/// </summary>
Modded = 1 << 2,
/// <summary>
/// A planet is considered modded if it depends on this asset, or if the asset already has the Modded flag above.
/// </summary>
ModdedOnPlanets = 1 << 3,
}

public static class AssetSafetyLevelExtensions
Expand All @@ -26,29 +30,30 @@ public static AssetFlags FromAssetType(GameAssetType type, GameAssetFormat? meth
{
// Common asset types created by the game
GameAssetType.Level => AssetFlags.None,
GameAssetType.StreamingLevelChunk => AssetFlags.None,
GameAssetType.StreamingLevelChunk => AssetFlags.None | AssetFlags.ModdedOnPlanets,
GameAssetType.Plan => AssetFlags.None,
GameAssetType.ThingRecording => AssetFlags.None,
GameAssetType.SyncedProfile => AssetFlags.None,
GameAssetType.GriefSongState => AssetFlags.None,
GameAssetType.Quest => AssetFlags.None,
GameAssetType.AdventureSharedData => AssetFlags.None,
GameAssetType.AdventureCreateProfile => AssetFlags.None,
GameAssetType.ChallengeGhost => AssetFlags.None,
GameAssetType.ThingRecording => AssetFlags.None | AssetFlags.ModdedOnPlanets,
GameAssetType.SyncedProfile => AssetFlags.None | AssetFlags.ModdedOnPlanets,
GameAssetType.GriefSongState => AssetFlags.None | AssetFlags.ModdedOnPlanets,
GameAssetType.Quest => AssetFlags.None | AssetFlags.ModdedOnPlanets,
GameAssetType.AdventureSharedData => AssetFlags.None | AssetFlags.ModdedOnPlanets,
GameAssetType.AdventureCreateProfile => AssetFlags.None | AssetFlags.ModdedOnPlanets,
GameAssetType.ChallengeGhost => AssetFlags.None | AssetFlags.ModdedOnPlanets,

// Common media types created by the game
GameAssetType.VoiceRecording => AssetFlags.Media,
GameAssetType.VoiceRecording => AssetFlags.Media | AssetFlags.ModdedOnPlanets,
GameAssetType.Painting => AssetFlags.Media,
GameAssetType.Texture => AssetFlags.Media,
GameAssetType.Jpeg => AssetFlags.Media,
GameAssetType.Png => AssetFlags.Media,
GameAssetType.Tga => AssetFlags.Media,
GameAssetType.Mip => AssetFlags.Media,
GameAssetType.Tga => AssetFlags.Media | AssetFlags.ModdedOnPlanets,
GameAssetType.Mip => AssetFlags.Media | AssetFlags.ModdedOnPlanets,

// Uncommon, but still vanilla assets created by the game in niche scenarios
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
GameAssetType.Material => AssetFlags.None,
GameAssetType.Bevel => AssetFlags.None,
// Uncommon, but still vanilla assets created by the game in niche scenarios.
// While not image/audio data like the other media types, GfxMaterial is marked as media because this file can contain full PS3 shaders.
GameAssetType.GfxMaterial => AssetFlags.Media | AssetFlags.ModdedOnPlanets,
GameAssetType.Material => AssetFlags.None | AssetFlags.ModdedOnPlanets,
GameAssetType.Bevel => AssetFlags.None | AssetFlags.ModdedOnPlanets,

// Modded media types
GameAssetType.GameDataTexture => AssetFlags.Media | AssetFlags.Modded,
Expand Down
10 changes: 10 additions & 0 deletions Refresh.Database/Models/Users/GameUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ public partial class GameUser : IRateLimitUser
public string Lbp3PlanetsHash { get; set; } = "0";
public string VitaPlanetsHash { get; set; } = "0";

public bool AreBetaPlanetsModded { get; set; }
public bool AreLbp2PlanetsModded { get; set; }
public bool AreLbp3PlanetsModded { get; set; }
public bool AreVitaPlanetsModded { get; set; }

public string YayFaceHash { get; set; } = "0";
public string BooFaceHash { get; set; } = "0";
public string MehFaceHash { get; set; } = "0";
Expand Down Expand Up @@ -119,6 +124,11 @@ public partial class GameUser : IRateLimitUser

public GameUserRole Role { get; set; }

/// <summary>
/// Whether planets containing mods or VoiceRecordings should be shown in-game
/// </summary>
public bool ShowModdedPlanets { get; set; } = true;

/// <summary>
/// Whether modded content should be shown in level listings
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions Refresh.Database/Query/IApiEditUserRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public interface IApiEditUserRequest
bool? RedirectGriefReportsToPhotos { get; set; }
bool? UnescapeXmlSequences { get; set; }
string? EmailAddress { get; set; }
bool? ShowModdedPlanets { get; set; }
bool? ShowModdedContent { get; set; }
bool? ShowReuploadedContent { get; set; }
Visibility? LevelVisibility { get; set; }
Expand Down
10 changes: 10 additions & 0 deletions Refresh.Interfaces.APIv3/Endpoints/Admin/AdminUserApiEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ public ApiResponse<ApiAdminUserPlanetsResponse> GetUserPlanetsByUuid(RequestCont
Lbp2PlanetsHash = user.Lbp2PlanetsHash,
Lbp3PlanetsHash = user.Lbp3PlanetsHash,
VitaPlanetsHash = user.VitaPlanetsHash,
BetaPlanetsHash = user.BetaPlanetsHash,
AreLbp2PlanetsModded = user.AreLbp2PlanetsModded,
AreLbp3PlanetsModded = user.AreLbp3PlanetsModded,
AreVitaPlanetsModded = user.AreVitaPlanetsModded,
AreBetaPlanetsModded = user.AreBetaPlanetsModded,
};
}

Expand All @@ -123,6 +128,11 @@ public ApiResponse<ApiAdminUserPlanetsResponse> GetUserPlanetsByUsername(Request
Lbp2PlanetsHash = user.Lbp2PlanetsHash,
Lbp3PlanetsHash = user.Lbp3PlanetsHash,
VitaPlanetsHash = user.VitaPlanetsHash,
BetaPlanetsHash = user.BetaPlanetsHash,
AreLbp2PlanetsModded = user.AreLbp2PlanetsModded,
AreLbp3PlanetsModded = user.AreLbp3PlanetsModded,
AreVitaPlanetsModded = user.AreVitaPlanetsModded,
AreBetaPlanetsModded = user.AreBetaPlanetsModded,
};
}

Expand Down
Loading