Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encoded data upload support #5

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Runtime/Classes/EncodedImage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using UnityEngine;

namespace ModIO
{
public class EncodedImage
{
public string extension;
public byte[] data;

public static EncodedImage PNGFromTexture2D(Texture2D texture2D)
{
return new EncodedImage
{
extension = "png",
data = texture2D.EncodeToPNG()
};
}
}
}
11 changes: 11 additions & 0 deletions Runtime/Classes/EncodedImage.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 37 additions & 11 deletions Runtime/Classes/ModProfileDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public class ModProfileDetails
/// <seealso cref="ModIOUnity.EditModProfile"/>
#if UNITY_2019_4_OR_NEWER
public Texture2D logo;
/// <summary>
/// Logo encoded in supported format.
/// </summary>
/// <seealso cref="logo"/>
public EncodedImage encodedLogo;
#else
public byte[] logo;
#endif
Expand All @@ -45,6 +50,11 @@ public class ModProfileDetails
/// <remarks>Can be null</remarks>
#if UNITY_2019_4_OR_NEWER
public Texture2D[] images;
/// <summary>
/// Images encoded in supported format.
/// </summary>
/// <seealso cref="images"/>
public IReadOnlyList<EncodedImage> encodedImages;
#else
public List<byte[]> images;
#endif
Expand Down Expand Up @@ -125,28 +135,44 @@ public class ModProfileDetails
/// <remarks>Can be null</remarks>
public CommunityOptions? communityOptions = CommunityOptions.AllowCommenting;

internal byte[] GetLogo()
internal bool HasLogo()
{
return logo != null || encodedLogo != null;
}

internal EncodedImage GetLogo()
{
#if UNITY_2019_4_OR_NEWER
// If a Texture2D type is not set to 'Sprite (2D or UI)' it will get flagged
// by cloudflare as suspicious and be rejected. This will return a 403
return logo.EncodeToPNG();
// If a Texture2D type is not set to 'Sprite (2D or UI)' it will get flagged
// by cloudflare as suspicious and be rejected. This will return a 403
if (encodedLogo == null)
encodedLogo = EncodedImage.PNGFromTexture2D(logo);
return encodedLogo;
#else
return logo;
return logo;
#endif
}


internal bool HasGalleryImages()
{
return encodedImages != null || images != null;
}

internal List<byte[]> GetGalleryImages()
{
#if UNITY_2019_4_OR_NEWER
List<byte[]> gallery = new List<byte[]>();
foreach(var texture in images)
if (encodedImages == null)
{
gallery.Add(texture.EncodeToPNG());
List<EncodedImage> gallery = new List<EncodedImage>();
foreach(var texture in images)
{
gallery.Add(EncodedImage.PNGFromTexture2D(texture));
}
encodedImages = gallery;
}
return gallery;
return encodedImages;
#else
return images;
return images;
#endif
}
}
Expand Down
12 changes: 10 additions & 2 deletions Runtime/Classes/ModfileDetails.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace ModIO
using System.IO;

