Asciifarm/asciifarm/client/gameclient.py

148 lines
4.4 KiB
Python
Raw Normal View History

2017-10-15 21:30:31 +00:00
#! /usr/bin/python3
import os
2017-10-15 21:30:31 +00:00
import sys
import curses
import threading
import json
import getpass
import argparse
2017-10-26 08:30:51 +00:00
from .display.screen import Screen
2017-10-19 10:23:26 +00:00
import string
2017-12-28 21:47:36 +00:00
from .display.display import Display
2017-10-15 21:30:31 +00:00
class Client:
2017-10-29 14:11:47 +00:00
def __init__(self, stdscr, display, name, connection, keybindings, logFile=None):
2017-10-15 21:30:31 +00:00
self.stdscr = stdscr
2017-10-26 10:43:46 +00:00
self.display = display
2017-10-15 21:30:31 +00:00
self.name = name
self.keepalive = True
self.connection = connection
2017-10-29 14:11:47 +00:00
self.logFile = logFile
2017-10-15 21:30:31 +00:00
self.commands = {}
2017-12-28 21:47:36 +00:00
if "input" in keybindings:
for key, commands in keybindings["input"].items():
if isinstance(commands[0], str):
commands = [commands]
self.commands[key] = [("send", ["input", command]) for command in commands]
if "control" in keybindings:
for key, commands in keybindings["control"].items():
if isinstance(commands[0], str):
commands = [commands]
self.commands[key] = commands
2017-10-19 10:23:26 +00:00
2017-12-28 21:47:36 +00:00
self.controlsString = """\
Default Controls:
wasd or arrows:
Move around
e: Grab
q: Drop
E: Use
r: Interact
f: Attack
t: Chat"""
2017-10-23 20:38:40 +00:00
self.display.showInfo(self.controlsString)
2017-12-28 21:47:36 +00:00
self.actions = {
"send": (lambda data: self.connection.send(json.dumps(data))),
"text": (lambda: self.readString())
}
2017-12-28 21:47:36 +00:00
def readString(self):
text = self.display.getString()
string = str(text, "utf-8")
if string:
self.connection.send(json.dumps(["input", ["say", string]]))
def start(self):
2017-10-15 21:30:31 +00:00
threading.Thread(target=self.listen, daemon=True).start()
self.connection.send(json.dumps(["name", self.name]))
2017-10-15 21:30:31 +00:00
self.command_loop()
2017-10-23 20:38:40 +00:00
2017-10-15 21:30:31 +00:00
def listen(self):
self.connection.listen(self.update, self.close)
def close(self, err=None):
self.keepalive = False
sys.exit()
def update(self, databytes):
if not self.keepalive:
sys.exit()
datastr = databytes.decode('utf-8')
data = json.loads(datastr)
if len(data) and isinstance(data[0], str):
data = [data]
for msg in data:
msgType = msg[0]
if msgType == 'error':
error = msg[1]
if error == "nametaken":
print("error: name is already taken", file=sys.stderr)
self.close()
if msgType == 'field':
field = msg[1]
2017-10-26 09:03:59 +00:00
fieldWidth = field['width']
fieldHeight = field['height']
self.display.resizeField((fieldWidth, fieldHeight))
fieldCells = field['field']
mapping = field['mapping']
2017-10-26 09:03:59 +00:00
self.display.drawFieldCells(
(tuple(reversed(divmod(i, fieldWidth))),
mapping[spr])
for i, spr in enumerate(fieldCells))
if msgType == 'changecells'and len(msg[1]):
2017-10-26 09:03:59 +00:00
self.display.drawFieldCells(msg[1])
if msgType == "playerpos":
self.display.setFieldCenter(msg[1])
if msgType == "health":
health = msg[1]
if health:
self.display.setHealth(*health)
else:
self.log("You have died. Restart the client to respawn")
if msgType == "inventory":
self.display.setInventory(msg[1])
if msgType == "ground":
self.display.setGround(msg[1])
2017-10-29 14:01:47 +00:00
if msgType == "message":
self.log(msg[1])
2017-10-19 10:23:26 +00:00
2017-10-26 09:03:59 +00:00
self.display.update()
def log(self, text):
self.display.addMessage(text)
if self.logFile:
with(open(self.logFile, 'a')) as f:
f.write(text+'\n')
2017-10-15 21:30:31 +00:00
def command_loop(self):
while self.keepalive:
key = self.stdscr.getch()
if key == 27:
self.keepalive = False
return
try:
keyname = str(curses.keyname(key), "utf-8")
except ValueError:
continue
if keyname in self.commands:
2017-12-28 21:47:36 +00:00
for command, *data in self.commands[keyname]:
self.actions[command](*data)
2017-10-19 10:23:26 +00:00
2017-10-15 21:30:31 +00:00
2017-10-15 21:30:31 +00:00