Files
Whiskerbound/game.py

314 lines
12 KiB
Python

from data.cat import Cat
from systems.ui import clear, title
from systems.world import shelter, house, shop, work
import systems.ui as ui
import data.save
import data.text
import os
import json
import traceback
import base64
import time
class Game:
def __init__(self):
self.cat = None
def settings(self):
while True:
match ui.select(
"Please choose an option", ["Prepare for savefile transfer", "Back"]
):
case "Back":
return False
case "Prepare for savefile transfer":
print(
"This tool is for transfering your savefile to another device without causing the tamper detection."
)
print(
"If you confirm, the game will save and then exit, at this point you will copy your game files and saves folder over."
)
print(
"DO NOT RELAUNCH THE GAME before copying or it will undo this tool"
)
if ui.confirm():
data.save.save(self.cat)
return True
return False
def options_menu(self):
options = ["Back"]
if not os.path.exists("WEB_VERSION"):
options[0:0] = [ # AI came up with this, what the heck is [0:0]
"Save",
"Save and quit",
"Quit",
"Settings",
]
else:
options[0:0] = [
"Save",
"Save and quit",
"Quit",
]
while True:
match ui.select(
"Please choose an option",
options,
):
case "Save":
data.save.save(self.cat)
case "Save and quit":
print("Goodbye!")
data.save.save(self.cat)
return True
case "Quit":
if ui.confirm("Are you sure you want to quit without saving?"):
print("Goodbye!")
return True
case "Settings":
if self.settings():
return True
case "Back":
return False
def new_game(self):
self.cat = shelter()
if not os.path.exists("WEB_VERSION"):
print("Saving...")
data.save.save(self.cat)
print("Save complete.")
self.game_loop()
def game_loop(self):
if os.path.exists(
"admin_handle.py"
): # TODO: make this for specific uuids, like a thing to handle stuff for specific uuids, like give money, but make sure to remove the thing after, and maybe a admin_panel.py to configure a json which admin_handle.py also reads for stuff. i gtg.
import admin_handle # type: ignore
admin_handle.handle(self.cat)
self.cat.apply_decay()
self.cat.last_login = time.time()
ui.current_cat = self.cat
while True:
match ui.select(
"Please choose an option",
["Go to your house", "Go to the shop", "Go to work", "Options"],
):
case "Go to your house":
house(self.cat)
case "Go to the shop":
shop(self.cat)
case "Go to work":
work(self.cat)
case "Options":
if self.options_menu():
return
case _:
return
def load_game(self):
if os.path.exists("WEB_VERSION"):
print(
"Please paste your savefile on the next line, you can PROBABLY use CTRL+V. Press enter to cancel."
)
savetext = ui.text("Enter here:")
if savetext:
try:
self.cat = Cat(**json.loads(base64.b64decode(savetext).decode()))
except:
print(
"The savefile you gave was unable to load, please make sure you pasted correctly. Otherwise, it may have broken."
)
else:
print(
f"Savefile loaded successfully! Continuing save with {self.cat.name}."
)
return True
return False
save = "saves/" + ui.select(
"Please choose a savefile to load", os.listdir("saves")
)
try:
self.cat = data.save.load(save)
except:
print("The savefile you selected was unable to load, it may be corrupt.")
return False
else:
print(
f"Savefile loaded successfully! Continuing save with {self.cat.name}."
)
return True
def run(self):
title()
if os.path.exists("WEB_VERSION"):
print(
"If you're on telnet, pretend that everything that says web version says telnet version, I'm too lazy to fix it. Also don't use CTRL+C or CTRL+V they don't work on telnet. If you don't know what telnet is, ignore this."
)
print(
f"This is a web version of {data.text.GAME_NAME}, here is some important info. To anyone outside of Germany, this game is running on a cheap VPS I got, the company didn't have any US locations available, so I had to get a Germany one, sorry for the high ping (I also have to deal with it, I'm in the US)\nPls don't hack this"
)
print(
"Update: You can now use CTRL+C and CTRL+V, and most other CTRL keys shouldn't crash the game (CTRL+R) will reload still, so any web browser stuff that could break it still will. To anyone that didn't know about this, CTRL keys used to crash the game."
)
if os.path.exists("debug.json"):
bypass_tamper_check = False
debug_config = None
with open("debug.json", "r") as f:
content = f.read()
if content.strip():
debug_config = json.loads(content)
if debug_config:
if debug_config.get("bypass_tamper_check_message", None):
if (
debug_config["bypass_tamper_check_message"]
== data.text.BYPASS_TAMPER_CHECK_MESSAGE
):
if debug_config.get("bypass_tamper_check_enable", False):
bypass_tamper_check = True
if debug_config.get("auto_load_savefile", None):
try:
self.cat = data.save.load(
debug_config["auto_load_savefile"],
bypass_tamper_check=bypass_tamper_check,
)
self.game_loop()
except:
print(
"There was an error loading the autoload savefile, please check your configuration."
)
else:
print(f"{self.cat.name} says bye")
return
options = ["New Game", "Release Notes", "Credits"]
if (
os.path.exists("saves")
and os.listdir("saves")
or os.path.exists("WEB_VERSION")
):
options.insert(0, "Load Game")
if True: # not os.path.exists("WEB_VERSION"):
options.append("Quit")
print(f"Welcome to {data.text.GAME_NAME}")
while True:
choice = ui.select("Please choose an option", choices=options)
if choice == "New Game":
self.new_game()
elif choice == "Load Game":
if self.load_game():
self.game_loop()
elif choice == "Quit":
return True
elif choice == "Release Notes":
print()
with open("RELEASE_NOTES.txt", "r") as f:
release_notes = f.read()
print(release_notes.strip())
print()
elif choice == "Credits":
print()
with open("CREDITS.txt", "r") as f:
credits = f.read()
print(credits.strip())
print()
def main():
try:
game = Game()
result = game.run()
except: # horrible coding right here
print("Developer stuff incoming, if you can, tell me what this says:")
traceback.print_exc()
print(
"Welp, seems that the game crashed, idk why. A common cause of this is, as of now, IDK, because I fixed the CTRL issue (tell me if it crashed from CTRL+something). If you're on the desktop version, reopen it, if you're on the web version, reload.\nOtherwise, great job! You found an issue in the game! If you can, please tell me."
)
if os.path.exists("WEB_VERSION"):
print(
"I could try to give you your savefile, though it might not appear, here's what should be your current savefile:"
)
try:
print(
'"'
+ base64.b64encode(json.dumps(game.cat.to_dict()).encode()).decode()
+ '"'
)
except:
print("Welp, the game broke too much :(.")
print(
"It's above this message, if theres nothing, the game broke too much, sorry."
)
print(
"Copy it if you can, you paste it into the Load Game menu option when you select it BTW."
)
print(
"I'm gonna try to do some other stuff to save RN, if there's a bunch of errors under here, it's PROBABLY fine :)"
)
try:
data.save.handle_uuid_stuff(game.cat)
except:
print("Yep, that did NOT go as planned.")
print("If there's no errors above this, yay.")
else:
if ui.confirm("Would you like me to attmept to run the save feature?"):
try:
data.save.save(game.cat)
except:
print("Sorry, the game is too broken to save :(")
print(
"Bye I guess, sorry about the crash, you can relaunch if you want :)?"
)
else:
if not result:
print(
"So, it seems the game managed to exit, without it meaning to exit, you found a bug! Great job! If you can, please tell me what happened. If you know my Gitea server link, create an issue on the Whiskerbound repository. Sorry, you gotta reload."
)
if os.path.exists("WEB_VERSION"):
print(
"I could try to give you your savefile, though it might not appear, here's what should be your current savefile:"
)
try:
print(
'"'
+ base64.b64encode(
json.dumps(game.cat.to_dict()).encode()
).decode()
+ '"'
)
except:
print("Welp, the game broke too much :(.")
print(
"It's above this message, if theres nothing, the game broke too much, sorry."
)
print(
"Copy it if you can, you paste it into the Load Game menu option when you select it BTW."
)
print(
"I'm gonna try to do some other stuff to save RN, if there's a bunch of errors under here, it's PROBABLY fine :)"
)
try:
data.save.handle_uuid_stuff(game.cat)
except:
print("Yep, that did NOT go as planned.")
print("If there's no errors above this, yay.")
else:
if ui.confirm("Would you like me to attmept to run the save feature?"):
try:
data.save.save(game.cat)
except:
print("Sorry, the game is too broken to save :(")
print(
"Bye I guess, sorry about the crash, you can relaunch if you want :)?"
)
if __name__ == "__main__":
main()