namespace ModIO
{
public class ModfileDetails
{
Expand All @@ -12,7 +14,13 @@ public class ModfileDetails
/// its contents will be compressed and uploaded when submitted via
/// ModIOUnity.UploadModfile.
/// </summary>
public string directory;
public string? directory;

/// <summary>
/// Compressed data to send.
/// Alternative to <cref>directory</cref> for creating mods in memory.
/// </summary>
public MemoryStream compressedDirectory

/// <summary>
/// the changelog for this file version of the mod.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ namespace ModIO.Implementation
{
internal class CompressOperationMultiple : CompressOperationBase
{
public IEnumerable<byte[]> data;
public IEnumerable<EncodedImage> data;

public CompressOperationMultiple(IEnumerable<byte[]> compressed, ProgressHandle progressHandle)
public CompressOperationMultiple(IEnumerable<EncodedImage> compressed, ProgressHandle progressHandle)
: base(progressHandle)
{
this.data = compressed;
Expand All @@ -31,11 +31,12 @@ public override async Task<ResultAnd<MemoryStream>> Compress()
{
zipStream.SetLevel(3);

foreach(var bytes in data)
foreach(var encodedImage in data)
{
string entryName = $"image_{count}.png";
string entryName = $"image_{count}.{encodedImage.extension}";
count++;

byte[] bytes = encodedImage.data;
using(MemoryStream memoryStream = new MemoryStream())
{
memoryStream.Write(bytes, 0, bytes.Length);
Expand Down
56 changes: 34 additions & 22 deletions Runtime/ModIO.Implementation/Classes/ModIOUnityImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2005,7 +2005,7 @@ public static async Task<Result> EditModProfile(ModProfileDetails modDetails)
+ " The 'tags' array in the ModProfileDetails will be ignored.");
}

var config = modDetails.logo != null
var config = modDetails.HasLogo()
? API.Requests.EditMod.RequestPOST(modDetails)
: API.Requests.EditMod.RequestPUT(modDetails);

Expand Down Expand Up @@ -2353,12 +2353,7 @@ public static async Task<Result> UploadModfile(ModfileDetails modfile)
if(IsInitialized(out result) && IsAuthenticatedSessionValid(out result)
&& IsModfileDetailsValid(modfile, out result))
{
CompressOperationDirectory compressOperation = new CompressOperationDirectory(modfile.directory);

Task<ResultAnd<MemoryStream>> compressTask = compressOperation.Compress();


var compressionTaskResult = await openCallbacks.Run(callbackConfirmation, compressTask);
var compressionTaskResult = await GetCompressedData(modfile, callbackConfirmation);
result = compressionTaskResult.result;

if(!result.Succeeded())
Expand All @@ -2370,9 +2365,6 @@ public static async Task<Result> UploadModfile(ModfileDetails modfile)
}
else
{
Logger.Log(LogLevel.Verbose, $"Compressed file ({modfile.directory})"
+ $"\nstream length: {compressionTaskResult.value.Length}");

callbackConfirmation = openCallbacks.New();
var requestConfig = await API.Requests.AddModFile.Request(modfile, compressionTaskResult.value);
Task<ResultAnd<ModfileObject>> task = WebRequestManager.Request<ModfileObject>(requestConfig, currentUploadHandle);
Expand All @@ -2399,6 +2391,23 @@ public static async Task<Result> UploadModfile(ModfileDetails modfile)
openCallbacks.Complete(callbackConfirmation);

return result;

static async Task<ResultAnd<MemoryStream>> GetCompressedData(ModfileDetails modfile, TaskCompletionSource<bool> callbackConfirmation)
{
if(modfile.compressedDirectory != null) {
Logger.Log(LogLevel.Verbose, $"Using supplied MemoryStream of length: {modfile.compressedDirectory.Length}");
return ResultAnd.Create(ResultBuilder.Success, modfile.compressedDirectory);
}


CompressOperationDirectory compressOperation = new CompressOperationDirectory(modfile.directory);
Task<ResultAnd<MemoryStream>> compressTask = compressOperation.Compress();

var compressionTaskResult = await openCallbacks.Run(callbackConfirmation, compressTask);
Logger.Log(LogLevel.Verbose, $"Compressed file ({modfile.directory})"
+ $"\nstream length: {compressionTaskResult.value.Length}");
return compressionTaskResult;
}
}

public static async void UploadModMedia(ModProfileDetails modProfileDetails, Action<Result> callback)
Expand Down Expand Up @@ -2467,15 +2476,18 @@ public static async void ArchiveModProfile(ModId modId, Action<Result> callback)

static bool IsModfileDetailsValid(ModfileDetails modfile, out Result result)
{
// Check directory exists
if(!DataStorage.TryGetModfileDetailsDirectory(modfile.directory,
out string notbeingusedhere))
if(modfile.compressedDirectory == null)
{
Logger.Log(LogLevel.Error,
"The provided directory in ModfileDetails could not be found or"
+ $" does not exist ({modfile.directory}).");
result = ResultBuilder.Create(ResultCode.IO_DirectoryDoesNotExist);
return false;
// Check directory exists
if(!DataStorage.TryGetModfileDetailsDirectory(modfile.directory,
out string _))
{
Logger.Log(LogLevel.Error,
"The provided directory in ModfileDetails could not be found or"
+ $" does not exist ({modfile.directory}).");
result = ResultBuilder.Create(ResultCode.IO_DirectoryDoesNotExist);
return false;
}
}

// check metadata isn't too large
Expand Down Expand Up @@ -2504,8 +2516,8 @@ static bool IsModfileDetailsValid(ModfileDetails modfile, out Result result)

static bool IsModProfileDetailsValid(ModProfileDetails modDetails, out Result result)
{
if(modDetails.logo == null || string.IsNullOrWhiteSpace(modDetails.summary)
|| string.IsNullOrWhiteSpace(modDetails.name))
if(!modDetails.HasLogo() || string.IsNullOrWhiteSpace(modDetails.summary)
|| string.IsNullOrWhiteSpace(modDetails.name))
{
Logger.Log(
LogLevel.Error,
Expand All @@ -2530,9 +2542,9 @@ static bool IsModProfileDetailsValidForEdit(ModProfileDetails modDetails, out Re
return false;
}

if(modDetails.logo != null)
if(modDetails.HasLogo())
{
if(modDetails.logo.EncodeToPNG().Length > 8388608)
if(modDetails.GetLogo().data.Length > 8388608)
{
Logger.Log(LogLevel.Error,
"The provided logo in ModProfileDetails exceeds 8 megabytes");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ public static WebRequestConfig Request(ModProfileDetails details)
}
}

if(details.logo != null)
request.AddField("logo","logo.png", details.GetLogo());
if(details.HasLogo())
{
var logo = details.GetLogo();
request.AddField("logo", $"logo.{logo.extension}", logo.data);
}

return request;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.IO;
using System.Threading.Tasks;
using UnityEngine;

namespace ModIO.Implementation.API.Requests
{
Expand All @@ -15,13 +14,16 @@ public static async Task<ResultAnd<WebRequestConfig>> Request(ModProfileDetails
ShouldRequestTimeout = false,
};

if(details.logo != null)
request.AddField("logo", "logo.png", details.logo.EncodeToPNG());
if(details.HasLogo())
{
var logo = details.GetLogo();
request.AddField("logo", $"logo.{logo.extension}", logo.data);
}

if(details.images != null)
if(details.HasGalleryImages())
{
var imageBytes = details.GetGalleryImages();
CompressOperationMultiple zipOperation = new CompressOperationMultiple(imageBytes, null);
var encodedImages = details.GetGalleryImages();
CompressOperationMultiple zipOperation = new CompressOperationMultiple(encodedImages, null);

ResultAnd<MemoryStream> resultAnd = await zipOperation.Compress();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ public static WebRequestConfig InternalRequest(ModProfileDetails details, string

request.AddField("metadata_blob", details.metadata);

if(details.logo != null)
request.AddField("logo", "logo.png", details.GetLogo());
if(details.HasLogo())
{
var logo = details.GetLogo();
request.AddField("logo", $"logo.{logo.extension}", logo.data);
}

return request;
}
Expand Down