Skip to content

Instantly share code, notes, and snippets.

@guipenedo
Created March 27, 2020 19:04
Show Gist options
  • Save guipenedo/575322ec014835825c2fa89c45c1ce80 to your computer and use it in GitHub Desktop.
Save guipenedo/575322ec014835825c2fa89c45c1ce80 to your computer and use it in GitHub Desktop.
Tampermonkey script to sell/buy resources for premium points - bypassing TW's detection technique
// ==UserScript==
// @name Premium Exchange Sell If Stock Not Full
// @description Automatically sell resources when the stock is not full. Fucks up their detection technique
// @author FunnyPocketBook, PhilipsNostrum
// @version 2.1
// @include https://*/game.php*screen=market*mode=exchange*
// @namespace https://greasyfork.org/users/151096
// ==/UserScript==
createInput();
var buyOrSell = 6; // Change this to 5 to buy resources, 6 to sell resources
var merchAvail = document.getElementById("market_merchant_available_count").innerText; // Get number of available merchants
var userInputSellResCap = parseInt(localStorage.getItem("premium_sell_res_cap")); // Get the user set cap for resources
var userInputSellRateCap = parseInt(localStorage.getItem("premium_sell_rate_cap")); // Get the user set cap for rate
var start = new Date();
function isInteger(x) {
"use strict";
return (typeof x === 'number') && (x % 1 === 0);
}
function createInput() {
"use strict";
var userInputParent = document.getElementById("premium_exchange_form");
var input = document.createElement("input");
input.setAttribute("id", "premium_sell_res_cap");
input.setAttribute("type", "text");
input.setAttribute("placeholder", '"10000" to keep 10k');
input.setAttribute("style", "width:180px;");
if (!isInteger(parseInt(localStorage.getItem("premium_sell_res_cap")))) {
input.setAttribute("value", "");
} else {
input.setAttribute("value", localStorage.getItem("premium_sell_res_cap"));
}
userInputParent.parentNode.insertBefore(input, userInputParent);
var input2 = document.createElement("input");
input2.setAttribute("id", "premium_sell_rate_cap");
input2.setAttribute("type", "text");
input2.setAttribute("placeholder", '"200" to sell when price < 200');
input2.setAttribute("style", "width:180px;");
if (!isInteger(parseInt(localStorage.getItem("premium_sell_rate_cap")))) {
input2.setAttribute("value", "");
} else {
input2.setAttribute("value", localStorage.getItem("premium_sell_rate_cap"));
}
userInputParent.parentNode.insertBefore(input2, userInputParent);
var okButton = document.createElement("button");
okButton.innerHTML = "OK";
okButton.setAttribute("id", "buttonSetCap");
okButton.setAttribute("class", "btn");
userInputParent.parentNode.insertBefore(okButton, userInputParent);
var resCapInput = document.getElementById("premium_sell_res_cap");
var rateCapInput = document.getElementById("premium_sell_rate_cap");
/* If caps have been set, put it in the newly created input field */
if (!isInteger(parseInt(localStorage.getItem("premium_sell_res_cap")))) {
resCapInput.setAttribute("value", "");
} else {
resCapInput.setAttribute("value", localStorage.getItem("premium_sell_res_cap"));
}
if (!isInteger(parseInt(localStorage.getItem("premium_sell_rate_cap")))) {
rateCapInput.setAttribute("value", "");
} else {
rateCapInput.setAttribute("value", localStorage.getItem("premium_sell_rate_cap"));
}
}
/* OK button calls this function */
document.getElementById("buttonSetCap").addEventListener("click", function setCap() {
localStorage.setItem("premium_sell_res_cap", document.getElementById("premium_sell_res_cap").value);
localStorage.setItem("premium_sell_rate_cap", document.getElementById("premium_sell_rate_cap").value);
userInputSellResCap = parseInt(localStorage.getItem("premium_sell_res_cap"));
userInputSellRateCap = parseInt(localStorage.getItem("premium_sell_rate_cap"));
});
/* Call for every resource to get the info */
function resInfo(res) {
var number;
switch(res) {
case "wood":
number = 0;
break;
case "stone":
number = 1;
break;
case "iron":
number = 2;
break;
}
var info = {
num: number,
name: res,
price: parseInt(document.getElementById("premium_exchange_rate_" + res).children[0].innerText),
max: parseInt(document.getElementById("premium_exchange_capacity_" + res).innerHTML), // Maximum amount of resources that can currently fit in the premium exchange
stock: parseInt(document.getElementById("premium_exchange_stock_" + res).innerHTML),
inVillage: parseInt(document.getElementById(res).innerText),
init: function() {
this.cap = this.inVillage - parseInt(localStorage.getItem("premium_sell_res_cap"));
return this;
}
}.init();
return info;
}
function getSellValue(res){
merchAvail = document.getElementById("market_merchant_available_count").textContent;
var sellThis = Math.min((res.max - res.stock), Math.floor((res.inVillage - userInputSellResCap)/res.price)*res.price - res.price + 1);
if (Math.ceil(sellThis / 1000) > merchAvail) {
sellThis = merchAvail * 1000 - res.price;
}
if (sellThis < 0) {
sellThis = 0;
}
return sellThis;
}
function ppsToBeMade(res){
if(res.stock < res.max && res.inVillage > userInputSellResCap && res.price <= userInputSellRateCap && res.price <= res.inVillage)
return Math.ceil(1.0*getSellValue(res)/res.price);
return 0;
}
function canMakePps(){
return ppsToBeMade(resInfo("wood")) > 0 || ppsToBeMade(resInfo("stone")) > 0 || ppsToBeMade(resInfo("iron")) > 0;
}
function sellItem(list, i){
if(i == 3){
setTimeout(()=>{sellResource();},5000);
return;
}
let res = list[i];
if(ppsToBeMade(res) > 0) {
/* Empty every input box */
document.querySelectorAll("#premium_exchange_form > table > tbody > tr > td > div:nth-child(1) > input").forEach(function(el) {
el.value = "";
});
let sellThis = getSellValue(res);
if (sellThis != 0) {
document.querySelectorAll("#premium_exchange_form > table > tbody > tr:nth-child(" + buyOrSell + ") > td > div:nth-child(1) > input")[res.num].value = sellThis;
var confirmCallback = PremiumExchange.confirmOrder;
PremiumExchange.confirmOrder = function(e){
TribalWars._ah = {
TribalWarsTE: 1
};
e.mb = 1;
confirmCallback(e);
}
document.getElementsByClassName("btn-premium-exchange-buy")[0].click();
setTimeout(function() {
if(document.querySelector(".evt-confirm-btn") != null)
document.querySelector(".evt-confirm-btn").click();
setTimeout(function(){
sellItem(list, i + 1);
}, 6000);
}, 5000);
}
} else sellItem(list, i+1);
}
function getAllRes(){
return [resInfo("wood"), resInfo("stone"), resInfo("iron")];
}
function shouldWait(){
var allRes = getAllRes();
for(let i = 0; i < 3; i++){
if(allRes[i].stock != allRes[i].max)
return false;
}
return true;
}
function sellResource() {
console.log("Attempting sell");
"use strict";
merchAvail = document.getElementById("market_merchant_available_count").textContent;
if(merchAvail > 0 && canMakePps()){
console.log("Can make pps!");
var allRes = getAllRes();
allRes = allRes.sort((a,b) => {return ppsToBeMade(b)-ppsToBeMade(a)});
sellItem(allRes, 0);
} else {
console.log("Can not make pps. Waiting to switch.");
setTimeout(function(){
if($("#village_switch_right span").length > 0)
$("#village_switch_right span").click();
else sellResource();
}, Math.max(15*1000, (start.getTime() + 30*1000) - (new Date()).getTime()));
}
}
sellResource();
@pawlik1306
Copy link

