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 tags=new List(); IAmazonS3 s3Client; #region Monobehaviour void Start() { s3Client = new AmazonS3Client(RegionEndpoint.GetBySystemName(regionSystemName)); } protected override void OnDestroy() { base.OnDestroy(); s3Client?.Dispose(); } #endregion protected List GetTagSet() { List tagSet = new List(); foreach (var t in tags) tagSet.Add(t); return tagSet; } #region Upload Protected protected override async Task 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 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 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 } }