evennia/session.py

167 lines
5 KiB
Python
Executable file

import time, sys
import cPickle as pickle
from twisted.conch.telnet import StatefulTelnetProtocol
import cmdhandler
from apps.objects.models import Object
from django.contrib.auth.models import User
import commands_general
import functions_db
import functions_general
import session_mgr
class SessionProtocol(StatefulTelnetProtocol):
"""
This class represents a player's sesssion. From here we branch down into
other various classes, please try to keep this one tidy!
"""
def connectionMade(self):
"""
What to do when we get a connection.
"""
self.prep_session()
functions_general.log_infomsg('Connection: %s' % (self,))
session_mgr.add_session(self)
self.game_connect_screen()
def getClientAddress(self):
"""
Returns the client's address and port in a tuple. For example
('127.0.0.1', 41917)
"""
return self.transport.client
def prep_session(self):
self.server = self.factory.server
self.address = self.getClientAddress()
self.name = None
self.uid = None
self.logged_in = False
# The time the user last issued a command.
self.cmd_last = time.time()
# Player-visible idle time, excluding the IDLE command.
self.cmd_last_visible = time.time()
# Total number of commands issued.
self.cmd_total = 0
# The time when the user connected.
self.conn_time = time.time()
self.channels_subscribed = {}
def disconnectClient(self):
"""
Manually disconnect the client.
"""
self.transport.loseConnection()
def connectionLost(self, reason):
"""
Execute this when a client abruplty loses their connection.
"""
functions_general.log_infomsg('Disconnect: %s' % (self,))
self.handle_close()
def load_user_channels(self):
"""
Un-pickle a user's channel list from their CHANLIST attribute.
"""
chan_list = self.get_pobject().get_attribute_value("CHANLIST")
if chan_list:
self.channels_subscribed = pickle.loads(chan_list)
def lineReceived(self, data):
"""
Any line return indicates a command for the purpose of a MUD. So we take
the user input and pass it to our command handler.
"""
line = (''.join(data))
line = line.strip('\r')
uinput = line
# Stuff anything we need to pass in this dictionary.
cdat = {"server": self.factory.server, "uinput": uinput, "session": self}
cmdhandler.handle(cdat)
def handle_close(self):
"""
Break the connection and do some accounting.
"""
pobject = self.get_pobject()
if pobject:
pobject.set_flag("CONNECTED", False)
pobject.get_location().emit_to_contents("%s has disconnected." % (pobject.get_name(show_dbref=False),), exclude=pobject)
self.disconnectClient()
self.logged_in = False
session_mgr.remove_session(self)
def get_pobject(self):
"""
Returns the object associated with a session.
"""
try:
result = Object.objects.get(id=self.uid)
return result
except:
return False
def game_connect_screen(self):
"""
Show the banner screen.
"""
buffer = '-'*50
buffer += ' \n\rWelcome to Evennia!\n\r'
buffer += '-'*50 + '\n\r'
buffer += """Please type one of the following to begin:\n\r
connect <email> <password>\n\r
create \"<username>\" <email> <password>\n\r"""
buffer += '-'*50
self.msg(buffer)
def is_loggedin(self):
"""
Returns a boolean True if the session is logged in.
"""
try:
return self.logged_in
except:
return False
def login(self, user):
"""
After the user has authenticated, handle logging him in.
"""
self.uid = user.id
self.name = user.username
self.logged_in = True
self.conn_time = time.time()
pobject = self.get_pobject()
pobject.set_flag("CONNECTED", True)
session_mgr.disconnect_duplicate_session(self)
self.msg("You are now logged in as %s." % (self.name,))
pobject.get_location().emit_to_contents("%s has connected." % (pobject.get_name(),), exclude=pobject)
cdat = {"session": self, "uinput":'look', "server": self.factory.server}
cmdhandler.handle(cdat)
functions_general.log_infomsg("Login: %s" % (self,))
pobject.set_attribute("Last", "%s" % (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()),))
pobject.set_attribute("Lastsite", "%s" % (self.address[0],))
self.load_user_channels()
def msg(self, message):
"""
Sends a message to the session.
"""
self.sendLine("%s" % (message,))
def __str__(self):
"""
String representation of the user session class. We use
this a lot in the server logs and stuff.
"""
if self.is_loggedin():
symbol = '#'
else:
symbol = '?'
return "<%s> %s@%s" % (symbol, self.name, self.address,)