This commit is contained in:
2026-05-17 15:12:16 +07:00
parent 93da00c206
commit bf0ebe447d
902 changed files with 142169 additions and 31515 deletions

View File

@@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
namespace DA_Assets.Networking
{
public class RequestSender
{
public static async Task<Texture2D> LoadImage(string url)
{
using (UnityWebRequest webRequest = UnityWebRequestTexture.GetTexture(url))
{
var asyncOp = webRequest.SendWebRequest();
while (!asyncOp.isDone)
{
await Task.Yield();
}
bool isRequestError;
#if UNITY_2020_1_OR_NEWER
isRequestError = webRequest.result != UnityWebRequest.Result.Success;
#else
isRequestError = webRequest.isNetworkError || webRequest.isHttpError;
#endif
if (isRequestError)
{
Debug.LogError($"LoadImage | {webRequest.error}");
return null;
}
else
{
Texture2D texture = DownloadHandlerTexture.GetContent(webRequest);
return texture;
}
}
}
public static async Task<string> Get(string url, int awaitDelayMs = 100)
{
using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
{
try
{
#if UNITY_6000_0_OR_NEWER
await webRequest.SendWebRequest();
#else
webRequest.SendWebRequest();
while (!webRequest.isDone)
await Task.Delay(awaitDelayMs);
#endif
}
catch (Exception ex)
{
Debug.LogException(ex);
return null;
}
bool isRequestError;
#if UNITY_2020_1_OR_NEWER
isRequestError = webRequest.result != UnityWebRequest.Result.Success;
#else
isRequestError = webRequest.isNetworkError || webRequest.isHttpError;
#endif
if (isRequestError)
{
Debug.LogError($"RequestSender.Get | {webRequest.error}");
return null;
}
else
{
string result = webRequest.downloadHandler.text;
return result;
}
}
}
public static async Task<string> Post(string url, string postData, string contentType, Dictionary<string, string> headers = null, int awaitDelayMs = 100)
{
using (UnityWebRequest webRequest = new UnityWebRequest(url, "POST"))
{
byte[] bodyRaw = Encoding.UTF8.GetBytes(postData);
webRequest.uploadHandler = new UploadHandlerRaw(bodyRaw);
webRequest.downloadHandler = new DownloadHandlerBuffer();
webRequest.SetRequestHeader("Content-Type", contentType);
if (headers != null)
{
foreach (var header in headers)
{
webRequest.SetRequestHeader(header.Key, header.Value);
}
}
try
{
#if UNITY_6000_0_OR_NEWER
await webRequest.SendWebRequest();
#else
webRequest.SendWebRequest();
while (!webRequest.isDone)
await Task.Delay(awaitDelayMs);
#endif
}
catch (Exception ex)
{
Debug.LogException(ex);
return null;
}
while (!webRequest.isDone)
await Task.Delay(awaitDelayMs);
bool isRequestError;
#if UNITY_2020_1_OR_NEWER
isRequestError = webRequest.result != UnityWebRequest.Result.Success;
#else
isRequestError = webRequest.isNetworkError || webRequest.isHttpError;
#endif
if (isRequestError)
{
string methodPath = $"{nameof(RequestSender)}.{nameof(Post)}";
Debug.LogError($"{methodPath} | Error: {webRequest.error}");
return null;
}
else
{
string result = webRequest.downloadHandler.text;
return result;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dce7cba30a6eedc46a3f8fbd927f8035
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,230 @@
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
namespace DA_Assets.Networking
{
public class UnityHttpClient : IDisposable
{
private readonly HttpClient _httpClient;
private HttpRequestMessage _requestMessage;
private CancellationTokenSource _cancellationTokenSource;
public DownloadHandler downloadHandler { get; private set; }
public long downloadedBytes { get; private set; }
public float downloadProgress { get; private set; }
public string error { get; private set; }
public bool isDone { get; private set; }
public HttpStatusCode responseCode { get; private set; }
public WR_Result result { get; private set; }
private UnityHttpClient(HttpMethod method, string url, HttpContent content = null)
{
_httpClient = new HttpClient
{
Timeout = TimeSpan.FromMinutes(5)
};
_requestMessage = new HttpRequestMessage(method, url);
if (content != null)
{
_requestMessage.Content = content;
}
downloadHandler = new DownloadHandler();
downloadedBytes = 0;
error = string.Empty;
isDone = false;
responseCode = 0;
result = WR_Result.InProgress;
downloadProgress = 0f;
}
public static UnityHttpClient Get(string url)
{
return new UnityHttpClient(HttpMethod.Get, url);
}
public static UnityHttpClient Post(string url, WWWForm form)
{
var content = new ByteArrayContent(form.data);
foreach (var header in form.headers)
{
content.Headers.Add(header.Key, header.Value);
}
return new UnityHttpClient(HttpMethod.Post, url, content);
}
public void SetRequestHeader(string name, string value)
{
if (_requestMessage.Headers.Contains(name))
{
_requestMessage.Headers.Remove(name);
}
_requestMessage.Headers.Add(name, value);
}
public async Task SendWebRequest(CancellationTokenSource cancellationTokenSource = null)
{
if (cancellationTokenSource == null)
{
_cancellationTokenSource = new CancellationTokenSource();
}
else
{
_cancellationTokenSource = cancellationTokenSource;
}
try
{
using (HttpResponseMessage response = await _httpClient.SendAsync(
_requestMessage,
HttpCompletionOption.ResponseHeadersRead,
_cancellationTokenSource.Token).ConfigureAwait(false))
{
responseCode = response.StatusCode;
if (response.IsSuccessStatusCode)
{
var contentLength = response.Content.Headers.ContentLength;
using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
using (var memoryStream = new MemoryStream())
{
if (contentLength.HasValue)
{
Progress<long> progress = new Progress<long>(totalBytes =>
{
downloadedBytes = totalBytes;
downloadProgress = (float)downloadedBytes / contentLength.Value;
});
await responseStream.CopyToAsync(memoryStream, 81920, progress, _cancellationTokenSource.Token).ConfigureAwait(false);
downloadProgress = 1f;
}
else
{
#if UNITY_2021_3_OR_NEWER
await responseStream.CopyToAsync(memoryStream, _cancellationTokenSource.Token).ConfigureAwait(false);
#else
await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false);
#endif
downloadProgress = -1f;
}
byte[] data = memoryStream.ToArray();
Encoding encoding = Encoding.UTF8;
string charset = response.Content.Headers.ContentType?.CharSet;
if (!string.IsNullOrEmpty(charset))
{
try
{
encoding = Encoding.GetEncoding(charset);
}
catch (Exception)
{
}
}
var text = encoding.GetString(data);
downloadHandler.SetData(data);
downloadHandler.SetText(text);
result = WR_Result.Success;
}
}
else
{
string errorMessage = $"Error: {response.StatusCode}";
downloadHandler.SetError(errorMessage);
error = errorMessage;
result = WR_Result.ProtocolError;
}
}
}
catch (Exception ex)
{
downloadHandler.SetError(ex.Message);
error = ex.Message;
result = WR_Result.ConnectionError;
}
finally
{
isDone = true;
}
}
public void Dispose()
{
_requestMessage?.Dispose();
_httpClient?.Dispose();
_cancellationTokenSource?.Cancel();
_cancellationTokenSource?.Dispose();
}
}
/// <summary>
/// https://stackoverflow.com/a/46497896
/// </summary>
public static class StreamExtensions
{
public static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long> progress = null, CancellationToken cancellationToken = default)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (!source.CanRead)
throw new ArgumentException("Has to be readable", nameof(source));
if (destination == null)
throw new ArgumentNullException(nameof(destination));
if (!destination.CanWrite)
throw new ArgumentException("Has to be writable", nameof(destination));
if (bufferSize < 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize));
var buffer = new byte[bufferSize];
long totalBytesRead = 0;
int bytesRead;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0)
{
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
totalBytesRead += bytesRead;
progress?.Report(totalBytesRead);
}
}
}
public class DownloadHandler
{
public byte[] data { get; private set; }
public string text { get; private set; }
public string error { get; private set; }
public void SetData(byte[] data)
{
this.data = data;
}
public void SetText(string text)
{
this.text = text;
}
public void SetError(string error)
{
this.error = error;
}
public bool HasError => !string.IsNullOrEmpty(error);
}
public enum WR_Result
{
InProgress,
Success,
ConnectionError,
ProtocolError,
DataProcessingError
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d750e6243861193479aca4fe9486e373
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: