140 lines
4.4 KiB
Python
140 lines
4.4 KiB
Python
import json
|
|
from data.cat import Cat
|
|
import os
|
|
import sys
|
|
import hashlib
|
|
import systems.ui
|
|
import shutil
|
|
import base64
|
|
import systems.ui
|
|
|
|
|
|
def punish(cat):
|
|
print(
|
|
"You have tampered with your cat, your cat is sad, you must pet your cat 20,000 times to continue playing."
|
|
)
|
|
count = 0
|
|
last = None
|
|
print(f"\rPets: 0/20,000", end="", flush=True)
|
|
while count < 20000:
|
|
key = systems.ui.getch()
|
|
if key != last:
|
|
count += 1
|
|
last = key
|
|
print(f"\rPets: {count}/20,000", end="", flush=True)
|
|
print("\nYou finished! Your cat is a bit upset but you may continue playing.")
|
|
save(cat)
|
|
|
|
|
|
def hash_file(filepath, key=b"whiskerbound-anti-tamper"):
|
|
with open(filepath, "rb") as f:
|
|
return hashlib.blake2s(f.read(), key=key).hexdigest()
|
|
|
|
|
|
def get_data_dir():
|
|
if sys.platform == "win32":
|
|
return os.path.join(os.environ["APPDATA"], "Whiskerbound")
|
|
else:
|
|
return os.path.join(
|
|
os.environ.get("XDG_DATA_HOME", os.path.expanduser("~/.local/share")),
|
|
"Whiskerbound",
|
|
)
|
|
|
|
|
|
def prepare_move():
|
|
data_dir = get_data_dir()
|
|
hash_path = os.path.join(data_dir, "dont hurt cats.json")
|
|
if os.path.exists(hash_path):
|
|
shutil.copy(hash_path, "saves/.moved")
|
|
print("Ready to move! Copy your saves folder to your new PC.")
|
|
else:
|
|
print("No save data to prepare.")
|
|
|
|
|
|
def handle_uuid_stuff(cat: Cat):
|
|
if os.path.exists("uuids.json"):
|
|
try:
|
|
with open("uuids.json", "r") as f:
|
|
uuids = json.load(f)
|
|
except:
|
|
return
|
|
if not uuids.get("enable"):
|
|
return
|
|
uuids[cat.cat_uuid] = {"name": cat.name, "last_login": cat.last_login}
|
|
try:
|
|
with open("uuids.json", "w") as f:
|
|
json.dump(uuids, f)
|
|
except:
|
|
return
|
|
else:
|
|
return
|
|
|
|
|
|
def save(cat: Cat, dont_save=False):
|
|
if os.path.exists("WEB_VERSION") and not dont_save:
|
|
print(
|
|
"Under this message, in quotes, will be a long string of text, this is your savefile, please copy this somewhere safe and make sure to copy the whole thing, you will paste it back to load your game. You SHOULD be able to use CTRL+C+."
|
|
)
|
|
print('"' + base64.b64encode(json.dumps(cat.to_dict()).encode()).decode() + '"')
|
|
handle_uuid_stuff(cat)
|
|
print(
|
|
"Your savefile has been printed above this, please save it somewhere safe."
|
|
)
|
|
print(
|
|
"Any progress done after this will not be saved in this string, please generate a new one to update your progress."
|
|
)
|
|
print("To get back to the main menu and quit, reload the page.")
|
|
systems.ui.press_any_key_to_continue("Press any key to continue.")
|
|
return
|
|
currentjson = {}
|
|
data_dir = get_data_dir()
|
|
hash_path = os.path.join(data_dir, "dont hurt cats.json")
|
|
if not os.path.exists("saves"):
|
|
os.mkdir("saves")
|
|
with open(f"saves/{cat.name}.kitten", "w") as f:
|
|
json.dump(cat.to_dict(), f)
|
|
|
|
os.makedirs(data_dir, exist_ok=True)
|
|
if os.path.exists(hash_path):
|
|
with open(hash_path, "r") as f:
|
|
currentjson = json.load(f)
|
|
|
|
currentjson[f"saves/{cat.name}.kitten"] = hash_file(f"saves/{cat.name}.kitten")
|
|
with open(hash_path, "w") as f:
|
|
json.dump(currentjson, f)
|
|
print("Saved.")
|
|
|
|
|
|
def load(
|
|
filepath, bypass_tamper_check=False, force_punish=False, hide_web_message=False
|
|
):
|
|
if os.path.exists("WEB_VERSION"):
|
|
if not hide_web_message:
|
|
print("Loading is disabled.")
|
|
punished = False
|
|
data_dir = get_data_dir()
|
|
hash_path = os.path.join(data_dir, "dont hurt cats.json")
|
|
file_hash = hash_file(filepath)
|
|
if not os.path.exists(hash_path) and os.path.exists("saves/.moved"):
|
|
os.makedirs(data_dir, exist_ok=True)
|
|
shutil.move("saves/.moved", hash_path)
|
|
if os.path.exists(hash_path):
|
|
with open(hash_path, "r") as f:
|
|
hashes = json.load(f)
|
|
if not filepath in hashes:
|
|
punished = True
|
|
else:
|
|
if not hashes[filepath] == file_hash:
|
|
punished = True
|
|
else:
|
|
pass # ur good
|
|
else:
|
|
punished = True
|
|
with open(filepath) as f:
|
|
raw = json.load(f)
|
|
cat = Cat(**raw)
|
|
if punished or force_punish:
|
|
if not bypass_tamper_check:
|
|
punish(cat)
|
|
return cat
|