Last active
July 1, 2024 20:07
-
-
Save bukowa/023584dd2e4377fd582472ecc07614ac to your computer and use it in GitHub Desktop.
tribal wars 2 dupe script resources duplication script bot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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...") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
revision 18: v1.0.0
Created up to 6 "dupes".