mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 14:53:50 +02:00
Fix cookie bug
This commit is contained in:
@@ -36,14 +36,6 @@ namespace VRCX
|
|||||||
MainForm.Instance.Browser.ShowDevTools();
|
MainForm.Instance.Browser.ShowDevTools();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes all cookies from the global cef cookie manager.
|
|
||||||
/// </summary>
|
|
||||||
public override void DeleteAllCookies()
|
|
||||||
{
|
|
||||||
Cef.GetGlobalCookieManager().DeleteCookies();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetVR(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand)
|
public override void SetVR(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand)
|
||||||
{
|
{
|
||||||
Program.VRCXVRInstance.SetActive(active, hmdOverlay, wristOverlay, menuButton, overlayHand);
|
Program.VRCXVRInstance.SetActive(active, hmdOverlay, wristOverlay, menuButton, overlayHand);
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ namespace VRCX
|
|||||||
{
|
{
|
||||||
// AppApi
|
// AppApi
|
||||||
public abstract void ShowDevTools();
|
public abstract void ShowDevTools();
|
||||||
public abstract void DeleteAllCookies();
|
|
||||||
public abstract void SetVR(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand);
|
public abstract void SetVR(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand);
|
||||||
public abstract void RefreshVR();
|
public abstract void RefreshVR();
|
||||||
public abstract void RestartVR();
|
public abstract void RestartVR();
|
||||||
|
|||||||
@@ -226,9 +226,17 @@ namespace VRCX
|
|||||||
if (File.Exists(filePath))
|
if (File.Exists(filePath))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var success = await ImageCache.SaveImageToFile(url, filePath);
|
try
|
||||||
|
{
|
||||||
return success ? filePath : null;
|
await ImageCache.SaveImageToFile(url, filePath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, "Failed to save print to file");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> SaveStickerToFile(string url, string ugcFolderPath, string monthFolder, string fileName)
|
public async Task<string> SaveStickerToFile(string url, string ugcFolderPath, string monthFolder, string fileName)
|
||||||
@@ -239,9 +247,17 @@ namespace VRCX
|
|||||||
if (File.Exists(filePath))
|
if (File.Exists(filePath))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var success = await ImageCache.SaveImageToFile(url, filePath);
|
try
|
||||||
|
{
|
||||||
return success ? filePath : null;
|
await ImageCache.SaveImageToFile(url, filePath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, "Failed to save print to file");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,10 +10,6 @@ namespace VRCX
|
|||||||
{
|
{
|
||||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public override void DeleteAllCookies()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ShowDevTools()
|
public override void ShowDevTools()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,11 +81,11 @@ namespace VRCX
|
|||||||
var vueDevtoolsCrxPath = Path.Join(Program.BaseDirectory, @"..\..\build-tools\Vue-js-devtools.crx");
|
var vueDevtoolsCrxPath = Path.Join(Program.BaseDirectory, @"..\..\build-tools\Vue-js-devtools.crx");
|
||||||
if (File.Exists(vueDevtoolsCrxPath))
|
if (File.Exists(vueDevtoolsCrxPath))
|
||||||
{
|
{
|
||||||
var VueDevtoolsPath = Path.Join(extensionsPath, "Vue-js-devtools");
|
var vueDevtoolsPath = Path.Join(extensionsPath, "Vue-js-devtools");
|
||||||
if (!Directory.Exists(VueDevtoolsPath))
|
if (!Directory.Exists(vueDevtoolsPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(VueDevtoolsPath);
|
Directory.CreateDirectory(vueDevtoolsPath);
|
||||||
ZipFile.ExtractToDirectory(vueDevtoolsCrxPath, VueDevtoolsPath);
|
ZipFile.ExtractToDirectory(vueDevtoolsCrxPath, vueDevtoolsPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ using System.Net;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
namespace VRCX;
|
namespace VRCX;
|
||||||
|
|
||||||
internal static class ImageCache
|
internal static class ImageCache
|
||||||
{
|
{
|
||||||
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
private static readonly string cacheLocation;
|
private static readonly string cacheLocation;
|
||||||
private static readonly HttpClient httpClient;
|
private static readonly HttpClient httpClient;
|
||||||
private static readonly List<string> ImageHosts =
|
private static readonly List<string> ImageHosts =
|
||||||
@@ -47,6 +49,31 @@ internal static class ImageCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<Stream> FetchImage(string url)
|
||||||
|
{
|
||||||
|
var uri = new Uri(url);
|
||||||
|
if (!ImageHosts.Contains(uri.Host))
|
||||||
|
throw new ArgumentException("Invalid image host", url);
|
||||||
|
|
||||||
|
var cookieString = string.Empty;
|
||||||
|
if (WebApi.Instance != null &&
|
||||||
|
WebApi.Instance._cookieContainer != null &&
|
||||||
|
uri.Host == "api.vrchat.cloud")
|
||||||
|
{
|
||||||
|
CookieCollection cookies = WebApi.Instance._cookieContainer.GetCookies(new Uri("https://api.vrchat.cloud"));
|
||||||
|
foreach (Cookie cookie in cookies)
|
||||||
|
cookieString += $"{cookie.Name}={cookie.Value};";
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||||
|
if (!string.IsNullOrEmpty(cookieString))
|
||||||
|
request.Headers.Add("Cookie", cookieString);
|
||||||
|
|
||||||
|
using var response = await httpClient.SendAsync(request);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
return await response.Content.ReadAsStreamAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<string> GetImage(string url, string fileId, string version)
|
public static async Task<string> GetImage(string url, string fileId, string version)
|
||||||
{
|
{
|
||||||
var directoryLocation = Path.Join(cacheLocation, fileId);
|
var directoryLocation = Path.Join(cacheLocation, fileId);
|
||||||
@@ -62,29 +89,17 @@ internal static class ImageCache
|
|||||||
Directory.Delete(directoryLocation, true);
|
Directory.Delete(directoryLocation, true);
|
||||||
Directory.CreateDirectory(directoryLocation);
|
Directory.CreateDirectory(directoryLocation);
|
||||||
|
|
||||||
var uri = new Uri(url);
|
try
|
||||||
if (!ImageHosts.Contains(uri.Host))
|
|
||||||
throw new ArgumentException("Invalid image host", url);
|
|
||||||
|
|
||||||
var cookieString = string.Empty;
|
|
||||||
if (WebApi.Instance != null && WebApi.Instance._cookieContainer != null)
|
|
||||||
{
|
{
|
||||||
CookieCollection cookies = WebApi.Instance._cookieContainer.GetCookies(new Uri("https://api.vrchat.cloud"));
|
var stream = await FetchImage(url);
|
||||||
foreach (Cookie cookie in cookies)
|
await using var fileStream =
|
||||||
cookieString += $"{cookie.Name}={cookie.Value};";
|
new FileStream(fileLocation, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||||
|
await stream.CopyToAsync(fileStream);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
|
||||||
if (!string.IsNullOrEmpty(cookieString))
|
|
||||||
request.Headers.Add("Cookie", cookieString);
|
|
||||||
|
|
||||||
using (var response = await httpClient.SendAsync(request))
|
|
||||||
{
|
{
|
||||||
response.EnsureSuccessStatusCode();
|
logger.Error(ex, "Failed to fetch image");
|
||||||
await using (var fileStream = new FileStream(fileLocation, FileMode.Create, FileAccess.Write, FileShare.None))
|
return string.Empty;
|
||||||
{
|
|
||||||
await response.Content.CopyToAsync(fileStream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var cacheSize = Directory.GetDirectories(cacheLocation).Length;
|
var cacheSize = Directory.GetDirectories(cacheLocation).Length;
|
||||||
@@ -94,6 +109,13 @@ internal static class ImageCache
|
|||||||
return fileLocation;
|
return fileLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task SaveImageToFile(string url, string path)
|
||||||
|
{
|
||||||
|
var stream = await FetchImage(url);
|
||||||
|
await using var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||||
|
await stream.CopyToAsync(fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
private static void CleanImageCache()
|
private static void CleanImageCache()
|
||||||
{
|
{
|
||||||
var dirInfo = new DirectoryInfo(cacheLocation);
|
var dirInfo = new DirectoryInfo(cacheLocation);
|
||||||
@@ -103,31 +125,4 @@ internal static class ImageCache
|
|||||||
folder.Delete(true);
|
folder.Delete(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<bool> SaveImageToFile(string url, string path)
|
|
||||||
{
|
|
||||||
var uri = new Uri(url);
|
|
||||||
if (!ImageHosts.Contains(uri.Host))
|
|
||||||
throw new ArgumentException("Invalid image host", url);
|
|
||||||
|
|
||||||
var cookieString = string.Empty;
|
|
||||||
if (WebApi.Instance != null && WebApi.Instance._cookieContainer != null)
|
|
||||||
{
|
|
||||||
var cookies = WebApi.Instance._cookieContainer.GetCookies(new Uri("https://api.vrchat.cloud"));
|
|
||||||
foreach (Cookie cookie in cookies)
|
|
||||||
cookieString += $"{cookie.Name}={cookie.Value};";
|
|
||||||
}
|
|
||||||
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
|
||||||
if (!string.IsNullOrEmpty(cookieString))
|
|
||||||
request.Headers.Add("Cookie", cookieString);
|
|
||||||
|
|
||||||
using var response = await httpClient.SendAsync(request);
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
await using var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
|
||||||
await response.Content.CopyToAsync(fileStream);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
186
Dotnet/WebApi.cs
186
Dotnet/WebApi.cs
@@ -1,7 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@@ -37,7 +40,7 @@ namespace VRCX
|
|||||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WebApi()
|
private WebApi()
|
||||||
{
|
{
|
||||||
#if LINUX
|
#if LINUX
|
||||||
if (Instance == null)
|
if (Instance == null)
|
||||||
@@ -89,7 +92,7 @@ namespace VRCX
|
|||||||
catch (UriFormatException)
|
catch (UriFormatException)
|
||||||
{
|
{
|
||||||
VRCXStorage.Instance.Set("VRCX_ProxyServer", string.Empty);
|
VRCXStorage.Instance.Set("VRCX_ProxyServer", string.Empty);
|
||||||
var message = "The proxy server URI you used is invalid.\nVRCX will close, please correct the proxy URI.";
|
const string message = "The proxy server URI you used is invalid.\nVRCX will close, please correct the proxy URI.";
|
||||||
#if !LINUX
|
#if !LINUX
|
||||||
System.Windows.Forms.MessageBox.Show(message, "Invalid Proxy URI", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
System.Windows.Forms.MessageBox.Show(message, "Invalid Proxy URI", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
#endif
|
#endif
|
||||||
@@ -106,6 +109,9 @@ namespace VRCX
|
|||||||
|
|
||||||
public void ClearCookies()
|
public void ClearCookies()
|
||||||
{
|
{
|
||||||
|
#if !LINUX
|
||||||
|
Cef.GetGlobalCookieManager().DeleteCookies();
|
||||||
|
#endif
|
||||||
_cookieContainer = new CookieContainer();
|
_cookieContainer = new CookieContainer();
|
||||||
SaveCookies();
|
SaveCookies();
|
||||||
}
|
}
|
||||||
@@ -125,38 +131,70 @@ namespace VRCX
|
|||||||
using var stream = new MemoryStream(Convert.FromBase64String((string)item[0]));
|
using var stream = new MemoryStream(Convert.FromBase64String((string)item[0]));
|
||||||
_cookieContainer = new CookieContainer();
|
_cookieContainer = new CookieContainer();
|
||||||
_cookieContainer.Add(System.Text.Json.JsonSerializer.Deserialize<CookieCollection>(stream));
|
_cookieContainer.Add(System.Text.Json.JsonSerializer.Deserialize<CookieCollection>(stream));
|
||||||
// _cookieContainer = (CookieContainer)new BinaryFormatter().Deserialize(stream); // from .NET framework
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Error($"Failed to load cookies: {e.Message}");
|
Logger.Error($"Failed to load cookies: {e.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Cookie> GetAllCookies()
|
||||||
|
{
|
||||||
|
var cookieTable = (Hashtable)_cookieContainer.GetType().InvokeMember("m_domainTable",
|
||||||
|
BindingFlags.NonPublic |
|
||||||
|
BindingFlags.GetField |
|
||||||
|
BindingFlags.Instance,
|
||||||
|
null,
|
||||||
|
_cookieContainer,
|
||||||
|
new object[] { });
|
||||||
|
|
||||||
|
var uniqueCookies = new Dictionary<string, Cookie>();
|
||||||
|
foreach (var item in cookieTable.Keys)
|
||||||
|
{
|
||||||
|
var domain = (string)item;
|
||||||
|
if (string.IsNullOrEmpty(domain))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (domain.StartsWith('.'))
|
||||||
|
domain = domain[1..];
|
||||||
|
|
||||||
|
var address = $"http://{domain}/";
|
||||||
|
if (!Uri.TryCreate(address, UriKind.Absolute, out var uri))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (Cookie cookie in _cookieContainer.GetCookies(uri))
|
||||||
|
{
|
||||||
|
var key = $"{domain}.{cookie.Name}";
|
||||||
|
if (!uniqueCookies.TryGetValue(key, out var value) ||
|
||||||
|
cookie.TimeStamp > value.TimeStamp)
|
||||||
|
{
|
||||||
|
cookie.Expires = DateTime.MaxValue;
|
||||||
|
uniqueCookies[key] = cookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return uniqueCookies.Values.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
public void SaveCookies()
|
public void SaveCookies()
|
||||||
{
|
{
|
||||||
if (_cookieDirty == false)
|
if (!_cookieDirty)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
foreach (Cookie cookie in _cookieContainer.GetAllCookies())
|
|
||||||
{
|
|
||||||
cookie.Expires = DateTime.MaxValue;
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var memoryStream = new MemoryStream())
|
var cookies = GetAllCookies();
|
||||||
{
|
using var memoryStream = new MemoryStream();
|
||||||
System.Text.Json.JsonSerializer.Serialize(memoryStream, _cookieContainer.GetAllCookies());
|
System.Text.Json.JsonSerializer.Serialize(memoryStream, cookies);
|
||||||
//new BinaryFormatter().Serialize(memoryStream, _cookieContainer);
|
SQLiteLegacy.Instance.ExecuteNonQuery(
|
||||||
SQLiteLegacy.Instance.ExecuteNonQuery(
|
"INSERT OR REPLACE INTO `cookies` (`key`, `value`) VALUES (@key, @value)",
|
||||||
"INSERT OR REPLACE INTO `cookies` (`key`, `value`) VALUES (@key, @value)",
|
new Dictionary<string, object>() {
|
||||||
new Dictionary<string, object>() {
|
{"@key", "default"},
|
||||||
{"@key", "default"},
|
{"@value", Convert.ToBase64String(memoryStream.ToArray())}
|
||||||
{"@value", Convert.ToBase64String(memoryStream.ToArray())}
|
}
|
||||||
}
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
_cookieDirty = false;
|
_cookieDirty = false;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -170,7 +208,7 @@ namespace VRCX
|
|||||||
_cookieDirty = true; // force cookies to be saved for lastUserLoggedIn
|
_cookieDirty = true; // force cookies to be saved for lastUserLoggedIn
|
||||||
|
|
||||||
using var memoryStream = new MemoryStream();
|
using var memoryStream = new MemoryStream();
|
||||||
System.Text.Json.JsonSerializer.Serialize(memoryStream, _cookieContainer.GetAllCookies());
|
System.Text.Json.JsonSerializer.Serialize(memoryStream, GetAllCookies());
|
||||||
return Convert.ToBase64String(memoryStream.ToArray());
|
return Convert.ToBase64String(memoryStream.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,44 +230,44 @@ namespace VRCX
|
|||||||
|
|
||||||
request.AutomaticDecompression = DecompressionMethods.All;
|
request.AutomaticDecompression = DecompressionMethods.All;
|
||||||
request.Method = "POST";
|
request.Method = "POST";
|
||||||
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
|
var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
|
||||||
request.ContentType = "multipart/form-data; boundary=" + boundary;
|
request.ContentType = "multipart/form-data; boundary=" + boundary;
|
||||||
Stream requestStream = request.GetRequestStream();
|
var requestStream = request.GetRequestStream();
|
||||||
if (options.TryGetValue("postData", out object postDataObject) == true)
|
if (options.TryGetValue("postData", out var postDataObject))
|
||||||
{
|
{
|
||||||
Dictionary<string, string> postData = new Dictionary<string, string>();
|
var postData = new Dictionary<string, string>();
|
||||||
postData.Add("data", (string)postDataObject);
|
postData.Add("data", (string)postDataObject);
|
||||||
string FormDataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n";
|
const string formDataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n";
|
||||||
foreach (string key in postData.Keys)
|
foreach (var key in postData.Keys)
|
||||||
{
|
{
|
||||||
string item = string.Format(FormDataTemplate, boundary, key, postData[key]);
|
var item = string.Format(formDataTemplate, boundary, key, postData[key]);
|
||||||
byte[] itemBytes = Encoding.UTF8.GetBytes(item);
|
var itemBytes = Encoding.UTF8.GetBytes(item);
|
||||||
await requestStream.WriteAsync(itemBytes, 0, itemBytes.Length);
|
await requestStream.WriteAsync(itemBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var imageData = options["imageData"] as string;
|
var imageData = options["imageData"] as string;
|
||||||
byte[] fileToUpload = Program.AppApiInstance.ResizeImageToFitLimits(Convert.FromBase64String(imageData), false);
|
var fileToUpload = Program.AppApiInstance.ResizeImageToFitLimits(Convert.FromBase64String(imageData), false);
|
||||||
string fileFormKey = "image";
|
const string fileFormKey = "image";
|
||||||
string fileName = "image.png";
|
const string fileName = "image.png";
|
||||||
string fileMimeType = "image/png";
|
const string fileMimeType = "image/png";
|
||||||
string HeaderTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n";
|
const string headerTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n";
|
||||||
string header = string.Format(HeaderTemplate, boundary, fileFormKey, fileName, fileMimeType);
|
var header = string.Format(headerTemplate, boundary, fileFormKey, fileName, fileMimeType);
|
||||||
byte[] headerbytes = Encoding.UTF8.GetBytes(header);
|
var headerBytes = Encoding.UTF8.GetBytes(header);
|
||||||
await requestStream.WriteAsync(headerbytes, 0, headerbytes.Length);
|
await requestStream.WriteAsync(headerBytes);
|
||||||
using (MemoryStream fileStream = new MemoryStream(fileToUpload))
|
using (var fileStream = new MemoryStream(fileToUpload))
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[1024];
|
var buffer = new byte[1024];
|
||||||
int bytesRead = 0;
|
var bytesRead = 0;
|
||||||
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
|
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
|
||||||
{
|
{
|
||||||
await requestStream.WriteAsync(buffer, 0, bytesRead);
|
await requestStream.WriteAsync(buffer.AsMemory(0, bytesRead));
|
||||||
}
|
}
|
||||||
fileStream.Close();
|
fileStream.Close();
|
||||||
}
|
}
|
||||||
byte[] newlineBytes = Encoding.UTF8.GetBytes("\r\n");
|
var newlineBytes = Encoding.UTF8.GetBytes("\r\n");
|
||||||
await requestStream.WriteAsync(newlineBytes, 0, newlineBytes.Length);
|
await requestStream.WriteAsync(newlineBytes);
|
||||||
byte[] endBytes = Encoding.UTF8.GetBytes("--" + boundary + "--");
|
var endBytes = Encoding.UTF8.GetBytes("--" + boundary + "--");
|
||||||
await requestStream.WriteAsync(endBytes, 0, endBytes.Length);
|
await requestStream.WriteAsync(endBytes);
|
||||||
requestStream.Close();
|
requestStream.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,11 +282,9 @@ namespace VRCX
|
|||||||
var fileData = options["fileData"] as string;
|
var fileData = options["fileData"] as string;
|
||||||
var sentData = Convert.FromBase64CharArray(fileData.ToCharArray(), 0, fileData.Length);
|
var sentData = Convert.FromBase64CharArray(fileData.ToCharArray(), 0, fileData.Length);
|
||||||
request.ContentLength = sentData.Length;
|
request.ContentLength = sentData.Length;
|
||||||
using (var sendStream = request.GetRequestStream())
|
await using var sendStream = request.GetRequestStream();
|
||||||
{
|
await sendStream.WriteAsync(sentData);
|
||||||
await sendStream.WriteAsync(sentData, 0, sentData.Length);
|
sendStream.Close();
|
||||||
sendStream.Close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task ImageUpload(HttpWebRequest request, IDictionary<string, object> options)
|
private static async Task ImageUpload(HttpWebRequest request, IDictionary<string, object> options)
|
||||||
@@ -258,48 +294,48 @@ namespace VRCX
|
|||||||
|
|
||||||
request.AutomaticDecompression = DecompressionMethods.All;
|
request.AutomaticDecompression = DecompressionMethods.All;
|
||||||
request.Method = "POST";
|
request.Method = "POST";
|
||||||
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
|
var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
|
||||||
request.ContentType = "multipart/form-data; boundary=" + boundary;
|
request.ContentType = "multipart/form-data; boundary=" + boundary;
|
||||||
Stream requestStream = request.GetRequestStream();
|
var requestStream = request.GetRequestStream();
|
||||||
if (options.TryGetValue("postData", out object postDataObject))
|
if (options.TryGetValue("postData", out object postDataObject))
|
||||||
{
|
{
|
||||||
var jsonPostData = (JObject)JsonConvert.DeserializeObject((string)postDataObject);
|
var jsonPostData = (JObject)JsonConvert.DeserializeObject((string)postDataObject);
|
||||||
string formDataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n";
|
const string formDataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n";
|
||||||
if (jsonPostData != null)
|
if (jsonPostData != null)
|
||||||
{
|
{
|
||||||
foreach (var data in jsonPostData)
|
foreach (var data in jsonPostData)
|
||||||
{
|
{
|
||||||
string item = string.Format(formDataTemplate, boundary, data.Key, data.Value);
|
var item = string.Format(formDataTemplate, boundary, data.Key, data.Value);
|
||||||
byte[] itemBytes = Encoding.UTF8.GetBytes(item);
|
var itemBytes = Encoding.UTF8.GetBytes(item);
|
||||||
await requestStream.WriteAsync(itemBytes, 0, itemBytes.Length);
|
await requestStream.WriteAsync(itemBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var imageData = options["imageData"] as string;
|
var imageData = options["imageData"] as string;
|
||||||
var matchingDimensions = options["matchingDimensions"] as bool? ?? false;
|
var matchingDimensions = options["matchingDimensions"] as bool? ?? false;
|
||||||
byte[] fileToUpload = Program.AppApiInstance.ResizeImageToFitLimits(Convert.FromBase64String(imageData), matchingDimensions);
|
var fileToUpload = Program.AppApiInstance.ResizeImageToFitLimits(Convert.FromBase64String(imageData), matchingDimensions);
|
||||||
|
|
||||||
string fileFormKey = "file";
|
const string fileFormKey = "file";
|
||||||
string fileName = "blob";
|
const string fileName = "blob";
|
||||||
string fileMimeType = "image/png";
|
const string fileMimeType = "image/png";
|
||||||
string HeaderTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n";
|
const string headerTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n";
|
||||||
string header = string.Format(HeaderTemplate, boundary, fileFormKey, fileName, fileMimeType);
|
var header = string.Format(headerTemplate, boundary, fileFormKey, fileName, fileMimeType);
|
||||||
byte[] headerbytes = Encoding.UTF8.GetBytes(header);
|
var headerBytes = Encoding.UTF8.GetBytes(header);
|
||||||
await requestStream.WriteAsync(headerbytes, 0, headerbytes.Length);
|
await requestStream.WriteAsync(headerBytes);
|
||||||
using (MemoryStream fileStream = new MemoryStream(fileToUpload))
|
using (var fileStream = new MemoryStream(fileToUpload))
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[1024];
|
var buffer = new byte[1024];
|
||||||
int bytesRead = 0;
|
var bytesRead = 0;
|
||||||
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
|
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
|
||||||
{
|
{
|
||||||
await requestStream.WriteAsync(buffer, 0, bytesRead);
|
await requestStream.WriteAsync(buffer.AsMemory(0, bytesRead));
|
||||||
}
|
}
|
||||||
fileStream.Close();
|
fileStream.Close();
|
||||||
}
|
}
|
||||||
byte[] newlineBytes = Encoding.UTF8.GetBytes("\r\n");
|
var newlineBytes = Encoding.UTF8.GetBytes("\r\n");
|
||||||
await requestStream.WriteAsync(newlineBytes, 0, newlineBytes.Length);
|
await requestStream.WriteAsync(newlineBytes);
|
||||||
byte[] endBytes = Encoding.UTF8.GetBytes("--" + boundary + "--");
|
var endBytes = Encoding.UTF8.GetBytes("--" + boundary + "--");
|
||||||
await requestStream.WriteAsync(endBytes, 0, endBytes.Length);
|
await requestStream.WriteAsync(endBytes);
|
||||||
requestStream.Close();
|
requestStream.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15453,8 +15453,7 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
|
|
||||||
API.getAvatarImages = function (params) {
|
API.getAvatarImages = function (params) {
|
||||||
return this.call(`file/${params.fileId}`, {
|
return this.call(`file/${params.fileId}`, {
|
||||||
method: 'GET',
|
method: 'GET'
|
||||||
params
|
|
||||||
}).then((json) => {
|
}).then((json) => {
|
||||||
var args = {
|
var args = {
|
||||||
json,
|
json,
|
||||||
|
|||||||
Reference in New Issue
Block a user