Greasy Fork is available in English.
Add sorting functionality to the guild members table in Milky Way Idle game
// ==UserScript==
// @name [MWI]Guild Members Table Sorting
// @name:zh-CN [银河奶牛]公会成员表格排序
// @namespace https://cnb.cool/shenhuanjie/skyner-cn/tamper-monkey-script/mwi-guid-members-table-sorting
// @version 1.0.6
// @description Add sorting functionality to the guild members table in Milky Way Idle game
// @description:zh-CN 为银河放置游戏的公会成员表格添加排序功能
// @author shenhuanjie
// @license MIT
// @match https://www.milkywayidle.com/*
// @match https://test.milkywayidle.com/*
// @icon https://www.milkywayidle.com/favicon.svg
// @grant none
// @homepage https://cnb.cool/shenhuanjie/skyner-cn/tamper-monkey-script/mwi-guid-members-table-sorting
// @supportURL https://cnb.cool/shenhuanjie/skyner-cn/tamper-monkey-script/mwi-guid-members-table-sorting/-/issues
// ==/UserScript==
(function() {
'use strict';
// 判断用户语言环境
const isChinese = navigator.language.includes('zh');
const messages = {
zh: {
scriptStarted: '公会成员表格排序脚本已启动',
tableNotFound: '未找到公会成员表格,等待用户点击重试',
tableFound: '已找到公会成员表格,开始绑定排序功能',
headerClicked: '第 {column} 列表头被点击,当前点击次数: {count}',
resetSort: '第 {column} 列表头第三次被点击,重置表格排序',
sortDirectionChanged: '第 {column} 列的排序方向切换为: {direction}',
sortCompleted: '第 {column} 列排序完成',
styleAdded: '已添加必要表格样式',
hideButton: '已隐藏转让会长按钮'
},
en: {
scriptStarted: 'Guild members table sorting script has been started',
tableNotFound: 'Guild members table not found. Waiting for user click to retry',
tableFound: 'Guild members table found. Starting to bind sorting function',
headerClicked: 'The header of column {column} has been clicked. Current click count: {count}',
resetSort: 'The header of column {column} has been clicked for the third time. Resetting table sorting',
sortDirectionChanged: 'The sorting direction of column {column} has been changed to: {direction}',
sortCompleted: 'Sorting of column {column} is completed',
styleAdded: 'Necessary table styles have been added',
hideButton: 'The "Transfer Guild Master" button has been hidden'
}
};
function getMessage(key, replacements = {}) {
const lang = isChinese? 'zh' : 'en';
let message = messages[lang][key];
for (const [placeholder, value] of Object.entries(replacements)) {
message = message.replace(`{${placeholder}}`, value);
}
return message;
}
console.log(getMessage('scriptStarted'));
let table = null;
let hideTransferBtn = null;
function initTableSort() {
// 使用属性选择器进行模糊匹配
table = document.querySelector('[class^="GuildPanel_membersTable__"]');
if (!table) {
// console.log(getMessage('tableNotFound'));
return;
}
console.log(getMessage('tableFound'));
const headers = table.querySelectorAll('th');
let sortDirections = Array(headers.length).fill(null);
let clickCounts = Array(headers.length).fill(0);
const initialRows = Array.from(table.querySelectorAll('tbody tr'));
headers.forEach((header, index) => {
header.addEventListener('click', () => {
clickCounts[index]++;
// console.log(getMessage('headerClicked', { column: index + 1, count: clickCounts[index] }));
if (clickCounts[index] === 3) {
// console.log(getMessage('resetSort', { column: index + 1 }));
const tbody = table.querySelector('tbody');
initialRows.forEach(row => tbody.appendChild(row));
headers.forEach(h => {
h.classList.remove('asc', 'desc');
});
sortDirections[index] = null;
clickCounts[index] = 0;
return;
}
const rows = Array.from(table.querySelectorAll('tbody tr'));
if (sortDirections[index] === 'asc') {
sortDirections[index] = 'desc';
} else {
sortDirections[index] = 'asc';
}
// console.log(getMessage('sortDirectionChanged', { column: index + 1, direction: sortDirections[index] }));
headers.forEach(h => {
h.classList.remove('asc', 'desc');
});
if (sortDirections[index] === 'asc') {
header.classList.add('asc');
} else {
header.classList.add('desc');
}
rows.sort((a, b) => {
const keyA = getCellValue(a, index);
const keyB = getCellValue(b, index);
let comparison;
if (typeof keyA === 'number' && typeof keyB === 'number') {
comparison = keyA - keyB;
} else if (typeof keyA ==='string' && typeof keyB ==='string') {
comparison = keyA.localeCompare(keyB);
} else if (keyA instanceof SVGElement && keyB instanceof SVGElement) {
const useA = keyA.querySelector('use');
const useB = keyB.querySelector('use');
const hrefA = useA? useA.getAttribute('href') : '';
const hrefB = useB? useB.getAttribute('href') : '';
comparison = hrefA.localeCompare(hrefB);
} else {
comparison = 0;
}
return sortDirections[index] === 'asc'? comparison : -comparison;
});
const tbody = table.querySelector('tbody');
rows.forEach(row => tbody.appendChild(row));
// console.log(getMessage('sortCompleted', { column: index + 1 }));
});
});
const style = document.createElement('style');
style.textContent = `
th {
cursor: pointer;
}
th.asc::after {
content: ' ↑';
}
th.desc::after {
content: ' ↓';
}
`;
document.head.appendChild(style);
console.log(getMessage('styleAdded'));
}
initTableSort();
if (!table) {
document.addEventListener('click', function clickHandler() {
initTableSort();
if (table) {
document.removeEventListener('click', clickHandler);
}
});
}
if(!hideTransferBtn){
document.addEventListener('click', function clickHandler() {
// 隐藏转让会长按钮
const actionButtonDivs = document.querySelectorAll('[class^="GuildPanel_actionButtons__"]');
actionButtonDivs.forEach(div => {
const buttons = div.querySelectorAll('button');
buttons.forEach(button => {
const targetText = isChinese? '转让会长' : 'Transfer Guild Master';
if (button.textContent.trim() === targetText) {
button.style.display = 'none';
console.log(getMessage('hideButton'));
hideTransferBtn = true;
}
});
});
});
}
function getCellValue(row, index) {
const cell = row.querySelectorAll('td')[index];
const svg = cell.querySelector('svg');
if (svg) {
return svg;
}
const text = cell.textContent.trim();
const num = parseFloat(text);
return isNaN(num)? text : num;
}
})();