// ==UserScript==
// @name Xbox CLoud Gaming优化整合
// @name:zh-CN Xbox CLoud Gaming优化整合
// @namespace http://tampermonkey.net/xbox/nft
// @version 1.0.3
// @description:zh-cn 整合和修改现有脚本,感谢@TGSAN,@刘翠两位大佬,该脚本支持ios,pc,安卓,优化项(ios语言中文繁体选择+免代理直连+PC安卓振动+safari免添加桌面+禁用低画质+隐藏滚动条+裸连网络中强制开启触屏控制+美化打开basic触控方式后的左上角basic悬浮按钮的样式) 【xbox云游戏交流群531602832】
// @author 奈非天
// @match https://www.xbox.com/*/play*
// @run-at document-start
// @grant unsafeWindow
// @original-script https://gf.qytechs.cn/zh-CN/scripts/455741-xbox-cloud-gaming%E4%BC%98%E5%8C%96%E6%95%B4%E5%90%88
// @description 整合和修改现有脚本,感谢@TGSAN,@刘翠两位大佬,该脚本支持ios,pc,安卓,优化项(ios语言中文繁体选择+免代理直连+PC安卓振动+safari免添加桌面+禁用低画质+隐藏滚动条+裸连网络中强制开启触屏控制+美化打开basic触控方式后的左上角basic悬浮按钮的样式) 【xbox云游戏交流群531602832】
// ==/UserScript==
(function() {
'use strict';
// Your code here...
const originFetch = fetch;
let windowCtx = self.window;
if (self.unsafeWindow) {
console.log("使用unsafeWindow模式");
windowCtx = self.unsafeWindow;
} else {
console.log("使用原生模式");
}
function HookProperty(object, property, value)
{
Object.defineProperty(object, property, {
value: value
});
}
let fakeuad = {
"brands": [
{
"brand": "Microsoft Edge",
"version": "999"
},
{
"brand": "Chromium",
"version": "999"
},
{
"brand": "Not=A?Brand",
"version": "24"
}
],
"mobile": false,
"platform": "Windows"
};
try{
HookProperty(windowCtx.navigator, "userAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/999.0.0.0 Safari/537.36 Edg/999.0.0.0");
HookProperty(windowCtx.navigator, "appVersion", "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/999.0.0.0 Safari/537.36 Edg/999.0.0.0");
HookProperty(windowCtx.navigator, "platform", "Win32");
HookProperty(windowCtx.navigator, "appName", "Netscape");
HookProperty(windowCtx.navigator, "appCodeName", "Mozilla");
HookProperty(windowCtx.navigator, "product", "Gecko");
HookProperty(windowCtx.navigator, "vendor", "Google Inc.");
HookProperty(windowCtx.navigator, "vendorSub", "");
HookProperty(windowCtx.navigator, "maxTouchPoints", undefined);
HookProperty(windowCtx.navigator, "userAgentData", fakeuad);
HookProperty(windowCtx.navigator, "connection", undefined);
HookProperty(windowCtx.navigator, "standalone", true);
}catch(e){}
windowCtx.fetch = (...arg) => {
//fetch = (...arg) => {
// console.log('fetch arg', ...arg);
let arg0 = arg[0];
let url = "";
let isRequest = false;
switch (typeof arg0) {
case "object":
url = arg0.url;
isRequest = true;
break;
case "string":
url = arg0;
break;
default:
break;
}
if (url.indexOf('xgpuweb.gssv-play-prod.xboxlive.com/v2/login/user') > -1){
console.log('xff欺骗开始'+url)
return new Promise((resolve, reject) => {
if (isRequest && arg0.method == "POST") {
arg0.json().then(json => {
let body = JSON.stringify(json);
arg[0].headers.set('x-forwarded-for','168.126.63.1')
arg[0] = new Request(url, {
method: arg0.method,
headers: arg0.headers,
body: body,
});
originFetch(...arg).then(res => {
console.log('xff欺骗结束')
resolve(res);
}).catch(err => {
reject(err);
});
});
} else {
console.error("[ERROR] Not a request.");
return originFetch(...arg);
}
});
}else if (url.indexOf('/v5/sessions/cloud/play') > -1) {
console.log('语言开始')
document.documentElement.style.overflowY = "hidden"
// Start Configuration
return new Promise((resolve, reject) => {
if (isRequest && arg0.method == "POST") {
arg0.json().then(json => {
let selectedLanguage = ""
var yuyan = confirm("确定是简体,取消是繁体");
if(yuyan){
selectedLanguage="zh-CN"
}else{
selectedLanguage="zh-TW"
}
json["settings"]["locale"] = selectedLanguage;
let body = JSON.stringify(json);
arg[0] = new Request(url, {
method: arg0.method,
headers: arg0.headers,
body: body,
mode: arg0.mode,
credentials: arg0.credentials,
cache: arg0.cache,
redirect: arg0.redirect,
referrer: arg0.referrer,
integrity: arg0.integrity
});
originFetch(...arg).then(res => {
console.log('语言结束')
resolve(res);
let cssChanged= setInterval(function(){
let basicBtn=$('.EditErgoMenu-module__basicControlsButtonColor___1sLIY');
if(basicBtn!=null){
if(basicBtn.css('color')!='black'){
$('.EditErgoMenu-module__basicControlsButtonColor___1sLIY').text('X')
$('.EditErgoMenu-module__basicControlsButtonColor___1sLIY').css('background-color',' #dc353500')
//$('.EditErgoMenu-module__basicControlsButtonColor___1sLIY').css('color',' black')
$('.EditErgoMenu-module__basicControlsButtonColor___1sLIY').css('width',' 10px')
$('.EditErgoMenu-module__basicControlsButtonColor___1sLIY').css('min-width',' 10px')
}
}
},2000)
}).catch(err => {
reject(err);
});
});
} else {
console.error("[ERROR] Not a request.");
return originFetch(...arg);
}
});
} else if (url.indexOf('/v2/login/user') > -1 && url.indexOf('xgpuweb.gssv-play-prod.xboxlive.com')<0) {
console.log('允许修改区域开始')
return new Promise((resolve, reject) => {
originFetch(...arg).then(res => {
res.json().then(json => {
// console.error(json);
json["offeringSettings"]["allowRegionSelection"] = true;
let body = JSON.stringify(json);
let newRes = new Response(body, {
status: res.status,
statusText: res.statusText,
headers: res.headers
})
console.log('允许修改区域结束')
resolve(newRes);
}).catch(err => {
reject(err);
});
}).catch(err => {
reject(err);
});
});
}else if (url.indexOf('/v2/titles') > -1) { // /v2/titles or /v2/titles/mru
// Enable CustomTouchOverlay
console.log('修改触摸开始')
return new Promise((resolve, reject) => {
originFetch(...arg).then(res => {
res.json().then(json => {
// console.error(json);
try {
json["results"].forEach(result => {
if (result["details"]["supportedInputTypes"].includes("CustomTouchOverlay") === false) {
result["details"]["supportedInputTypes"].push("CustomTouchOverlay");
// console.log("[Xbox Cloud Gaming Global Touch Controll] Hook " + result["titleId"]);
}
if (result["details"]["supportedInputTypes"].includes("MKB") === false) {
result["details"]["supportedInputTypes"].push("MKB");
// console.log("[Xbox Cloud Gaming Global Touch Controll] Hook " + result["titleId"]);
}
if (result["details"]["supportedInputTypes"].includes("GenericTouch") === false) {
result["details"]["supportedInputTypes"].push("GenericTouch");
// console.log("[Xbox Cloud Gaming Global Touch Controll] Hook " + result["titleId"]);
}
if (result["details"]["supportedInputTypes"].includes("NativeTouch") === false) {
result["details"]["supportedInputTypes"].push("NativeTouch");
// console.log("[Xbox Cloud Gaming Global Touch Controll] Hook " + result["titleId"]);
}
});
} catch (err) {}
let body = JSON.stringify(json);
let newRes = new Response(body, {
status: res.status,
statusText: res.statusText,
headers: res.headers
})
resolve(newRes);
console.log('修改触摸结束')
}).catch(err => {
reject(err);
});
}).catch(err => {
reject(err);
});
});
}else {
return originFetch(...arg);
}
}
zhengdong()
function zhengdong(){
const useControllerVibration = true;
const useMobileVibration = true;
let haptic = null;
let xinputMaxHaptic = 65535;
RTCPeerConnection.prototype.createDataChannelOriginal = RTCPeerConnection.prototype.createDataChannel;
RTCPeerConnection.prototype.createDataChannel = function (...params) {
let dc = this.createDataChannelOriginal(...params)
if (dc.label == "input") {
dc.addEventListener("message", function (de) {
if (typeof(de.data) == "object") {
let dataBytes = new Uint8Array(de.data);
if (dataBytes[0] == 128) {
let leftM = dataBytes[3] / 255;
let rightM = dataBytes[4] / 255;
let leftT = dataBytes[5] / 255;
let rightT = dataBytes[6] / 255;
if (haptic) haptic.SetState(leftM * xinputMaxHaptic, rightM * xinputMaxHaptic);
}
}
});
dc.addEventListener("close", function () {
if (haptic) haptic.SetState(0, 0);
});
}
return dc;
}
// Compile with Webpack, disable UglifyJS
class WebHaptic {
constructor(t = !0, e = !0) {
this.isRunning = !1,
this.lms = 0,
this.mp = 0,
this.supportch = !1,
this.enablech = !0,
this.supportwvh = !1,
this.enablewvh = !0,
this.gamepads = [],
this.enablewvh = t,
this.enablewvh && (this.supportwvh = WebHaptic.IsSupportWebVibrateHaptic()),
this.enablech = e,
this.enablech && (this.supportch = WebHaptic.IsSupportControllerHaptic()),
this.onGamepadConnected = (t => { console.log("A gamepad was connected:" + t.gamepad.id), this.UpdateGamepads() }),
this.onGamepadDisonnected = (t => { console.log("A gamepad was disconnected:" + t.gamepad.id), this.UpdateGamepads() }),
this.supportch && (window.addEventListener("gamepadconnected", this.onGamepadConnected), window.addEventListener("gamepaddisconnected", this.onGamepadDisonnected), this.UpdateGamepads())
}
static IsSupportControllerHaptic() {
var t, e;
return !!(window.Gamepad && window.GamepadHapticActuator && (null === (e = null === (t = window.GamepadHapticActuator) || void 0 === t ? void 0 : t.prototype) || void 0 === e ? void 0 : e.hasOwnProperty("playEffect")))
}
static IsSupportWebVibrateHaptic() {
return !!window.navigator.vibrate
}
static IsSupport() {
return WebHaptic.IsSupportControllerHaptic() || WebHaptic.IsSupportWebVibrateHaptic()
}
EnableControllerHaptic() {
this.enablech = !0
}
DisableControllerHaptic() {
this.enablech = !1
}
EnableWebVibrateHaptic() {
this.enablewvh = !0
}
DisableWebVibrateHaptic() {
this.enablewvh = !1
}
Dispose() {
this.SetState(0, 0),
this.supportch && (window.removeEventListener("gamepadconnected", this.onGamepadConnected), window.removeEventListener("gamepaddisconnected", this.onGamepadDisonnected))
}
SetState(t, e) {
this.updateTimeoutId && clearTimeout(this.updateTimeoutId), (this.enablewvh || 0 == t || 0 == e) && this.SetWebHapticState(t, e), (this.enablech || 0 == t || 0 == e) && this.SetControllerState(t, e)
}
SetWebHapticState(t, e) {
if (this.supportwvh) {
let i = .5, a = 65535, o = Math.max(t, e * i);
o != this.lms && (this.lms = o, this.mp = o / a, o > 0 ? 0 == this.isRunning && (this.isRunning = !0, this.OnVibrateTick(this)) : (this.isRunning = !1, window.navigator.vibrate(0)))
}
}
SetControllerState(t, e) {
var i, a;
if (this.supportch) {
let o = 65535, r = 1e3, n = t / o, s = e / o;
for (const [t, e] of Object.entries(this.gamepads)) null != e && (null === (a = null === (i = e) || void 0 === i ? void 0 : i.vibrationActuator) || void 0 === a || a.playEffect("dual-rumble", {
duration: r,
strongMagnitude: n,
weakMagnitude: s
}))
}
}
UpdateGamepads() {
this.gamepads = navigator.getGamepads()
}
OnVibrateTick(t) {
t.lms > 0 && 1 == t.isRunning && (t.mp < .075 ? t.LowVibrate(t, t.mp) : this.mp < .88 ? t.MidVibrate(t, t.mp) : t.HighVibrate(t, t.mp))
}
HighVibrate(t, e) {
let i = 100 * e;
window.navigator.vibrate(i), setTimeout(() => { t.OnVibrateTick(t) }, i)
}
MidVibrate(t, e) {
let i = 50 * e;
window.navigator.vibrate(i), setTimeout(() => { t.OnVibrateTick(t) }, i)
}
LowVibrate(t, e) {
let i = 100 - e / .025 * 100;
window.navigator.vibrate(2), setTimeout(() => { t.OnVibrateTick(t) }, i)
}
}
if(WebHaptic.IsSupportWebVibrateHaptic){
haptic = new WebHaptic(useMobileVibration, useControllerVibration);
}
}
})();