SteamGemOneClick

一键合成宝珠

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        SteamGemOneClick
// @namespace   [email protected]
// @description 一键合成宝珠
// @include     /^https?:\/\/steamcommunity\.com\/id\/[^\/]+\/inventory\//
// @version     2017-6-14
// @grant       none
// jshint esversion:6
// ==/UserScript==

// Start
SteamInventoryQuickGrindToGoo();
SteamInventoryShowGemValue();

// 显示物品宝珠价值的对应宝珠价格(¥)
function SteamInventoryShowGemValue(){
	// console.log("[SteamGemOneClick] SteamInventoryShowGemValue()"); // DEBUG
	const GEM_PRICE_REGEX = /\d+\.\d+/g;
	const GEM_VALUE_REGEX = /^\d+/g;
	const GEM_PRICE_CNY_API_URL = "https://steamcommunity.com/market/priceoverview/?appid=753&currency=23&market_hash_name=753-Sack%20of%20Gems";
	const GEM_PRICE_REFRESH_INTERVAL_MILLISECONDS = 45000;
	var gemBagPrice = 0.0;
	var xhr = new XMLHttpRequest();
	xhr.responseType = "json";
	
	xhr.onload = e => {
		// console.log("[SteamGemOneClick] Gem price info: %o", xhr.response); // DEBUG
		if(xhr.response && xhr.response.lowest_price){
			gemBagPrice = Number.parseFloat(xhr.response.lowest_price.match(GEM_PRICE_REGEX)[0]);
		} else {
			gemBagPrice = 0.0;
		}
		// console.log("[SteamGemOneClick] Gem price: %o", gemBagPrice); // DEBUG
	}
	
	// 定时获取当前一袋宝珠的价格
	function RefreshGemPrice (){
		xhr.open("GET", GEM_PRICE_CNY_API_URL);
		xhr.send();
		setTimeout(RefreshGemPrice, GEM_PRICE_REFRESH_INTERVAL_MILLISECONDS);
	}
	
	// 宝珠价值文字
	var gemValueTargets = document.querySelectorAll(".item_scrap_value");
	//点开物品时更新宝珠价格显示
	var invPageObserver = new MutationObserver(
		recs=>{
			for(var rec of recs){
				// console.log("[SteamGemOneClick] rec class: " + rec.target.classList); // DEBUG
				if(rec.target.id !== "gem_price"){
					// console.log("[SteamGemOneClick] Mutation Record: %o", rec); // DEBUG
					// Update Gem Price
					let gemValue = Number.parseFloat(rec.target.textContent.match(GEM_VALUE_REGEX));
					let gemPriceSpan = rec.target.parentNode.querySelector("#gem_price");
					if(gemPriceSpan){
						gemPriceSpan.textContent = " (¥ " + ((gemValue / 1000) * gemBagPrice).toFixed(3) + ")";
					}
				}
			}
		}
	);
	var config = { childList: true };
	// 添加宝珠¥价格文字
	for(var target of gemValueTargets){
		AddGemPriceDisplay(target);
		invPageObserver.observe(target, config);
	}
	
	// 在宝珠价值后显示宝珠价格
	function AddGemPriceDisplay (gemValueSpan){
		var gemPriceSpan = document.createElement("span");
		gemPriceSpan.id = "gem_price";
		gemPriceSpan.className = "item_scrap_value"; // 只是为了借用样式
		gemValueSpan.parentNode.appendChild(gemPriceSpan);
	}
	
	RefreshGemPrice();
}

