// ==UserScript==
// @name wsmud_funny
// @namespace suqing
// @version 0.1.11
// @author sq
// @match http://game.wsmud.com/*
// @match http://www.wsmud.com/*
// @homepage https://gf.qytechs.cn/zh-CN/scripts/380709
// @description 武神传说脚本,内置了许多小功能。
// @run-at document-start
// @require http://code.jquery.com/jquery-3.3.1.min.js
// @require https://cdn.bootcss.com/jquery.nicescroll/3.7.6/jquery.nicescroll.min.js
// @grant unsafeWindow
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_getValue
// @grant GM_setClipboard
// ==/UserScript==
(function() {
'use strict';
let funny = {
scriptName: GM_info.script.name,
scriptVersion: GM_info.script.version,
scriptAuthor: GM_info.script.author,
webSocket: undefined,
onmessage_fn: undefined,
role: {
jy: 0,
qn: 0,
},
skills: {},
sleep: function(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
},
scroll: function(className) {
let a = $(`.${className}`)[0].scrollTop,
b = $(`.${className}`)[0].scrollHeight,
h = Math.ceil($(`.${className}`).height()); // 向上取整
// console.log(`scroll => scrollTop=${a} scrollHeight=${b} height=${h}`);
if (a < b - h) {
$(`.${className}`)[0].scrollTop = a + 1;
setTimeout(`funny.scroll("${className}")`, 1000/120);
}
},
// 向服务器发送消息
sendmessage: function(message) {
if (typeof message === "string") { // 1. 字符串
send(message);
} else if (message instanceof Array) { // 2. 数组
action(message);
async function action(message) {
for (const m of message) {
await funny.sleep(1000);
send(m);
}
}
}
function send(message) { // 发送
if ($("#sendmessage").attr("cmd")) {
$("#sendmessage").attr("cmd", message);
} else {
$(".container").append($(`<span id="sendmessage" cmd="${message}"><span>`));
}
$("#sendmessage").click();
}
},
// 截获到的接收的消息
onmessage: function(message) {
// 0. 分析处理
let data = message.data || "error";
if ((data.includes("{") && data.includes("}")) || (data.includes("[") && data.includes("]"))) {
data = new Function("return " + data + ";")();
}
// 1. 重新连线
if (/重新连线。|欢迎登陆<HIW>武神传说<\/HIW>/.test(data)) {
$(".content-message pre").append(`${data}\n`);
getScore();
$(".content-message pre").append(`${funny.scriptName} ${funny.scriptVersion}\n`);
async function getScore() { // 模拟点击
await funny.sleep(100);
funny.sendmessage("score"); // 属性 1
await funny.sleep(100);
funny.sendmessage("score2"); // 属性 2
await funny.sleep(100);
$("[command=skills]").click(); // 点击技能
await funny.sleep(100);
$(".dialog-close").click(); // 关闭窗口
$("[command=showcombat]").click(); // 点击动作
$("[command=showtool]").click(); // 点击菜单
await funny.sleep(1000);
funny.sendmessage("tasks"); // 任务
};
return;
}
// 1.2 自动吃养精丹
if (data.type === "addAction" && data.name === "养精丹") {
funny.sendmessage(`use ${data.id}`);
}
if (data.type === "actions" && data.actions) {
data.actions.forEach(item => {
funny.sendmessage("stopstate");
if (item.name === "养精丹") {
for (let i = 1; i <= 10; i ++) setTimeout(() => funny.sendmessage(item.cmd), i * 500);
}
});
setTimeout(() => funny.sendmessage("dazuo"), 5000);
}
// 1.3 自动查看任务
if (data.type === "dialog" && data.dialog === "tasks") {
if (data.items) {
$(".content-message pre").append(`- - - - -\n`);
data.items.forEach(item => {
let array = ["0", "进行中", "可领取", "已完成"];
if (item.state === 2) {
setTimeout(() => {
funny.sendmessage(`taskover ${item.id}`);
}, 1000);
}
$(".content-message pre").append(`${item.title} => ${array[item.state]}\n`);
});
$(".content-message pre").append(`- - - - -\n`);
}
}
// 2. 经验潜能
if (/<hig>你获得了.*点经验,.*点潜能.*/.test(data)) {
// 你获得了1360点经验,1360点潜能,六两白银八十个铜板。
let array = data.split(/你获得了|点经验,|点潜能/);
funny.role.jy += parseInt(array[1]);
funny.role.qn += parseInt(array[2]);
$(".remove_jyqn").remove();
$(".content-message pre").append(`${data}\n`);
$(".content-message pre").append(`<span class="remove_jyqn">共计获得了${funny.role.jy}点经验,${funny.role.qn}点潜能。\n</span>`);
funny.scroll("content-message");
return;
}
if (/恭喜你战胜了武道塔守护者,你现在可以进入下一层。/.test(data)) {
funny.sendmessage("go up");
$(".content-message pre").append(`${data}\n`);
return;
}
// 3. 物品收获
if (/你从.*的尸体里拿出来.*|你获得了|<hig>恭喜你.*/.test(data)) {
funny.onmessage_fn.apply(this, arguments);
if (/你获得了.*<wht>|银子/.test(data)) {
} else {
$(".pickup").append(`${data}<br>`);
funny.scroll("pickup");
}
return;
}
// 4. 聊天消息
if (data.type === "msg") {
// 补充 => 发送文字表情的时候是没有 name 属性的
data.name = (data.name === "" || data.name === undefined) ? `` : `${data.name}:`;
if (data.ch === "chat") {
let levels = ["<hic>闲聊</hic>", "<hic>闲聊</hic>", "<hic>闲聊</hic>", "<hiy>宗师</hiy>", "<hiz>武圣</hiz>", "<hio>武帝</hio>", "<hir>武神</hir>"];
$(".chat").append(
$(`<span cmd="look3 ${data.uid}"><hic>【${levels[data.lv]}】${data.name}${data.content}</hic><br></span>`)
.click(function() { funny.sendmessage(`${$(this).attr("cmd")}`); })
);
} else if (data.ch === "fam") {
$(".fam").append(
$(`<span cmd="look3 ${data.uid}"><hiy>【${data.fam}】${data.name}${data.content}</hiy><br></span>`)
.click(function() { funny.sendmessage(`${$(this).attr("cmd")}`); })
);
} else if (data.ch === "pty") {
$(".pty").append(
$(`<span cmd="look3 ${data.uid}"><hiz>【帮派】${data.name}${data.content}</hiz><br></span>`)
.click(function() { funny.sendmessage(`${$(this).attr("cmd")}`); })
);
} else if (data.ch === "tm") {
$(".tm").append(`<hig>【队伍】${data.name}${data.content}</hig><br>`);
} else if (data.ch === "es") {
$(".es").append(`<hio>【${data.server}】${data.name}${data.content}</hio><br>`);
} else if (data.ch === "rumor") {
$(".rumor").append(`<him>【谣言】${data.content}</him><br>`);
if (/听说有人得到了.*/.test(data.content)) {
let array = data.content.split(/听说有人得到了/);
funny.sendmessage(`chat 恭贺大佬喜提「${array[1]}」!`);
} else if (/听说武帝.*闭关修炼似有所悟,你随之受益获得了.*/.test(data.content)) {
// 听说武帝xxxx闭关修炼似有所悟,你随之受益获得了xxxx经验,xxxx潜能
let array = data.content.split(/听说武帝|闭关修炼/);
funny.sendmessage(`chat 感谢武帝「${array[1]}」的出关奖励!`);
}
} else if (data.ch === "sys") {
$(".sys").append(`<hir>【系统】${data.content}</hir><br>`);
}
funny.scroll(data.ch);
funny.onmessage_fn.apply(this, arguments);
$(".channel").html("");
return;
}
// 5. 战斗消息
if (/<hir>看起来.*想杀死你!<\/hir>/.test(data)) {
let array = data.split(/看起来|想杀死/);
$(".content-message pre").append(`<hir>${array[1]} => 开始攻击你!<hir>\n`);
return;
} else if (/你对著.*喝道:「.*」/.test(data)) {
// 你对著木头人喝道:「小王八蛋!今日不是你死就是我活!」
let array = data.split(/你对著|喝道/);
$(".content-message pre").append(`<hir>你 => 开始攻击${array[1]}!<hir>\n`);
return;
} else if (/.*造成<.*>.*<\/.*>点.*/.test(data)) {
// 结果只是轻轻地碰到,比拍苍蝇稍微重了点,造成<wht>316</wht>点伤害!
// (木头人<HIG>看起来充满活力,一点也不累。</HIG>)
let array = data.split(/.*造成<wht>|.*造成<hir>|<\/wht>点|<\/hir>点|伤害|\(|<HIG>.*<\/HIG>|<HIY>.*<\/HIY>|<RED>.*<\/RED>|<HIR>.*<\/HIR>/);
console.log(data);
console.log(array);
// $(".content-message pre").append(`${array.toString()}`);
$(".content-message pre").append(`${array[4]}受到<wht>${array[1]}</wht>点<hir>${array[2]}</hir>伤害!\n`);
// $(".content-message pre").append(`${array[4]}受到<wht>${array[2]}</wht>点伤害!\n`);
return;
}
// 6. 房间描述
if (data.type === "room") {
funny.onmessage_fn.apply(this, arguments);
$(".room_desc").css("overflow", "hidden");
if (/<cmd cmd='.*'>.*<\/cmd>/.test(data.desc)) {
$(".room_desc").css("white-space", "normal");
} else {
$(".room_desc").css("white-space", "nowrap");
}
return;
}
// 7. 屏蔽文本
if (/.*你轻声吟道:.*|吃太多养精丹了/.test(data)) {
return;
}
// 8. 自动击杀
if (data.type === "itemadd") {
if (/蒙古兵|十夫长|百夫长|千夫长|万夫长/.test(data.name)) {
if (data.id) funny.sendmessage(`kill ${data.id}`);
}
}
// 9. 自动分解
if (data.type === "dialog" && data.dialog === "pack") {
if (data.name) {
if (/☆|★|<hiy>|<hiz>|<hio>|<hir>/.test(data.name)) {
// 强化过的装备 黄色 紫色 橙色 红色 都不会分解
} else if (/大宋|蒙古|笠子|混天|曙光|鲲鹏|真武|君子|罗汉/.test(data.name)) {
funny.sendmessage(`fenjie ${data.id}`);
}
}
}
// 10. 打坐时间
if (/你的最大内力增加了.*点。/.test(data)) {
let n = parseInt(data.toString().replace(/[^0-9]/ig, "")),
max = parseInt(funny.role.max_mp),
limit = parseInt(funny.role.limit_mp);
let time = (limit - max) / (n * 6); // X分钟 => X小时X分钟
let timeString = time < 60 ? `${parseInt(time)}分钟` : `${parseInt(time / 60)}小时${parseInt(time % 60)}分钟`;
$(".role_dazuo_time").html(timeString);
funny.onmessage_fn.apply(this, arguments);
$(".remove_dzsj").remove();
$(".content-message pre").append(`<span class="remove_dzsj">- - - - -\n当前内力: ${max}\n上限内力: ${limit}\n需要时间: ${timeString}\n- - - - -\n</span>`);
return;
}
// 11. 状态屏蔽
if (data.type === "state" && data.state) {
funny.state = data.state;
$(".state-bar").removeClass("hide");
$(".state-bar").html(`<span class="title">${data.state}</span>`);
$("[command=stopstate]")[0].style.display = "inline";
if (data.state === "你正在练习技能") {
(async function fn() {
funny.sendmessage("score");
await funny.sleep(500);
funny.sendmessage("score2");
await funny.sleep(500);
$(".dialog-close").click();
})();
}
return;
}
// 12. 属性
if (data.type === "dialog" && data.dialog === "score") {
for (const key in data) funny.role[key] = data[key];
if (/小昭|哔哩梨/.test(funny.role.name)) funny.role.name = "<hio>小皮鞭抽你丫</hio>";
for (const key in funny.role) $(`.role_${key}`).html(funny.role[key]);
}
// 13. 技能
if (data.type === "dialog" && data.dialog === "skills") {
if (data.items) { // 所有技能数据
funny.skills = data.items;
funny.role["skill_limit"] = data.limit; // 等级上限
} else if (data.id && data.level) { // 单个技能变动
for (const skill of funny.skills) {
if (skill.id === data.id) {
skill.level = data.level;
break;
}
}
} else if (data.id && data.exp) {
let name = "", k = 0, level = 0;
let djsx = parseInt(funny.role.skill_limit); // 等级上限
let xxxl = parseInt(funny.role.study_per); // 学习效率
let lxxl = parseInt(funny.role.lianxi_per); // 练习效率
let xtwx = parseInt(funny.role.int); // 先天悟性
let htwx = parseInt(funny.role.int_add); // 后天悟性
if (funny.skills) {
for (const skill of funny.skills) {
if (skill.id === data.id) {
name = skill.name;
level = parseInt(skill.level);
if (/<wht>.*/.test(name)) k = 1; // 白
if (/<hig>.*/.test(name)) k = 2;
if (/<hic>.*/.test(name)) k = 3;
if (/<hiy>.*/.test(name)) k = 4;
if (/<hiz>.*/.test(name)) k = 5;
if (/<hio>.*/.test(name)) k = 6; // 橙
if (/<hir>.*/.test(name)) k = 7; // 红
break;
}
}
}
let qianneng = (djsx * djsx - level * level) * 2.5 * k;
if (funny.state === "你正在练习技能") {
let time = qianneng / (xtwx + htwx) / (1 + lxxl / 100 - xtwx / 100) / 12;
let timeString = time < 60 ? `${parseInt(time)}分钟` : `${parseInt(time / 60)}小时${parseInt(time % 60)}分钟`;
$(".lx").remove();
$(".content-message pre").append(`练习${name}消耗了${parseInt(qianneng / time / 12)}点潜能。\n`);
$(".content-message pre").append(`<span class="lx">- - - - -\n角色悟性: ${xtwx}+${htwx}\n练习效率: ${lxxl}%\n等级上限: ${djsx}级\n需要潜能: ${qianneng}\n需要时间: ${timeString}\n- - - - -\n</span>`);
funny.scroll("content-message");
}
}
}
funny.onmessage_fn.apply(this, arguments);
// funny.scroll("content-message");
console.log(data);
},
};
// 暴露 funny
unsafeWindow.funny = funny;
// 检查 WebSocket
if (WebSocket) {
unsafeWindow.WebSocket = function(url) { funny.webSocket = new WebSocket(url); };
unsafeWindow.WebSocket.prototype = {
get url() { return funny.webSocket.url; },
get protocol() { return funny.webSocket.protocol; },
get readyState() { return funny.webSocket.readyState; },
get bufferedAmount() { return funny.webSocket.bufferedAmount; },
get extensions() { return funny.webSocket.extensions; },
get binaryType() { return funny.webSocket.binaryType; },
set binaryType(type) { funny.webSocket.binaryType = type; },
get onerror() { return funny.webSocket.onerror; },
set onerror(fn) { funny.webSocket.onerror = fn; },
get onopen() { return funny.webSocket.onopen; },
set onopen(fn) { funny.webSocket.onopen = fn; },
get onclose() { return funny.webSocket.onclose; },
set onclose(fn) { funny.webSocket.onclose = fn; },
close: function () { funny.webSocket.close(); },
get onmessage() { return funny.webSocket.onmessage; },
set onmessage(fn) { // 接收
funny.onmessage_fn = fn;
funny.webSocket.onmessage = funny.onmessage;
},
send: function (message) { // 发送
funny.webSocket.send(message);
// stopstate
if (message === "stopstate") {
$(".state-bar").addClass("hide");
$("[command=stopstate]")[0].style.display = "none";
}
$(".console").append($(`<div> >> ${message}\n</div>`));
funny.scroll("console");
},
};
} else {
console.log(`(${funny.scriptName})\nError: 无法获取 window.WebSocket!`);
}
// 操作 Document
$(document).ready(function() {
// 标记 是否移动端
let isMobile = /Android|iPhone|iPad|iPod/.test(navigator.userAgent);
// 移除游戏原聊天频道
if (!isMobile) GM_addStyle(`.channel{display:none;}`);
// 移除底部 Info
$(".signinfo").addClass("hide");
GM_addStyle(`.content-bottom{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;}`); // 屏蔽连击按钮触发复制
GM_addStyle(`.room-item>.item-name{margin-left: 14px;}`); // 角色列表左侧的外边距
$(".room_items")[0].style.maxHeight = "240px"; // 房间列表大概可以显示 20 个人物
// 隐藏部分滚动条
$(".state-bar")[0].style.overflow = "hidden";
$(".combat-commands")[0].style.overflow = "hidden";
$(".dialog-content")[0].style.overflowX = "hidden";
// 三栏布局
$("body").append($(`<div class="left box"></div>`));
$("body").append($(`<div class="right box"></div>`));
$(".container").addClass("box");
$(".login-content").addClass("box");
GM_addStyle(`
body {
width: 100%;
display: flex;
flex-flow: row no-wrap;
}
.box {
width: 360px;
flex: 0 0 auto;
}
.container, .login-content {
flex: 1 0 auto;
}
.left {
order: -1;
}
.right {
order: 1;
}
`);
// left
// combat-panel
// $(".tool-item").show();
// $(".combat-panel").removeClass("hide");
setLeft();
setRight();
setNiceScroll();
function setLeft() {
$(".left").append(
$(`<table class="role"></table>`).append(
$(`<tr><td colspan="4"><hiy>角色信息</hiy></td></tr>`),
$(`<tr><td colspan="4" class="role_name">ROLE_NAME</td></tr>`),
$(`<tr><td>ID</td><td colspan="3" class="role_id"></td></tr>`),
$(`<tr><td>性别</td><td class="role_gender"></td><td>境界</td><td class="role_level"></td></tr>`),
$(`<tr><td>年龄</td><td colspan="3" class="role_age"></td></tr>`),
$(`<tr><td>经验</td><td colspan="3"><hig class="role_exp"></hig></td></tr>`),
$(`<tr><td>潜能</td><td colspan="3"><hig class="role_pot"></hig></td></tr>`),
$(`<tr><td>气血</td><td colspan="3"><span class="role_hp"></span>/<hic class="role_max_hp"></hic></td></tr>`),
$(`<tr><td>内力</td><td colspan="3"><span class="role_mp"></span>/<hic class="role_max_mp"></hic></td></tr>`),
$(`<tr><td>内力上限</td><td colspan="3"><hic class="role_limit_mp"></hic></td></tr>`),
$(`<tr><td>臂力</td><td><hiy class="role_str"></hiy>+<span class="role_str_add"></span></td><td>根骨</td><td><hiy class="role_con"></hiy>+<span class="role_con_add"></span></td></tr>`),
$(`<tr><td>身法</td><td><hiy class="role_dex"></hiy>+<span class="role_dex_add"></span></td><td>悟性</td><td><hiy class="role_int"></hiy>+<span class="role_int_add"></span></td></tr>`),
$(`<tr><td>攻击</td><td><hig class="role_gj"></hig></td><td>终伤</td><td><hig class="role_add_sh"></hig></td></tr>`),
$(`<tr><td>防御</td><td><hig class="role_fy"></hig></td><td>命中</td><td><hig class="role_mz"></hig></td></tr>`),
$(`<tr><td>招架</td><td><hig class="role_zj"></hig></td><td>躲闪</td><td><hig class="role_ds"></hig></td></tr>`),
$(`<tr><td>暴击</td><td><hig class="role_bj"></hig></td><td>攻速</td><td><hig class="role_gjsd"></hig></td></tr>`),
$(`<tr><td>门派</td><td><hic class="role_family"></hic></td><td>功绩</td><td><hic class="role_gongji"></hic></td></tr>`),
$(`<tr><td>忽视防御</td><td class="role_diff_fy"></td><td>伤害减免</td><td class="role_diff_sh"></td></tr>`),
$(`<tr><td>暴击伤害</td><td class="role_add_bj"></td><td>暴击抵抗</td><td class="role_diff_bj"></td></tr>`),
$(`<tr><td>增加忙乱</td><td class="role_busy"></td><td>忽视忙乱</td><td class="role_diff_busy"></td></tr>`),
$(`<tr><td>释放速度</td><td class="role_releasetime"></td><td>冷却速度</td><td class="role_distime"></td></tr>`),
$(`<tr><td>打坐效率</td><td class="role_dazuo_per"></td><td>内力减耗</td><td class="role_expend_mp"></td></tr>`),
$(`<tr><td>练习效率</td><td class="role_lianxi_per"></td><td>学习效率</td><td class="role_study_per"></td></tr>`),
)
);
$(".left").append(`<div class="console"></div>`);
$(".left").append(
$(`<div class="send_controller"></div>`).append(
$(`<input type="text" autocomplete="off" id="send_value">`).keypress(function(key) {
if (key.which == 13) $("#send_btn").click();
}),
$(`<button type="button" id="send_btn">发送</button>`).click(function() {
let value = $("#send_value").val();
if (value) funny.sendmessage(value);
$("#send_value").val("");
}),
)
);
GM_addStyle(`
.left {
display: flex;
flex-direction: column;
}
.role {
order: 0;
flex: 0 0 auto;
width: 100%;
flex: 0 0 auto;
table-layout: fixed;
border-collapse: collapse;
}
.role td {
width: 60px;
overflow: hidden;
text-align: center;
white-space: nowrap;
border: #008000 solid 1px;
}
.console {
order: 5;
flex: 1 0 auto;
height: 80px;
overflow: auto;
}
.send_controller {
order: 6;
flex: 0 0 auto;
height: 30px;
display: flex;
}
.send_controller input {
flex: 1 0 auto;
height: auto;
}
.send_controller button {
height: auto;
}
`);
}
function setRight() {
$(".right").append(
$(`<div class="msg chat"></div>`),
$(`<div class="msg tm"></div>`),
$(`<div class="msg fam"></div>`),
$(`<div class="msg pty"></div>`),
$(`<div class="msg es"></div>`),
$(`<div class="msg sys rumor"></div>`),
$(`<div class="msg pickup"></div>`),
);
GM_addStyle(`.right {
height: 100%;
display: flex;
flex-direction: column;
}`);
GM_addStyle(`.msg {
height: auto;
overflow:auto;
flex: 0 0 auto;
font-size: 14px;
max-height:calc(14px * 8);
}`);
GM_addStyle(`.chat {
flex: 1 1 auto;
max-height: 100%;
}`);
}
function setNiceScroll() {
$("html").niceScroll();
let scroll = [
".room_items", ".state-bar",
".console", ".msg",
];
scroll.forEach(name => {
$(name).niceScroll({ autohidemode: true });
});
}
checkMobile();
function checkMobile() {
if (/Android|iPhone|iPad|iPod/.test(navigator.userAgent)) {
$(".left").hide();
$(".right").hide();
GM_addStyle(`.channel { display:inline; }`);
}
}
});
})();
/* 颜色标签
<wht></wht> 白色
<hig></hig> 绿
<hic></hic> 蓝
<hiy></hiy> 黄
<hiz></hiz> 紫
<hio></hio> 橙
<hir></hir> 红
<him></him> 亮紫色 谣言
*/