mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-07 06:56:04 +02:00
use internal http request
This commit is contained in:
@@ -60,11 +60,13 @@ namespace VRCX
|
|||||||
CpuMonitor.Instance.Init();
|
CpuMonitor.Instance.Init();
|
||||||
Discord.Instance.Init();
|
Discord.Instance.Init();
|
||||||
SQLite.Instance.Init();
|
SQLite.Instance.Init();
|
||||||
|
WebApi.Instance.Init();
|
||||||
LogWatcher.Instance.Init();
|
LogWatcher.Instance.Init();
|
||||||
VRCXVR.Init();
|
VRCXVR.Init();
|
||||||
Application.Run(new MainForm());
|
Application.Run(new MainForm());
|
||||||
VRCXVR.Exit();
|
VRCXVR.Exit();
|
||||||
LogWatcher.Instance.Exit();
|
LogWatcher.Instance.Exit();
|
||||||
|
WebApi.Instance.Exit();
|
||||||
SQLite.Instance.Exit();
|
SQLite.Instance.Exit();
|
||||||
Discord.Instance.Exit();
|
Discord.Instance.Exit();
|
||||||
CpuMonitor.Instance.Exit();
|
CpuMonitor.Instance.Exit();
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ namespace VRCX
|
|||||||
};
|
};
|
||||||
repository.Register("VRCX", VRCX.Instance, true, options);
|
repository.Register("VRCX", VRCX.Instance, true, options);
|
||||||
repository.Register("SharedVariable", SharedVariable.Instance, false, options);
|
repository.Register("SharedVariable", SharedVariable.Instance, false, options);
|
||||||
|
repository.Register("WebApi", WebApi.Instance, true, options);
|
||||||
repository.Register("VRCXStorage", VRCXStorage.Instance, false, options);
|
repository.Register("VRCXStorage", VRCXStorage.Instance, false, options);
|
||||||
repository.Register("SQLite", SQLite.Instance, true, options);
|
repository.Register("SQLite", SQLite.Instance, true, options);
|
||||||
repository.Register("LogWatcher", LogWatcher.Instance, true, options);
|
repository.Register("LogWatcher", LogWatcher.Instance, true, options);
|
||||||
|
|||||||
@@ -131,6 +131,7 @@
|
|||||||
<Compile Include="Browser.cs" />
|
<Compile Include="Browser.cs" />
|
||||||
<Compile Include="NoopDragHandler.cs" />
|
<Compile Include="NoopDragHandler.cs" />
|
||||||
<Compile Include="RenderHandler.cs" />
|
<Compile Include="RenderHandler.cs" />
|
||||||
|
<Compile Include="WebApi.cs" />
|
||||||
<Compile Include="SQLite.cs" />
|
<Compile Include="SQLite.cs" />
|
||||||
<Compile Include="SharedVariable.cs" />
|
<Compile Include="SharedVariable.cs" />
|
||||||
<Compile Include="Util.cs" />
|
<Compile Include="Util.cs" />
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
using CefSharp;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
|
||||||
|
namespace VRCX
|
||||||
|
{
|
||||||
|
public class WebApi
|
||||||
|
{
|
||||||
|
private readonly string COOKIE_FILE_NAME = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cookies.dat");
|
||||||
|
public static WebApi Instance { get; private set; }
|
||||||
|
private CookieContainer _cookieContainer;
|
||||||
|
|
||||||
|
static WebApi()
|
||||||
|
{
|
||||||
|
Instance = new WebApi();
|
||||||
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WebApi()
|
||||||
|
{
|
||||||
|
_cookieContainer = new CookieContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Init()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var file = File.Open(COOKIE_FILE_NAME, FileMode.Open, FileAccess.Read))
|
||||||
|
{
|
||||||
|
_cookieContainer = (CookieContainer)new BinaryFormatter().Deserialize(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Exit()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var file = File.Open(COOKIE_FILE_NAME, FileMode.Create, FileAccess.Write))
|
||||||
|
{
|
||||||
|
new BinaryFormatter().Serialize(file, _cookieContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearCookies()
|
||||||
|
{
|
||||||
|
_cookieContainer = new CookieContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CS4014
|
||||||
|
public async void Execute(IDictionary<string, object> options, IJavascriptCallback callback)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var request = WebRequest.CreateHttp((string)options["url"]);
|
||||||
|
request.CookieContainer = _cookieContainer;
|
||||||
|
request.KeepAlive = true;
|
||||||
|
|
||||||
|
if (options.TryGetValue("headers", out object headers) == true)
|
||||||
|
{
|
||||||
|
foreach (var header in (IEnumerable<KeyValuePair<string, object>>)headers)
|
||||||
|
{
|
||||||
|
var key = header.Key;
|
||||||
|
var value = header.Value.ToString();
|
||||||
|
|
||||||
|
if (string.Compare(key, "Content-Type", StringComparison.OrdinalIgnoreCase) == 0)
|
||||||
|
{
|
||||||
|
request.ContentType = value;
|
||||||
|
}
|
||||||
|
else if (string.Compare(key, "User-Agent", StringComparison.OrdinalIgnoreCase) == 0)
|
||||||
|
{
|
||||||
|
request.UserAgent = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request.Headers.Add(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.TryGetValue("method", out object method) == true)
|
||||||
|
{
|
||||||
|
var _method = (string)method;
|
||||||
|
request.Method = _method;
|
||||||
|
|
||||||
|
if (string.Compare(_method, "GET", StringComparison.OrdinalIgnoreCase) != 0 &&
|
||||||
|
options.TryGetValue("body", out object body) == true)
|
||||||
|
{
|
||||||
|
using (var stream = await request.GetRequestStreamAsync())
|
||||||
|
using (var streamWriter = new StreamWriter(stream))
|
||||||
|
{
|
||||||
|
await streamWriter.WriteAsync((string)body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var response = await request.GetResponseAsync() as HttpWebResponse)
|
||||||
|
using (var stream = response.GetResponseStream())
|
||||||
|
using (var streamReader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
callback.ExecuteAsync(null, new
|
||||||
|
{
|
||||||
|
data = await streamReader.ReadToEndAsync(),
|
||||||
|
status = response.StatusCode
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (WebException webException)
|
||||||
|
{
|
||||||
|
if (webException.Response is HttpWebResponse response)
|
||||||
|
{
|
||||||
|
using (var stream = response.GetResponseStream())
|
||||||
|
using (var streamReader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
callback.ExecuteAsync(null, new
|
||||||
|
{
|
||||||
|
data = await streamReader.ReadToEndAsync(),
|
||||||
|
status = response.StatusCode
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callback.ExecuteAsync(webException.Message, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
callback.ExecuteAsync(e.Message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback.Dispose();
|
||||||
|
}
|
||||||
|
#pragma warning restore CS4014
|
||||||
|
}
|
||||||
|
}
|
||||||
+64
-58
@@ -13,12 +13,13 @@ import locale from 'element-ui/lib/locale/lang/en';
|
|||||||
|
|
||||||
import sharedRepository from './repository/shared.js';
|
import sharedRepository from './repository/shared.js';
|
||||||
import configRepository from './repository/config.js';
|
import configRepository from './repository/config.js';
|
||||||
|
|
||||||
window.sharedRepository = sharedRepository;
|
window.sharedRepository = sharedRepository;
|
||||||
window.configRepository = configRepository;
|
window.configRepository = configRepository;
|
||||||
|
import webApiService from './service/webapi.js';
|
||||||
|
|
||||||
(async function () {
|
(async function () {
|
||||||
await CefSharp.BindObjectAsync(
|
await CefSharp.BindObjectAsync(
|
||||||
|
'WebApi',
|
||||||
'VRCX',
|
'VRCX',
|
||||||
'SharedVariable', // DO NOT DIRECT ACCESS
|
'SharedVariable', // DO NOT DIRECT ACCESS
|
||||||
'VRCXStorage',
|
'VRCXStorage',
|
||||||
@@ -330,30 +331,25 @@ window.configRepository = configRepository;
|
|||||||
API.pendingGetRequests = new Map();
|
API.pendingGetRequests = new Map();
|
||||||
|
|
||||||
API.call = function (endpoint, options) {
|
API.call = function (endpoint, options) {
|
||||||
var resource = `https://api.vrchat.cloud/api/1/${endpoint}`;
|
|
||||||
var init = {
|
var init = {
|
||||||
|
url: `https://api.vrchat.cloud/api/1/${endpoint}`,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
mode: 'cors',
|
|
||||||
credentials: 'include',
|
|
||||||
cache: 'no-cache',
|
|
||||||
redirect: 'follow',
|
|
||||||
referrerPolicy: 'no-referrer',
|
|
||||||
...options
|
...options
|
||||||
};
|
};
|
||||||
var { params } = init;
|
var { params } = init;
|
||||||
var isGetRequest = init.method === 'GET';
|
var isGetRequest = init.method === 'GET';
|
||||||
if (isGetRequest) {
|
if (isGetRequest === true) {
|
||||||
// transform body to url
|
// transform body to url
|
||||||
if (params === Object(params)) {
|
if (params === Object(params)) {
|
||||||
var url = new URL(resource);
|
var url = new URL(init.url);
|
||||||
var { searchParams } = url;
|
var { searchParams } = url;
|
||||||
for (var key in params) {
|
for (var key in params) {
|
||||||
searchParams.set(key, params[key]);
|
searchParams.set(key, params[key]);
|
||||||
}
|
}
|
||||||
resource = url.toString();
|
init.url = url.toString();
|
||||||
}
|
}
|
||||||
// merge requests
|
// merge requests
|
||||||
var req = this.pendingGetRequests.get(resource);
|
var req = this.pendingGetRequests.get(init.url);
|
||||||
if (req !== undefined) {
|
if (req !== undefined) {
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
@@ -366,45 +362,50 @@ window.configRepository = configRepository;
|
|||||||
? JSON.stringify(params)
|
? JSON.stringify(params)
|
||||||
: '{}';
|
: '{}';
|
||||||
}
|
}
|
||||||
var req = fetch(resource, init).catch((err) => {
|
var req = webApiService.execute(init).catch((err) => {
|
||||||
this.$throw(0, err);
|
this.$throw(0, err);
|
||||||
}).then((res) => res.json().catch(() => {
|
}).then((response) => {
|
||||||
if (res.ok) {
|
try {
|
||||||
|
response.data = JSON.parse(response.data);
|
||||||
|
return response;
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
if (response.status === 200) {
|
||||||
this.$throw(0, 'Invalid JSON response');
|
this.$throw(0, 'Invalid JSON response');
|
||||||
}
|
}
|
||||||
this.$throw(res.status);
|
this.$throw(res.status);
|
||||||
}).then((json) => {
|
}).then(({ data, status }) => {
|
||||||
if (res.ok) {
|
if (data === Object(data)) {
|
||||||
if (json.success === Object(json.success)) {
|
if (status === 200) {
|
||||||
new Noty({
|
if (data.success === Object(data.success)) {
|
||||||
type: 'success',
|
new Noty({
|
||||||
text: escapeTag(json.success.message)
|
type: 'success',
|
||||||
}).show();
|
text: escapeTag(data.success.message)
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
return json;
|
if (data.error === Object(data.error)) {
|
||||||
}
|
|
||||||
if (json === Object(json)) {
|
|
||||||
if (json.error === Object(json.error)) {
|
|
||||||
this.$throw(
|
this.$throw(
|
||||||
json.error.status_code || res.status,
|
data.error.status_code || status,
|
||||||
json.error.message,
|
data.error.message,
|
||||||
json.error.data
|
data.error.data
|
||||||
);
|
);
|
||||||
} else if (typeof json.error === 'string') {
|
} else if (typeof data.error === 'string') {
|
||||||
this.$throw(
|
this.$throw(
|
||||||
json.status_code || res.status,
|
data.status_code || status,
|
||||||
json.error
|
data.error
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$throw(res.status, json);
|
this.$throw(status, data);
|
||||||
return json;
|
return data;
|
||||||
}));
|
});
|
||||||
if (isGetRequest) {
|
if (isGetRequest === true) {
|
||||||
req.finally(() => {
|
req.finally(() => {
|
||||||
this.pendingGetRequests.delete(resource);
|
this.pendingGetRequests.delete(init.url);
|
||||||
});
|
});
|
||||||
this.pendingGetRequests.set(resource, req);
|
this.pendingGetRequests.set(init.url, req);
|
||||||
}
|
}
|
||||||
return req;
|
return req;
|
||||||
};
|
};
|
||||||
@@ -817,7 +818,7 @@ window.configRepository = configRepository;
|
|||||||
API.currentUser = {};
|
API.currentUser = {};
|
||||||
|
|
||||||
API.$on('LOGOUT', function () {
|
API.$on('LOGOUT', function () {
|
||||||
VRCX.DeleteAllCookies();
|
webApiService.clearCookies();
|
||||||
this.isLoggedIn = false;
|
this.isLoggedIn = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -3341,28 +3342,33 @@ window.configRepository = configRepository;
|
|||||||
return style;
|
return style;
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.checkAppVersion = function () {
|
$app.methods.checkAppVersion = async function () {
|
||||||
var url = 'https://api.github.com/repos/pypy-vrc/VRCX/releases/latest';
|
var response = await webApiService.execute({
|
||||||
fetch(url).then((res) => res.json()).then((json) => {
|
url: 'https://api.github.com/repos/pypy-vrc/VRCX/releases/latest',
|
||||||
if (json === Object(json) &&
|
method: 'GET',
|
||||||
json.name &&
|
headers: {
|
||||||
json.published_at) {
|
'User-Agent': 'VRCX'
|
||||||
this.latestAppVersion = `${json.name} (${formatDate(json.published_at, 'YYYY-MM-DD HH24:MI:SS')})`;
|
|
||||||
if (json.name > this.appVersion) {
|
|
||||||
new Noty({
|
|
||||||
type: 'info',
|
|
||||||
text: `Update available!!<br>${this.latestAppVersion}`,
|
|
||||||
timeout: 60000,
|
|
||||||
callbacks: {
|
|
||||||
onClick: () => VRCX.OpenLink('https://github.com/pypy-vrc/VRCX/releases')
|
|
||||||
}
|
|
||||||
}).show();
|
|
||||||
this.notifyMenu('more');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.latestAppVersion = 'Error occured';
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
var json = JSON.parse(response.data);
|
||||||
|
if (json === Object(json) &&
|
||||||
|
json.name &&
|
||||||
|
json.published_at) {
|
||||||
|
this.latestAppVersion = `${json.name} (${formatDate(json.published_at, 'YYYY-MM-DD HH24:MI:SS')})`;
|
||||||
|
if (json.name > this.appVersion) {
|
||||||
|
new Noty({
|
||||||
|
type: 'info',
|
||||||
|
text: `Update available!!<br>${this.latestAppVersion}`,
|
||||||
|
timeout: 60000,
|
||||||
|
callbacks: {
|
||||||
|
onClick: () => VRCX.OpenLink('https://github.com/pypy-vrc/VRCX/releases')
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
this.notifyMenu('more');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.latestAppVersion = 'Error occured';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.updateLoop = function () {
|
$app.methods.updateLoop = function () {
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// requires binding of WebApi
|
||||||
|
|
||||||
|
class WebApiService {
|
||||||
|
clearCookies() {
|
||||||
|
return WebApi.ClearCookies();
|
||||||
|
}
|
||||||
|
|
||||||
|
execute(options) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
WebApi.Execute(options, (err, response) => {
|
||||||
|
if (err !== null) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve(response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var self = new WebApiService();
|
||||||
|
|
||||||
|
export {
|
||||||
|
self as default,
|
||||||
|
WebApiService
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user