eigenein / epicwar Goto Github PK
View Code? Open in Web Editor NEW:trophy: Epic War VK.com bot
Home Page: https://vk.com/clashofthronez
:trophy: Epic War VK.com bot
Home Page: https://vk.com/clashofthronez
Bot skips barracks if user is locked that is not good.
Epic War supports requests pipelining (i.e. making several calls within one HTTP request). Might be a good idea to use it.
click_alliance_daily_gift
should not be called if the gift is already activated.
Help shouldn't be sent if nobody needs help.
try … catch ValueError
and has_value(…)
are weird.Need to subclass enum.Enum
so that unknown values will be automatically added in runtime (with names like unknown_123
).
This will help to understand how everything works just by looking into the Telegram channel.
Instead of just:
2016-08-10 00:10:18 [I] Made 22 requests. Bye!
I'd like to see:
This will help to broadcast main information to the Telegram channel.
Need to investigate which tokens are passed to i-epicwar-vk.progrestar.net.
For sure secret
is a constant for each user that can be obtained from a browser manually.
The another one is still unknown.
That's not very effective:
classmethod
def not_upgradable(cls):
return {
cls.builder_hut,
cls.clan_house,
cls.jeweler_house,
cls.tavern,
}
Log bastion gifts somewhere to a database to analyze it later.
Otherwise we get "too many" error while hiring units.
Bot makes additional getBuildings
call after upgradeBuilding
but it can be avoided. I just need to update Building.is_completed
and self.incomplete_buildings
.
Bot does not use it since it's not implemented as the builder's house level up.
create_enum
looks very ugly and doesn't allow me to use static code analysis tools.
It's much prettier to use NewType so that I'll be ready for any IDs. For some predefined constants introduce usual class attributes.
Remember that Library
will be broken since it relies on the fact that instances of different enum types are different.
Move resource collection to a separate loop. This way I'll be able to call update_self_info
only once.
Looks like state
call returns some state that is corresponding to a main call. I can try to use it when I need to refresh resources and buildings. Example:
{
"date": 1471644485.9929,
"results": [
{
"ident": "group_0_body",
"result": {
"buildingId": 1144,
"reward": {
"resource": [
{
"id": 26,
"amount": 209
}
]
},
"available": {
"resource": [
{
"id": 26,
"amount": 209
}
]
}
}
},
{
"ident": "group_1_body",
"result": {
"resource": [
{
"id": 1,
"amount": 2416207
},
{
"id": 2,
"amount": 15303182
},
{
"id": 5,
"amount": 28
},
{
"id": 26,
"amount": 42641
},
{
"id": 4,
"amount": 41
},
{
"id": 6,
"amount": 13
},
{
"id": 20,
"amount": 0
},
{
"id": 3,
"amount": 13
},
{
"id": 8,
"amount": 35
},
{
"id": 7,
"amount": 0
},
{
"id": 9,
"amount": 34
},
{
"id": 27,
"amount": 2976
},
{
"id": 29,
"amount": 172
},
{
"id": 34,
"amount": 0
},
{
"id": 40,
"amount": 188
},
{
"id": 38,
"amount": 0
},
{
"id": 39,
"amount": 0
},
{
"id": 51,
"amount": 0
},
{
"id": 21,
"amount": 50
},
{
"id": 50,
"amount": 84
},
{
"id": 52,
"amount": 10
},
{
"id": 57,
"amount": 0
},
{
"id": 55,
"amount": 0
},
{
"id": 104,
"amount": 245
},
{
"id": 59,
"amount": 3
},
{
"id": 89,
"amount": 1
},
{
"id": 79,
"amount": 2
},
{
"id": 69,
"amount": 2
},
{
"id": 88,
"amount": 1
},
{
"id": 78,
"amount": 1
},
{
"id": 68,
"amount": 2
},
{
"id": 70,
"amount": 0
},
{
"id": 111,
"amount": 11
},
{
"id": 41,
"amount": 0
},
{
"id": 126,
"amount": 117
},
{
"id": 127,
"amount": 0
},
{
"id": 123,
"amount": 0
},
{
"id": 128,
"amount": 0
},
{
"id": 58,
"amount": 1
},
{
"id": 131,
"amount": 132
},
{
"id": 130,
"amount": 0
},
{
"id": 132,
"amount": 0
},
{
"id": 145,
"amount": 23
},
{
"id": 147,
"amount": 0
},
{
"id": 146,
"amount": 0
},
{
"id": 80,
"amount": 1
},
{
"id": 90,
"amount": 0
},
{
"id": 60,
"amount": 1
},
{
"id": 153,
"amount": 298
},
{
"id": 155,
"amount": 0
},
{
"id": 154,
"amount": 0
},
{
"id": 156,
"amount": 0
},
{
"id": 81,
"amount": 0
},
{
"id": 162,
"amount": 57
},
{
"id": 164,
"amount": 0
},
{
"id": 163,
"amount": 0
},
{
"id": 169,
"amount": 0
},
{
"id": 161,
"amount": 141
},
{
"id": 167,
"amount": 0
},
{
"id": 91,
"amount": 1
},
{
"id": 172,
"amount": 0
},
{
"id": 171,
"amount": 1
}
],
"buildingChanged": [
{
"id": 1144,
"typeId": 31,
"flip": false,
"level": 1,
"x": 23,
"y": 21,
"completed": true,
"volume": 0,
"stateTimestamp": 1471644485,
"hitpoints": 920,
"disabled": false,
"speedMultiplier": 1.1000001,
"boosts": [
673,
673
],
"completeTime": 0
}
]
}
}
]
}
farm_cemetery
should not be called if there is no cemetery in the village.
50% threshold does not work very well for different levels. Need to change the condition.
❌ Critical error:
Traceback (most recent call last):
File "/home/eigenein/epicwar/epicbot/__main__.py", line 88, in step
epicbot.bot.Bot(obj, api, library).step()
File "/home/eigenein/epicwar/epicbot/bot.py", line 120, in step
self.play_pvp()
File "/home/eigenein/epicwar/epicbot/bot.py", line 440, in play_pvp
battle_result, new_resources = self.api.finish_battle(battle.battle_id, commands)
AttributeError: 'NoneType' object has no attribute 'battle_id'
Now as bastions battle #22 is stable feature, the bot can collect all this bread automatically.
After #28.
I'd like to remove the binary asset, simplify library loading and use git diff
to see changes in library.
Write a script to download the library from the specified URL, unzip it and put into an auto-generated Python module with sort_keys=True
.
When units are being hired and barracks is being upgraded on the same step, hiring partially fails. This happens because barracks status is not updated properly.
Because now some of them are not logged properly.
Participating in bastion battles.
Currently bot accepts the very first defender fights against it.
Bot could try to evaluate some defenders before accepting a battle.
Max amount stored in lib.json
:
"unlocks": {
"building": [
{
"typeId": 631,
"maxLevel": 10,
"maxAmount": 1
}
]
}
Bot doesn't check if there is already a research in progress that leads to the useless upgrade requests.
2016-08-18 17:24:19 [I] Trying to upgrade units…
2016-08-18 17:24:19 [I] Upgrading unit goblin to level 4…
2016-08-18 17:24:20 [E] Failed to upgrade: not_available.
2016-08-18 17:24:20 [I] Upgrading unit knight to level 4…
2016-08-18 17:24:21 [E] Failed to upgrade: not_available.
2016-08-18 17:24:21 [I] Upgrading unit troll to level 3…
2016-08-18 17:24:22 [E] Failed to upgrade: not_available.
2016-08-18 17:24:22 [I] Upgrading unit orc to level 3…
2016-08-18 17:24:23 [E] Failed to upgrade: not_available.
Gifts should not be sent if they have been already sent earlier the same day.
This is a meta-issue to develop the 2nd version of the bot that will be able to run continuously and react on events (e.g. upgrade finished, bastion is available, units hired etc) immediately.
requests
to aiohttp
typing.NewType
for game enumstyping.NewType
Now the bot tries to farm every task regardless of its completion status.
Need to check a task progress before trying to complete it.
alliance_randomWar_cycle_get
{
"state": [],
"result": {
"timestampStart": 1473260400,
"id": 1473260400,
"timestampEnd": 1473865200
}
}
alliance_randomWar_status
{
"result": {
"war": {
"timestampEnd": 1473346800,
"id": 1473260404257675978,
"randomWarCycleId": 1,
"timestampStart": 1473260400
},
"opponent": {
"warId": 1473260404257675978,
"allianceId": 549928,
"score": 415
},
"alliance": {
"warId": 1473260404257675978,
"allianceId": 334586,
"score": 230
}
},
"state": []
}
Because amounts are not updated, units from the gift are not spawned in PvP. Also this prevents new units from hiring.
Now I'm able to track all the resources spent. Thus, it makes sense to refresh current resource amount "online" without making any requests to API.
It makes sense to use collections.Counter
to store resource amounts.
Conditions for extended areas are listed in lib.json
. Example:
"destroyConditions": {
"building": [
{
"typeId": 1,
"level": 9,
"amount": 1
}
]
}
The relevant part of the code:
if (
building.type in BuildingType.extended_areas() and
self.can_upgrade(building.type, building.level, building_levels) and
building.is_completed
):
logging.info("Cleaning %s #%s…", building.type.name, building.id)
error = self.epic_war.destruct_building(building.id, False)
if error == Error.ok:
self.update_self_info()
self.audit_log.append("Clean *{}*.".format(building.type.name))
else:
logging.error("Failed to clean extended area.")
Replace summary log lines with Telegram broadcasting.
The bot is getting bigger and bigger. Now is good time to split into separate modules.
Keep bot.py
script to import the package and call __main__.main()
.
Traverse resource buildings at the very end. Thanks to this I will be able to stop collecting from a certain building type once zero amount is collected.
This will allow to:
Add a command line option to allow the bot automatically upgrade the castle.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.