mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-04-19 19:14:51 +00:00
Parse root level version instead of relying on token gameversion. (#332)
* Implement root level revision parsing * Fix class naming * Implement suggestions from code review * Safety checks and remove deploy build * Don't attempt to parse LVLt and change branch nomenclature. * Treat text formatted resources as unsafe * Update magic header of test script file * Fix LBP Vita revision check Co-authored-by: Jayden <jvyden@jvyden.xyz>
This commit is contained in:
parent
e937f4f7cb
commit
a599732894
4 changed files with 96 additions and 24 deletions
|
@ -8,7 +8,6 @@ using LBPUnion.ProjectLighthouse.Logging;
|
|||
using LBPUnion.ProjectLighthouse.PlayerData;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
|
||||
using LBPUnion.ProjectLighthouse.Serialization;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
|
@ -47,6 +46,12 @@ public class PublishController : ControllerBase
|
|||
|
||||
if (string.IsNullOrEmpty(slot.ResourceCollection)) slot.ResourceCollection = slot.RootLevel;
|
||||
|
||||
LbpFile? rootLevel = LbpFile.FromHash(slot.RootLevel);
|
||||
if (rootLevel == null) return this.BadRequest();
|
||||
|
||||
GameVersion slotVersion = FileHelper.ParseLevelVersion(rootLevel);
|
||||
if (slotVersion == GameVersion.Unknown) slotVersion = gameToken.GameVersion;
|
||||
|
||||
// Republish logic
|
||||
if (slot.SlotId != 0)
|
||||
{
|
||||
|
@ -54,7 +59,7 @@ public class PublishController : ControllerBase
|
|||
if (oldSlot == null) return this.NotFound();
|
||||
if (oldSlot.CreatorId != user.UserId) return this.BadRequest();
|
||||
}
|
||||
else if (user.GetUsedSlotsForGame(gameToken.GameVersion) > ServerConfiguration.Instance.UserGeneratedContentLimits.EntitledSlots)
|
||||
else if (user.GetUsedSlotsForGame(slotVersion) > ServerConfiguration.Instance.UserGeneratedContentLimits.EntitledSlots)
|
||||
{
|
||||
return this.StatusCode(403, "");
|
||||
}
|
||||
|
@ -127,6 +132,11 @@ public class PublishController : ControllerBase
|
|||
return this.BadRequest();
|
||||
}
|
||||
|
||||
GameVersion slotVersion = FileHelper.ParseLevelVersion(rootLevel);
|
||||
|
||||
slot.GameVersion = slotVersion;
|
||||
if (slotVersion == GameVersion.Unknown) slot.GameVersion = gameToken.GameVersion;
|
||||
|
||||
// Republish logic
|
||||
if (slot.SlotId != 0)
|
||||
{
|
||||
|
@ -177,16 +187,6 @@ public class PublishController : ControllerBase
|
|||
|
||||
slot.TeamPick = oldSlot.TeamPick;
|
||||
|
||||
// Only update a slot's gameVersion if the level was actually change
|
||||
if (oldSlot.RootLevel != slot.RootLevel)
|
||||
{
|
||||
slot.GameVersion = gameToken.GameVersion;
|
||||
}
|
||||
else
|
||||
{
|
||||
slot.GameVersion = oldSlot.GameVersion;
|
||||
}
|
||||
|
||||
if (slot.MinimumPlayers == 0 || slot.MaximumPlayers == 0)
|
||||
{
|
||||
slot.MinimumPlayers = 1;
|
||||
|
@ -198,7 +198,7 @@ public class PublishController : ControllerBase
|
|||
return this.Ok(oldSlot.Serialize(gameToken.GameVersion));
|
||||
}
|
||||
|
||||
if (user.GetUsedSlotsForGame(gameToken.GameVersion) > ServerConfiguration.Instance.UserGeneratedContentLimits.EntitledSlots)
|
||||
if (user.GetUsedSlotsForGame(slotVersion) > ServerConfiguration.Instance.UserGeneratedContentLimits.EntitledSlots)
|
||||
{
|
||||
Logger.Warn("Rejecting level upload, too many published slots", LogArea.Publish);
|
||||
return this.BadRequest();
|
||||
|
@ -216,7 +216,6 @@ public class PublishController : ControllerBase
|
|||
slot.CreatorId = user.UserId;
|
||||
slot.FirstUploaded = TimeHelper.UnixTimeMilliseconds();
|
||||
slot.LastUpdated = TimeHelper.UnixTimeMilliseconds();
|
||||
slot.GameVersion = gameToken.GameVersion;
|
||||
|
||||
if (slot.MinimumPlayers == 0 || slot.MaximumPlayers == 0)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
FSH
|
||||
FSHb
|
||||
|
||||
this is not my stuff to upload so its just gonna be a file like this for now :/
|
|
@ -0,0 +1,27 @@
|
|||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse.Files;
|
||||
using LBPUnion.ProjectLighthouse.Levels;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.MigrationTasks;
|
||||
|
||||
public class CleanupSlotVersionMismatchMigration : IMigrationTask
|
||||
{
|
||||
public string Name() => "Cleanup slot versions";
|
||||
|
||||
async Task<bool> IMigrationTask.Run(Database database)
|
||||
{
|
||||
foreach (Slot slot in database.Slots)
|
||||
{
|
||||
LbpFile rootLevel = LbpFile.FromHash(slot.RootLevel);
|
||||
if (rootLevel == null) continue;
|
||||
|
||||
GameVersion slotVersion = FileHelper.ParseLevelVersion(rootLevel);
|
||||
|
||||
if (slotVersion != GameVersion.Unknown) slot.GameVersion = slotVersion;
|
||||
}
|
||||
|
||||
await database.SaveChangesAsync();
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ using ICSharpCode.SharpZipLib.Zip.Compression;
|
|||
using LBPUnion.ProjectLighthouse.Configuration;
|
||||
using LBPUnion.ProjectLighthouse.Extensions;
|
||||
using LBPUnion.ProjectLighthouse.Logging;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
|
@ -50,6 +51,51 @@ public static class FileHelper
|
|||
};
|
||||
}
|
||||
|
||||
public static GameVersion ParseLevelVersion(LbpFile file)
|
||||
{
|
||||
if (file.FileType != LbpFileType.Level || file.Data.Length < 16 || file.Data[3] != 'b') return GameVersion.Unknown;
|
||||
|
||||
// Revision numbers borrowed from https://github.com/ennuo/toolkit/blob/main/src/main/java/ennuo/craftworld/resources/structs/Revision.java
|
||||
|
||||
const ushort lbp2Latest = 0x3F8;
|
||||
const ushort lbp1Latest = 0x272;
|
||||
const ushort lbpVitaLatest = 0x3E2;
|
||||
const ushort lbpVitaDescriptor = 0x4431;
|
||||
// There are like 1600 revisions so this doesn't cover everything
|
||||
uint revision = 0;
|
||||
|
||||
// construct a 32 bit number from 4 individual bytes
|
||||
for (int i = 4; i <= 7; i++)
|
||||
{
|
||||
revision <<= 8;
|
||||
revision |= file.Data[i];
|
||||
}
|
||||
|
||||
if (revision >= 0x271)
|
||||
{
|
||||
// construct a 16 bit number from 2 individual bytes
|
||||
ushort branchDescriptor = (ushort) (file.Data[12] << 8 | file.Data[13]);
|
||||
if (revision == lbpVitaLatest && branchDescriptor == lbpVitaDescriptor) return GameVersion.LittleBigPlanetVita;
|
||||
}
|
||||
|
||||
|
||||
GameVersion version = GameVersion.Unknown;
|
||||
if (revision <= lbp1Latest)
|
||||
{
|
||||
version = GameVersion.LittleBigPlanet1;
|
||||
}
|
||||
else if (revision >> 0x10 != 0)
|
||||
{
|
||||
version = GameVersion.LittleBigPlanet3;
|
||||
}
|
||||
else if(revision <= lbp2Latest)
|
||||
{
|
||||
version = GameVersion.LittleBigPlanet2;
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
public static LbpFileType DetermineFileType(byte[] data)
|
||||
{
|
||||
if (data.Length == 0) return LbpFileType.Unknown; // Can't be anything if theres no data.
|
||||
|
@ -63,18 +109,18 @@ public static class FileHelper
|
|||
string footer = Encoding.ASCII.GetString(readLastBytes(reader, 4));
|
||||
if (footer == "FARC") return LbpFileType.FileArchive;
|
||||
|
||||
byte[] header = reader.ReadBytes(3);
|
||||
byte[] header = reader.ReadBytes(4);
|
||||
|
||||
return Encoding.ASCII.GetString(header) switch
|
||||
{
|
||||
"REC" => LbpFileType.MotionRecording,
|
||||
"PRF" => LbpFileType.CrossLevel,
|
||||
"PTG" => LbpFileType.Painting,
|
||||
"TEX" => LbpFileType.Texture,
|
||||
"FSH" => LbpFileType.Script,
|
||||
"VOP" => LbpFileType.Voice,
|
||||
"LVL" => LbpFileType.Level,
|
||||
"PLN" => LbpFileType.Plan,
|
||||
"RECb" => LbpFileType.MotionRecording,
|
||||
"PRFb" => LbpFileType.CrossLevel,
|
||||
"PTGb" => LbpFileType.Painting,
|
||||
"TEX " => LbpFileType.Texture,
|
||||
"FSHb" => LbpFileType.Script,
|
||||
"VOPb" => LbpFileType.Voice,
|
||||
"LVLb" => LbpFileType.Level,
|
||||
"PLNb" => LbpFileType.Plan,
|
||||
_ => readAlternateHeader(reader),
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue