This commit is contained in:
Ilya Bezrukov 2024-07-31 04:45:12 +03:00
commit 837113ea9c
3 changed files with 114 additions and 0 deletions

12
Dockerfile Normal file
View File

@ -0,0 +1,12 @@
FROM python:3.10-alpine
# install requirements
RUN --mount=type=cache,target=/root/.cache/pip \
--mount=type=bind,source=requirements.txt,target=requirements.txt \
pip install -r requirements.txt
COPY tap.py /app/
WORKDIR /app
CMD ["python3", "tap.py"]

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
requests

101
tap.py Normal file
View File

@ -0,0 +1,101 @@
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))
MAX_TAPS = int(os.getenv("MAX_TAPS", 1000))
MIN_TAPS = int(os.getenv("MIN_TAPS", 0))
RAND_DELTA = int(os.getenv("RAND_DELTA", 50))
EXTRA_WAIT = int(os.getenv("EXTRA_WAIT", 5))
AUTH = os.getenv("AUTH")
DRY_RUN = bool(int(os.getenv("DRY_RUN", False)))
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
@classmethod
def fake(cls):
tap_count = random.randint(MIN_TAPS + RAND_DELTA, MAX_TAPS - RAND_DELTA)
tap_regen = int(ONETAP_TIME * tap_count * GEN_PER_SEC)
tap_available = max(min(MAX_TAPS - tap_count + tap_regen, MAX_TAPS), MIN_TAPS)
regen_wait = (MAX_TAPS - 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
if DRY_RUN:
print(tap)
else:
if not tap_request(tap):
rs.kill()
time.sleep(tap.regen_wait)
finally:
print("Total earned:", total_earned)
if __name__ == "__main__":
main()