Skip to content

Instantly share code, notes, and snippets.

@bukowa
Last active July 1, 2024 20:07
Show Gist options
  • Save bukowa/023584dd2e4377fd582472ecc07614ac to your computer and use it in GitHub Desktop.
Save bukowa/023584dd2e4377fd582472ecc07614ac to your computer and use it in GitHub Desktop.
tribal wars 2 dupe script resources duplication script bot
function run_dupe(_RESOLVE) {
// nie zmieniaj wioski jak skrypt dziala
// jak skonczy rekrutowac to odswiez przegladarke
// co chcesz rekrutowac
// jesli pusty policzymy najlepszy
let recruitUnit = "";
// co chcesz wyslac
const sendUnit = "spear";
// ile chcesz wyslac
const sendAmount = 1;
// ile atakow wyslac
const sendAttacksCount = 50;
///////////////////////////////////////
/////// SUKCES ZALEZY OD TYCH 4 USTAWIEN
///////////////////////////////////////
// ile czekac miedzy atakami na barbarzynce
const delayBetweenAttacks = 100;
// ile czekac miedzy "nacisnieciem" rekrutuj
const delayBetweenRecruits = 250;
// ile razy "nacisnac" rekrutuj
const recruitClicks = 9;
// w ktorej sekundzie rekrutowac
const recruitAtSecond = 4;
///////////////////////////////////////
///////////////////////////////////////
const $rootScope = injector.get('$rootScope');
const eventTypeProvider = injector.get('eventTypeProvider');
const modelDataService = window.injector.get('modelDataService');
const socketService = window.injector.get("socketService");
const routeProvider = window.injector.get("routeProvider");
const recruitService = window.injector.get("recruitingService");
_toRecruit = toRecruit(recruitUnit);
recruitUnit = _toRecruit[0];
recruitAmount = _toRecruit[1];
console.log(`recruiting ${recruitAmount} ${recruitUnit}`);
function recruitUnits() {
console.log("recruiting units");
for (let i = 0; i < recruitClicks; i++) {
new Promise(resolve => setTimeout(() => {
console.log(`recruiting ${i + 1}`);
recruitService.recruit("barracks", recruitUnit, recruitAmount);
resolve();
}, i*delayBetweenRecruits));
}
unregister();
_RESOLVE()
}
// returns (unit, amount)
function toRecruit(_recruitUnit) {
let _recruitable = modelDataService.getSelectedVillage().getUnitInfo()['recruitable'];
let calcMaxRecruitable = (unit) =>
recruitService.calculateMaxRecruitable(modelDataService.getSelectedVillage(), unit);
let getCurrentFood = () =>
modelDataService.getSelectedVillage().getResources()['data']['resources']['food'];
let cost = {
'spear': 1,
'sword': 1,
'archer': 1,
'axe': 1,
'light_cavalry': 4,
'mounted_archer': 5,
'heavy_cavalry': 6,
'ram': 5,
'catapult': 8,
}
let finalUnit = "";
let finalMax = 0;
// pick the best unit
// the best unit is the on that can be recruited
// the most times (food wise)
if (_recruitUnit === "") {
let bestUnit = "";
let bestMax = 0;
let bestTimes = 0;
for (let unit in cost) {
let _bestMax = calcMaxRecruitable(unit);
let _foodCostUnit = cost[unit] * _bestMax;
let _times = Math.floor(getCurrentFood() / _foodCostUnit);
if (_times > bestMax && _recruitable[unit] === true) {
bestUnit = unit;
bestMax = _bestMax;
bestTimes = _times;
}
}
finalUnit = bestUnit;
finalMax = bestMax;
} else {
finalUnit = _recruitUnit;
finalMax = calcMaxRecruitable(_recruitUnit);
}
// make sure we have more food than the cost *2
let foodCost = cost[finalUnit] * finalMax;
let food = getCurrentFood();
if (food < foodCost * 2) {
throw `not enough food to recruit ${finalUnit} ${finalMax}`;
}
if (finalMax === 0) {
throw `cannot recruit ${finalUnit}`;
}
if (_recruitable[finalUnit] !== true) {
throw `cannot recruit ${finalUnit} in this village`;
}
return [finalUnit, finalMax];
}
const selectedVillage = modelDataService.getSelectedVillage()['data'];
let targetVillageId = null;
socketService.emit(routeProvider.MAP_GET_NEAREST_BARBARIAN_VILLAGE, {
'x': selectedVillage.x,
'y': selectedVillage.y
}, async (village) => {
targetVillageId = village.id;
for (let i = 0; i < sendAttacksCount; i++) {
await sleep(delayBetweenAttacks);
socketService.emit(routeProvider.SEND_CUSTOM_ARMY, {
"start_village": selectedVillage.villageId,
"target_village": village.id,
"type": "attack",
"units": {[sendUnit]: sendAmount},
"catapult_target": "headquarter",
"officers": {},
"icon": 0,
},
console.log,
);
console.log(`sent attack ${i + 1}`);
}
console.log("done sending attacks");
console.log(commands)
console.log(commands_ids)
// if it's not done after next 5sec just cancel all commands
await new Promise(r => setTimeout(() => {
if (!done) {
console.log('Error: Try again... not done... cancelling commands...')
cancelAllCommands();
r();
}
}, 5000))
})
let commands = {};
let commands_ids = [];
let done = false;
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function cancelAllCommands() {
console.log("canceling all commands")
commands_ids.forEach(x => socketService.emit(routeProvider.COMMAND_CANCEL, {command_id: x}));
}
function getCurrentTime() {
return Math.floor(new Date().getTime());
}
function recruitAfter() {
let best = getTimestampWithHigherNext(commands) * 1000;
console.log('commands', commands)
console.log('best', best);
console.log('now', getCurrentTime());
let at = best - getCurrentTime() + 330;
console.log('at', at)
return at;
}
function handleCommandSend(data) {
let t = data['time_completed'];
commands[t] = (commands[t] || 0) + 1;
commands_ids.push(data['command_id']);
}
unregister = $rootScope.$on(eventTypeProvider.COMMAND_SENT, async (info, data) => {
console.log("command received")
console.log(data)
if (done) {
return;
}
if (data.target.id != targetVillageId) {
console.log("target village is bad");
return;
}
if (data.home.id != selectedVillage.villageId) {
console.log("selected village is bad");
return;
}
if (data.direction == "forward") {
console.log("correct direction")
handleCommandSend(data);
if (Object.keys(commands).length >= recruitAtSecond) {
done = true;
console.log("\n\n\n\n\n\nDONE\n\n\n\n\n\n")
let timestamps = Object.keys(commands).sort();
let final = timestamps[recruitAtSecond-1] ;
console.log(timestamps)
console.log('final', final)
let time = getCurrentTime();
let diff = final * 1000 - time;
console.log('diff', diff)
setTimeout(recruitUnits, diff)
}
}
});
function getTimestampWithHigherNext(commands) {
let timestamps = Object.keys(commands).sort();
for (let i = 1; i < timestamps.length - 1; i++) {
let currentTimestamp = timestamps[i];
let previousTimestamp = timestamps[i - 1];
if (commands[currentTimestamp] > 5 && commands[previousTimestamp] > 5) {
return previousTimestamp;
}
}
return null;
}
}
await new Promise(resolve => {
run_dupe(resolve)
});
console.log("done...")
@bukowa
Copy link
Author

bukowa commented Jul 1, 2024

revision 18: v1.0.0

Created up to 6 "dupes".

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