Hi all,
I love using Simba for none RS things (I haven't played/botted since RSC).
I use it for a game called Forge of Empires. It's like an online multiplayer version of age of empires. Within this game you can make profit by investing in other peoples building (called sniping).
I've written a Simba script that opens up each friends great buildling list then clicks on the most profitable building type (The Arc) and if its possible to invest in clicks the mouse cursor on the number field, holds until I manually check the calculations and type the correct investment amount if its possible.
The script holds until it detects I have manually closed the window then continues opening each players building list (repeating until I manually stop he script by quickly pressing alt+tab, f2).
The game is HTML5 and the JSON data is not encrypted. People get detected and banned if they directly interact with the game data sending post requests, but I don't think they can detect if you passively read the data. This has been done for automatic calculators such as https://github.com/foe-mmr/FOE-CLI-GB-COST-CALCULATOR which processes the JSON data and shows you the investment calculations (such as INVEST: 73 REWARD: 5)
My dream would be to pass those 2 numbers into Simba and instead of waiting for me then perform the logic 'if reward > 0 then sendkeys(invest);'
Has anyone done something like this before? Is there any recommended research I can do that would help me learn how to apply this? I can get simba to perform colour clicking but I don't know what I don't know when it comes to moving data in/out of Simba.
My sniping code using Simba 13 rc2:
Additional code is not needed to check if I already invested or the profitable spots are taken as this is already done in the simba code, meaning the only time the data is there will be when its possible to lock a spot for profit.HTML Code:program new; {$i SRL/shared.simba} {$i SRL/osr.simba} const bphunt := 0; lowfp :=0; var foudn : string; page,w,j,k,l,m,h,x,y,i,xbarl,xbarh,fpboxclicked : integer=0; viewgb :tboxarray; gbwindow := DTMFromString('mWAAAAHicY2FgYDjIDME7gfgEEBcwMjCsYGJg+AOkfwMxOQAAqx4GKA=='); // gblocked := DTMFromString('mAAEAAHic42FgYDjLCMFcTBCcBsVLoPgfFEsyQ3AqEOeRQIdYKTOEWKswOKgIoOBkL0OGFG9jOB+sDohFgG7Ch5EBOp9UAAAa5xMd'); gblocked := DTMFromString('mrAAAAHic42BgYJjBxMDgxMzA8AFIvwXiACDuAWJ+oNgcII5mYWCIAuJAIE4H4vtAucdAfJMJwkYHDioCDCFWygwvbqwHs9GBCBomFgAASPENsQ=='); arcicon := BitmapFromString(8, 8, 'meJwBwAA//wMRHAIHECMwIkpTWH6Yf7DKyyG30RNDODtrdQIDAlFdXi4sITQzMkBCP520vXaOkzU7NQwREUFJOjpAM0+Siz2iltr//83r2TlCSE5XXSQkITY9OF5/g2RudXqKfK3Jzyg0JUJMQTs9MhEUFj09MgJWTImem1ZmZBVfVj2cjBA5L19scW9nUdnm4Zq3xQsfHRpSQxRFOx8zKCQuKKCwoO/+/E+LdDyVgipVgzpqnlBpdycyOmmBf1+Z1E6LzGem5zlXSDQ='); fpbox := DTMFromString('mggAAAHicY2NgYFBlZmDYCcSvgDgRiOOhtCsQO0OxBRAHQsVCreUZGBkZwRjEBuHdq9YwiAHNwobxAwAQ+AlV'); Procedure checkgb; begin for i := low(viewgb) to high(viewgb) do begin mouse.Click(viewgb[i],1); repeat wait(1000,1200) until(finddtm(gbwindow,x,y,0,0,w-1,h-1) or (findbitmap(arcicon,x,y))); wait(400); if (findbitmap(arcicon,x,y)) then if ((not findcolortolerance(l,m,2780974,inttobox(x+329,y-7,x+340,y+11),36)) and (bphunt = 0) and (not findcolortolerance(l,m,8433091,inttobox(x+474,y-5,x+499,y+5),36)) ) //sniping, checks progress bar for green to see if the fp has already been invested or ((findcolortolerance(l,m,2780974,inttobox(x+xbarl,y-7,x+xbarh,y+11),36)) and (bphunt = 1) and (not findcolortolerance(l,m,8433091,inttobox(x+474,y-5,x+499,y+5),36))) then //bphunting begin mouse.Click(inttobox(x+529,y-6,x+647,y+8),1); //opens snipeable arc repeat begin wait(1000,1200); if (not finddtm(fpbox,x,y,0,0,w-1,h-1)) then begin wait(400,1400); presskey(27); //closes gb window then gb list window wait(400,1400); presskey(27); end; if (finddtm(fpbox,x,y,0,0,w-1,h-1)) and (fpboxclicked = 0) and (bphunt =0) then begin wait(400,1400); mouse.Click(inttobox(x+10,y-3,x+110,y+3),1); //clicks the cursor so you can type investment number mouse.Move(inttobox(322,330,325,333)); fpboxclicked :=1; end; end; until(findcolortolerance(l,m,528671,inttobox(0,h-20,7,h-1),2)); //waits until you close gb windows end; fpboxclicked :=0; if (not findcolortolerance(l,m,528671,inttobox(0,h-20,7,h-1),2)) then //gb windows still open begin repeat wait(400,1400); presskey(27); wait(400,1400); until(findcolortolerance(l,m,528671,inttobox(0,h-20,7,h-1),2)) end; end; end; begin GetClientDimensions(w,h); setlength(viewgb,5); viewgb[0] := inttobox(343,h-68,358,h-53); viewgb[1] := inttobox(451,h-68,464,h-53); viewgb[2] := inttobox(559,h-68,571,h-53); viewgb[3] := inttobox(664,h-68,678,h-53); viewgb[4] := inttobox(771,h-68,786,h-53); if (lowfp=1) then begin xbarl := 340; xbarh := 345; end else begin xbarl := 324; xbarh := 329; end; activateclient(); repeat checkgb; wait(400,1400); page:= page+1; mouse.Click(inttobox(908,h-73,918,h-60),1); wait(400,1400); until (page=16); end.
The data that would be useful would be forge_points_for_level_up: 22321, (in this case invested_forge_points doesn't exist so can be = 0),
The calculation would be (forge_points_for_level_up - invested_forge_points) / 2
My theory is the simplest way to do it would be use the script as is, then the code loads a building I'm able to invest in (when if (finddtm(fpbox,x,y,0,0,w-1,h-1)) and (fpboxclicked = 0) and (bphunt =0) then is true) find the most recent
requestClass: "CityMapService"
requestMethod: "updateEntity"
and take the forge_points_for_level_up from it
and if it exists take invested_forge_points else invested_forge_points := 0;
do the calculation resultOfCalculation := (forge_points_for_level_up - invested_forge_points) / 2;
then sendkeys(resultOfCalculation); then press escape button twice and continue script
Example of JSON data:
HTML Code:[{responseData: {time: 1610367624, __class__: "Time"}, requestClass: "TimeService",…},…] 0: {responseData: {time: 1610367624, __class__: "Time"}, requestClass: "TimeService",…} requestClass: "TimeService" requestId: 566 requestMethod: "updateTime" responseData: {time: 1610367624, __class__: "Time"} time: 1610367624 __class__: "Time" __class__: "ServerResponse" 1: {responseData: [,…], requestClass: "CityMapService", requestMethod: "updateEntity", requestId: 566,…} requestClass: "CityMapService" requestId: 566 requestMethod: "updateEntity" responseData: [,…] 0: {id: 107, player_id: 3053379, cityentity_id: "X_FutureEra_Landmark1", type: "greatbuilding", x: 43,…} bonus: {amount: -1, value: 95.6, type: "contribution_boost", __class__: "GreatBuildingCityMapBonus"} amount: -1 type: "contribution_boost" value: 95.6 __class__: "GreatBuildingCityMapBonus" cityentity_id: "X_FutureEra_Landmark1" connected: 1 id: 107 level: 136 max_level: 137 player_id: 3053379 state: {,…} boosted: false current_product: {goods: [{good_id: "bromine", value: 274, __class__: "CityGood"},…], name: "clan_goods",…} asset_name: "clan_goods" goods: [{good_id: "bromine", value: 274, __class__: "CityGood"},…] 0: {good_id: "bromine", value: 274, __class__: "CityGood"} good_id: "bromine" value: 274 __class__: "CityGood" 1: {good_id: "compound_fluid", value: 274, __class__: "CityGood"} good_id: "compound_fluid" value: 274 __class__: "CityGood" 2: {good_id: "nickel", value: 274, __class__: "CityGood"} good_id: "nickel" value: 274 __class__: "CityGood" 3: {good_id: "platinum_crystals", value: 274, __class__: "CityGood"} good_id: "platinum_crystals" value: 274 __class__: "CityGood" 4: {good_id: "processed_material", value: 274, __class__: "CityGood"} good_id: "processed_material" value: 274 __class__: "CityGood" name: "clan_goods" production_time: 86400 __class__: "CityEntityClanGoodsProduct" forge_points_for_level_up: 22321 is_motivated: false next_state_transition_at: 2147483647 next_state_transition_in: 2147483647 __class__: "ProducingState" type: "greatbuilding" x: 43 y: 53 __class__: "CityMapEntity" __class__: "ServerResponse" 2: {responseData: {,…}, requestClass: "GreatBuildingsService", requestMethod: "getConstruction",…} requestClass: "GreatBuildingsService" requestId: 566 requestMethod: "getConstruction" responseData: {,…} next_passive_bonus: {amount: -1, value: 95.7, type: "contribution_boost", __class__: "GreatBuildingCityMapBonus"} amount: -1 type: "contribution_boost" value: 95.7 __class__: "GreatBuildingCityMapBonus" next_production_bonus: {value: 276, type: "clan_goods", __class__: "GreatBuildingClanBonus"} type: "clan_goods" value: 276 __class__: "GreatBuildingClanBonus" ownerEra: {era: "SpaceAgeAsteroidBelt", mainBuildingUrl: "H_SS_SpaceAgeAsteroidBelt_Townhall.png",…} era: "SpaceAgeAsteroidBelt" mainBuildingUrl: "H_SS_SpaceAgeAsteroidBelt_Townhall.png" __class__: "Era" rankings: [{rank: 1, player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…},…},…] 0: {rank: 1, player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…},…} player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…} avatar: "addon_portrait_id_unknown" canSabotage: false name: "No contributor yet" showAvatarFrame: false __class__: "OtherPlayer" rank: 1 reward: {blueprints: 23, strategy_point_amount: 2625, resources: {medals: 66834, __class__: "CityResource"},…} blueprints: 23 resources: {medals: 66834, __class__: "CityResource"} medals: 66834 __class__: "CityResource" strategy_point_amount: 2625 __class__: "GreatBuildingRankingRowReward" __class__: "GreatBuildingRankingRow" 1: {rank: 2, player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…},…} player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…} avatar: "addon_portrait_id_unknown" canSabotage: false name: "No contributor yet" showAvatarFrame: false __class__: "OtherPlayer" rank: 2 reward: {blueprints: 17, strategy_point_amount: 1315, resources: {medals: 33417, __class__: "CityResource"},…} blueprints: 17 resources: {medals: 33417, __class__: "CityResource"} medals: 33417 __class__: "CityResource" strategy_point_amount: 1315 __class__: "GreatBuildingRankingRowReward" __class__: "GreatBuildingRankingRow" 2: {rank: 3, player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…},…} player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…} avatar: "addon_portrait_id_unknown" canSabotage: false name: "No contributor yet" showAvatarFrame: false __class__: "OtherPlayer" rank: 3 reward: {blueprints: 13, strategy_point_amount: 440, resources: {medals: 16709, __class__: "CityResource"},…} blueprints: 13 resources: {medals: 16709, __class__: "CityResource"} medals: 16709 __class__: "CityResource" strategy_point_amount: 440 __class__: "GreatBuildingRankingRowReward" __class__: "GreatBuildingRankingRow" 3: {rank: 4, player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…},…} player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…} avatar: "addon_portrait_id_unknown" canSabotage: false name: "No contributor yet" showAvatarFrame: false __class__: "OtherPlayer" rank: 4 reward: {blueprints: 11, strategy_point_amount: 110, resources: {medals: 6683, __class__: "CityResource"},…} blueprints: 11 resources: {medals: 6683, __class__: "CityResource"} medals: 6683 __class__: "CityResource" strategy_point_amount: 110 __class__: "GreatBuildingRankingRowReward" __class__: "GreatBuildingRankingRow" 4: {rank: 5, player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…},…} player: {canSabotage: false, showAvatarFrame: false, name: "No contributor yet",…} avatar: "addon_portrait_id_unknown" canSabotage: false name: "No contributor yet" showAvatarFrame: false __class__: "OtherPlayer" rank: 5 reward: {blueprints: 9, strategy_point_amount: 20, resources: {medals: 3342, __class__: "CityResource"},…} blueprints: 9 resources: {medals: 3342, __class__: "CityResource"} medals: 3342 __class__: "CityResource" strategy_point_amount: 20 __class__: "GreatBuildingRankingRowReward" __class__: "GreatBuildingRankingRow" __class__: "GreatBuildingConstruction" __class__: "ServerResponse"