// 添加快速碾碎物品为宝珠按钮
function SteamInventoryQuickGrindToGoo(){
	// console.log("[SteamGemOneClick] SteamInventoryQuickGrindToGoo()"); // DEBUG
	var gooTargets = document.querySelectorAll(".item_scrap_actions");
	var invPageObserver = new MutationObserver(
		recs=>{
			for(var rec of recs){
				// console.log("[SteamGemOneClick] rec class: " + rec.target.classList); // DEBUG
				if(!rec.target.classList.contains("quick_grind")
					&&!rec.target.classList.contains("quick_grind_enabler")
					&& rec.target.classList.contains("btn_small")){
					// console.log("[SteamGemOneClick] Mutation Record: %o", rec); // DEBUG
					// Update href of our button
					var grindQuickBtn = rec.target.parentNode.querySelector(".quick_grind");
					if(grindBtn && grindQuickBtn){
						grindQuickBtn.href = rec.target.href.replace("GrindIntoGoo", "GrindIntoGooQuick");
					}
				}
			}
		}
	);
	var config = { attributes: true, subtree: true };
	for(var target of gooTargets){
		var grindBtn = target.querySelector(".btn_small");
		AddQuickGrindLaunchButton(grindBtn, grindBtn.parentNode);
		AddQuickGrindToGooButton(grindBtn, grindBtn.parentNode);
		invPageObserver.observe(target, config);
	}
	// 捏造一个快速碾碎函数出来
	DefineQuickGrind();
	
	// 添加安全启动快速碾碎按钮
	function AddQuickGrindLaunchButton(classNameCopyFrom, nodeAppendTo){
		if(classNameCopyFrom && nodeAppendTo){
			var btn = document.createElement("a");
			btn.className = classNameCopyFrom.className + " quick_grind_enabler";
			btn.innerHTML = "<span>☢启用快速合成☢</span>";
			btn.onclick = function(){
					let launchButtons = document.querySelectorAll(".quick_grind_enabler");
					let grindQuickButtons = document.querySelectorAll(".quick_grind");
					for(let btn of launchButtons){
						$J(btn).fadeOut(1000);
					}
					for(let btn of grindQuickButtons){
						$J(btn).fadeIn(1000);
					}
				}
			nodeAppendTo.appendChild(btn);
		}
	}
	
	// 添加快速碾碎按钮(容器)
	function AddQuickGrindToGooButton(classNameCopyFrom, nodeAppendTo){
		if(classNameCopyFrom && nodeAppendTo){
			var btn = document.createElement("a");
			btn.className = classNameCopyFrom.className + " quick_grind";
			btn.innerHTML = "<span>☢快速合成☢【不可撤销!】</span>";
			btn.style.display = "none";
			nodeAppendTo.appendChild(btn);
		}
	}
	
	// 捏造快速碾碎函数
	function DefineQuickGrind(){
		if(window.GrindIntoGoo){
			// console.log("[SteamGemOneClick] GrindIntoGoo exist"); // DEBUG
			var newFuncStr = window.GrindIntoGoo.toSource();
			// Change function name
			// Remove confirm dialog
			// Change result dialog to notification
			// No inventory reload (Your item is not updated but can grind them without refresh)
			newFuncStr = newFuncStr.replace("GrindIntoGoo", "GrindIntoGooQuick");
			newFuncStr = newFuncStr.replace(/ShowConfirmDialog\( strDialogTitle, \$Content \)\.done/, "setTimeout");
			newFuncStr = newFuncStr.replace(
				/ShowAlertDialog\( strDialogTitle, data\.strHTML \);/,
				"Notification.requestPermission(()=>{var n = new Notification(strDialogTitle,{body:data.strHTML});});"
			);
			newFuncStr = newFuncStr.replace("ReloadCommunityInventory();", "/*ReloadCommunityInventory();*/");
			
			// Debug change
			// newFuncStr = newFuncStr.replace("var strActionURL", "console.log('[SteamGemOneClick] QuickGrind Called');\nvar strActionURL"); // DEBUG
			
			// console.log("[SteamGemOneClick] GrindIntoGooQuick: \n" + newFuncStr); // DEBUG
			window.eval(newFuncStr);
		} else {
			// console.log("[SteamGemOneClick] GrindIntoGoo not found"); // DEBUG
		}
	}
}