您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Blocked users can be synced but do not actually change anything in the SW results yet.
- // ==UserScript==
- // @name [GC] Organize SW Results
- // @namespace https://greasyfork.org/en/users/1225524-kaitlin
- // @match https://www.grundos.cafe/market/wizard*
- // @match https://www.grundos.cafe/guilds/guild/*/members*
- // @match https://www.grundos.cafe/block*
- // @require https://cdn.jsdelivr.net/npm/jquery@3.6.4/dist/jquery.min.js
- // @require https://update.greasyfork.org/scripts/487361/1389917/%5BGC%20%7C%20Library%5D%20-%20SSW%3A%20Savvy%20Shop%20Wiz.js
- // @grant GM.getValue
- // @grant GM.setValue
- // @grant GM.listValues
- // @license MIT
- // @version 2.0.1
- // @author Cupkait
- // @icon https://i.imgur.com/4Hm2e6z.png
- // @description Blocked users can be synced but do not actually change anything in the SW results yet.
- // ==/UserScript==
- createSSWMenu();
- addStyles();
- let wizList = document.querySelector('.sw_results');
- if (window.location.href.startsWith('https://www.grundos.cafe/market/wizard/') && wizList) {
- generateNewGrid();
- }
- async function grabData() {
- const resultsGrid = document.querySelector('.sw_results');
- const resultsRaw = resultsGrid.querySelectorAll('.data');
- const rawData = [];
- for (var i = 0; i < resultsRaw.length;) {
- var seller = resultsRaw[i].innerText;
- console.log(seller)
- var link = resultsRaw[i].innerHTML;
- var stock = parseInt(resultsRaw[i + 2].innerText,10);
- var price = parseInt(resultsRaw[i + 3].innerText.replace(/[^\d]/g, ''), 10);
- var row = {
- seller: seller,
- link: link,
- stock: stock,
- price: price
- };
- rawData.push(row);
- i = i + 4;
- }
- return rawData;
- }
- async function calculateValues() {
- let rawData = await grabData();
- let lowestPrice = Math.min(...rawData.map(item => item.price));
- rawData.forEach(item => {
- item.pricediff = item.price - lowestPrice;
- });
- return rawData;
- }
- async function getUsers() {
- let friendList = await GM.getValue('friendList', '[]');
- let guildsList = await GM.getValue('guildsList', '{}');
- let blockList = await GM.getValue('blockList', '[]');
- const guildMembers = Object.values(guildsList).flatMap(guild => guild.guildMembers);
- if (typeof friendList === 'string') {
- friendList = JSON.parse(friendList);
- }
- if (typeof guildMembers === 'string') {
- guildMembers = JSON.parse(guildMembers);
- }
- if (typeof blockList === 'string') {
- blockList = JSON.parse(blockList);
- }
- return { friendList, guildMembers, blockList };
- }
- async function createTableRow(item, friendList, guildMembers, blockList) {
- var price = item.price.toLocaleString() + " NP";
- let variance;
- let friendstatus = friendList.includes(item.seller);
- let guildstatus = guildMembers.includes(item.seller);
- let blockstatus = blockList.includes(item.seller);
- if (item.pricediff === 0) {
- variance = '<span style="color:green">— LOWEST —</span>';
- } else if (friendstatus || guildstatus) {
- variance = `<span style="color:red">(+${item.pricediff.toLocaleString()})</span>`;
- } else {
- variance = '—';
- }
- let row = document.createElement('tr');
- row.innerHTML = `
- <td>${item.link}</td>
- <td>${item.stock}</td>
- <td><strong>${price}</strong></td>
- <td><strong>${variance}</strong></td>
- `;
- if (friendstatus) {
- row.classList.add('friend');
- } else if (blockstatus) {
- row.classList.add('blocked');
- } else if (guildstatus) {
- row.classList.add('guild');
- }
- return row;
- }
- async function generateNewGrid() {
- const { friendList, guildMembers, blockList } = await getUsers();
- const newGrid = document.createElement('table');
- newGrid.innerHTML = `<thead><tr><th>Owner</th><th>Stock</th><th>Price</th><th>Variance</th></tr></thead>`;
- let rawData = await calculateValues();
- const newHeader = await updateHeader();
- rawData.sort((a, b) => {
- const aIsFriend = friendList.includes(a.seller);
- const bIsFriend = friendList.includes(b.seller);
- const aIsGuildMember = guildMembers.includes(a.seller);
- const bIsGuildMember = guildMembers.includes(b.seller);
- if ((aIsFriend || aIsGuildMember) && !(bIsFriend || bIsGuildMember)) return -1;
- if (!(aIsFriend || aIsGuildMember) && (bIsFriend || bIsGuildMember)) return 1;
- return 0;
- });
- const tbody = document.createElement('tbody');
- for (const item of rawData) {
- const row = await createTableRow(item, friendList, guildMembers, blockList);
- tbody.appendChild(row);
- }
- newGrid.appendChild(tbody);
- const oldGrid = document.querySelector('.sw_results');
- oldGrid.insertAdjacentElement('beforebegin', newGrid);
- oldGrid.style.display = 'none';
- }
- async function updateHeader() {
- }
- function addStyles() {
- const newGridStyle = document.createElement('style');
- newGridStyle.innerHTML = `
- #sswmenu {
- display: none;
- border-radius: 15px 15px 15px 0px;
- border-bottom: 3px solid;
- position: absolute;
- z-index: 999;
- width: 250px;
- height: 250px;
- bottom: 0%;
- left: 100%;
- margin: -3px;
- padding: 10px;
- background-color: #d2d0cc;
- box-shadow: 5px 0 5px rgba(0, 0, 0, 0.5);
- }
- #sswcontainer {
- position: relative;
- border-bottom: 3px solid;
- padding: 5px 10px 5px 0px;
- height: 30px;
- width: 100%;
- top: 00%;
- left: 0px;
- background-color: #d2d0cc;
- box-shadow: 5px 0 5px rgba(0, 0, 0, 0.5);
- }
- #sswsettings {
- position: relative;
- font-size: 16px;
- font-weight: bold;
- font-family: courier;
- border-radius: 5px;
- padding: 5px;
- width: 100%;
- height: auto;
- border: 1px solid rgb(204, 204, 204);
- cursor: pointer;
- background-color: lightgray;
- }
- #menubutton {
- height: 35px;
- width: 90%;
- margin: 5px;
- }
- table {
- position: relative;
- min-width: 80%;
- margin: 1em auto;
- width: max-content;
- max-width: 100%;
- text-align: center;
- border-collapse: collapse;
- }
- th,
- td {
- position: relative;
- padding: 4px;
- z-index: 3;
- }
- th {
- background-color: var(--grid_head);
- }
- tr {
- position: relative;
- min-width: 100%;
- margin: 1em auto;
- width: max-content;
- max-width: 100%;
- text-align: center;
- border-collapse: collapse;
- }
- tr:nth-child(even) {
- background-color: var(--grid_even);
- }
- tr:nth-child(odd) {
- background-color: var(--grid_odd);
- }
- .friend::after {
- content: "";
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-color: #00801a54;
- z-index: 1;
- }
- .guild::after {
- content: "";
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-color: #2c008054;
- z-index: 1;
- }
- .blocked {
- opacity:10%
- }
- .blocked:hover {
- opacity:85%
- }
- `;
- document.head.appendChild(newGridStyle);
- }
- // SYNCING BELOW
- function removeUsersManually() {
- var userInput = prompt(
- 'Which username would you like to remove from your list? Enter one username then click OK.'
- );
- if (userInput !== null && userInput.trim() !== '') {
- var index = friendList.findIndex(name => name
- .toLowerCase() === userInput.trim().toLowerCase());
- if (index !== -1) {
- friendList.splice(index, 1);
- GM.setValue('friendList', friendList);
- console.log('Removed', userInput.trim(),
- 'from the friend list.');
- } else {
- console.log(userInput.trim(),
- 'not found in the friend list.');
- }
- if (window.location.href ===
- 'https://www.grundos.cafe/market/wizard/') {
- if (confirm(
- 'Do you want to reload the page to see the updated results?'
- )) {
- location.reload();
- }
- }
- } else {
- console.log('No username entered. Operation canceled.');
- }
- }
- $(ManualRemove).on('click', removeUsersManually);
- async function syncFriendsList() {
- try {
- const response = await fetch(
- 'https://www.grundos.cafe/neofriends/');
- const html = await response.text();
- const doc = new DOMParser().parseFromString(html,
- 'text/html');
- const uniqueUsernames = new Set();
- doc.querySelectorAll(
- 'div.market_grid [href*="/userlookup/?user="]')
- .forEach(function (element) {
- uniqueUsernames.add(element.getAttribute(
- 'href').split('=')[1]);
- });
- console.log("Friends List Synced");
- return Array.from(uniqueUsernames);
- } catch (error) {
- console.error('Error fetching and extracting usernames:',
- error);
- return [];
- }
- }
- $(SyncFriends).on('click', async function () {
- console.log("clicked")
- const usernames = await syncFriendsList();
- friendList = usernames;
- GM.setValue('friendList', friendList);
- console.log('Synced usernames:', usernames);
- });
- function syncBlockedList() {
- if (window.location.href === 'https://www.grundos.cafe/block/') {
- const blockList = $('.block_list').find('span').map(
- function () {
- return $(this).text();
- }).get();
- GM.setValue('blockList', blockList);
- console.log('blockList stored:', blockList);
- } else {
- if (confirm(
- 'You can only do this from the Blocked Users page. Want to open it in a new tab?'
- )) {
- window.open('https://www.grundos.cafe/block/', '_blank');
- } else {
- console.log('User declined. No blocked sync occured.');
- }
- }
- }
- $(SyncBlocked).on('click', syncBlockedList);
- function syncGuildMembers() {
- if (/^https:\/\/www\.grundos\.cafe\/guilds\/guild\/.+\/members\//.test(window.location.href)) {
- const userName = /user=(.*?)"/g.exec(document.body.innerHTML)[1];
- const guildIdentifier = window.location.href.match(/guild\/([^\/-]+)/)?.[1];
- const guildName = $('.guild-header strong').eq(0).text();
- const guildID = "guildID_" + guildIdentifier;
- const guildMembers = [...new Set($('div.member-grid [href*="/userlookup/?user="]')
- .map(function() {
- return $(this).attr('href').split('=')[1];
- })
- .filter(function(guildMember) {
- return guildMember !== userName;
- })
- )];
- GM.getValue('guildsList', {}).then(function(guildsList) {
- guildsList[guildID] = {
- 'guildName': guildName,
- 'guildMembers': guildMembers
- };
- GM.setValue('guildsList', guildsList);
- });
- } else {
- if (confirm('You can only do this from the Guild Members page. Want to open it in a new tab?')) {
- window.open('https://www.grundos.cafe/guilds/', '_blank');
- } else {
- console.log('User declined. No action occurred.');
- }
- }
- }
- $(SyncGuild).on('click', syncGuildMembers);