牛牛
当前为
// ==UserScript==
// @name 牛牛战斗助手
// @namespace http://tampermonkey.net/
// @version 2025-05-16
// @description 牛牛
// @icon https://www.milkywayidle.com/favicon.svg
// @author You
// @match https://www.milkywayidle.com/*
// @grant GM_xmlhttpRequest
// @license MIT
// ==/UserScript==
(function() {
if (document.URL.includes("test.milkywayidle.com"))return;
const host = "https://niuniu.0xa2c2a.shop"
let config={
sikll_upload: host + "/api/player",
party_upload:host + "/api/party",
}
// 拦截WS
function hookWebSocket() {
const dataProperty = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "data");
const oriGet = dataProperty.get;
dataProperty.get = hookedGet;
Object.defineProperty(MessageEvent.prototype, "data", dataProperty);
function hookedGet() {
const socket = this.currentTarget;
if (!(socket instanceof WebSocket)) {
return oriGet.call(this);
}
if (socket.url.indexOf("api.milkywayidle.com/ws") <= -1 && socket.url.indexOf("api-test.milkywayidle.com/ws") <= -1) {
return oriGet.call(this);
}
const message = oriGet.call(this);
Object.defineProperty(this, "data", { value: message });
return handleMessage(message);
}
}
hookWebSocket();
// WS拦截后处理,主进程
function handleMessage(message,debug=false) {
let obj = JSON.parse(message);
if (obj && obj.type === "init_character_data") {
// 组队情况
addPartyButton();
addPlayerButton();
// 上传初始化登录(不可用)数据
uploadInitCharacterData(obj);
}else if (obj && obj.type === "profile_shared"){
// 上传玩家面板数据
uploadProfileShared(obj);
}
//other
return message;
}
// 上传玩家面板数据
function uploadProfileShared(obj){
let data={};
let profile = obj.profile;
data.name=profile.sharableCharacter.name
if(profile.sharableCharacter.gameMode !== "standard")return;
data.weapon = profile.hideWearableItems?null:getWeapon(profile?.wearableItemMap['/item_locations/main_hand']?.itemHrid);
let ranged,attack,power,magic = "";
for( const item of profile.characterSkills){
if(item.skillHrid === "/skills/ranged"){
ranged = item.experience.toFixed();
data.id=item.characterID;
}else if(item.skillHrid === "/skills/attack"){
attack = item.experience.toFixed();
} else if(item.skillHrid === "/skills/power"){
power = item.experience.toFixed();
}else if(item.skillHrid === "/skills/magic"){
magic = item.experience.toFixed();
}
}
data.skill=ranged+","+attack+","+power+","+magic;
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'POST',
url: config.sikll_upload,
headers: {
"Content-Type": "application/json",
"reporter":data.id
},
data:JSON.stringify(data),
onload: function (response) {
resolve();
},
onerror: function (error) {
reject(error);
}
});
});
}
function getWeapon(mainHand){
if(!mainHand) return null;
mainHand = mainHand.substr(7);
return mainHand
}
// 上传初始化登录(不可用)数据
function uploadInitCharacterData(obj){
const fake_profile_shared={}
fake_profile_shared.type="profile_shared";
fake_profile_shared.profile={};
fake_profile_shared.profile.characterSkills=obj.characterSkills;
fake_profile_shared.profile.combatLevel=obj.combatUnit.combatDetails.combatLevel;
if(obj.guild){
fake_profile_shared.profile.guildName=obj.guild.name;
fake_profile_shared.profile.guildRole=obj.guildCharacterMap[obj.character.id].role;
}else{
fake_profile_shared.profile.guildName="";
fake_profile_shared.profile.guildRole="";
}
fake_profile_shared.profile.sharableCharacter=obj.character;
fake_profile_shared.profile.wearableItemMap={}
obj.characterItems.forEach(item=>{
if(item.itemLocationHrid!='/item_locations/inventory'){
fake_profile_shared.profile.wearableItemMap[item.itemLocationHrid]=item;
}
})
uploadProfileShared(fake_profile_shared);
uploadPartyInfo(obj);
}
// 上传组队数据
function uploadPartyInfo(obj){
let data={};
const partyInfo = obj?.partyInfo
if((!partyInfo) || (partyInfo?.party?.status !== "battling")) return;
data.id=partyInfo.party.id;
data.map=partyInfo.party.actionHrid.substr(16);
data.players="";
for(let k in partyInfo.sharableCharacterMap){
if(data.players) data.players += ","
data.players += k+":"+partyInfo.sharableCharacterMap[k].name
}
let reporter = obj.user.id;
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'POST',
url: config.party_upload,
headers: {
"Content-Type": "application/json",
"reporter":reporter
},
data:JSON.stringify(data),
onload: function (response) {
resolve();
},
onerror: function (error) {
reject(error);
}
});
});
}
//组队情况
function addPartyButton() {
const waitForNavi = () => {
const targetNode = document.querySelector("div.NavigationBar_minorNavigationLinks__dbxh7"); // 确认这个选择器是否适合你的环境
const navigationLinks = document.querySelectorAll('div.NavigationBar_minorNavigationLink__31K7Y');
let toolLink;
for (let link of navigationLinks) {
if (link.textContent.includes('插件设置')||link.textContent.includes('Script settings')) {
toolLink = link;
break;
}
}
if (targetNode&&toolLink) {
let statsButton = document.createElement("div");
statsButton.setAttribute("class", "NavigationBar_minorNavigationLink__31K7Y");
statsButton.style.color = toolLink.style.color;
statsButton.innerHTML = "国人组队情况";
statsButton.addEventListener("click", () => {
window.open("https://niuniu.0xa2c2a.shop/party.html", "_blank");
});
// 将按钮添加到目标节点
targetNode.insertBefore(statsButton, toolLink.nextSibling);
} else {
setTimeout(addPartyButton, 200);
}
};
waitForNavi(); // 开始等待目标节点出现
}
//组队情况
function addPlayerButton() {
const waitForNavi = () => {
const targetNode = document.querySelector("div.NavigationBar_minorNavigationLinks__dbxh7"); // 确认这个选择器是否适合你的环境
const navigationLinks = document.querySelectorAll('div.NavigationBar_minorNavigationLink__31K7Y');
let toolLink;
for (let link of navigationLinks) {
if (link.textContent.includes('插件设置')||link.textContent.includes('Script settings')) {
toolLink = link;
break;
}
}
if (targetNode&&toolLink) {
let statsButton = document.createElement("div");
statsButton.setAttribute("class", "NavigationBar_minorNavigationLink__31K7Y");
statsButton.style.color = toolLink.style.color;
statsButton.innerHTML = "战斗排行榜";
statsButton.addEventListener("click", () => {
window.open("https://niuniu.0xa2c2a.shop/player.html", "_blank");
});
// 将按钮添加到目标节点
targetNode.insertBefore(statsButton, toolLink.nextSibling);
} else {
setTimeout(addPlayerButton, 200);
}
};
waitForNavi(); // 开始等待目标节点出现
}
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址