Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import base64
- import json
- import time
- import random
- from datetime import datetime
- import requests
- import threading
- from requests.adapters import HTTPAdapter, Retry
- from sys import exit
- from utils import sleep_with_note, init_session
- DEFAULT_EXCHANGE = 'bingx'
- def clamp(n, min, max):
- if n < min:
- return min
- elif n > max:
- return max
- else:
- return n
- class HamsterKombat:
- def __init__(self, bearer_token, proxy, exit_time):
- self.exit_time = exit_time
- self.session = init_session(bearer_token, proxy)
- self.base_url = 'https://api.hamsterkombatgame.io/'
- self.user_name = ''
- self.level = 1
- self.earnPerTap = 1
- self.availableTaps = 1000
- self.tapsRecoverPerSec = 3
- self.maxTaps = 1000
- self.totalCoins = 0
- self.balanceCoins = 0
- self.earnPassivePerHour = 0
- self.upgrades = {}
- self.boosts = {}
- self.daily_quest = {}
- self.daily_cipher = {}
- self.initialize_session()
- def get_url(self, url):
- return self.base_url + url + '/'
- def initialize_session(self):
- self.session.get('https://app.hamsterkombatgame.io/clicker/')
- self.session.get('https://hamsterkombatgame.io/clicker/')
- auth_url = self.get_url('auth/me-telegram')
- res = self.post_and_validate(auth_url, None)
- tg_user: dict = res['telegramUser']
- self.user_name = next(
- (name for key in ['firstName', 'lastName', 'username'] if (name := tg_user.get(key)) and name), None)
- def get_click_url(self, url_part):
- return self.get_url('clicker' + '/' + url_part)
- def clicked_post(self, url_part):
- url = self.get_click_url(url_part)
- response = self.post_and_validate(url, None)
- return response
- def sync_game_values(self, sync_data):
- def set_sync_attr(name):
- setattr(self, name, int(sync_data[name]))
- attrs = ['availableTaps',
- 'tapsRecoverPerSec',
- 'level',
- 'earnPerTap',
- 'maxTaps',
- 'totalCoins',
- 'balanceCoins',
- 'earnPassivePerHour'
- ]
- [set_sync_attr(val) for val in attrs]
- pass
- def post_and_validate(self, url, data, ts_1000=False):
- last_err = None
- i = 0
- while i < 15:
- i += 1
- if data and 'timestamp' in data:
- data['timestamp'] = int(time.time() * (1000 if ts_1000 else 1))
- res = self.session.post(url, json=data)
- if not res.ok:
- # print(f'{url=} {data=}')
- # print(f'{self.user_name} Error: {res} {res.text}')
- last_err = res
- sleep_time = 1
- if res.status_code == 503 or i == 9:
- sleep_time = 100
- elif res.status_code == 500:
- i -= 1
- sleep_time = 5
- if res.status_code == 400:
- data = res.json()
- if 'error_code' in data:
- if data['error_code'] == 'UPGRADE_COOLDOWN':
- return {'Error': 'UPGRADE_COOLDOWN', 'Data': data['cooldownSeconds']}
- if data and 'availableTaps' in data:
- data['availableTaps'] = self.set_available_taps(sleep_time)
- time.sleep(sleep_time)
- continue
- else:
- return res.json()
- raise Exception(f'{self.user_name} post send error {url} {data} {last_err} {last_err.text}')
- def buy_upgrade(self, upgrade):
- # print(f'buyed upgrade\n {upgrade}')
- name = upgrade['id']
- url = self.get_click_url('buy-upgrade')
- data = {
- 'upgradeId': name,
- 'timestamp': int(time.time()*1000)
- }
- print(f'{self.user_name} buy upgrade: {name}')
- data_for_buy = self.post_and_validate(url, data, True)
- if 'Error' in data_for_buy:
- if data_for_buy['Error'] == 'UPGRADE_COOLDOWN':
- upgrade['cooldownSeconds'] = data_for_buy['Data']
- else:
- self.upgrades = data_for_buy['upgradesForBuy']
- self.daily_quest = data_for_buy['dailyCombo']
- self.balanceCoins -= upgrade['price']
- def buy_boost(self, boost):
- # print(f'buyed boost\n {boost}')
- name = boost['id']
- url = self.get_click_url('buy-boost')
- data = {
- 'boostId': name,
- 'timestamp': int(time.time())
- }
- print(f'{self.user_name} buy boost: {name}')
- self.boosts = self.post_and_validate(url, data)['boostsForBuy']
- self.balanceCoins -= boost['price']
- def check_energy_recharge(self):
- for bt in self.boosts:
- if bt['id'] == 'BoostFullAvailableTaps':
- if bt['cooldownSeconds'] == 0 and (self.availableTaps < (self.maxTaps/5)):
- self.buy_boost(bt)
- break
- def check_daily_quest(self):
- if len(self.daily_quest['upgradeIds']) == 3 and not self.daily_quest['isClaimed']:
- url = self.get_click_url('claim-daily-combo')
- self.post_and_validate(url, [])
- self.daily_quest['isClaimed'] = True
- def claim_key(self):
- sync_response = self.session.post("https://api.hamsterkombatgame.io/clicker/sync")
- user_id = str(sync_response.json()["clickerUser"]["id"])
- encoded_cipher = base64.b64encode(f"0300000000|{user_id}".encode()).decode()
- time.sleep(1)
- start_response = self.session.post("https://api.hamsterkombatgame.io/clicker/start-keys-minigame")
- if start_response.status_code == 400:
- error_response = start_response.json()
- if error_response.get("error_code") == "KEYS-MINIGAME_WAITING":
- print("Вы уже получили ключи")
- return
- else:
- print(f"Ошибка запуска мини-игры: {start_response.status_code}, {start_response.text}")
- return
- time.sleep(2)
- claim_response = self.session.post(
- "https://api.hamsterkombatgame.io/clicker/claim-daily-keys-minigame",
- json={"cipher": encoded_cipher}
- )
- if claim_response.status_code == 200:
- response_json = claim_response.json()
- balance_keys = response_json['clickerUser']['balanceKeys']
- bonus_keys = response_json['dailyKeysMiniGame']['bonusKeys']
- print(f"Баланс ключей: {balance_keys}")
- print(f"Ключи за мини-игру: +{bonus_keys}")
- return
- elif claim_response.status_code == 400:
- print("Вы уже получили ключи сегодня")
- return
- else:
- error_message = claim_response.json().get("error_message", "Неизвестная ошибка")
- print(f"Ошибка получения ежедневных ключей: {claim_response.status_code}, {error_message}")
- return
- @staticmethod
- def daily_cipher_decode(cipher):
- modified_cipher = cipher[:3] + cipher[4:]
- decoded_bytes = base64.b64decode(modified_cipher)
- return decoded_bytes.decode('utf-8')
- def get_daily_cipher_reward(self):
- cipher_b64 = self.daily_cipher['cipher']
- cur_word = self.daily_cipher_decode(cipher_b64)
- url = self.get_click_url('claim-daily-cipher')
- data = {
- 'cipher': cur_word
- }
- self.post_and_validate(url, data)
- print(f'{self.user_name} Daily cipher success')
- pass
- @staticmethod
- def get_hours_until_listing():
- target_date = datetime(2024, 7, 5)
- current_time = datetime.now()
- time_until = target_date - current_time
- return int(time_until.total_seconds() / 3600)
- def try_to_buy_something(self):
- def sort_key(item):
- if item['price'] == 0:
- return float('inf')
- else:
- return (item['profitPerHour'] - item['currentProfitPerHour']) / item['price']
- self.check_energy_recharge()
- if self.balanceCoins < (self.earnPassivePerHour * 3):
- return
- self.upgrades = sorted(self.upgrades, key=sort_key, reverse=True)
- self.boosts = sorted(self.boosts, key=lambda x: x['price'])
- for bt in self.boosts:
- if bt['cooldownSeconds'] > 0:
- continue
- elif bt['id'] == 'BoostFullAvailableTaps':
- continue
- elif bt['price'] < (self.balanceCoins / 20) and bt['price'] < 80000: # buy only the cheapest boosts
- self.buy_boost(bt)
- return
- for up in self.upgrades:
- if up['isExpired'] or not up['isAvailable']:
- continue
- if 'maxLevel' in up:
- if up['level'] >= up['maxLevel']:
- continue
- if 'cooldownSeconds' in up:
- if up['cooldownSeconds'] > 0:
- continue
- if up['price'] < self.balanceCoins:
- profit = sort_key(up)
- if self.balanceCoins < 101_000_000:
- if (profit * self.get_hours_until_listing()) < 1.0:
- return # first item here have the highest profit, check over no need
- self.buy_upgrade(up)
- self.check_daily_quest()
- return
- def get_daily_bonus(self, tasks: dict):
- bad_names = ['invite_friends', 'subscribe_youtube_channel']
- for task in tasks['tasks']:
- if not task['isCompleted'] and task['id'] not in bad_names:
- taskId = task['id']
- url = self.get_click_url('check-task')
- data = {
- "taskId": taskId
- }
- self.post_and_validate(url, data)
- print(f'{self.user_name} complete task {taskId}')
- def set_cur_exchange(self):
- url = self.get_click_url('select-exchange')
- data = {
- "exchangeId": DEFAULT_EXCHANGE
- }
- self.post_and_validate(url, data)
- print(f'{self.user_name} set exchange to {DEFAULT_EXCHANGE}')
- def set_available_taps(self, timeout):
- bonus = int(timeout * self.tapsRecoverPerSec)
- self.availableTaps += bonus
- self.availableTaps = clamp(self.availableTaps, bonus, self.maxTaps)
- return self.availableTaps
- def perform_tap(self):
- current_timestamp = int(time.time())
- taps = (20 + random.randint(-5, 5)) * self.tapsRecoverPerSec / self.earnPerTap
- taps = clamp(taps, 5, 100)
- data = {
- "count": int(taps),
- "availableTaps": self.availableTaps,
- "timestamp": current_timestamp
- }
- response = self.post_and_validate(self.get_url('clicker/tap'), data)
- answer = response['clickerUser']
- self.sync_game_values(answer)
- print(f'{self.user_name} Score: {self.balanceCoins}; '
- f'Energy: {self.availableTaps}/{self.maxTaps}; '
- f'CoinsPerHour: {self.earnPassivePerHour}; '
- f'CoinsPerClick: {self.earnPerTap}'
- )
- modifier = self.earnPerTap/self.tapsRecoverPerSec if (self.availableTaps < int(self.maxTaps / 10)) else - 10
- sleep_time = clamp(taps / self.tapsRecoverPerSec * self.earnPerTap + modifier, 1, 100)
- if self.availableTaps == 0:
- sleep_time = (self.maxTaps / self.tapsRecoverPerSec / 10) + random.randint(-3, 3)
- self.set_available_taps(sleep_time)
- self.try_to_buy_something()
- time.sleep(sleep_time)
- if time.time() > self.exit_time:
- print(f'{self.user_name} goes on break')
- exit(0)
- def run(self):
- config = self.clicked_post('config')
- self.daily_cipher: dict = config['dailyCipher']
- if not self.daily_cipher['isClaimed']:
- self.get_daily_cipher_reward()
- sync_data = self.clicked_post('sync')['clickerUser']
- if sync_data['exchangeId'] != DEFAULT_EXCHANGE:
- self.set_cur_exchange()
- self.sync_game_values(sync_data)
- data_for_buy = self.clicked_post('upgrades-for-buy')
- self.upgrades = data_for_buy['upgradesForBuy']
- self.daily_quest = data_for_buy['dailyCombo']
- self.boosts = self.clicked_post('boosts-for-buy')['boostsForBuy']
- tasks = self.clicked_post('list-tasks')
- self.check_daily_quest()
- self.get_daily_bonus(tasks)
- self.claim_key()
- while True:
- self.perform_tap()
- def main():
- debug = False
- def run_instance(token, proxy, exit_time):
- instance = HamsterKombat(token, proxy, exit_time)
- instance.run()
- while True:
- with open('config.json', 'r') as file:
- data = json.load(file)
- tokens = data['tokens']
- proxy_tokens = data['proxy_tokens']
- proxy = data['proxy']
- exit_time = time.time() + 60 * 60 + random.randint(0, 15 * 60)
- threads = []
- for token in tokens:
- thread = threading.Thread(target=run_instance, args=(token, None, exit_time,))
- threads.append(thread)
- thread.start()
- if debug:
- break
- if not debug:
- for token in proxy_tokens:
- thread = threading.Thread(target=run_instance, args=(token, proxy, exit_time,))
- threads.append(thread)
- thread.start()
- for thread in threads:
- thread.join()
- print('All threads complete. Wait two hour +- 15 min before restart')
- total_sleep_time = (60 * 60 * 2) + random.randint(-15 * 60, 15 * 60)
- sleep_with_note(total_sleep_time)
- if __name__ == '__main__':
- main()
Add Comment
Please, Sign In to add comment