evennia/session.py

209 lines
6.6 KiB
Python
Raw Normal View History

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
2006-12-22 01:40:40 +00:00
import session_mgr
2006-11-20 18:54:10 +00:00
class SessionProtocol(StatefulTelnetProtocol):
2006-11-20 18:54:10 +00:00
"""
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.
"""
session_mgr.add_session(self)
self.game_connect_screen()
self.prep_session()
2007-05-24 03:36:58 +00:00
functions_general.log_infomsg('Connection: %s' % (self,))
functions_general.log_infomsg('Sessions active: %d' % (len(session_mgr.get_session_list()),))
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()
2006-11-20 18:54:10 +00:00
self.name = None
self.uid = None
2006-11-20 18:54:10 +00:00
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()
2006-11-20 18:54:10 +00:00
# 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.
"""
print "DISCONNECT:", reason.getErrorMessage()
def has_user_channel(self, cname, alias_search=False, return_muted=False):
"""
Is this session subscribed to the named channel?
return_muted: (bool) Take the user's enabling/disabling of the channel
into consideration?
"""
has_channel = False
if alias_search:
# Search by aliases only.
cdat = self.channels_subscribed.get(cname, False)
# No key match, fail immediately.
if not cdat:
return False
# If channel status is taken into consideration, see if the user
# has the channel muted or not.
if return_muted:
return cdat[1]
else:
return True
else:
# Search by complete channel name.
chan_list = self.channels_subscribed.values()
for chan in chan_list:
# Check for a name match
if cname == chan[0]:
has_channel = True
# If channel status is taken into consideration, see if the user
# has the channel muted or not.
if return_muted is False and not chan[1]:
has_channel = False
break
return has_channel
def set_user_channel(self, alias, cname, listening):
"""
Add a channel to a session's channel list.
"""
self.channels_subscribed[alias] = [cname, listening]
self.get_pobject().set_attribute("CHANLIST", pickle.dumps(self.channels_subscribed))
def del_user_channel(self, alias):
"""
Remove a channel from a session's channel list.
"""
del self.channels_subscribed[alias]
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")
2007-05-16 20:04:03 +00:00
if chan_list:
self.channels_subscribed = pickle.loads(chan_list)
def lineReceived(self, data):
2006-11-20 18:54:10 +00:00
"""
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.
2006-11-20 18:54:10 +00:00
"""
line = (''.join(data))
2006-11-20 18:54:10 +00:00
line = line.strip('\r')
uinput = line
2006-11-20 18:54:10 +00:00
# Stuff anything we need to pass in this dictionary.
cdat = {"server": self.factory.server, "uinput": uinput, "session": self}
cmdhandler.handle(cdat)
2006-11-20 18:54:10 +00:00
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()
2006-11-20 18:54:10 +00:00
self.logged_in = False
2006-12-22 01:40:40 +00:00
session_mgr.remove_session(self)
print 'Sessions active:', len(session_mgr.get_session_list())
2006-11-20 18:54:10 +00:00
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):
2006-11-20 18:54:10 +00:00
"""
Show the banner screen.
2006-11-20 18:54:10 +00:00
"""
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"""
2006-11-28 22:40:27 +00:00
buffer += '-'*50
self.msg(buffer)
2006-11-20 18:54:10 +00:00
def login(self, user):
"""
After the user has authenticated, handle logging him in.
"""
self.uid = user.id
2006-11-20 18:54:10 +00:00
self.name = user.username
self.logged_in = True
self.conn_time = time.time()
pobject = self.get_pobject()
pobject.set_flag("CONNECTED", True)
2006-12-17 02:31:50 +00:00
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()
2006-11-28 22:40:27 +00:00
def msg(self, message):
"""
Sends a message to the session.
2006-11-28 22:40:27 +00:00
"""
self.sendLine("%s" % (message,))
2006-11-28 22:40:27 +00:00
2006-11-20 18:54:10 +00:00
def __str__(self):
"""
String representation of the user session class. We use
this a lot in the server logs and stuff.
"""
if self.logged_in:
symbol = '#'
else:
symbol = '?'
return "<%s> %s@%s" % (symbol, self.name, self.address,)