the script has stopped working

@guipenedo
Copy link
Author

the script has stopped working

I've stopped playing and unfortunately won't be updating it any longer

@pawlik1306
Copy link

Ok thanks for the answer

@fares57
Copy link

fares57 commented Jan 13, 2021

Hello. This is not working. I use it for the Greek server. First time I hit start , it has the work done as explained. But then, it keeps running without buying anything again. Only the first time , when you hit the start button, it really works.

And I am too bored to check the code now :p
Any ideas?

@guipenedo
Copy link
Author

Hello. This is not working. I use it for the Greek server. First time I hit start , it has the work done as explained. But then, it keeps running without buying anything again. Only the first time , when you hit the start button, it really works.

And I am too bored to check the code now :p
Any ideas?

Hello. As I said above I no longer play TW and as such will not be updating any of my TW related code. I am afraid you will have to look into the code yourself if you want to make it compatible with the most recent TW versions.

@fares57
Copy link

fares57 commented Jan 13, 2021

You're killing me (lol) but that's what I already do . Thanks for the whole work you've done though!

@fares57
Copy link

fares57 commented Jan 13, 2021

One last question please: When you made it, it was constantly working and buying or only for the first time?

I ask so I can tell weather it is an code issue or tribal wars made some changes so I need to seek the answer there.

Thanks!

@takeitslow1
Copy link

i've pay for this update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment