diff options
| author | troido <troido@protonmail.com> | 2020-03-06 11:26:59 +0100 |
|---|---|---|
| committer | troido <troido@protonmail.com> | 2020-03-06 11:26:59 +0100 |
| commit | dd07ff4d686f07cdc9736627dd0ef099ef5e4e4f (patch) | |
| tree | f43310b3779a95efd74a40ba8139cf146ad49051 /asciifarm/client | |
| parent | c9366616079240cd7ee3d243c9f6897d40b4267d (diff) | |
new directory structure for the separate client repo
Diffstat (limited to 'asciifarm/client')
| -rw-r--r-- | asciifarm/client/__init__.py | 0 | ||||
| -rw-r--r-- | asciifarm/client/__main__.py | 16 | ||||
| -rw-r--r-- | asciifarm/client/commandhandler.py | 150 | ||||
| -rw-r--r-- | asciifarm/client/connection.py | 30 | ||||
| -rw-r--r-- | asciifarm/client/display.py | 174 | ||||
| -rw-r--r-- | asciifarm/client/gameclient.py | 173 | ||||
| -rw-r--r-- | asciifarm/client/inputhandler.py | 98 | ||||
| -rw-r--r-- | asciifarm/client/layout.xml | 44 | ||||
| -rw-r--r-- | asciifarm/client/listselector.py | 49 | ||||
| -rw-r--r-- | asciifarm/client/loaders.py | 81 | ||||
| -rw-r--r-- | asciifarm/client/main.py | 65 | ||||
| -rw-r--r-- | asciifarm/client/parseargs.py | 66 | ||||
| -rw-r--r-- | asciifarm/client/paths.py | 7 |
13 files changed, 0 insertions, 953 deletions
diff --git a/asciifarm/client/__init__.py b/asciifarm/client/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/asciifarm/client/__init__.py +++ /dev/null diff --git a/asciifarm/client/__main__.py b/asciifarm/client/__main__.py deleted file mode 100644 index 2841ae9..0000000 --- a/asciifarm/client/__main__.py +++ /dev/null @@ -1,16 +0,0 @@ - - -import sys - -if sys.version_info[0] < 3: - print("This game is written in python 3.\nRun 'python3 "+sys.argv[0]+"' or './"+sys.argv[0]+"'") - sys.exit(-1) - -if __package__ == "asciifarm.client": - from . import main -else: - import os.path - sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..")) - from asciifarm.client import main - -main.main() diff --git a/asciifarm/client/commandhandler.py b/asciifarm/client/commandhandler.py deleted file mode 100644 index ec5baa3..0000000 --- a/asciifarm/client/commandhandler.py +++ /dev/null @@ -1,150 +0,0 @@ - -import json - -try: - import hy -except ImportError as e: - hy = None - hyErr = e - -class InvalidCommandException(Exception): - pass - - -class CommandHandler: - - def __init__(self, client): - self.client = client - - self.commands = { - "input": self.input, - "move": self.move, - "say": self.say, - "pick": self.pick, - "chat": self.chat, - "log": self.log, - "do": self.do, - "runinput": self.runInput, - "selectwidget": self.selectWidget, - "selectitem": self.selectItem, - "inputwithselected": self.actWithSelected, - "use": self.useSelected, - "drop": self.dropSelected, - "take": self.takeSelected, - "eval": self.eval, - "exec": self.exec, - "scrollchat": self.scrollChat, - "json": self.json, - "j": self.json, - "ijson": self.ijson, - "ij": self.ijson, - "hy": self.hy - } - - self.evalArgs = { - "self": self, - "client": self.client, - "connection": self.client.connection, - "display": self.client.display, - "print": self.log - } - - def execute(self, action): - if action is None: - return - if isinstance(action[0], str): - command = action[0] - if command in self.commands: - self.commands[command](*action[1:]) - else: - raise InvalidCommandException("Invalid command '{}'".format(command)) - else: - raise Exception("Command should be a string") - - - # Commands - - def input(self, action): - self.client.sendInput(action) - - def move(self, direction): - self.input(["move", direction]) - - def say(self, text): - self.input(["say", text]) - - def pick(self, option): - self.input(["interact", [None, "north", "south", "east", "west"], option]) - - def chat(self, text): - self.client.sendChat( text) - - - def log(self, text): - self.client.log(text) - - def do(self, actions): - for action in actions: - self.execute(action) - - def runInput(self, startText=""): - self.client.inputHandler.startTyping(startText) - - def selectWidget(self, value, relative=False, modular=False): - self.client.display.selectMenu(value, relative, modular) - - def selectItem(self, value, relative=False, modular=False): - self.client.display.selectItem(None, value, relative, modular) - - def actWithSelected(self, action, menu): - self.input([action, self.client.display.getSelectedItem(menu).getSelected()]) - - def useSelected(self): - menu = self.client.display.getSelectedMenu() - selected = self.client.display.getSelectedItem(menu) - if menu in ("inventory", "equipment"): - self.input(["use", menu, selected]) - elif menu == "ground": - self.input(["interact", selected]) - - def dropSelected(self): - menu = self.client.display.getSelectedMenu() - selected = self.client.display.getSelectedItem(menu) - if menu == "inventory": - action = "drop" - else: - return - self.input([action, selected]) - - def takeSelected(self): - menu = self.client.display.getSelectedMenu() - selected = self.client.display.getSelectedItem(menu) - if menu == "ground": - action = "take" - else: - return - self.input([action, selected]) - - def eval(self, text): - self.log(eval(text, self.evalArgs)) - - def exec(self, text): - exec(text, self.evalArgs) - - def hy(self, code): - if hy is None: - self.log(hyErr) - return - expr = hy.read_str(code) - self.log(hy.eval(expr, self.evalArgs)) - - def scrollChat(self, lines): - self.client.display.scrollBack(lines) - - def json(self, text): - self.execute(json.loads(text)) - - def ijson(self, text): - self.input(json.loads(text)) - - diff --git a/asciifarm/client/connection.py b/asciifarm/client/connection.py deleted file mode 100644 index 0a188c3..0000000 --- a/asciifarm/client/connection.py +++ /dev/null @@ -1,30 +0,0 @@ - -import socket - -from asciifarm.common.tcommunicate import send, receive - -class Connection: - - def __init__(self, socketType): - if socketType == "abstract" or socketType == "unix": - sockType = socket.AF_UNIX - elif socketType == "inet": - sockType = socket.AF_INET - else: - raise ValueError("Invalid socket type: %r" % (socketType,)) - self.sock = socket.socket(sockType, socket.SOCK_STREAM) - - def connect(self, address): - self.sock.connect(address) - - def listen(self, callback, onError): - while True: - try: - data = receive(self.sock) - except Exception as err: - onError(err) - else: - callback(data) - - def send(self, message): - send(self.sock, message) diff --git a/asciifarm/client/display.py b/asciifarm/client/display.py deleted file mode 100644 index edd5acb..0000000 --- a/asciifarm/client/display.py +++ /dev/null @@ -1,174 +0,0 @@ - - - -import os -from ratuil.layout import Layout -from ratuil.bufferedscreen import BufferedScreen as Screen -#from ratuil.screen import Screen -from ratuil.textstyle import TextStyle -from asciifarm.common.utils import get -from .listselector import ListSelector - - -SIDEWIDTH = 20 - -ALPHABET = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" - -class Display: - - def __init__(self, charMap): - - self.characters = {} - - def parseSprite(sprite): - if isinstance(sprite, str): - return (sprite, None, None) - char = get(sprite, 0, " ") - fg = get(sprite, 1) - bg = get(sprite, 2) - return (char, fg, bg) - for name, sprite in charMap["mapping"].items(): - vals = parseSprite(sprite) - if vals: - self.characters[name] = vals - - for name, colours in charMap.get("writable", {}).items(): - fg = get(colours, 0) - bg = get(colours, 1) - for i in range(min(len(ALPHABET), len(charMap.get("alphabet", [])))): - self.characters[name + '-' + ALPHABET[i]] = (charMap["alphabet"][i], fg, bg) - - self.defaultChar = parseSprite(charMap.get("default", "?")) - - self.messageColours = charMap.get("msgcolours", {}) - - fname = os.path.join(os.path.dirname(__file__), "layout.xml") - self.layout = Layout.from_xml_file(fname) - self.layout.get("field").set_char_size(charMap.get("charwidth", 1)) - - self.screen = Screen() - self.screen.clear() - - self.layout.set_target(self.screen) - self.layout.update() - - - - # temporary, until these have a better place - self.inventory = ListSelector(self.getWidget("inventory")) - self.inventory._debug_name = "inventory" - self.equipment = ListSelector(self.getWidget("equipment")) - self.equipment._debug_name = "equipment" - self.ground = ListSelector(self.getWidget("ground")) - self.ground._debug_name = "ground" - self.switch = ListSelector(self.getWidget("switchtitles")) - self.switch._debug_name = "switch" - - self.switch.setItems(["inventory", "equipment", "ground"]) - self.menus = { - "inventory": self.inventory, - "equipment": self.equipment, - "ground": self.ground - } - - self.layout.get("switch").select(0) - - - def getWidget(self, name): - return self.layout.get(name) - - def resizeField(self, size): - self.getWidget("field").set_size(*size) - self.getWidget("fieldbackground").change() - - def drawFieldCells(self, cells): - field = self.getWidget("field") - for cell in cells: - (x, y), spriteNames = cell - if not len(spriteNames): - char, fg, bg = self.getChar(' ') - else: - char, fg, bg = self.getChar(spriteNames[0]) - for spriteName in spriteNames[1:]: - if bg is not None: - break - _char, _fg, bg = self.getChar(spriteName) - field.change_cell(x, y, char, TextStyle(fg, bg)) - - - def setFieldCenter(self, pos): - self.getWidget("field").set_center(*pos) - - def setHealth(self, health, maxHealth): - if health is None: - health = 0 - if maxHealth is None: - maxHealth = 0 - self.getWidget("health").set_total(maxHealth) - self.getWidget("health").set_filled(health) - self.getWidget("healthtitle").format({"filled": health, "total":maxHealth}) - - - def showInfo(self, infostring): - self.getWidget("info").set_text(infostring) - - def selectMenu(self, *args, **kwargs): - self.switch.select(*args, **kwargs) - self.layout.get("switch").select(self.getSelectedMenu()) - - def getSelectedMenu(self): - return self.switch.getSelectedItem() - - def getSelectedItem(self, menu=None): - return self._getMenu(menu).getSelected() - - def selectItem(self, menu=None, *args, **kwargs): - self._getMenu(menu).select(*args, **kwargs) - - def _getMenu(self, name=None): - if name is None: - name = self.getSelectedMenu() - name = name.casefold() - return self.menus[name] - - def setInventory(self, items): - self.inventory.setItems(items) - - - def setEquipment(self, slots): - self.equipment.setItems([ - slot + ": " + (item if item else "") - for slot, item in slots - ]) - - def setGround(self, items): - self.ground.setItems(items) - - - def addMessage(self, message, msgtype=None): - if msgtype is not None: - style = TextStyle(*self.messageColours.get(msgtype, (7,0))) - else: - style = None - self.getWidget("msg").add_message(message, style) - - def log(self, message): - self.addMessage(str(message)) - - def scrollBack(self, amount, relative=True): - self.getWidget("msg").scroll(amount, relative) - - def setInputString(self, string, cursor): - self.getWidget("textinput").set_text(string, cursor) - - def update(self): - self.layout.update() - self.screen.update() - - def getChar(self, sprite): - """This returns the character belonging to some spritename. This does not read a character""" - return self.characters.get(sprite, self.defaultChar) - - def update_size(self): - self.screen.reset() - diff --git a/asciifarm/client/gameclient.py b/asciifarm/client/gameclient.py deleted file mode 100644 index c0f702c..0000000 --- a/asciifarm/client/gameclient.py +++ /dev/null @@ -1,173 +0,0 @@ - - -import os -import sys - -import threading -import json -import getpass -import argparse -import string -from queue import Queue - -import ratuil.inputs - -from .inputhandler import InputHandler -from asciifarm.common import messages - -class Client: - - def __init__(self, display, name, connection, keybindings, logFile=None): - - self.display = display - self.name = name - self.keepalive = True - self.connection = connection - self.logFile = logFile - self.closeMessage = None - - self.inputHandler = InputHandler(self, keybindings["actions"]) - - self.controlsString = keybindings.get("help", "") - - self.display.showInfo(self.controlsString) - self.queue = Queue() - - - def sendMessage(self, message): - self.connection.send(message.to_json_bytes()) - - def sendInput(self, inp): - message = messages.InputMessage(inp) - self.sendMessage(message) - - def sendChat(self, text): - try: - self.sendMessage(messages.ChatMessage(text)) - except messages.InvalidMessageError as e: - self.log(e.description) - - def start(self): - self.sendMessage(messages.NameMessage(self.name)) - threading.Thread(target=self.listen, daemon=True).start() - threading.Thread(target=self.getInput, daemon=True).start() - - self.command_loop() - - def listen(self): - self.connection.listen(self.pushMessage, self.onConnectionError) - - def pushMessage(self, databytes): - self.queue.put(("message", databytes)) - - def onConnectionError(self, error): - self.queue.put(("error", error)) - - def getInput(self): - while True: - key = ratuil.inputs.get_key() - self.queue.put(("input", key)) - - def close(self, msg=None): - self.keepalive = False - self.closeMessage = msg - - - def update(self, databytes): - if len(databytes) == 0: - self.close("Connection closed by server") - return - datastr = databytes.decode('utf-8') - msg = json.loads(datastr) - message = messages.messages[msg[0]].from_json(msg) - if isinstance(message, messages.ErrorMessage): - error = message.errType - if error == "nametaken": - self.close("error: name is already taken") - return - if error == "invalidname": - self.close("Invalid name error: "+ str(message.description)) - return - self.log(message.errType + ": " + message.description) - elif isinstance(message, messages.MessageMessage): - self.log(message.text, message.type) - elif isinstance(message, messages.WorldMessage): - for msg in message.updates: - self.handleWorldUpdate(msg) - - def handleWorldUpdate(self, msg): - msgType = msg[0] - if msgType == 'field': - field = msg[1] - fieldWidth = field['width'] - fieldHeight = field['height'] - self.display.resizeField((fieldWidth, fieldHeight)) - fieldCells = field['field'] - mapping = field['mapping'] - self.display.drawFieldCells( - ( - tuple(reversed(divmod(i, fieldWidth))), - mapping[spr] - ) - for i, spr in enumerate(fieldCells)) - - if msgType == 'changecells' and len(msg[1]): - self.display.drawFieldCells(msg[1]) - - if msgType == "playerpos": - self.display.setFieldCenter(msg[1]) - - if msgType == "health": - health, maxHealth = msg[1] - self.display.setHealth(health, maxHealth) - if maxHealth is None: - self.log("You have died. Restart the client to respawn") - if msgType == "inventory": - self.display.setInventory(msg[1]) - if msgType == "equipment": - self.display.setEquipment(msg[1]) - if msgType == "ground": - self.display.setGround(msg[1]) - if msgType == "message": - type, text = msg[1][:2] - self.log(text, type) - if msgType == "options": - if msg[1] != None: - description, options = msg[1] - self.log(description) - for option in options: - self.log(option) - - - def log(self, text, type=None): - if not isinstance(text, str): - text = str(text) - self.display.addMessage(text, type) - if self.logFile: - with(open(self.logFile, 'a')) as f: - f.write("[{}] {}\n".format(type or "", text)) - - - def command_loop(self): - while self.keepalive: - self.display.update() - action = self.queue.get() - if action[0] == "message": - self.update(action[1]) - elif action[0] == "input": - if action[1] == "^C": - raise KeyboardInterrupt - self.inputHandler.onInput(action[1]) - elif action[0] == "error": - raise action[1] - elif action[0] == "sigwinch": - self.display.update_size() - else: - raise Exception("invalid action in queue") - - def onSigwinch(self, signum, frame): - self.queue.put(("sigwinch", (signum, frame))) - - - - diff --git a/asciifarm/client/inputhandler.py b/asciifarm/client/inputhandler.py deleted file mode 100644 index 4281c01..0000000 --- a/asciifarm/client/inputhandler.py +++ /dev/null @@ -1,98 +0,0 @@ - -import string - -from .commandhandler import CommandHandler, InvalidCommandException - -import ratuil.inputs as inp - - -class InputHandler: - - def __init__(self, client, keybindings): - self.client = client - self.keybindings = keybindings - self.commandHandler = CommandHandler(self.client) - - self.typing = False - self.string = "" - self.cursor = 0 - - - def onInput(self, key): - if not self.typing: - keyName = key - if keyName in self.keybindings: - self.commandHandler.execute(self.keybindings[keyName]) - else: - self.addKey(key) - - - def processString(self, message): - if message: - if message[0] == '/': - if len(message) == 1: - return - if message[1] == '/': - self.commandHandler.chat(message[1:]) - else: - try: - command, _sep, arg = message[1:].partition(' ') - try: - self.commandHandler.execute([command, arg]) - except Exception as e: - self.log(e) - except InvalidCommandException as e: - self.client.log(", ".join(e.args)) - else: - self.commandHandler.chat(message) - - def startTyping(self, startText=""): - self.typing = True - if startText and not self.string: - self.string = startText - self.cursor = len(self.string) - - self.showString() - - def showString(self): - self.client.display.setInputString(self.string, self.cursor if self.typing else None) - - def addKey(self, key): - if key == inp.BACKSPACE: - self.string = self.string[:self.cursor-1] + self.string[self.cursor:] - self.cursor = max(self.cursor - 1, 0) - elif key == inp.RIGHT: - self.cursor = min(self.cursor + 1, len(self.string)) - elif key == inp.LEFT: - self.cursor = max(self.cursor - 1, 0) - elif key == inp.DELETE: - self.string = self.string[:self.cursor] + self.string[self.cursor+1:] - elif key == inp.HOME: - self.cursor = 0 - elif key == inp.END: - self.cursor = len(self.string) - - elif key == inp.ESCAPE: - # throw away entered string and go back to game - self.typing = False - self.string = "" - self.cursor = 0 - elif key == inp.ENTER: - # process entered string and reset it - message = self.string - self.string = "" - self.cursor = 0 - self.typing = False - self.processString(message) - elif key == "^I": # tab - # return to game but keep entered string - self.typing = False - elif key.isprintable() and len(key) == 1: - self.string = self.string[:self.cursor] + key + self.string[self.cursor:] - self.cursor += len(key) - - self.showString() - - - - diff --git a/asciifarm/client/layout.xml b/asciifarm/client/layout.xml deleted file mode 100644 index d50ecba..0000000 --- a/asciifarm/client/layout.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0"?> -<hbox> - <vbox width="20" align="right"> - <textbox id="healthtitle" height="1" format="true">Health ({filled}/{total})</textbox> - <bar id="health" height="1" full-char="#" empty-char="_" full-style="fg:2; bg:2" empty-style="fg:1; bg: 1;"></bar> - <listing id="switchtitles" height="0"></listing> - <switchbox id="switch" height="50%"> - <vbox key="inventory"> - <textbox height="1">Inventory:</textbox> - <listing id="inventory"> - milk - eggs - bread - </listing> - </vbox> - <vbox key="equipment"> - <textbox height="1">Equipment:</textbox> - <listing id="equipment"> - cotton underwear - cotton shirt - jeans - friendship bracelet - </listing> - </vbox> - <vbox key="ground"> - <textbox height="1">Ground:</textbox> - <listing id="ground"> - concrete - </listing> - </vbox> - </switchbox> - <textbox id="info" wrap="words"></textbox> - </vbox> - <vbox> - <textinput id="textinput" align="bottom" height="1">hello</textinput> - <log id="msg" align="bottom" height="20%%"> - Welcome to asciifarm - </log> - <overlay> - <fill id="fieldbackground" char=" "></fill> - <field id="field"></field> - </overlay> - </vbox> -</hbox> diff --git a/asciifarm/client/listselector.py b/asciifarm/client/listselector.py deleted file mode 100644 index b88b967..0000000 --- a/asciifarm/client/listselector.py +++ /dev/null @@ -1,49 +0,0 @@ - -from asciifarm.common import utils - - -class ListSelector: - - def __init__(self, widget): - self.widget = widget - self.items = [] - self.selector = 0 - - def getSelected(self): - return self.selector - - def select(self, value, relative=False, modular=False): - invLen = len(self.items) - if relative: - value += self.selector - if modular and invLen: - value %= invLen - if value < 0: - value = 0 - if value >= invLen: - value = invLen-1 - if value in range(invLen): - self.doSelect(value) - - def doSelect(self, value): - self.selector = value - self.widget.select(value) - - def setItems(self, items): - self.items = items - self.selector = utils.clamp(self.selector, 0, len(items)-1) - self.widget.set_items([self.itemName(item) for item in self.items]) - self.widget.select(self.selector) - - def getItem(self, num): - return self.items[num] - - def getSelectedItem(self): - return self.getItem(self.getSelected()) - - def getNumItems(self): - return len(self.items) - - def itemName(self, item): - return item - diff --git a/asciifarm/client/loaders.py b/asciifarm/client/loaders.py deleted file mode 100644 index efdd1c0..0000000 --- a/asciifarm/client/loaders.py +++ /dev/null @@ -1,81 +0,0 @@ - -import os - -from .paths import keybindingsPath, charmapPath -import json - - -standardKeyFiles = { - "default": os.path.join(keybindingsPath, "default.json"), - "azerty": os.path.join(keybindingsPath, "azerty.json") -} - -def loadKeybindings(name): - fname = None - if name in standardKeyFiles: - fname = standardKeyFiles[name] - else: - fname = name - with open(fname) as f: - data = json.load(f) - bindings = {} - help = "" - for ftemplate in data.get("templates", []): - if ftemplate.partition(os.sep)[0] in {".", ".."}: - ftemplate = os.path.relpath(ftemplate, fname) - template = loadKeybindings(ftemplate) - bindings.update(template.get("actions", {})) - help = template.get("help", help) - bindings.update(data.get("actions", {})) - help = data.get("help", help) - return {"actions": bindings, "help": help} - - -standardCharFiles = {name: os.path.join(charmapPath, file) for name, file in { - "default": "fullwidth.json", - "halfwidth": "halfwidth.json", - "hw": "halfwidth.json", - "fullwidth": "fullwidth.json", - "fw": "fullwidth.json", - "emoji": "emoji.json" -}.items()} - -def loadCharmap(name): - fname = None - if name in standardCharFiles: - fname = standardCharFiles[name] - else: - fname = name - with open(fname) as f: - data = json.load(f) - - templates = [] - for ftemplate in data.get("templates", []): - if ftemplate.partition(os.sep)[0] in {".", ".."}: - ftemplate = os.path.relpath(ftemplate, fname) - templates.append(loadCharmap(ftemplate)) - - templates.append(data) - - mapping = {} - writable = {} - default = None - charwidth = 1 - alphabet = "" - msgcolours = {} - - for template in templates: - mapping.update(template.get("mapping", {})) - writable.update(template.get("writable", {})) - default = template.get("default", default) - charwidth = template.get("charwidth", charwidth) - alphabet = template.get("alphabet", alphabet) - msgcolours.update(template.get("msgcolours", {})) - return { - "mapping": mapping, - "writable": writable, - "default": default, - "charwidth": charwidth, - "alphabet": alphabet, - "msgcolours": msgcolours - } diff --git a/asciifarm/client/main.py b/asciifarm/client/main.py deleted file mode 100644 index d720477..0000000 --- a/asciifarm/client/main.py +++ /dev/null @@ -1,65 +0,0 @@ -#! /usr/bin/python3 - -import json - -import sys -import termios -import tty -import signal -#import os - -from .connection import Connection -from .gameclient import Client -from .display import Display -from .parseargs import parse_args -from ratuil.screen import Screen - -def main(argv=None): - - (name, socketType, address, keybindings, characters, colours, logfile) = parse_args(argv) - - - connection = Connection(socketType) - try: - connection.connect(address) - except ConnectionRefusedError: - print("ERROR: Could not connect to server.\nAre you sure that the server is running and that you're connecting to the right address?", file=sys.stderr) - return - - error = None - closeMessage = None - - #os.environ.setdefault("ESCDELAY", "25") - - fd = sys.stdin.fileno() - oldterm = termios.tcgetattr(fd) - - try: - - tty.setraw(sys.stdin) - Screen.default.hide_cursor() - - display = Display(characters) - client = Client(display, name, connection, keybindings, logfile) - signal.signal(signal.SIGWINCH, client.onSigwinch) - try: - client.start() - except KeyboardInterrupt: - client.close("^C caught, goodbye") - except Exception as e: - # throw the execption outside ncurses - # so the cleanup can happen first - error = e - closeMessage = client.closeMessage - finally: - ## Set everything back to normal - termios.tcsetattr(fd, termios.TCSADRAIN, oldterm) - Screen.default.finalize() - - - if error is not None: - raise error - - if closeMessage: - print(closeMessage, file=sys.stderr) - diff --git a/asciifarm/client/parseargs.py b/asciifarm/client/parseargs.py deleted file mode 100644 index a8b393b..0000000 --- a/asciifarm/client/parseargs.py +++ /dev/null @@ -1,66 +0,0 @@ - - -import argparse -import getpass -import json -import os -import os.path - -from . import loaders - - -defaultAdresses = { - "abstract": "asciifarm", - "unix": "asciifarm.socket", - "inet": "localhost:9021", -} - -def parse_args(argv): - - parser = argparse.ArgumentParser(description="The client to AsciiFarm. Run this to connect to to the server.", epilog=""" - Gameplay information: - Walk around and explore the rooms. - Kill the goblins and plant the seeds. - - ~troido""", formatter_class=argparse.RawDescriptionHelpFormatter) - parser.add_argument('-n', '--name', help='Your player name (must be unique!). Defaults to username on inet sockets and tildename on unix socket (including abstract). Apart from the tilde in a tildename all characters must be unicode letters, numbers or connection puctuation. The maximum size of a name is 256 bytes when encoded as utf8', default=None) - parser.add_argument("-a", "--address", help="The address of the socket. When the socket type is 'abstract' this is just a name. When it is 'unix' this is a filename. When it is 'inet' is should be in the format 'address:port', eg 'localhost:8080'. Defaults depends on the socket type") - parser.add_argument("-s", "--socket", help="the socket type. 'unix' is unix domain sockets, 'abstract' is abstract unix domain sockets and 'inet' is inet sockets. ", choices=["abstract", "unix", "inet"], default="abstract") - parser.add_argument('-k', '--keybindings', help='The file with the keybinding configuration. This file is a JSON file.', default="default") - parser.add_argument('-c', '--characters', help='The file with the character mappings for the graphics. If it is either of these names: {} it will be loaded from the charmaps directory.'.format(list(loaders.standardCharFiles.keys())), default="default") - parser.add_argument('-o', '--logfile', help='All game messages will be written to this file.', default=None) - - colourGroup = parser.add_mutually_exclusive_group() - colourGroup.add_argument('-l', '--colours', '--colors', help='enable colours! :)', action="store_true") - colourGroup.add_argument('-b', '--nocolours', '--nocolors', help='disable colours! :)', action="store_true") - - args = parser.parse_args(argv) - - charmap = loaders.loadCharmap(args.characters) - - keybindings = loaders.loadKeybindings(args.keybindings) - - address = args.address - if address is None: - address = defaultAdresses[args.socket] - if args.socket == "abstract": - address = '\0' + address - elif args.socket == "inet": - hostname, sep, port = address.partition(':') - address = (hostname, int(port)) - - colours = True - if args.colours: - colours = True - elif args.nocolours: - colours = False - - name = args.name - if name is None: - username = getpass.getuser() - if args.socket == "unix" or args.socket == "abstract": - name = "~"+username - else: - name = username - - return (name, args.socket, address, keybindings, charmap, colours, args.logfile) diff --git a/asciifarm/client/paths.py b/asciifarm/client/paths.py deleted file mode 100644 index 407d54c..0000000 --- a/asciifarm/client/paths.py +++ /dev/null @@ -1,7 +0,0 @@ - -import os.path - -clientPath = os.path.dirname(__file__) -farmsPath = os.path.normpath(os.path.join(clientPath, "..")) -charmapPath = os.path.join(farmsPath, "charmaps") -keybindingsPath = os.path.join(farmsPath, "keybindings") |
