You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

134 lines
4.6 KiB

using UnityEngine;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using Amazon.S3;
using Amazon;
using Amazon.S3.Transfer;
using Amazon.S3.Model;
using System.Collections.Generic;
namespace UltraCombos.Upload
{
[System.Serializable]
public class S3Tag
{
public string key;
public string value;
public static implicit operator Tag(S3Tag t) => new Tag { Key = t.key, Value = t.value };
}
public class AwsS3Uploader : Uploader
{
[SerializeField]
private string regionSystemName = "ap-northeast-2";
public string bucketName = "ultracombos.project";
public bool onlyBucketURL = false;
public List<S3Tag> tags=new List<S3Tag>();
IAmazonS3 s3Client;
#region Monobehaviour
void Start()
{
s3Client = new AmazonS3Client(RegionEndpoint.GetBySystemName(regionSystemName));
}
protected override void OnDestroy()
{
base.OnDestroy();
s3Client?.Dispose();
}
#endregion
protected List<Tag> GetTagSet()
{
List<Tag> tagSet = new List<Tag>();
foreach (var t in tags)
tagSet.Add(t);
return tagSet;
}
#region Upload Protected
protected override async Task<string> Upload(byte[] byteData, string remoteFilePath)
{
MemoryStream ms = new MemoryStream();
ms.Write(byteData, 0, byteData.Length);
ms.Seek(0, SeekOrigin.Begin);
var request = new TransferUtilityUploadRequest()
{
BucketName = bucketName,
InputStream = ms,
StorageClass = S3StorageClass.Standard,
Key = remoteFilePath,
CannedACL = S3CannedACL.PublicRead,
TagSet = GetTagSet(),
};
return await UploadAsync(request);
}
protected override async Task<string> Upload(string filePath, string remoteFilePath)
{
Debug.Log("Uploading file: " + filePath+ " to " + remoteFilePath);
var request = new TransferUtilityUploadRequest()
{
BucketName = bucketName,
FilePath = filePath,
StorageClass = S3StorageClass.Standard,
Key = remoteFilePath,
CannedACL = S3CannedACL.PublicRead,
TagSet = GetTagSet(),
};
return await UploadAsync(request);
}
public override string GetHostURL()// (string remoteFilePath, bool escape = true)
{
if (onlyBucketURL)
return $"http://{EscapeURL(bucketName)}";
else
return $"https://s3.{regionSystemName}.amazonaws.com/{EscapeURL(bucketName)}";
}
private async Task<string> UploadAsync(TransferUtilityUploadRequest request)
{
Debug.Log($"Uploading to S3: {request.BucketName}/{request.Key}");
if (s3Client == null)
{
Debug.LogError("S3 client is not initialized.");
return $"{ERR_MSG} S3 client is not initialized.";
}
var timeout_cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds));
var linked_cts = CancellationTokenSource.CreateLinkedTokenSource(timeout_cts.Token, cts.Token);
TransferUtility fileTransferUtility = null;
try
{
fileTransferUtility = new TransferUtility(s3Client);
await fileTransferUtility.UploadAsync(request, linked_cts.Token);
return $"{GetHostURL()}/{EscapeURL(request.Key)}";
}
catch (Exception e)
{
Debug.LogError($"Upload failed: {e.Message}\n{e.StackTrace}");
if(timeout_cts.IsCancellationRequested)
return $"{ERR_MSG} The operation has timed out.";
if (cts.IsCancellationRequested)
return $"{ERR_MSG} AwsS3Uploader was disposed.";
return $"{ERR_MSG} {e.Message}\n{e.StackTrace}";
}
finally
{
try { request?.InputStream.Close(); } catch {}
try { request?.InputStream.Dispose(); } catch {}
try { linked_cts?.Dispose(); } catch {}
try { timeout_cts?.Dispose(); } catch {}
try { fileTransferUtility?.Dispose(); } catch {}
}
}
#endregion
}
}