shiftgears/mud.py

88 lines
3.2 KiB
Python
Raw Permalink Normal View History

2020-04-16 12:58:21 +00:00
import traceback
import uuid
from twisted.internet.protocol import Factory
from auth import Auth
from database import DbSession
from netclass import netclass_root, jsonconverter
from servermessage import ServerMessage, ServerMessageStream
import pong
import save
from messagehandler import handlers
class MudConnection(ServerMessageStream):
def __init__(self, factory, addr):
self.factory = factory
self.addr = addr
self.authsession = None
super().__init__()
def connectionMade(self):
self.dbsession = DbSession()
self.pong = pong.PongState(self)
self.auth = Auth(self.dbsession, self.addr.host)
print(f"{self.addr.host} connected.")
self.send_message("Welcome", str(uuid.uuid4()))
# If the server shuts down, all the clients that were left open
# will reconnect as soon as it comes back on. But, they don't
# bother to re-authenticate on their own, so the server has to
# prompt them to save to get the copy of the auth token that is
# in the save. When the client joins on its own startup,
# and authenticates anyway, hopefully this won't matter...
#self.run_command("sos.save")
# but it is commented out cause the lua script doesn't work
def connectionLost(self, reason):
print(f"{self.addr.host} disconnected.")
self.closing = True
self.pong.leave()
self.dbsession.close()
def serverMessageReceived(self, message):
if message.Name not in ["pong_mp_setballpos", "pong_mp_setopponenty"]:
print(f"{self.addr.host}: {message.Name}({repr(message.Contents)})")
if message.Name in handlers:
try:
handlers[message.Name](self, message.Contents)
self.dbsession.commit()
except:
self.dbsession.rollback()
self.error(traceback.format_exc())
traceback.print_exc()
else:
self.error(f"Unimplemented message {message.Name}. Thanks for using Shift Gears!")
def send_message(self, name, contents = None, guid = None):
if contents is not None and not isinstance(contents, str):
contents = jsonconverter.to_json(contents)
guid = str(guid)
self.sendServerMessage(ServerMessage(name, contents, guid))
def error(self, message):
# The content of the Error message is deserialised at the other
# end as an Exception, but only the Message member is read.
self.send_message("Error", {"ClassName":"System.Exception","Message":message,"Data":None,"InnerException":None,"HelpURL":None,"StackTraceString":None,"RemoteStackTraceString":None,"RemoteStackIndex":0,"ExceptionMethod":None,"HResult":-2146233088,"Source":None})
# executes Lua code on the client...its that easy
def run(self, script):
self.send_message("run", {"script": script})
# executes a ShiftOS command on the client
def run_command(self, cmd):
# We don't use trm_invokecommand because it expects the prompt
# to be sent to it before the command and it's not always
# feasible to figure out what the prompt is.
self.run(f"sos.runCommand({repr(cmd)})")
def infobox(self, msg, title = "MUD"):
self.invoke_command("infobox.show" + jsonconverter.to_json({"title": title, "msg": msg}))
class MudConnectionFactory(Factory):
def __init__(self):
self.pong = pong.PongMatchmaking()
def buildProtocol(self, addr):
return MudConnection(self, addr)