106 lines
2.5 KiB
Python
106 lines
2.5 KiB
Python
import time
|
|
import os
|
|
import random
|
|
import signal
|
|
import sys
|
|
from dataclasses import dataclass
|
|
|
|
import requests
|
|
|
|
|
|
URL = "https://api.hamsterkombatgame.io/clicker/tap"
|
|
|
|
ONETAP_TIME = float(os.getenv("ONETAP_TIME", 0.1614))
|
|
GEN_PER_SEC = int(os.getenv("GEN_PER_SEC", 3))
|
|
ENERGY_MAX = int(os.getenv("ENERGY_MAX", 1000))
|
|
|
|
RAND_MIN = int(os.getenv("RAND_MIN", ENERGY_MAX // 2))
|
|
RAND_MAX = int(os.getenv("RAND_MAX", ENERGY_MAX))
|
|
|
|
AUTH = os.getenv("AUTH")
|
|
DRY_RUN = bool(int(os.getenv("DRY_RUN", False)))
|
|
EXTRA_WAIT = int(os.getenv("EXTRA_WAIT", 5))
|
|
|
|
|
|
|
|
class RunState:
|
|
def __init__(self, initial: bool = True):
|
|
self._running = initial
|
|
signal.signal(signal.SIGINT, self.sighandler)
|
|
signal.signal(signal.SIGTERM, self.sighandler)
|
|
|
|
@property
|
|
def running(self):
|
|
return self._running
|
|
|
|
def sighandler(self, signum, frame):
|
|
self.kill()
|
|
|
|
def kill(self):
|
|
self._running = False
|
|
sys.exit(0)
|
|
|
|
|
|
@dataclass
|
|
class Tap:
|
|
tap_count: int
|
|
tap_available: int
|
|
regen_wait: int
|
|
|
|
@staticmethod
|
|
def clamp(x):
|
|
return max(min(x, ENERGY_MAX), 0)
|
|
|
|
@classmethod
|
|
def fake(cls):
|
|
tap_count = random.randint(RAND_MIN, RAND_MAX)
|
|
tap_regen = int(ONETAP_TIME * tap_count * GEN_PER_SEC)
|
|
tap_available = Tap.clamp(ENERGY_MAX - tap_count + tap_regen, ENERGY_MAX)
|
|
regen_wait = (ENERGY_MAX - tap_available) // GEN_PER_SEC + EXTRA_WAIT
|
|
return cls(tap_count, tap_available, regen_wait)
|
|
|
|
def to_json(self):
|
|
return {"count": self.tap_count, "availableTaps": self.tap_available}
|
|
|
|
|
|
def tap_request(tap: Tap):
|
|
payload = tap.to_json()
|
|
payload.update({"timestamp": int(time.time())})
|
|
try:
|
|
r = requests.post(URL, headers={"authorization": AUTH}, json=payload)
|
|
except Exception as ex:
|
|
print(ex)
|
|
return False
|
|
if r.status_code != 200:
|
|
print(r.status_code, r.text)
|
|
return False
|
|
return True
|
|
|
|
|
|
def main():
|
|
if not AUTH:
|
|
raise RuntimeError("AUTH not set")
|
|
if DRY_RUN:
|
|
print("This is dry-run (requests will not be sent)")
|
|
|
|
rs = RunState()
|
|
total_earned = 0
|
|
|
|
try:
|
|
while rs.running:
|
|
tap = Tap.fake()
|
|
total_earned += tap.tap_count
|
|
print("tap:", tap.tap_count, "earned:", total_earned)
|
|
|
|
if not DRY_RUN:
|
|
if not tap_request(tap):
|
|
rs.kill()
|
|
|
|
time.sleep(tap.regen_wait)
|
|
finally:
|
|
print("Total earned:", total_earned)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|