Indentation change 3-4 spaces.

Possible files that need to be cleanedup;
commands/info.py:cmd_list
commands/general.py:cmd_who
commands/comsys.py:cmd_who

cmdtable.py
ansi.py
This commit is contained in:
loki77 2008-06-13 19:52:29 +00:00
parent 740d715c72
commit 3fe644ef17
31 changed files with 1856 additions and 1856 deletions

138
ansi.py
View file

@ -3,92 +3,92 @@ import re
ANSI related stuff. ANSI related stuff.
""" """
ansi = {} ansi = {}
ansi["beep"] = "\07" ansi["beep"] = "\07"
ansi["escape"] = "\033" ansi["escape"] = "\033"
ansi["normal"] = "\033[0m" ansi["normal"] = "\033[0m"
ansi["underline"] = "\033[4m" ansi["underline"] = "\033[4m"
ansi["hilite"] = "\033[1m" ansi["hilite"] = "\033[1m"
ansi["blink"] = "\033[5m" ansi["blink"] = "\033[5m"
ansi["inverse"] = "\033[7m" ansi["inverse"] = "\033[7m"
ansi["inv_hilite"] = "\033[1;7m" ansi["inv_hilite"] = "\033[1;7m"
ansi["inv_blink"] = "\033[7;5m" ansi["inv_blink"] = "\033[7;5m"
ansi["blink_hilite"] = "\033[1;5m" ansi["blink_hilite"] = "\033[1;5m"
ansi["inv_blink_hilite"] = "\033[1;5;7m" ansi["inv_blink_hilite"] = "\033[1;5;7m"
# Foreground colors # Foreground colors
ansi["black"] = "\033[30m" ansi["black"] = "\033[30m"
ansi["red"] = "\033[31m" ansi["red"] = "\033[31m"
ansi["green"] = "\033[32m" ansi["green"] = "\033[32m"
ansi["yellow"] = "\033[33m" ansi["yellow"] = "\033[33m"
ansi["blue"] = "\033[34m" ansi["blue"] = "\033[34m"
ansi["magenta"] = "\033[35m" ansi["magenta"] = "\033[35m"
ansi["cyan"] = "\033[36m" ansi["cyan"] = "\033[36m"
ansi["white"] = "\033[37m" ansi["white"] = "\033[37m"
# Background colors # Background colors
ansi["back_black"] = "\033[40m" ansi["back_black"] = "\033[40m"
ansi["back_red"] = "\033[41m" ansi["back_red"] = "\033[41m"
ansi["back_green"] = "\033[42m" ansi["back_green"] = "\033[42m"
ansi["back_yellow"] = "\033[43m" ansi["back_yellow"] = "\033[43m"
ansi["back_blue"] = "\033[44m" ansi["back_blue"] = "\033[44m"
ansi["back_magenta"] = "\033[45m" ansi["back_magenta"] = "\033[45m"
ansi["back_cyan"] = "\033[46m" ansi["back_cyan"] = "\033[46m"
ansi["back_white"] = "\033[47m" ansi["back_white"] = "\033[47m"
# Formatting Characters # Formatting Characters
ansi["return"] = "\r\n" ansi["return"] = "\r\n"
ansi["tab"] = "\t" ansi["tab"] = "\t"
ansi["space"] = " " ansi["space"] = " "
def parse_ansi(string, strip_ansi=False, strip_formatting=False): def parse_ansi(string, strip_ansi=False, strip_formatting=False):
""" """
Parses a string, subbing color codes as needed. Parses a string, subbing color codes as needed.
""" """
if strip_formatting: if strip_formatting:
char_return = "" char_return = ""
char_tab = "" char_tab = ""
char_space = "" char_space = ""
else: else:
char_return = ansi["return"] char_return = ansi["return"]
char_tab = ansi["tab"] char_tab = ansi["tab"]
char_space = ansi["space"] char_space = ansi["space"]
ansi_subs = [ ansi_subs = [
(r'%r', char_return), (r'%r', char_return),
(r'%t', char_tab), (r'%t', char_tab),
(r'%b', char_space), (r'%b', char_space),
(r'%cf', ansi["blink"]), (r'%cf', ansi["blink"]),
(r'%ci', ansi["inverse"]), (r'%ci', ansi["inverse"]),
(r'%ch', ansi["hilite"]), (r'%ch', ansi["hilite"]),
(r'%cn', ansi["normal"]), (r'%cn', ansi["normal"]),
(r'%cx', ansi["black"]), (r'%cx', ansi["black"]),
(r'%cX', ansi["back_black"]), (r'%cX', ansi["back_black"]),
(r'%cr', ansi["red"]), (r'%cr', ansi["red"]),
(r'%cR', ansi["back_red"]), (r'%cR', ansi["back_red"]),
(r'%cg', ansi["green"]), (r'%cg', ansi["green"]),
(r'%cG', ansi["back_green"]), (r'%cG', ansi["back_green"]),
(r'%cy', ansi["yellow"]), (r'%cy', ansi["yellow"]),
(r'%cY', ansi["back_yellow"]), (r'%cY', ansi["back_yellow"]),
(r'%cb', ansi["blue"]), (r'%cb', ansi["blue"]),
(r'%cB', ansi["back_blue"]), (r'%cB', ansi["back_blue"]),
(r'%cm', ansi["magenta"]), (r'%cm', ansi["magenta"]),
(r'%cM', ansi["back_magenta"]), (r'%cM', ansi["back_magenta"]),
(r'%cc', ansi["cyan"]), (r'%cc', ansi["cyan"]),
(r'%cC', ansi["back_cyan"]), (r'%cC', ansi["back_cyan"]),
(r'%cw', ansi["white"]), (r'%cw', ansi["white"]),
(r'%cW', ansi["back_white"]), (r'%cW', ansi["back_white"]),
] ]
for sub in ansi_subs: for sub in ansi_subs:
p = re.compile(sub[0], re.DOTALL) p = re.compile(sub[0], re.DOTALL)
if strip_ansi: if strip_ansi:
string = p.sub("", string) string = p.sub("", string)
else: else:
string = p.sub(sub[1], string) string = p.sub(sub[1], string)
if strip_ansi: if strip_ansi:
return '%s' % (string) return '%s' % (string)
else: else:
return '%s%s' % (string, ansi["normal"]) return '%s%s' % (string, ansi["normal"])

View file

@ -1,26 +1,26 @@
from django.db import models from django.db import models
class CommandAlias(models.Model): class CommandAlias(models.Model):
""" """
Command aliases. If the player enters the value equal to user_input, the Command aliases. If the player enters the value equal to user_input, the
command denoted by equiv_command is used instead. command denoted by equiv_command is used instead.
""" """
user_input = models.CharField(max_length=50) user_input = models.CharField(max_length=50)
equiv_command = models.CharField(max_length=50) equiv_command = models.CharField(max_length=50)
class Admin: class Admin:
list_display = ('user_input', 'equiv_command',) list_display = ('user_input', 'equiv_command',)
class Meta: class Meta:
verbose_name_plural = "Command aliases" verbose_name_plural = "Command aliases"
ordering = ['user_input'] ordering = ['user_input']
class ConfigValue(models.Model): class ConfigValue(models.Model):
""" """
Experimental new config model. Experimental new config model.
""" """
conf_key = models.CharField(max_length=100) conf_key = models.CharField(max_length=100)
conf_value = models.TextField() conf_value = models.TextField()
class Admin: class Admin:
list_display = ('conf_key', 'conf_value',) list_display = ('conf_key', 'conf_value',)

View file

@ -1,23 +1,23 @@
from django.db import models from django.db import models
class GenericPerm(models.Model): class GenericPerm(models.Model):
""" """
This is merely a container class for some generic permissions that don't This is merely a container class for some generic permissions that don't
fit under a particular module. fit under a particular module.
""" """
class Meta: class Meta:
permissions = ( permissions = (
("announce", "May use @wall to make announcements"), ("announce", "May use @wall to make announcements"),
("boot", "May use @boot to kick players"), ("boot", "May use @boot to kick players"),
("builder", "Can build and modify objects"), ("builder", "Can build and modify objects"),
("chown_all", "Can @chown anything to anyone."), ("chown_all", "Can @chown anything to anyone."),
("free_money", "Has infinite money"), ("free_money", "Has infinite money"),
("long_fingers", "May get/look/examine etc. from a distance"), ("long_fingers", "May get/look/examine etc. from a distance"),
("steal", "May give negative money"), ("steal", "May give negative money"),
("set_hide", "May set themself invisible"), ("set_hide", "May set themself invisible"),
("tel_anywhere", "May @teleport anywhere"), ("tel_anywhere", "May @teleport anywhere"),
("tel_anyone", "May @teleport anything"), ("tel_anyone", "May @teleport anything"),
("see_session_data", "May see detailed player session data"), ("see_session_data", "May see detailed player session data"),
("process_control", "May shutdown/restart/reload the game"), ("process_control", "May shutdown/restart/reload the game"),
("manage_players", "Can change passwords, siteban, etc."), ("manage_players", "Can change passwords, siteban, etc."),
) )

View file

@ -2,39 +2,39 @@ from django.db import models
import ansi import ansi
class HelpEntry(models.Model): class HelpEntry(models.Model):
""" """
A generic help entry. A generic help entry.
""" """
topicname = models.CharField(max_length=255) topicname = models.CharField(max_length=255)
entrytext = models.TextField(blank=True, null=True) entrytext = models.TextField(blank=True, null=True)
staff_only = models.BooleanField(default=0) staff_only = models.BooleanField(default=0)
class Admin: class Admin:
list_display = ('id', 'topicname', 'staff_only') list_display = ('id', 'topicname', 'staff_only')
list_filter = ('staff_only',) list_filter = ('staff_only',)
search_fields = ['entrytext'] search_fields = ['entrytext']
class Meta: class Meta:
verbose_name_plural = "Help entries" verbose_name_plural = "Help entries"
ordering = ['topicname'] ordering = ['topicname']
def __str__(self): def __str__(self):
return self.topicname return self.topicname
def get_topicname(self): def get_topicname(self):
""" """
Returns the topic's name. Returns the topic's name.
""" """
try: try:
return self.topicname return self.topicname
except: except:
return None return None
def get_entrytext_ingame(self): def get_entrytext_ingame(self):
""" """
Gets the entry text for in-game viewing. Gets the entry text for in-game viewing.
""" """
try: try:
return ansi.parse_ansi(self.entrytext) return ansi.parse_ansi(self.entrytext)
except: except:
return None return None

View file

@ -2,43 +2,43 @@ from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
class NewsTopic(models.Model): class NewsTopic(models.Model):
""" """
Represents a news topic. Represents a news topic.
""" """
name = models.CharField(max_length=75, unique=True) name = models.CharField(max_length=75, unique=True)
description = models.TextField(blank=True) description = models.TextField(blank=True)
icon = models.ImageField(upload_to='newstopic_icons', default='newstopic_icons/default.png', blank=True, help_text="Image for the news topic.") icon = models.ImageField(upload_to='newstopic_icons', default='newstopic_icons/default.png', blank=True, help_text="Image for the news topic.")
def __str__(self): def __str__(self):
try: try:
return self.name return self.name
except: except:
return "Invalid" return "Invalid"
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
class Admin: class Admin:
list_display = ('name', 'icon') list_display = ('name', 'icon')
class NewsEntry(models.Model): class NewsEntry(models.Model):
""" """
An individual news entry. An individual news entry.
""" """
author = models.ForeignKey(User, related_name='author') author = models.ForeignKey(User, related_name='author')
title = models.CharField(max_length=255) title = models.CharField(max_length=255)
body = models.TextField() body = models.TextField()
topic = models.ForeignKey(NewsTopic, related_name='newstopic') topic = models.ForeignKey(NewsTopic, related_name='newstopic')
date_posted = models.DateTimeField(auto_now_add=True) date_posted = models.DateTimeField(auto_now_add=True)
def __str__(self): def __str__(self):
return self.title return self.title
class Meta: class Meta:
ordering = ('-date_posted',) ordering = ('-date_posted',)
verbose_name_plural = "News entries" verbose_name_plural = "News entries"
class Admin: class Admin:
list_display = ('title', 'author', 'topic', 'date_posted') list_display = ('title', 'author', 'topic', 'date_posted')
list_filter = ('topic',) list_filter = ('topic',)
search_fields = ['title'] search_fields = ['title']

View file

@ -1,8 +1,8 @@
from django.conf.urls.defaults import * from django.conf.urls.defaults import *
urlpatterns = patterns('apps.news.views', urlpatterns = patterns('apps.news.views',
(r'^show/(?P<entry_id>\d+)/$', 'show_news'), (r'^show/(?P<entry_id>\d+)/$', 'show_news'),
(r'^archive/$', 'news_archive'), (r'^archive/$', 'news_archive'),
(r'^search/$', 'search_form'), (r'^search/$', 'search_form'),
(r'^search/results/$', 'search_results'), (r'^search/results/$', 'search_results'),
) )

View file

@ -2,8 +2,8 @@
This is a very simple news application, with most of the expected features This is a very simple news application, with most of the expected features
like: like:
* News categories/topics * News categories/topics
* Searchable archives * Searchable archives
""" """
from django.shortcuts import render_to_response, get_object_or_404 from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext from django.template import RequestContext
@ -18,109 +18,109 @@ from apps.news.models import NewsTopic, NewsEntry
# The sidebar text to be included as a variable on each page. There's got to # The sidebar text to be included as a variable on each page. There's got to
# be a better, cleaner way to include this on every page. # be a better, cleaner way to include this on every page.
sidebar = """ sidebar = """
<p class='doNotDisplay doNotPrint'>This page&rsquo;s menu:</p> <p class='doNotDisplay doNotPrint'>This page&rsquo;s menu:</p>
<ul id='side-bar'> <ul id='side-bar'>
<li><a href='/news/archive'>News Archive</a></li> <li><a href='/news/archive'>News Archive</a></li>
<li><a href='/news/search'>Search News</a></li> <li><a href='/news/search'>Search News</a></li>
</ul> </ul>
""" """
class SearchForm(forms.Form): class SearchForm(forms.Form):
""" """
Class to represent a news search form under Django's newforms. This is used Class to represent a news search form under Django's newforms. This is used
to validate the input on the search_form view, as well as the search_results to validate the input on the search_form view, as well as the search_results
view when we're picking the query out of GET. This makes searching safe view when we're picking the query out of GET. This makes searching safe
via the search form or by directly inputing values via GET key pairs. via the search form or by directly inputing values via GET key pairs.
""" """
search_terms = forms.CharField(max_length=100, min_length=3, required=True) search_terms = forms.CharField(max_length=100, min_length=3, required=True)
def show_news(request, entry_id): def show_news(request, entry_id):
""" """
Show an individual news entry. Display some basic information along with Show an individual news entry. Display some basic information along with
the title and content. the title and content.
""" """
news_entry = get_object_or_404(NewsEntry, id=entry_id) news_entry = get_object_or_404(NewsEntry, id=entry_id)
pagevars = { pagevars = {
"page_title": "News Entry", "page_title": "News Entry",
"news_entry": news_entry, "news_entry": news_entry,
"sidebar": sidebar "sidebar": sidebar
} }
context_instance = RequestContext(request) context_instance = RequestContext(request)
return render_to_response('news/show_entry.html', pagevars, context_instance) return render_to_response('news/show_entry.html', pagevars, context_instance)
def news_archive(request): def news_archive(request):
""" """
Shows an archive of news entries. Shows an archive of news entries.
TODO: Expand this a bit to allow filtering by month/year. TODO: Expand this a bit to allow filtering by month/year.
""" """
news_entries = NewsEntry.objects.all().order_by('-date_posted') news_entries = NewsEntry.objects.all().order_by('-date_posted')
# TODO: Move this to either settings.py or the SQL configuration. # TODO: Move this to either settings.py or the SQL configuration.
entries_per_page = 15 entries_per_page = 15
pagevars = { pagevars = {
"page_title": "News Archive", "page_title": "News Archive",
"browse_url": "/news/archive", "browse_url": "/news/archive",
"sidebar": sidebar "sidebar": sidebar
} }
return gv_list_detail.object_list(request, news_entries, template_name='news/archive.html', extra_context=pagevars, paginate_by=entries_per_page) return gv_list_detail.object_list(request, news_entries, template_name='news/archive.html', extra_context=pagevars, paginate_by=entries_per_page)
def search_form(request): def search_form(request):
""" """
Render the news search form. Don't handle much validation at all. If the Render the news search form. Don't handle much validation at all. If the
user enters a search term that meets the minimum, send them on their way user enters a search term that meets the minimum, send them on their way
to the results page. to the results page.
""" """
if request.method == 'GET': if request.method == 'GET':
# A GET request was sent to the search page, load the value and # A GET request was sent to the search page, load the value and
# validate it. # validate it.
search_form = SearchForm(request.GET) search_form = SearchForm(request.GET)
if search_form.is_valid(): if search_form.is_valid():
# If the input is good, send them to the results page with the # If the input is good, send them to the results page with the
# query attached in GET variables. # query attached in GET variables.
return HttpResponseRedirect('/news/search/results/?search_terms='+ search_form.cleaned_data['search_terms']) return HttpResponseRedirect('/news/search/results/?search_terms='+ search_form.cleaned_data['search_terms'])
else: else:
# Brand new search, nothing has been sent just yet. # Brand new search, nothing has been sent just yet.
search_form = SearchForm() search_form = SearchForm()
pagevars = { pagevars = {
"page_title": "Search News", "page_title": "Search News",
"search_form": search_form, "search_form": search_form,
"debug": debug, "debug": debug,
"sidebar": sidebar "sidebar": sidebar
} }
context_instance = RequestContext(request) context_instance = RequestContext(request)
return render_to_response('news/search_form.html', pagevars, context_instance) return render_to_response('news/search_form.html', pagevars, context_instance)
def search_results(request): def search_results(request):
""" """
Shows an archive of news entries. Use the generic news browsing template. Shows an archive of news entries. Use the generic news browsing template.
""" """
# TODO: Move this to either settings.py or the SQL configuration. # TODO: Move this to either settings.py or the SQL configuration.
entries_per_page = 15 entries_per_page = 15
# Load the form values from GET to validate against. # Load the form values from GET to validate against.
search_form = SearchForm(request.GET) search_form = SearchForm(request.GET)
# You have to call is_valid() or cleaned_data won't be populated. # You have to call is_valid() or cleaned_data won't be populated.
valid_search = search_form.is_valid() valid_search = search_form.is_valid()
# This is the safe data that we can pass to queries without huge worry of # This is the safe data that we can pass to queries without huge worry of
# badStuff(tm). # badStuff(tm).
cleaned_get = search_form.cleaned_data cleaned_get = search_form.cleaned_data
# Perform searches that match the title and contents. # Perform searches that match the title and contents.
# TODO: Allow the user to specify what to match against and in what # TODO: Allow the user to specify what to match against and in what
# topics/categories. # topics/categories.
news_entries = NewsEntry.objects.filter(Q(title__contains=cleaned_get['search_terms']) | Q(body__contains=cleaned_get['search_terms'])) news_entries = NewsEntry.objects.filter(Q(title__contains=cleaned_get['search_terms']) | Q(body__contains=cleaned_get['search_terms']))
pagevars = { pagevars = {
"page_title": "Search Results", "page_title": "Search Results",
"searchtext": cleaned_get['search_terms'], "searchtext": cleaned_get['search_terms'],
"browse_url": "/news/search/results", "browse_url": "/news/search/results",
"sidebar": sidebar "sidebar": sidebar
} }
return gv_list_detail.object_list(request, news_entries, template_name='news/archive.html', extra_context=pagevars, paginate_by=entries_per_page) return gv_list_detail.object_list(request, news_entries, template_name='news/archive.html', extra_context=pagevars, paginate_by=entries_per_page)

View file

@ -1,5 +1,5 @@
from django.conf.urls.defaults import * from django.conf.urls.defaults import *
urlpatterns = patterns('apps.website.views', urlpatterns = patterns('apps.website.views',
(r'^$', 'page_index'), (r'^$', 'page_index'),
) )

View file

@ -11,47 +11,47 @@ the other applications.
""" """
def page_index(request): def page_index(request):
""" """
Main root page. Main root page.
""" """
# Some misc. configurable stuff. # Some misc. configurable stuff.
# TODO: Move this to either SQL or settings.py based configuration. # TODO: Move this to either SQL or settings.py based configuration.
fpage_player_limit = 4 fpage_player_limit = 4
fpage_news_entries = 2 fpage_news_entries = 2
# A QuerySet of recent news entries. # A QuerySet of recent news entries.
news_entries = NewsEntry.objects.all().order_by('-date_posted')[:fpage_news_entries] news_entries = NewsEntry.objects.all().order_by('-date_posted')[:fpage_news_entries]
# Dictionary containing database statistics. # Dictionary containing database statistics.
objstats = functions_db.object_totals() objstats = functions_db.object_totals()
# A QuerySet of the most recently connected players. # A QuerySet of the most recently connected players.
recent_players = functions_db.get_recently_connected_players()[:fpage_player_limit] recent_players = functions_db.get_recently_connected_players()[:fpage_player_limit]
pagevars = { pagevars = {
"page_title": "Front Page", "page_title": "Front Page",
"news_entries": news_entries, "news_entries": news_entries,
"players_connected_recent": recent_players, "players_connected_recent": recent_players,
"num_players_connected": functions_db.get_connected_players().count(), "num_players_connected": functions_db.get_connected_players().count(),
"num_players_registered": functions_db.num_total_players(), "num_players_registered": functions_db.num_total_players(),
"num_players_connected_recent": functions_db.get_recently_connected_players().count(), "num_players_connected_recent": functions_db.get_recently_connected_players().count(),
"num_players_registered_recent": functions_db.get_recently_created_players().count(), "num_players_registered_recent": functions_db.get_recently_created_players().count(),
"num_players": objstats["players"], "num_players": objstats["players"],
"num_rooms": objstats["rooms"], "num_rooms": objstats["rooms"],
"num_things": objstats["things"], "num_things": objstats["things"],
"num_exits": objstats["exits"], "num_exits": objstats["exits"],
} }
context_instance = RequestContext(request) context_instance = RequestContext(request)
return render_to_response('index.html', pagevars, context_instance) return render_to_response('index.html', pagevars, context_instance)
def to_be_implemented(request): def to_be_implemented(request):
""" """
A notice letting the user know that this particular feature hasn't been A notice letting the user know that this particular feature hasn't been
implemented yet. implemented yet.
""" """
pagevars = { pagevars = {
"page_title": "To Be Implemented...", "page_title": "To Be Implemented...",
} }
context_instance = RequestContext(request) context_instance = RequestContext(request)
return render_to_response('tbi.html', pagevars, context_instance) return render_to_response('tbi.html', pagevars, context_instance)

View file

@ -2,10 +2,10 @@ from django.conf import settings
import gameconf import gameconf
def general_context(request): def general_context(request):
""" """
Returns common Evennia-related context stuff. Returns common Evennia-related context stuff.
""" """
return { return {
'game_name': gameconf.get_configvalue('site_name'), 'game_name': gameconf.get_configvalue('site_name'),
'media_url': settings.MEDIA_URL, 'media_url': settings.MEDIA_URL,
} }

View file

@ -14,245 +14,245 @@ something.
""" """
class UnknownCommand(Exception): class UnknownCommand(Exception):
""" """
Throw this when a user enters an an invalid command. Throw this when a user enters an an invalid command.
""" """
def match_exits(pobject, searchstr): def match_exits(pobject, searchstr):
""" """
See if we can find an input match to exits. See if we can find an input match to exits.
""" """
exits = pobject.get_location().get_contents(filter_type=4) exits = pobject.get_location().get_contents(filter_type=4)
return functions_db.list_search_object_namestr(exits, searchstr, match_type="exact") return functions_db.list_search_object_namestr(exits, searchstr, match_type="exact")
def parse_command(command_string): def parse_command(command_string):
""" """
Tries to handle the most common command strings and returns a dictionary with various data. Tries to handle the most common command strings and returns a dictionary with various data.
Common command types: Common command types:
- Complex: - Complex:
@pemit[/option] <target>[/option]=<data> @pemit[/option] <target>[/option]=<data>
- Simple: - Simple:
look look
look <target> look <target>
I'm not married to either of these terms, but I couldn't think of anything better. If you can, lets change it :) I'm not married to either of these terms, but I couldn't think of anything better. If you can, lets change it :)
The only cases that I haven't handled is if someone enters something like: The only cases that I haven't handled is if someone enters something like:
@pemit <target> <target>/<switch>=<data> @pemit <target> <target>/<switch>=<data>
- Ends up considering both targets as one with a space between them, and the switch as a switch. - Ends up considering both targets as one with a space between them, and the switch as a switch.
@pemit <target>/<switch> <target>=<data> @pemit <target>/<switch> <target>=<data>
- Ends up considering the first target a target, and the second target as part of the switch. - Ends up considering the first target a target, and the second target as part of the switch.
""" """
# Each of the bits of data starts off as None, except for the raw, original # Each of the bits of data starts off as None, except for the raw, original
# command # command
parsed_command = dict( parsed_command = dict(
raw_command=command_string, raw_command=command_string,
data=None, data=None,
original_command=None, original_command=None,
original_targets=None, original_targets=None,
base_command=None, base_command=None,
command_switches=None, command_switches=None,
targets=None, targets=None,
target_switches=None target_switches=None
) )
try: try:
# If we make it past this next statement, then this is what we # If we make it past this next statement, then this is what we
# consider a complex command # consider a complex command
(command_parts, data) = command_string.split('=', 1) (command_parts, data) = command_string.split('=', 1)
parsed_command['data'] = data parsed_command['data'] = data
# First we deal with the command part of the command and break it # First we deal with the command part of the command and break it
# down into the base command, along with switches # down into the base command, along with switches
# If we make it past the next statement, then they must have # If we make it past the next statement, then they must have
# entered a command like: # entered a command like:
# p =<data> # p =<data>
# So we should probably just let it get caught by the ValueError # So we should probably just let it get caught by the ValueError
# again and consider it a simple command # again and consider it a simple command
(total_command, total_targets) = command_parts.split(' ', 1) (total_command, total_targets) = command_parts.split(' ', 1)
parsed_command['original_command'] = total_command parsed_command['original_command'] = total_command
parsed_command['original_targets'] = total_targets parsed_command['original_targets'] = total_targets
split_command = total_command.split('/') split_command = total_command.split('/')
parsed_command['base_command'] = split_command[0] parsed_command['base_command'] = split_command[0]
parsed_command['command_switches'] = split_command[1:] parsed_command['command_switches'] = split_command[1:]
# Now we move onto the target data # Now we move onto the target data
try: try:
# Look for switches- if they give target switches, then we don't # Look for switches- if they give target switches, then we don't
# accept multiple targets # accept multiple targets
(target, switch_string) = total_targets.split('/', 1) (target, switch_string) = total_targets.split('/', 1)
parsed_command['targets'] = [target] parsed_command['targets'] = [target]
parsed_command['target_switches'] = switch_string.split('/') parsed_command['target_switches'] = switch_string.split('/')
except ValueError: except ValueError:
# Alright, no switches, so lets consider multiple targets # Alright, no switches, so lets consider multiple targets
parsed_command['targets'] = total_targets.split() parsed_command['targets'] = total_targets.split()
except ValueError: except ValueError:
# Ok, couldn't find an =, so not a complex command # Ok, couldn't find an =, so not a complex command
try: try:
(command, data) = command_string.split(' ', 1) (command, data) = command_string.split(' ', 1)
parsed_command['base_command'] = command parsed_command['base_command'] = command
parsed_command['data'] = data parsed_command['data'] = data
except ValueError: except ValueError:
# No arguments # No arguments
# ie: # ie:
# - look # - look
parsed_command['base_command'] = command_string parsed_command['base_command'] = command_string
return parsed_command return parsed_command
def handle(cdat): def handle(cdat):
""" """
Use the spliced (list) uinput variable to retrieve the correct Use the spliced (list) uinput variable to retrieve the correct
command, or return an invalid command error. command, or return an invalid command error.
We're basically grabbing the player's command by tacking We're basically grabbing the player's command by tacking
their input on to 'cmd_' and looking it up in the GenCommands their input on to 'cmd_' and looking it up in the GenCommands
class. class.
""" """
session = cdat['session'] session = cdat['session']
server = cdat['server'] server = cdat['server']
try: try:
# TODO: Protect against non-standard characters. # TODO: Protect against non-standard characters.
if cdat['uinput'] == '': if cdat['uinput'] == '':
return
parsed_input = {}
parsed_input['parsed_command'] = parse_command(cdat['uinput'])
# First we split the input up by spaces.
parsed_input['splitted'] = cdat['uinput'].split()
# Now we find the root command chunk (with switches attached).
parsed_input['root_chunk'] = parsed_input['splitted'][0].split('/')
# And now for the actual root command. It's the first entry in root_chunk.
parsed_input['root_cmd'] = parsed_input['root_chunk'][0].lower()
# Keep around the full, raw input in case a command needs it
cdat['raw_input'] = cdat['uinput']
# Now we'll see if the user is using an alias. We do a dictionary lookup,
# if the key (the player's root command) doesn't exist on the dict, we
# don't replace the existing root_cmd. If the key exists, its value
# replaces the previously splitted root_cmd. For example, sa -> say.
alias_list = server.cmd_alias_list
parsed_input['root_cmd'] = alias_list.get(parsed_input['root_cmd'],parsed_input['root_cmd'])
# This will hold the reference to the command's function.
cmd = None
if session.logged_in:
# Store the timestamp of the user's last command.
session.cmd_last = time.time()
# Lets the users get around badly configured NAT timeouts.
if parsed_input['root_cmd'] == 'idle':
return return
# Increment our user's command counter. parsed_input = {}
session.cmd_total += 1 parsed_input['parsed_command'] = parse_command(cdat['uinput'])
# Player-visible idle time, not used in idle timeout calcs.
session.cmd_last_visible = time.time()
# Just in case. Prevents some really funky-case crashes. # First we split the input up by spaces.
if len(parsed_input['root_cmd']) == 0: parsed_input['splitted'] = cdat['uinput'].split()
raise UnknownCommand # Now we find the root command chunk (with switches attached).
parsed_input['root_chunk'] = parsed_input['splitted'][0].split('/')
# And now for the actual root command. It's the first entry in root_chunk.
parsed_input['root_cmd'] = parsed_input['root_chunk'][0].lower()
# Keep around the full, raw input in case a command needs it
cdat['raw_input'] = cdat['uinput']
# Shortened say alias. # Now we'll see if the user is using an alias. We do a dictionary lookup,
if parsed_input['root_cmd'][0] == '"': # if the key (the player's root command) doesn't exist on the dict, we
parsed_input['splitted'].insert(0, "say") # don't replace the existing root_cmd. If the key exists, its value
parsed_input['splitted'][1] = parsed_input['splitted'][1][1:] # replaces the previously splitted root_cmd. For example, sa -> say.
parsed_input['root_cmd'] = 'say' alias_list = server.cmd_alias_list
# Shortened pose alias. parsed_input['root_cmd'] = alias_list.get(parsed_input['root_cmd'],parsed_input['root_cmd'])
elif parsed_input['root_cmd'][0] == ':':
parsed_input['splitted'].insert(0, "pose")
parsed_input['splitted'][1] = parsed_input['splitted'][1][1:]
parsed_input['root_cmd'] = 'pose'
# Pose without space alias.
elif parsed_input['root_cmd'][0] == ';':
parsed_input['splitted'].insert(0, "pose/nospace")
parsed_input['root_chunk'] = ['pose', 'nospace']
parsed_input['splitted'][1] = parsed_input['splitted'][1][1:]
parsed_input['root_cmd'] = 'pose'
# Channel alias match.
elif functions_comsys.plr_has_channel(session,
parsed_input['root_cmd'],
alias_search=True,
return_muted=True):
calias = parsed_input['root_cmd']
cname = functions_comsys.plr_cname_from_alias(session, calias)
cmessage = ' '.join(parsed_input['splitted'][1:])
if cmessage == "who":
functions_comsys.msg_cwho(session, cname)
return
elif cmessage == "on":
functions_comsys.plr_chan_on(session, calias)
return
elif cmessage == "off":
functions_comsys.plr_chan_off(session, calias)
return
elif cmessage == "last":
functions_comsys.msg_chan_hist(session, cname)
return
second_arg = "%s=%s" % (cname, cmessage)
parsed_input['splitted'] = ["@cemit/sendername", second_arg]
parsed_input['root_chunk'] = ['@cemit', 'sendername', 'quiet']
parsed_input['root_cmd'] = '@cemit'
# Get the command's function reference (Or False) # This will hold the reference to the command's function.
cmdtuple = cmdtable.return_cmdtuple(parsed_input['root_cmd']) cmd = None
if cmdtuple:
# If there is a permissions element to the entry, check perms.
if cmdtuple[1]:
if not session.get_pobject().user_has_perm_list(cmdtuple[1]):
session.msg(defines_global.NOPERMS_MSG)
return
# If flow reaches this point, user has perms and command is ready.
cmd = cmdtuple[0]
else:
# Not logged in, look through the unlogged-in command table.
cmdtuple = cmdtable.return_cmdtuple(parsed_input['root_cmd'], unlogged_cmd=True)
if cmdtuple:
cmd = cmdtuple[0]
# Debugging stuff. if session.logged_in:
#session.msg("ROOT : %s" % (parsed_input['root_cmd'],)) # Store the timestamp of the user's last command.
#session.msg("SPLIT: %s" % (parsed_input['splitted'],)) session.cmd_last = time.time()
if callable(cmd):
cdat['uinput'] = parsed_input
try:
cmd(cdat)
except:
session.msg("Untrapped error, please file a bug report:\n%s" % (format_exc(),))
functions_general.log_errmsg("Untrapped error, evoker %s: %s" %
(session, format_exc()))
return
if session.logged_in: # Lets the users get around badly configured NAT timeouts.
# If we're not logged in, don't check exits. if parsed_input['root_cmd'] == 'idle':
pobject = session.get_pobject() return
exit_matches = match_exits(pobject, ' '.join(parsed_input['splitted']))
if exit_matches: # Increment our user's command counter.
targ_exit = exit_matches[0] session.cmd_total += 1
if targ_exit.get_home(): # Player-visible idle time, not used in idle timeout calcs.
cdat['uinput'] = parsed_input session.cmd_last_visible = time.time()
# SCRIPT: See if the player can traverse the exit # Just in case. Prevents some really funky-case crashes.
if not targ_exit.get_scriptlink().default_lock({ if len(parsed_input['root_cmd']) == 0:
"pobject": pobject raise UnknownCommand
}):
session.msg("You can't traverse that exit.") # Shortened say alias.
else: if parsed_input['root_cmd'][0] == '"':
pobject.move_to(targ_exit.get_home()) parsed_input['splitted'].insert(0, "say")
session.execute_cmd("look") parsed_input['splitted'][1] = parsed_input['splitted'][1][1:]
else: parsed_input['root_cmd'] = 'say'
session.msg("That exit leads to nowhere.") # Shortened pose alias.
elif parsed_input['root_cmd'][0] == ':':
parsed_input['splitted'].insert(0, "pose")
parsed_input['splitted'][1] = parsed_input['splitted'][1][1:]
parsed_input['root_cmd'] = 'pose'
# Pose without space alias.
elif parsed_input['root_cmd'][0] == ';':
parsed_input['splitted'].insert(0, "pose/nospace")
parsed_input['root_chunk'] = ['pose', 'nospace']
parsed_input['splitted'][1] = parsed_input['splitted'][1][1:]
parsed_input['root_cmd'] = 'pose'
# Channel alias match.
elif functions_comsys.plr_has_channel(session,
parsed_input['root_cmd'],
alias_search=True,
return_muted=True):
calias = parsed_input['root_cmd']
cname = functions_comsys.plr_cname_from_alias(session, calias)
cmessage = ' '.join(parsed_input['splitted'][1:])
if cmessage == "who":
functions_comsys.msg_cwho(session, cname)
return
elif cmessage == "on":
functions_comsys.plr_chan_on(session, calias)
return
elif cmessage == "off":
functions_comsys.plr_chan_off(session, calias)
return
elif cmessage == "last":
functions_comsys.msg_chan_hist(session, cname)
return
second_arg = "%s=%s" % (cname, cmessage)
parsed_input['splitted'] = ["@cemit/sendername", second_arg]
parsed_input['root_chunk'] = ['@cemit', 'sendername', 'quiet']
parsed_input['root_cmd'] = '@cemit'
# Get the command's function reference (Or False)
cmdtuple = cmdtable.return_cmdtuple(parsed_input['root_cmd'])
if cmdtuple:
# If there is a permissions element to the entry, check perms.
if cmdtuple[1]:
if not session.get_pobject().user_has_perm_list(cmdtuple[1]):
session.msg(defines_global.NOPERMS_MSG)
return
# If flow reaches this point, user has perms and command is ready.
cmd = cmdtuple[0]
else:
# Not logged in, look through the unlogged-in command table.
cmdtuple = cmdtable.return_cmdtuple(parsed_input['root_cmd'], unlogged_cmd=True)
if cmdtuple:
cmd = cmdtuple[0]
# Debugging stuff.
#session.msg("ROOT : %s" % (parsed_input['root_cmd'],))
#session.msg("SPLIT: %s" % (parsed_input['splitted'],))
if callable(cmd):
cdat['uinput'] = parsed_input
try:
cmd(cdat)
except:
session.msg("Untrapped error, please file a bug report:\n%s" % (format_exc(),))
functions_general.log_errmsg("Untrapped error, evoker %s: %s" %
(session, format_exc()))
return return
# If we reach this point, we haven't matched anything. if session.logged_in:
raise UnknownCommand # If we're not logged in, don't check exits.
pobject = session.get_pobject()
exit_matches = match_exits(pobject, ' '.join(parsed_input['splitted']))
if exit_matches:
targ_exit = exit_matches[0]
if targ_exit.get_home():
cdat['uinput'] = parsed_input
# SCRIPT: See if the player can traverse the exit
if not targ_exit.get_scriptlink().default_lock({
"pobject": pobject
}):
session.msg("You can't traverse that exit.")
else:
pobject.move_to(targ_exit.get_home())
session.execute_cmd("look")
else:
session.msg("That exit leads to nowhere.")
return
except UnknownCommand: # If we reach this point, we haven't matched anything.
session.msg("Huh? (Type \"help\" for help.)") raise UnknownCommand
except UnknownCommand:
session.msg("Huh? (Type \"help\" for help.)")

View file

@ -18,73 +18,73 @@ permissions tuple.
""" """
# -- Unlogged-in Command Table -- # -- Unlogged-in Command Table --
# Command Name Command Function Privilege Tuple # Command Name Command Function Privilege Tuple
uncon_ctable = { uncon_ctable = {
"connect": (commands.unloggedin.cmd_connect, None), "connect": (commands.unloggedin.cmd_connect, None),
"create": (commands.unloggedin.cmd_create, None), "create": (commands.unloggedin.cmd_create, None),
"quit": (commands.unloggedin.cmd_quit, None), "quit": (commands.unloggedin.cmd_quit, None),
} }
# -- Command Table -- # -- Command Table --
# Command Name Command Function Privilege Tuple # Command Name Command Function Privilege Tuple
ctable = { ctable = {
"addcom": (commands.comsys.cmd_addcom, None), "addcom": (commands.comsys.cmd_addcom, None),
"comlist": (commands.comsys.cmd_comlist, None), "comlist": (commands.comsys.cmd_comlist, None),
"delcom": (commands.comsys.cmd_delcom, None), "delcom": (commands.comsys.cmd_delcom, None),
"drop": (commands.general.cmd_drop, None), "drop": (commands.general.cmd_drop, None),
"examine": (commands.general.cmd_examine, None), "examine": (commands.general.cmd_examine, None),
"get": (commands.general.cmd_get, None), "get": (commands.general.cmd_get, None),
"help": (commands.general.cmd_help, None), "help": (commands.general.cmd_help, None),
"idle": (commands.general.cmd_idle, None), "idle": (commands.general.cmd_idle, None),
"inventory": (commands.general.cmd_inventory, None), "inventory": (commands.general.cmd_inventory, None),
"look": (commands.general.cmd_look, None), "look": (commands.general.cmd_look, None),
"page": (commands.general.cmd_page, None), "page": (commands.general.cmd_page, None),
"pose": (commands.general.cmd_pose, None), "pose": (commands.general.cmd_pose, None),
"quit": (commands.general.cmd_quit, None), "quit": (commands.general.cmd_quit, None),
"say": (commands.general.cmd_say, None), "say": (commands.general.cmd_say, None),
"time": (commands.general.cmd_time, None), "time": (commands.general.cmd_time, None),
"uptime": (commands.general.cmd_uptime, None), "uptime": (commands.general.cmd_uptime, None),
"version": (commands.general.cmd_version, None), "version": (commands.general.cmd_version, None),
"who": (commands.general.cmd_who, None), "who": (commands.general.cmd_who, None),
"@alias": (commands.objmanip.cmd_alias, None), "@alias": (commands.objmanip.cmd_alias, None),
"@boot": (commands.privileged.cmd_boot, ("genperms.manage_players")), "@boot": (commands.privileged.cmd_boot, ("genperms.manage_players")),
"@ccreate": (commands.comsys.cmd_ccreate, ("objects.add_commchannel")), "@ccreate": (commands.comsys.cmd_ccreate, ("objects.add_commchannel")),
"@cdestroy": (commands.comsys.cmd_cdestroy, ("objects.delete_commchannel")), "@cdestroy": (commands.comsys.cmd_cdestroy, ("objects.delete_commchannel")),
"@cemit": (commands.comsys.cmd_cemit, None), "@cemit": (commands.comsys.cmd_cemit, None),
"@clist": (commands.comsys.cmd_clist, None), "@clist": (commands.comsys.cmd_clist, None),
"@create": (commands.objmanip.cmd_create, ("genperms.builder")), "@create": (commands.objmanip.cmd_create, ("genperms.builder")),
"@describe": (commands.objmanip.cmd_description, None), "@describe": (commands.objmanip.cmd_description, None),
"@destroy": (commands.objmanip.cmd_destroy, ("genperms.builder")), "@destroy": (commands.objmanip.cmd_destroy, ("genperms.builder")),
"@dig": (commands.objmanip.cmd_dig, ("genperms.builder")), "@dig": (commands.objmanip.cmd_dig, ("genperms.builder")),
"@emit": (commands.general.cmd_emit, ("genperms.announce")), "@emit": (commands.general.cmd_emit, ("genperms.announce")),
# "@pemit": (commands.general.cmd_pemit, None), # "@pemit": (commands.general.cmd_pemit, None),
"@find": (commands.objmanip.cmd_find, ("genperms.builder")), "@find": (commands.objmanip.cmd_find, ("genperms.builder")),
"@link": (commands.objmanip.cmd_link, ("genperms.builder")), "@link": (commands.objmanip.cmd_link, ("genperms.builder")),
"@list": (commands.info.cmd_list, ("genperms.process_control")), "@list": (commands.info.cmd_list, ("genperms.process_control")),
"@name": (commands.objmanip.cmd_name, None), "@name": (commands.objmanip.cmd_name, None),
"@nextfree": (commands.objmanip.cmd_nextfree, ("genperms.builder")), "@nextfree": (commands.objmanip.cmd_nextfree, ("genperms.builder")),
"@newpassword": (commands.privileged.cmd_newpassword, ("genperms.manage_players")), "@newpassword": (commands.privileged.cmd_newpassword, ("genperms.manage_players")),
"@open": (commands.objmanip.cmd_open, ("genperms.builder")), "@open": (commands.objmanip.cmd_open, ("genperms.builder")),
"@password": (commands.general.cmd_password, None), "@password": (commands.general.cmd_password, None),
"@ps": (commands.info.cmd_ps, ("genperms.process_control")), "@ps": (commands.info.cmd_ps, ("genperms.process_control")),
"@reload": (commands.privileged.cmd_reload, ("genperms.process_control")), "@reload": (commands.privileged.cmd_reload, ("genperms.process_control")),
"@set": (commands.objmanip.cmd_set, None), "@set": (commands.objmanip.cmd_set, None),
"@shutdown": (commands.privileged.cmd_shutdown, ("genperms.process_control")), "@shutdown": (commands.privileged.cmd_shutdown, ("genperms.process_control")),
"@stats": (commands.info.cmd_stats, None), "@stats": (commands.info.cmd_stats, None),
"@teleport": (commands.objmanip.cmd_teleport, ("genperms.builder")), "@teleport": (commands.objmanip.cmd_teleport, ("genperms.builder")),
"@unlink": (commands.objmanip.cmd_unlink, ("genperms.builder")), "@unlink": (commands.objmanip.cmd_unlink, ("genperms.builder")),
"@wall": (commands.general.cmd_wall, ("genperms.announce")), "@wall": (commands.general.cmd_wall, ("genperms.announce")),
"@wipe": (commands.objmanip.cmd_wipe, None), "@wipe": (commands.objmanip.cmd_wipe, None),
} }
def return_cmdtuple(func_name, unlogged_cmd=False): def return_cmdtuple(func_name, unlogged_cmd=False):
""" """
Returns a reference to the command's tuple. If there are no matches, Returns a reference to the command's tuple. If there are no matches,
returns false. returns false.
""" """
if not unlogged_cmd: if not unlogged_cmd:
cfunc = ctable.get(func_name, False) cfunc = ctable.get(func_name, False)
else: else:
cfunc = uncon_ctable.get(func_name, False) cfunc = uncon_ctable.get(func_name, False)
return cfunc return cfunc

View file

@ -13,281 +13,281 @@ now.
""" """
def cmd_addcom(cdat): def cmd_addcom(cdat):
""" """
addcom addcom
Adds an alias for a channel. Adds an alias for a channel.
addcom foo=Bar addcom foo=Bar
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = cdat['server']
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
if len(args) == 0: if len(args) == 0:
session.msg("You need to specify a channel alias and name.") session.msg("You need to specify a channel alias and name.")
return return
eq_args = args[0].split('=') eq_args = args[0].split('=')
if len(eq_args) < 2: if len(eq_args) < 2:
session.msg("You need to specify a channel name.") session.msg("You need to specify a channel name.")
return return
chan_alias = eq_args[0] chan_alias = eq_args[0]
chan_name = eq_args[1] chan_name = eq_args[1]
if len(chan_name) == 0: if len(chan_name) == 0:
session.msg("You need to specify a channel name.") session.msg("You need to specify a channel name.")
return return
if chan_alias in session.channels_subscribed: if chan_alias in session.channels_subscribed:
session.msg("You are already on that channel.") session.msg("You are already on that channel.")
return return
name_matches = functions_comsys.cname_search(chan_name, exact=True) name_matches = functions_comsys.cname_search(chan_name, exact=True)
if name_matches: if name_matches:
chan_name_parsed = name_matches[0].get_name() chan_name_parsed = name_matches[0].get_name()
session.msg("You join %s, with an alias of %s." % \ session.msg("You join %s, with an alias of %s." % \
(chan_name_parsed, chan_alias)) (chan_name_parsed, chan_alias))
functions_comsys.plr_set_channel(session, chan_alias, chan_name_parsed, True) functions_comsys.plr_set_channel(session, chan_alias, chan_name_parsed, True)
# Announce the user's joining. # Announce the user's joining.
join_msg = "[%s] %s has joined the channel." % \ join_msg = "[%s] %s has joined the channel." % \
(chan_name_parsed, pobject.get_name(show_dbref=False)) (chan_name_parsed, pobject.get_name(show_dbref=False))
functions_comsys.send_cmessage(chan_name_parsed, join_msg) functions_comsys.send_cmessage(chan_name_parsed, join_msg)
else: else:
session.msg("Could not find channel %s." % (chan_name,)) session.msg("Could not find channel %s." % (chan_name,))
def cmd_delcom(cdat): def cmd_delcom(cdat):
""" """
delcom delcom
Removes the specified alias to a channel. If this is the last alias, Removes the specified alias to a channel. If this is the last alias,
the user is effectively removed from the channel. the user is effectively removed from the channel.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
uinput= cdat['uinput']['splitted'] uinput= cdat['uinput']['splitted']
chan_alias = ' '.join(uinput[1:]) chan_alias = ' '.join(uinput[1:])
if len(chan_alias) == 0: if len(chan_alias) == 0:
session.msg("You must specify a channel alias.") session.msg("You must specify a channel alias.")
return return
if chan_alias not in session.channels_subscribed: if chan_alias not in session.channels_subscribed:
session.msg("You are not on that channel.") session.msg("You are not on that channel.")
return return
chan_name = session.channels_subscribed[chan_alias][0] chan_name = session.channels_subscribed[chan_alias][0]
session.msg("You have left %s." % (chan_name,)) session.msg("You have left %s." % (chan_name,))
functions_comsys.plr_del_channel(session, chan_alias) functions_comsys.plr_del_channel(session, chan_alias)
# Announce the user's leaving. # Announce the user's leaving.
leave_msg = "[%s] %s has left the channel." % \ leave_msg = "[%s] %s has left the channel." % \
(chan_name, pobject.get_name(show_dbref=False)) (chan_name, pobject.get_name(show_dbref=False))
functions_comsys.send_cmessage(chan_name, leave_msg) functions_comsys.send_cmessage(chan_name, leave_msg)
def cmd_comlist(cdat): def cmd_comlist(cdat):
""" """
Lists the channels a user is subscribed to. Lists the channels a user is subscribed to.
""" """
session = cdat['session'] session = cdat['session']
session.msg("Alias Channel Status") session.msg("Alias Channel Status")
for chan in session.channels_subscribed: for chan in session.channels_subscribed:
if session.channels_subscribed[chan][1]: if session.channels_subscribed[chan][1]:
chan_on = "On" chan_on = "On"
else: else:
chan_on = "Off" chan_on = "Off"
session.msg("%-9.9s %-19.19s %s" % session.msg("%-9.9s %-19.19s %s" %
(chan, session.channels_subscribed[chan][0], chan_on)) (chan, session.channels_subscribed[chan][0], chan_on))
session.msg("-- End of comlist --") session.msg("-- End of comlist --")
def cmd_allcom(cdat): def cmd_allcom(cdat):
""" """
allcom allcom
Allows the user to universally turn off or on all channels they are on, Allows the user to universally turn off or on all channels they are on,
as well as perform a "who" for all channels they are on. as well as perform a "who" for all channels they are on.
""" """
pass pass
def cmd_clearcom(cdat): def cmd_clearcom(cdat):
""" """
clearcom clearcom
Effectively runs delcom on all channels the user is on. It will remove their aliases, Effectively runs delcom on all channels the user is on. It will remove their aliases,
remove them from the channel, and clear any titles they have set. remove them from the channel, and clear any titles they have set.
""" """
pass pass
def cmd_clist(cdat): def cmd_clist(cdat):
""" """
@clist @clist
Lists all available channels on the game. Lists all available channels on the game.
""" """
session = cdat['session'] session = cdat['session']
session.msg("** Channel Owner Description") session.msg("** Channel Owner Description")
for chan in functions_comsys.get_all_channels(): for chan in functions_comsys.get_all_channels():
session.msg("%s%s %-13.13s %-15.15s %-45.45s" % session.msg("%s%s %-13.13s %-15.15s %-45.45s" %
('-', '-', chan.get_name(), chan.get_owner().get_name(), 'No Description')) ('-', '-', chan.get_name(), chan.get_owner().get_name(), 'No Description'))
session.msg("-- End of Channel List --") session.msg("-- End of Channel List --")
def cmd_cdestroy(cdat): def cmd_cdestroy(cdat):
""" """
@cdestroy @cdestroy
Destroys a channel. Destroys a channel.
""" """
session = cdat['session'] session = cdat['session']
uinput= cdat['uinput']['splitted'] uinput= cdat['uinput']['splitted']
cname = ' '.join(uinput[1:]) cname = ' '.join(uinput[1:])
if cname == '': if cname == '':
session.msg("You must supply a name!") session.msg("You must supply a name!")
return return
name_matches = functions_comsys.cname_search(cname, exact=True) name_matches = functions_comsys.cname_search(cname, exact=True)
if not name_matches: if not name_matches:
session.msg("Could not find channel %s." % (cname,)) session.msg("Could not find channel %s." % (cname,))
else: else:
session.msg("Channel %s destroyed." % (name_matches[0],)) session.msg("Channel %s destroyed." % (name_matches[0],))
name_matches.delete() name_matches.delete()
def cmd_cset(cdat): def cmd_cset(cdat):
""" """
@cset @cset
Sets various flags on a channel. Sets various flags on a channel.
""" """
pass pass
def cmd_ccharge(cdat): def cmd_ccharge(cdat):
""" """
@ccharge @ccharge
Sets the cost to transmit over a channel. Default is free. Sets the cost to transmit over a channel. Default is free.
""" """
pass pass
def cmd_cboot(cdat): def cmd_cboot(cdat):
""" """
@cboot @cboot
Kicks a player or object from the channel. Kicks a player or object from the channel.
""" """
pass pass
def cmd_cemit(cdat): def cmd_cemit(cdat):
""" """
@cemit @cemit
@cemit/noheader <message> @cemit/noheader <message>
@cemit/sendername <message> @cemit/sendername <message>
Allows the user to send a message over a channel as long as Allows the user to send a message over a channel as long as
they own or control it. It does not show the user's name unless they they own or control it. It does not show the user's name unless they
provide the /sendername switch. provide the /sendername switch.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
server = cdat['server'] server = cdat['server']
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
switches = cdat['uinput']['root_chunk'][1:] switches = cdat['uinput']['root_chunk'][1:]
if len(args) == 0: if len(args) == 0:
session.msg("Channel emit what?") session.msg("Channel emit what?")
return return
# Combine the arguments into one string, split it by equal signs into # Combine the arguments into one string, split it by equal signs into
# channel (entry 0 in the list), and message (entry 1 and above). # channel (entry 0 in the list), and message (entry 1 and above).
eq_args = ' '.join(args).split('=') eq_args = ' '.join(args).split('=')
cname = eq_args[0] cname = eq_args[0]
cmessage = ' '.join(eq_args[1:]) cmessage = ' '.join(eq_args[1:])
if len(eq_args) != 2: if len(eq_args) != 2:
session.msg("You must provide a channel name and a message to emit.") session.msg("You must provide a channel name and a message to emit.")
return return
if len(cname) == 0: if len(cname) == 0:
session.msg("You must provide a channel name to emit to.") session.msg("You must provide a channel name to emit to.")
return return
if len(cmessage) == 0: if len(cmessage) == 0:
session.msg("You must provide a message to emit.") session.msg("You must provide a message to emit.")
return return
name_matches = functions_comsys.cname_search(cname, exact=True) name_matches = functions_comsys.cname_search(cname, exact=True)
try: try:
# Safety first, kids! # Safety first, kids!
cname_parsed = name_matches[0].get_name() cname_parsed = name_matches[0].get_name()
except: except:
session.msg("Could not find channel %s." % (cname,)) session.msg("Could not find channel %s." % (cname,))
return return
if "noheader" in switches: if "noheader" in switches:
if not pobject.user_has_perm("objects.emit_commchannel"): if not pobject.user_has_perm("objects.emit_commchannel"):
session.msg(defines_global.NOPERMS_MSG)
return
final_cmessage = cmessage
else:
if "sendername" in switches:
if not functions_comsys.plr_has_channel(session, cname_parsed, return_muted=False):
session.msg("You must be on %s to do that." % (cname_parsed,))
return
final_cmessage = "[%s] %s: %s" % (cname_parsed, pobject.get_name(show_dbref=False), cmessage)
else:
if not pobject.user_has_perm("objects.emit_commchannel"):
session.msg(defines_global.NOPERMS_MSG) session.msg(defines_global.NOPERMS_MSG)
return return
final_cmessage = "[%s] %s" % (cname_parsed, cmessage) final_cmessage = cmessage
else:
if "sendername" in switches:
if not functions_comsys.plr_has_channel(session, cname_parsed, return_muted=False):
session.msg("You must be on %s to do that." % (cname_parsed,))
return
final_cmessage = "[%s] %s: %s" % (cname_parsed, pobject.get_name(show_dbref=False), cmessage)
else:
if not pobject.user_has_perm("objects.emit_commchannel"):
session.msg(defines_global.NOPERMS_MSG)
return
final_cmessage = "[%s] %s" % (cname_parsed, cmessage)
if not "quiet" in switches: if not "quiet" in switches:
session.msg("Sent - %s" % (name_matches[0],)) session.msg("Sent - %s" % (name_matches[0],))
functions_comsys.send_cmessage(cname_parsed, final_cmessage) functions_comsys.send_cmessage(cname_parsed, final_cmessage)
def cmd_cwho(cdat): def cmd_cwho(cdat):
""" """
@cwho @cwho
Displays the name, status and object type for a given channel. Displays the name, status and object type for a given channel.
Adding /all after the channel name will list disconnected players Adding /all after the channel name will list disconnected players
as well. as well.
""" """
pass pass
def cmd_ccreate(cdat): def cmd_ccreate(cdat):
""" """
@ccreate @ccreate
Creates a new channel with the invoker being the default owner. Creates a new channel with the invoker being the default owner.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
uinput= cdat['uinput']['splitted'] uinput= cdat['uinput']['splitted']
cname = ' '.join(uinput[1:]) cname = ' '.join(uinput[1:])
if cname == '': if cname == '':
session.msg("You must supply a name!") session.msg("You must supply a name!")
return return
name_matches = functions_comsys.cname_search(cname, exact=True) name_matches = functions_comsys.cname_search(cname, exact=True)
if name_matches: if name_matches:
session.msg("A channel with that name already exists.") session.msg("A channel with that name already exists.")
else: else:
# Create and set the object up. # Create and set the object up.
cdat = {"name": cname, "owner": pobject} cdat = {"name": cname, "owner": pobject}
new_chan = functions_comsys.create_channel(cdat) new_chan = functions_comsys.create_channel(cdat)
session.msg("Channel %s created." % (new_chan.get_name(),)) session.msg("Channel %s created." % (new_chan.get_name(),))
def cmd_cchown(cdat): def cmd_cchown(cdat):
""" """
@cchown @cchown
Changes the owner of a channel. Changes the owner of a channel.
""" """
pass pass

View file

@ -1,70 +1,70 @@
import gameconf import gameconf
if not gameconf.host_os_is('nt'): if not gameconf.host_os_is('nt'):
# Don't import the resource module if the host OS is Windows. # Don't import the resource module if the host OS is Windows.
import resource import resource
import os import os
import functions_db import functions_db
import scheduler import scheduler
def cmd_list(cdat): def cmd_list(cdat):
""" """
Shows some game related information. Shows some game related information.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
argstr = ''.join(args) argstr = ''.join(args)
msg_invalid = "Unknown option. Use one of: commands, flags, process" msg_invalid = "Unknown option. Use one of: commands, flags, process"
if len(argstr) == 0: if len(argstr) == 0:
session.msg(msg_invalid) session.msg(msg_invalid)
elif argstr == "commands": elif argstr == "commands":
session.msg('Commands: '+ ' '.join(session.server.command_list())) session.msg('Commands: '+ ' '.join(session.server.command_list()))
elif argstr == "process": elif argstr == "process":
if not gameconf.host_os_is('nt'): if not gameconf.host_os_is('nt'):
loadvg = os.getloadavg() loadvg = os.getloadavg()
psize = resource.getpagesize() psize = resource.getpagesize()
rusage = resource.getrusage(resource.RUSAGE_SELF) rusage = resource.getrusage(resource.RUSAGE_SELF)
session.msg("Process ID: %10d %10d bytes per page" % (os.getpid(), psize)) session.msg("Process ID: %10d %10d bytes per page" % (os.getpid(), psize))
session.msg("Time used: %10d user %10d sys" % (rusage[0],rusage[1])) session.msg("Time used: %10d user %10d sys" % (rusage[0],rusage[1]))
session.msg("Integral mem:%10d shared %10d private%10d stack" % (rusage[3], rusage[4], rusage[5])) session.msg("Integral mem:%10d shared %10d private%10d stack" % (rusage[3], rusage[4], rusage[5]))
session.msg("Max res mem: %10d pages %10d bytes" % (rusage[2],rusage[2] * psize)) session.msg("Max res mem: %10d pages %10d bytes" % (rusage[2],rusage[2] * psize))
session.msg("Page faults: %10d hard %10d soft %10d swapouts" % (rusage[7], rusage[6], rusage[8])) session.msg("Page faults: %10d hard %10d soft %10d swapouts" % (rusage[7], rusage[6], rusage[8]))
session.msg("Disk I/O: %10d reads %10d writes" % (rusage[9], rusage[10])) session.msg("Disk I/O: %10d reads %10d writes" % (rusage[9], rusage[10]))
session.msg("Network I/O: %10d in %10d out" % (rusage[12], rusage[11])) session.msg("Network I/O: %10d in %10d out" % (rusage[12], rusage[11]))
session.msg("Context swi: %10d vol %10d forced %10d sigs" % (rusage[14], rusage[15], rusage[13])) session.msg("Context swi: %10d vol %10d forced %10d sigs" % (rusage[14], rusage[15], rusage[13]))
else: else:
session.msg("Feature not available on Windows.") session.msg("Feature not available on Windows.")
return return
elif argstr == "flags": elif argstr == "flags":
session.msg("Flags: "+" ".join(defines_global.SERVER_FLAGS)) session.msg("Flags: "+" ".join(defines_global.SERVER_FLAGS))
else: else:
session.msg(msg_invalid) session.msg(msg_invalid)
def cmd_ps(cdat): def cmd_ps(cdat):
""" """
Shows the process/event table. Shows the process/event table.
""" """
session = cdat['session'] session = cdat['session']
session.msg("-- Interval Events --") session.msg("-- Interval Events --")
for event in scheduler.schedule: for event in scheduler.schedule:
session.msg(" [%d/%d] %s" % (scheduler.get_event_nextfire(event), session.msg(" [%d/%d] %s" % (scheduler.get_event_nextfire(event),
scheduler.get_event_interval(event), scheduler.get_event_interval(event),
scheduler.get_event_description(event))) scheduler.get_event_description(event)))
session.msg("Totals: %d interval events" % (len(scheduler.schedule),)) session.msg("Totals: %d interval events" % (len(scheduler.schedule),))
def cmd_stats(cdat): def cmd_stats(cdat):
""" """
Shows stats about the database. Shows stats about the database.
4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage) 4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage)
""" """
session = cdat['session'] session = cdat['session']
stats_dict = functions_db.object_totals() stats_dict = functions_db.object_totals()
session.msg("%d objects = %d rooms, %d exits, %d things, %d players. (%d garbage)" % (stats_dict["objects"], session.msg("%d objects = %d rooms, %d exits, %d things, %d players. (%d garbage)" % (stats_dict["objects"],
stats_dict["rooms"], stats_dict["rooms"],
stats_dict["exits"], stats_dict["exits"],
stats_dict["things"], stats_dict["things"],
stats_dict["players"], stats_dict["players"],
stats_dict["garbage"])) stats_dict["garbage"]))

View file

@ -9,122 +9,122 @@ are generally @-prefixed commands, but there are exceptions.
""" """
def cmd_reload(cdat): def cmd_reload(cdat):
""" """
Reloads all modules. Reloads all modules.
""" """
session = cdat['session'] session = cdat['session']
server = session.server.reload(session) server = session.server.reload(session)
def cmd_boot(cdat): def cmd_boot(cdat):
""" """
Boot a player object from the server. Boot a player object from the server.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
eq_args = ' '.join(args).split('=') eq_args = ' '.join(args).split('=')
searchstring = ''.join(eq_args[0]) searchstring = ''.join(eq_args[0])
switches = cdat['uinput']['root_chunk'][1:] switches = cdat['uinput']['root_chunk'][1:]
switch_quiet = False switch_quiet = False
switch_port = False switch_port = False
if not pobject.is_staff(): if not pobject.is_staff():
session.msg("You do not have permission to do that.") session.msg("You do not have permission to do that.")
return return
if "quiet" in switches: if "quiet" in switches:
switch_quiet = True switch_quiet = True
if "port" in switches: if "port" in switches:
switch_port = True switch_port = True
if len(args) == 0: if len(args) == 0:
session.msg("Who would you like to boot?") session.msg("Who would you like to boot?")
return return
else: else:
boot_list = [] boot_list = []
if switch_port: if switch_port:
sessions = session_mgr.get_session_list(True) sessions = session_mgr.get_session_list(True)
for sess in sessions: for sess in sessions:
if sess.getClientAddress()[1] == int(searchstring): if sess.getClientAddress()[1] == int(searchstring):
boot_list.append(sess) boot_list.append(sess)
# We're done here # We're done here
break break
else: else:
# Grab the objects that match # Grab the objects that match
objs = functions_db.global_object_name_search(searchstring) objs = functions_db.global_object_name_search(searchstring)
if len(objs) < 1: if len(objs) < 1:
session.msg("Who would you like to boot?") session.msg("Who would you like to boot?")
return
if not objs[0].is_player():
session.msg("You can only boot players.")
return
if not pobject.controls_other(objs[0]):
if objs[0].is_superuser():
session.msg("You cannot boot a Wizard.")
return
else:
session.msg("You do not have permission to boot that player.")
return
if objs[0].is_connected_plr():
boot_list.append(session_mgr.session_from_object(objs[0]))
for boot in boot_list:
if not switch_quiet:
boot.msg("You have been disconnected by %s." % (pobject.name))
boot.disconnectClient()
session_mgr.remove_session(boot)
return return
if not objs[0].is_player():
session.msg("You can only boot players.")
return
if not pobject.controls_other(objs[0]):
if objs[0].is_superuser():
session.msg("You cannot boot a Wizard.")
return
else:
session.msg("You do not have permission to boot that player.")
return
if objs[0].is_connected_plr():
boot_list.append(session_mgr.session_from_object(objs[0]))
for boot in boot_list:
if not switch_quiet:
boot.msg("You have been disconnected by %s." % (pobject.name))
boot.disconnectClient()
session_mgr.remove_session(boot)
return
def cmd_newpassword(cdat): def cmd_newpassword(cdat):
""" """
Set a player's password. Set a player's password.
""" """
session = cdat['session'] session = cdat['session']
pobject = session.get_pobject() pobject = session.get_pobject()
args = cdat['uinput']['splitted'][1:] args = cdat['uinput']['splitted'][1:]
eq_args = ' '.join(args).split('=') eq_args = ' '.join(args).split('=')
searchstring = ''.join(eq_args[0]) searchstring = ''.join(eq_args[0])
newpass = ''.join(eq_args[1:]) newpass = ''.join(eq_args[1:])
if len(args) == 0: if len(args) == 0:
session.msg("What player's password do you want to change") session.msg("What player's password do you want to change")
return return
if len(newpass) == 0: if len(newpass) == 0:
session.msg("You must supply a new password.") session.msg("You must supply a new password.")
return return
target_obj = functions_db.standard_plr_objsearch(session, searchstring) target_obj = functions_db.standard_plr_objsearch(session, searchstring)
# Use standard_plr_objsearch to handle duplicate/nonexistant results. # Use standard_plr_objsearch to handle duplicate/nonexistant results.
if not target_obj: if not target_obj:
return return
if not target_obj.is_player(): if not target_obj.is_player():
session.msg("You can only change passwords on players.") session.msg("You can only change passwords on players.")
elif not pobject.controls_other(target_obj): elif not pobject.controls_other(target_obj):
session.msg("You do not control %s." % (target_obj.get_name(),)) session.msg("You do not control %s." % (target_obj.get_name(),))
else: else:
uaccount = target_obj.get_user_account() uaccount = target_obj.get_user_account()
if len(newpass) == 0: if len(newpass) == 0:
uaccount.set_password() uaccount.set_password()
else: else:
uaccount.set_password(newpass) uaccount.set_password(newpass)
uaccount.save() uaccount.save()
session.msg("%s - PASSWORD set." % (target_obj.get_name(),)) session.msg("%s - PASSWORD set." % (target_obj.get_name(),))
target_obj.emit_to("%s has changed your password." % (pobject.get_name(show_dbref=False),)) target_obj.emit_to("%s has changed your password." % (pobject.get_name(show_dbref=False),))
def cmd_shutdown(cdat): def cmd_shutdown(cdat):
""" """
Shut the server down gracefully. Shut the server down gracefully.
""" """
session = cdat['session'] session = cdat['session']
server = cdat['server'] server = cdat['server']
pobject = session.get_pobject() pobject = session.get_pobject()
session.msg('Shutting down...') session.msg('Shutting down...')
print 'Server shutdown by %s' % (pobject.get_name(show_dbref=False),) print 'Server shutdown by %s' % (pobject.get_name(show_dbref=False),)
server.shutdown() server.shutdown()

View file

@ -1,13 +1,13 @@
# Do not mess with the default types (0-5). This is passed to the Object # Do not mess with the default types (0-5). This is passed to the Object
# model's 'choices' argument. # model's 'choices' argument.
OBJECT_TYPES = ( OBJECT_TYPES = (
(0, 'NOTHING'), (0, 'NOTHING'),
(1, 'PLAYER'), (1, 'PLAYER'),
(2, 'ROOM'), (2, 'ROOM'),
(3, 'THING'), (3, 'THING'),
(4, 'EXIT'), (4, 'EXIT'),
(5, 'GOING'), (5, 'GOING'),
(6, 'GARBAGE'), (6, 'GARBAGE'),
) )
# Hate to duplicate the above, but it's the easiest way. # Hate to duplicate the above, but it's the easiest way.

View file

@ -9,247 +9,247 @@ Comsys functions.
""" """
def plr_get_cdict(session): def plr_get_cdict(session):
""" """
Returns the users's channel subscription dictionary. Use this instead of Returns the users's channel subscription dictionary. Use this instead of
directly referring to the session object. directly referring to the session object.
session: (SessionProtocol) Reference to a player session. session: (SessionProtocol) Reference to a player session.
""" """
return session.channels_subscribed return session.channels_subscribed
def plr_listening_channel(session, cstr, alias_search=False): def plr_listening_channel(session, cstr, alias_search=False):
""" """
Returns a player's listening status for a channel. Returns a player's listening status for a channel.
session: (SessionProtocol) Reference to a player session. session: (SessionProtocol) Reference to a player session.
cstr: (str) The channel name or alias (depending on alias_search). cstr: (str) The channel name or alias (depending on alias_search).
alias_search: (bool) If true, search by alias. Else search by full name. alias_search: (bool) If true, search by alias. Else search by full name.
""" """
return plr_has_channel(session, cstr, alias_search=alias_search, return plr_has_channel(session, cstr, alias_search=alias_search,
return_muted=False) return_muted=False)
def plr_cname_from_alias(session, calias): def plr_cname_from_alias(session, calias):
""" """
Returns a channel name given a channel alias. Returns a channel name given a channel alias.
session: (SessionProtocol) Reference to a player session. session: (SessionProtocol) Reference to a player session.
calias: (str) The channel alias. calias: (str) The channel alias.
""" """
return plr_get_cdict(session).get(calias, None)[0] return plr_get_cdict(session).get(calias, None)[0]
def plr_chan_off(session, calias): def plr_chan_off(session, calias):
""" """
Turn a channel off for a player. Turn a channel off for a player.
session: (SessionProtocol) Reference to a player session. session: (SessionProtocol) Reference to a player session.
calias: (str) The channel alias. calias: (str) The channel alias.
""" """
if not plr_listening_channel(session, calias, alias_search=True): if not plr_listening_channel(session, calias, alias_search=True):
session.msg("You're already not listening to that channel.") session.msg("You're already not listening to that channel.")
return return
else: else:
cname = plr_cname_from_alias(session, calias) cname = plr_cname_from_alias(session, calias)
cobj = get_cobj_from_name(cname) cobj = get_cobj_from_name(cname)
plr_set_channel_listening(session, calias, False) plr_set_channel_listening(session, calias, False)
session.msg("You have left %s." % (cname,)) session.msg("You have left %s." % (cname,))
send_cmessage(cname, "%s %s has left the channel." % (cobj.get_header(), send_cmessage(cname, "%s %s has left the channel." % (cobj.get_header(),
session.get_pobject().get_name(show_dbref=False))) session.get_pobject().get_name(show_dbref=False)))
def plr_chan_on(session, calias): def plr_chan_on(session, calias):
""" """
Turn a channel on for a player. Turn a channel on for a player.
session: (SessionProtocol) Reference to a player session. session: (SessionProtocol) Reference to a player session.
calias: (str) The channel alias. calias: (str) The channel alias.
""" """
plr_listening = plr_listening_channel(session, calias, alias_search=True) plr_listening = plr_listening_channel(session, calias, alias_search=True)
if plr_listening: if plr_listening:
session.msg("You're already listening to that channel.") session.msg("You're already listening to that channel.")
return return
else: else:
cname = plr_cname_from_alias(session, calias) cname = plr_cname_from_alias(session, calias)
cobj = get_cobj_from_name(cname) cobj = get_cobj_from_name(cname)
send_cmessage(cname, "%s %s has joined the channel." % (cobj.get_header(), send_cmessage(cname, "%s %s has joined the channel." % (cobj.get_header(),
session.get_pobject().get_name(show_dbref=False))) session.get_pobject().get_name(show_dbref=False)))
plr_set_channel_listening(session, calias, True) plr_set_channel_listening(session, calias, True)
session.msg("You have joined %s." % (cname,)) session.msg("You have joined %s." % (cname,))
def plr_has_channel(session, cname, alias_search=False, return_muted=False): def plr_has_channel(session, cname, alias_search=False, return_muted=False):
""" """
Is this session subscribed to the named channel? Is this session subscribed to the named channel?
session: (SessionProtocol) Reference to a player session. session: (SessionProtocol) Reference to a player session.
cname: (str) The channel name or alias (depending on alias_search) cname: (str) The channel name or alias (depending on alias_search)
alias_search: (bool) If False, search by full name. Else search by alias. alias_search: (bool) If False, search by full name. Else search by alias.
return_muted: (bool) Take the user's enabling/disabling of the channel return_muted: (bool) Take the user's enabling/disabling of the channel
into consideration? into consideration?
""" """
has_channel = False has_channel = False
if alias_search: if alias_search:
# Search by aliases only. # Search by aliases only.
cdat = plr_get_cdict(session).get(cname, False) cdat = plr_get_cdict(session).get(cname, False)
# No key match, fail immediately. # No key match, fail immediately.
if not cdat: if not cdat:
return False return False
# If channel status is taken into consideration, see if the user # If channel status is taken into consideration, see if the user
# has the channel muted or not. # has the channel muted or not.
if return_muted: if return_muted:
return True return True
else: else:
return cdat[1] return cdat[1]
else: else:
# Search by complete channel name. # Search by complete channel name.
chan_list = plr_get_cdict(session).values() chan_list = plr_get_cdict(session).values()
for chan in chan_list: for chan in chan_list:
# Check for a name match # Check for a name match
if cname == chan[0]: if cname == chan[0]:
has_channel = True has_channel = True
# If channel status is taken into consideration, see if the user # If channel status is taken into consideration, see if the user
# has the channel muted or not. # has the channel muted or not.
if return_muted is False and not chan[1]: if return_muted is False and not chan[1]:
has_channel = False has_channel = False
break break
return has_channel return has_channel
def plr_set_channel_listening(session, alias, listening): def plr_set_channel_listening(session, alias, listening):
""" """
Add a channel to a session's channel list. Add a channel to a session's channel list.
session: (SessionProtocol) A reference to the player session. session: (SessionProtocol) A reference to the player session.
alias: (str) The channel alias. alias: (str) The channel alias.
listening: (bool) A True or False value to determine listening status. listening: (bool) A True or False value to determine listening status.
""" """
plr_get_cdict(session).get(alias)[1] = listening plr_get_cdict(session).get(alias)[1] = listening
plr_pickle_channels(session) plr_pickle_channels(session)
def plr_set_channel(session, alias, cname, listening): def plr_set_channel(session, alias, cname, listening):
""" """
Set a channels alias, name, and listening status in one go, or add the Set a channels alias, name, and listening status in one go, or add the
channel if it doesn't already exist on a user's list. channel if it doesn't already exist on a user's list.
session: (SessionProtocol) A reference to the player session. session: (SessionProtocol) A reference to the player session.
alias: (str) The channel alias (also the key in the user's cdict) alias: (str) The channel alias (also the key in the user's cdict)
cname: (str) Desired channel name to set. cname: (str) Desired channel name to set.
listening: (bool) A True or False value to determine listening status. listening: (bool) A True or False value to determine listening status.
""" """
plr_get_cdict(session)[alias] = [cname, listening] plr_get_cdict(session)[alias] = [cname, listening]
plr_pickle_channels(session) plr_pickle_channels(session)
def plr_pickle_channels(session): def plr_pickle_channels(session):
""" """
Save the player's channel list to the CHANLIST attribute. Save the player's channel list to the CHANLIST attribute.
session: (SessionProtocol) A reference to the player session. session: (SessionProtocol) A reference to the player session.
""" """
session.get_pobject().set_attribute("CHANLIST", pickle.dumps(plr_get_cdict(session))) session.get_pobject().set_attribute("CHANLIST", pickle.dumps(plr_get_cdict(session)))
def plr_del_channel(session, alias): def plr_del_channel(session, alias):
""" """
Remove a channel from a session's channel list. Remove a channel from a session's channel list.
session: (SessionProtocol) A reference to the player session. session: (SessionProtocol) A reference to the player session.
alias: (str) The channel alias (also the key in the user's cdict) alias: (str) The channel alias (also the key in the user's cdict)
""" """
del plr_get_cdict(session)[alias] del plr_get_cdict(session)[alias]
def msg_chan_hist(session, channel_name): def msg_chan_hist(session, channel_name):
""" """
Sends a listing of subscribers to a channel given a channel name. Sends a listing of subscribers to a channel given a channel name.
session: (SessionProtocol) A reference to the player session. session: (SessionProtocol) A reference to the player session.
channel_name: (str) The channel's full name. channel_name: (str) The channel's full name.
""" """
cobj = get_cobj_from_name(channel_name) cobj = get_cobj_from_name(channel_name)
hist_list = CommChannelMessage.objects.filter(channel=cobj).order_by('date_sent')[0:20] hist_list = CommChannelMessage.objects.filter(channel=cobj).order_by('date_sent')[0:20]
for entry in hist_list: for entry in hist_list:
delta_days = datetime.datetime.now() - entry.date_sent delta_days = datetime.datetime.now() - entry.date_sent
days_elapsed = delta_days.days days_elapsed = delta_days.days
if days_elapsed > 0: if days_elapsed > 0:
time_str = entry.date_sent.strftime("%m.%d / %H:%M") time_str = entry.date_sent.strftime("%m.%d / %H:%M")
else: else:
time_str = entry.date_sent.strftime("%H:%M") time_str = entry.date_sent.strftime("%H:%M")
session.msg("[%s] %s" % (time_str, entry.message)) session.msg("[%s] %s" % (time_str, entry.message))
def msg_cwho(session, channel_name): def msg_cwho(session, channel_name):
""" """
Sends a listing of subscribers to a channel given a channel name. Sends a listing of subscribers to a channel given a channel name.
session: (SessionProtocol) A reference to the player session. session: (SessionProtocol) A reference to the player session.
channel_name: (str) The channel's full name. channel_name: (str) The channel's full name.
""" """
session.msg("--- Users Listening to %s ---" % (channel_name,)) session.msg("--- Users Listening to %s ---" % (channel_name,))
for plr_sess in get_cwho_list(channel_name): for plr_sess in get_cwho_list(channel_name):
session.msg(plr_sess.get_pobject().get_name(show_dbref=False)) session.msg(plr_sess.get_pobject().get_name(show_dbref=False))
session.msg("--- End Channel Listeners ---") session.msg("--- End Channel Listeners ---")
def get_cwho_list(channel_name, return_muted=False): def get_cwho_list(channel_name, return_muted=False):
""" """
Get all users on a channel. Get all users on a channel.
channel_name: (string) The name of the channel. channel_name: (string) The name of the channel.
return_muted: (bool) Return those who have the channel muted if True. return_muted: (bool) Return those who have the channel muted if True.
""" """
sess_list = session_mgr.get_session_list() sess_list = session_mgr.get_session_list()
return [sess for sess in sess_list if plr_has_channel(sess, channel_name, return_muted)] return [sess for sess in sess_list if plr_has_channel(sess, channel_name, return_muted)]
def send_cmessage(channel_name, message): def send_cmessage(channel_name, message):
""" """
Sends a message to all players on the specified channel. Sends a message to all players on the specified channel.
channel_name: (string) The name of the channel. channel_name: (string) The name of the channel.
message: (string) Message to send. message: (string) Message to send.
""" """
for user in get_cwho_list(channel_name, return_muted=False): for user in get_cwho_list(channel_name, return_muted=False):
user.msg(message) user.msg(message)
try: try:
chan_message = CommChannelMessage() chan_message = CommChannelMessage()
chan_message.channel = get_cobj_from_name(channel_name) chan_message.channel = get_cobj_from_name(channel_name)
chan_message.message = message chan_message.message = message
chan_message.save() chan_message.save()
except: except:
print "send_cmessage(): Can't find channel: %s" % (channel_name,) print "send_cmessage(): Can't find channel: %s" % (channel_name,)
def get_all_channels(): def get_all_channels():
""" """
Returns all channel objects. Returns all channel objects.
""" """
return CommChannel.objects.all() return CommChannel.objects.all()
def get_cobj_from_name(cname): def get_cobj_from_name(cname):
""" """
Returns the channel's object when given a name. Returns the channel's object when given a name.
""" """
return CommChannel.objects.get(name=cname) return CommChannel.objects.get(name=cname)
def create_channel(cdat): def create_channel(cdat):
""" """
Create a new channel. cdat is a dictionary that contains the following keys. Create a new channel. cdat is a dictionary that contains the following keys.
REQUIRED KEYS: REQUIRED KEYS:
* name: The name of the new channel. * name: The name of the new channel.
* owner: The creator of the channel. * owner: The creator of the channel.
""" """
new_chan = CommChannel() new_chan = CommChannel()
new_chan.name = ansi.parse_ansi(cdat["name"], strip_ansi=True) new_chan.name = ansi.parse_ansi(cdat["name"], strip_ansi=True)
new_chan.ansi_name = "[%s]" % (ansi.parse_ansi(cdat["name"]),) new_chan.ansi_name = "[%s]" % (ansi.parse_ansi(cdat["name"]),)
new_chan.set_owner(cdat["owner"]) new_chan.set_owner(cdat["owner"])
new_chan.save() new_chan.save()
return new_chan return new_chan
def cname_search(search_text, exact=False): def cname_search(search_text, exact=False):
""" """
Searches for a particular channel name. Returns a QuerySet with the Searches for a particular channel name. Returns a QuerySet with the
results. results.
exact: (bool) Do an exact (case-insensitive) name match if true. exact: (bool) Do an exact (case-insensitive) name match if true.
""" """
if exact: if exact:
return CommChannel.objects.filter(name__iexact=search_text) return CommChannel.objects.filter(name__iexact=search_text)
else: else:
return CommChannel.objects.filter(name__istartswith=search_text) return CommChannel.objects.filter(name__istartswith=search_text)

View file

@ -7,134 +7,134 @@ General commonly used functions.
""" """
def wildcard_to_regexp(instring): def wildcard_to_regexp(instring):
""" """
Converts a player-supplied string that may have wildcards in it to regular Converts a player-supplied string that may have wildcards in it to regular
expressions. This is useful for name matching. expressions. This is useful for name matching.
instring: (string) A string that may potentially contain wildcards (* or ?). instring: (string) A string that may potentially contain wildcards (* or ?).
""" """
regexp_string = "" regexp_string = ""
# If the string starts with an asterisk, we can't impose the beginning of # If the string starts with an asterisk, we can't impose the beginning of
# string (^) limiter. # string (^) limiter.
if instring[0] != "*": if instring[0] != "*":
regexp_string += "^" regexp_string += "^"
# Replace any occurances of * or ? with the appropriate groups. # Replace any occurances of * or ? with the appropriate groups.
regexp_string += instring.replace("*","(.*)").replace("?", "(.{1})") regexp_string += instring.replace("*","(.*)").replace("?", "(.{1})")
# If there's an asterisk at the end of the string, we can't impose the # If there's an asterisk at the end of the string, we can't impose the
# end of string ($) limiter. # end of string ($) limiter.
if instring[-1] != "*": if instring[-1] != "*":
regexp_string += "$" regexp_string += "$"
return regexp_string return regexp_string
def cmd_check_num_args(session, arg_list, min_args, errortext="Missing arguments!"): def cmd_check_num_args(session, arg_list, min_args, errortext="Missing arguments!"):
""" """
Check a player command's splitted argument list to make sure it contains Check a player command's splitted argument list to make sure it contains
the minimum allowable number of arguments. the minimum allowable number of arguments.
""" """
if len(arg_list) < min_args+1: if len(arg_list) < min_args+1:
session.msg(errortext) session.msg(errortext)
return False return False
return True return True
def log_errmsg(errormsg): def log_errmsg(errormsg):
""" """
Prints/logs an error message to the server log. Prints/logs an error message to the server log.
errormsg: (string) The message to be logged. errormsg: (string) The message to be logged.
""" """
log.err('ERROR: %s' % (errormsg,)) log.err('ERROR: %s' % (errormsg,))
#functions_comsys.send_cmessage("Errors", "[Errors] "+ errormsg) #functions_comsys.send_cmessage("Errors", "[Errors] "+ errormsg)
def log_infomsg(infomsg): def log_infomsg(infomsg):
""" """
Prints any generic debugging/informative info that should appear in the log. Prints any generic debugging/informative info that should appear in the log.
debugmsg: (string) The message to be logged. debugmsg: (string) The message to be logged.
""" """
log.msg('%s' % (infomsg,)) log.msg('%s' % (infomsg,))
#functions_comsys.send_cmessage("Info", "[Info] "+ infomsg) #functions_comsys.send_cmessage("Info", "[Info] "+ infomsg)
def time_format(seconds, style=0): def time_format(seconds, style=0):
""" """
Function to return a 'prettified' version of a value in seconds. Function to return a 'prettified' version of a value in seconds.
Style 0: 1d 08:30 Style 0: 1d 08:30
Style 1: 1d Style 1: 1d
Style 2: 1 day, 8 hours, 30 minutes, 10 seconds Style 2: 1 day, 8 hours, 30 minutes, 10 seconds
""" """
if seconds < 0: if seconds < 0:
seconds = 0 seconds = 0
else: else:
# We'll just use integer math, no need for decimal precision. # We'll just use integer math, no need for decimal precision.
seconds = int(seconds) seconds = int(seconds)
days = seconds / 86400 days = seconds / 86400
seconds -= days * 86400 seconds -= days * 86400
hours = seconds / 3600 hours = seconds / 3600
seconds -= hours * 3600 seconds -= hours * 3600
minutes = seconds / 60 minutes = seconds / 60
seconds -= minutes * 60 seconds -= minutes * 60
if style is 0: if style is 0:
""" """
Standard colon-style output. Standard colon-style output.
""" """
if days > 0: if days > 0:
retval = '%id %02i:%02i' % (days, hours, minutes,) retval = '%id %02i:%02i' % (days, hours, minutes,)
else: else:
retval = '%02i:%02i' % (hours, minutes,) retval = '%02i:%02i' % (hours, minutes,)
return retval return retval
elif style is 1: elif style is 1:
""" """
Simple, abbreviated form that only shows the highest time amount. Simple, abbreviated form that only shows the highest time amount.
""" """
if days > 0: if days > 0:
return '%id' % (days,) return '%id' % (days,)
elif hours > 0: elif hours > 0:
return '%ih' % (hours,) return '%ih' % (hours,)
elif minutes > 0: elif minutes > 0:
return '%im' % (minutes,) return '%im' % (minutes,)
else: else:
return '%is' % (seconds,) return '%is' % (seconds,)
elif style is 2: elif style is 2:
""" """
Full-detailed, long-winded format. Full-detailed, long-winded format.
""" """
days_str = hours_str = minutes_str = '' days_str = hours_str = minutes_str = ''
if days > 0: if days > 0:
days_str = '%i days, ' % (days,) days_str = '%i days, ' % (days,)
if days or hours > 0: if days or hours > 0:
hours_str = '%i hours, ' % (hours,) hours_str = '%i hours, ' % (hours,)
if hours or minutes > 0: if hours or minutes > 0:
minutes_str = '%i minutes, ' % (minutes,) minutes_str = '%i minutes, ' % (minutes,)
seconds_str = '%i seconds' % (seconds,) seconds_str = '%i seconds' % (seconds,)
retval = '%s%s%s%s' % (days_str, hours_str, minutes_str, seconds_str,) retval = '%s%s%s%s' % (days_str, hours_str, minutes_str, seconds_str,)
return retval return retval
def announce_all(message, with_ann_prefix=True): def announce_all(message, with_ann_prefix=True):
""" """
Announces something to all connected players. Announces something to all connected players.
""" """
if with_ann_prefix: if with_ann_prefix:
prefix = 'Announcement:' prefix = 'Announcement:'
else: else:
prefix = '' prefix = ''
for session in session_mgr.get_session_list(): for session in session_mgr.get_session_list():
session.msg('%s %s' % (prefix, message)) session.msg('%s %s' % (prefix, message))
def word_wrap(text, width=78): def word_wrap(text, width=78):
""" """
Wrap text to a certain number of characters. Wrap text to a certain number of characters.
text: (str) The text to wrap. text: (str) The text to wrap.
width: (int) The number of characters to wrap to. width: (int) The number of characters to wrap to.
""" """
return '\r\n'.join(textwrap.wrap(text, width)) return '\r\n'.join(textwrap.wrap(text, width))

View file

@ -3,27 +3,27 @@ from apps.helpsys.models import HelpEntry
Help system functions. Help system functions.
""" """
def find_topicmatch(pobject, topicstr): def find_topicmatch(pobject, topicstr):
""" """
Searches for matching topics based on player's input. Searches for matching topics based on player's input.
""" """
is_staff = pobject.is_staff() is_staff = pobject.is_staff()
if topicstr.isdigit(): if topicstr.isdigit():
if is_staff: if is_staff:
return HelpEntry.objects.filter(id=topicstr) return HelpEntry.objects.filter(id=topicstr)
else: else:
return HelpEntry.objects.filter(id=topicstr).exclude(staff_only=1) return HelpEntry.objects.filter(id=topicstr).exclude(staff_only=1)
else: else:
if is_staff: if is_staff:
return HelpEntry.objects.filter(topicname__istartswith=topicstr) return HelpEntry.objects.filter(topicname__istartswith=topicstr)
else: else:
return HelpEntry.objects.filter(topicname__istartswith=topicstr).exclude(staff_only=1) return HelpEntry.objects.filter(topicname__istartswith=topicstr).exclude(staff_only=1)
def find_topicsuggestions(pobject, topicstr): def find_topicsuggestions(pobject, topicstr):
""" """
Do a fuzzier "contains" match. Do a fuzzier "contains" match.
""" """
is_staff = pobject.is_staff() is_staff = pobject.is_staff()
if is_staff: if is_staff:
return HelpEntry.objects.filter(topicname__icontains=topicstr) return HelpEntry.objects.filter(topicname__icontains=topicstr)
else: else:
return HelpEntry.objects.filter(topicname__icontains=topicstr).exclude(staff_only=1) return HelpEntry.objects.filter(topicname__icontains=topicstr).exclude(staff_only=1)

View file

@ -8,26 +8,26 @@ Handle the setting/retrieving of server config directives.
""" """
def host_os_is(osname): def host_os_is(osname):
""" """
Check to see if the host OS matches the query. Check to see if the host OS matches the query.
""" """
if os.name == osname: if os.name == osname:
return True return True
return False return False
def get_configvalue(configname): def get_configvalue(configname):
""" """
Retrieve a configuration value. Retrieve a configuration value.
""" """
try: try:
return ConfigValue.objects.get(conf_key__iexact=configname).conf_value return ConfigValue.objects.get(conf_key__iexact=configname).conf_value
except: except:
functions_general.log_errmsg("Unable to get config value for %s:\n%s" % (configname, (format_exc()))) functions_general.log_errmsg("Unable to get config value for %s:\n%s" % (configname, (format_exc())))
def set_configvalue(configname, newvalue): def set_configvalue(configname, newvalue):
""" """
Sets a configuration value with the specified name. Sets a configuration value with the specified name.
""" """
conf = ConfigValue.objects.get(conf_key=configname) conf = ConfigValue.objects.get(conf_key=configname)
conf.conf_value = newvalue conf.conf_value = newvalue
conf.save() conf.save()

View file

@ -3,16 +3,16 @@ from apps.objects.models import Object
import gameconf import gameconf
def handle_setup(): def handle_setup():
# Set the initial user's username on the #1 object. # Set the initial user's username on the #1 object.
god_user = User.objects.filter(id=1)[0] god_user = User.objects.filter(id=1)[0]
god_user_obj = Object.objects.filter(id=1)[0] god_user_obj = Object.objects.filter(id=1)[0]
god_user_obj.set_name(god_user.username) god_user_obj.set_name(god_user.username)
groups = ("Immortals", "Wizards", "Builders", "Player Helpers") groups = ("Immortals", "Wizards", "Builders", "Player Helpers")
for group in groups: for group in groups:
newgroup = Group() newgroup = Group()
newgroup.name = group newgroup.name = group
newgroup.save() newgroup.save()
# We don't want to do initial setup tasks every startup, only the first. # We don't want to do initial setup tasks every startup, only the first.
gameconf.set_configvalue('game_firstrun', '0') gameconf.set_configvalue('game_firstrun', '0')

View file

@ -1,11 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
from django.core.management import execute_manager from django.core.management import execute_manager
try: try:
import settings # Assumed to be in the same directory. import settings # Assumed to be in the same directory.
except ImportError: except ImportError:
import sys import sys
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
sys.exit(1) sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":
execute_manager(settings) execute_manager(settings)

View file

@ -3,20 +3,20 @@ The ReloadMixin class is meant as an example, but should work
for basic purposes as a mixin inheritance. for basic purposes as a mixin inheritance.
""" """
class ReloadMixin(): class ReloadMixin():
""" """
This class is a generic reload mixin providing the two This class is a generic reload mixin providing the two
methods required to cache and reload an object. methods required to cache and reload an object.
""" """
def cache(self, reloader, do_save=True): def cache(self, reloader, do_save=True):
if do_save: if do_save:
if self.save and callable(self.save): if self.save and callable(self.save):
self.save() self.save()
else: else:
raise ValueError("This object does not have a save function, you must pass do_save=False for this object type.") raise ValueError("This object does not have a save function, you must pass do_save=False for this object type.")
reloader.cache_object(self) reloader.cache_object(self)
def reload(self, cache): def reload(self, cache):
for key, value in cache.iteritems(): for key, value in cache.iteritems():
if self.__dict__[key] != value: if self.__dict__[key] != value:
self.__dict__[key] = value self.__dict__[key] = value

View file

@ -9,19 +9,19 @@ modules to be reloaded at @reload.
# These are custom modules that have classes requiring state-saving. # These are custom modules that have classes requiring state-saving.
# These modules are reloaded before those in no_cache. # These modules are reloaded before those in no_cache.
cache = { cache = {
# This should be a dict of lists of tuples # This should be a dict of lists of tuples
# with the module name as a key, a list of tuples # with the module name as a key, a list of tuples
# with the class name as the first element of the # with the class name as the first element of the
# tuple, and True or False if this is a model # tuple, and True or False if this is a model
# for the database, like so: # for the database, like so:
# #
# 'modulename' : [ ('ModelA', True), ('ClassA', False) ], # 'modulename' : [ ('ModelA', True), ('ClassA', False) ],
# 'anothermod' : [ ('ClassB', False), ('ClassC', False) ], # 'anothermod' : [ ('ClassB', False), ('ClassC', False) ],
} }
# This is a list of modules that need to be reloaded at @reload. There # This is a list of modules that need to be reloaded at @reload. There
# is no state-saving, and these are reloaded after those cached above. # is no state-saving, and these are reloaded after those cached above.
no_cache = [ no_cache = [
# 'modulename', # 'modulename',
# 'anothermod', # 'anothermod',
] ]

View file

@ -1,51 +1,51 @@
import functions_general import functions_general
class ReloadManager(object): class ReloadManager(object):
objects_cache = {} objects_cache = {}
failed = [] failed = []
models = {} models = {}
def __init__(self, server): def __init__(self, server):
self.server = server self.server = server
def do_cache(self): def do_cache(self):
for module, info in self.models.iteritems(): for module, info in self.models.iteritems():
module_obj = __import__(module) module_obj = __import__(module)
for ituple in info: for ituple in info:
mclass = getattr(module_obj, info[0]) mclass = getattr(module_obj, info[0])
for instance in mclass.__instances__(): for instance in mclass.__instances__():
instance.cache(self, do_save=ituple[1]) instance.cache(self, do_save=ituple[1])
def do_reload(self): def do_reload(self):
self.do_cache() self.do_cache()
self.server.reload() self.server.reload()
self.reload_objects() self.reload_objects()
def cache_object(self, obj): def cache_object(self, obj):
obj_dict = {} obj_dict = {}
for key, value in obj.__dict__.iteritems(): for key, value in obj.__dict__.iteritems():
if not callable(obj[key]): if not callable(obj[key]):
obj_dict[key] = value obj_dict[key] = value
self.objects_cache[obj] = obj_dict self.objects_cache[obj] = obj_dict
def reload_objects(self): def reload_objects(self):
for obj, cache in self.objects_cache.iteritems(): for obj, cache in self.objects_cache.iteritems():
try: try:
obj.reload(cache) obj.reload(cache)
except: except:
functions_general.log_errmsg("Failed to reload cache for object: %s." % (obj,)) functions_general.log_errmsg("Failed to reload cache for object: %s." % (obj,))
self.failed.append(obj) self.failed.append(obj)
raise raise
self.objects_cache = {} self.objects_cache = {}
for obj in self.failed: for obj in self.failed:
try: try:
obj.__dict__.update(cache) obj.__dict__.update(cache)
except: except:
functions_general.log_errmsg("Failed to update object %s, giving up." %s (obj,)) functions_general.log_errmsg("Failed to update object %s, giving up." %s (obj,))
raise raise
self.failed = [] self.failed = []

View file

@ -13,96 +13,96 @@ ADDING AN EVENT:
# Dictionary of events with a list in the form of: # Dictionary of events with a list in the form of:
# [<function>, <interval>, <lastrantime>, <taskobject>, <description>] # [<function>, <interval>, <lastrantime>, <taskobject>, <description>]
schedule = { schedule = {
'evt_check_sessions': [events.evt_check_sessions, 60, time.time(), None, "Session consistency checks."] 'evt_check_sessions': [events.evt_check_sessions, 60, time.time(), None, "Session consistency checks."]
} }
def start_events(): def start_events():
""" """
Start the event system, which is built on Twisted's framework. Start the event system, which is built on Twisted's framework.
""" """
for event in schedule: for event in schedule:
event_func = get_event_function(event) event_func = get_event_function(event)
if callable(event_func): if callable(event_func):
# Set the call-back function for the task to trigger_event, but pass # Set the call-back function for the task to trigger_event, but pass
# a reference to the event function. # a reference to the event function.
event_task = task.LoopingCall(trigger_event, event_func, event) event_task = task.LoopingCall(trigger_event, event_func, event)
# Start the task up with the specified interval. # Start the task up with the specified interval.
event_task.start(get_event_interval(event), now=False) event_task.start(get_event_interval(event), now=False)
# Set a reference to the event's task object in the dictionary so we # Set a reference to the event's task object in the dictionary so we
# can re-schedule, start, and stop events from elsewhere. # can re-schedule, start, and stop events from elsewhere.
set_event_taskobj(event, event_task) set_event_taskobj(event, event_task)
def get_event(event_name): def get_event(event_name):
""" """
Return the relevant entry in the schedule dictionary for the named event. Return the relevant entry in the schedule dictionary for the named event.
event_name: (string) The key of the event in the schedule dictionary. event_name: (string) The key of the event in the schedule dictionary.
""" """
return schedule.get(event_name, None) return schedule.get(event_name, None)
def get_event_function(event_name): def get_event_function(event_name):
""" """
Return a reference to the event's function. Return a reference to the event's function.
event_name: (string) The key of the event in the schedule dictionary. event_name: (string) The key of the event in the schedule dictionary.
""" """
return get_event(event_name)[0] return get_event(event_name)[0]
def get_event_interval(event_name): def get_event_interval(event_name):
""" """
Return the event's execution interval. Return the event's execution interval.
event_name: (string) The key of the event in the schedule dictionary. event_name: (string) The key of the event in the schedule dictionary.
""" """
return get_event(event_name)[1] return get_event(event_name)[1]
def get_event_nextfire(event_name): def get_event_nextfire(event_name):
""" """
Returns a value in seconds when the event is going to fire off next. Returns a value in seconds when the event is going to fire off next.
event_name: (string) The key of the event in the schedule dictionary. event_name: (string) The key of the event in the schedule dictionary.
""" """
return (get_event(event_name)[2]+get_event_interval(event_name))-time.time() return (get_event(event_name)[2]+get_event_interval(event_name))-time.time()
def get_event_taskobj(event_name): def get_event_taskobj(event_name):
""" """
Returns an event's task object. Returns an event's task object.
event_name: (string) The key of the event in the schedule dictionary. event_name: (string) The key of the event in the schedule dictionary.
""" """
return get_event(event_name)[3] return get_event(event_name)[3]
def get_event_description(event_name): def get_event_description(event_name):
""" """
Returns an event's description. Returns an event's description.
event_name: (string) The key of the event in the schedule dictionary. event_name: (string) The key of the event in the schedule dictionary.
""" """
return get_event(event_name)[4] return get_event(event_name)[4]
def set_event_taskobj(event_name, taskobj): def set_event_taskobj(event_name, taskobj):
""" """
Sets an event's task object. Sets an event's task object.
event_name: (string) The key of the event in the schedule dictionary. event_name: (string) The key of the event in the schedule dictionary.
""" """
get_event(event_name)[3] = taskobj get_event(event_name)[3] = taskobj
def set_event_lastfired(event_name): def set_event_lastfired(event_name):
""" """
Sets an event's last fired time. Sets an event's last fired time.
event_name: (string) The key of the event in the schedule dictionary. event_name: (string) The key of the event in the schedule dictionary.
""" """
get_event(event_name)[2] = time.time() get_event(event_name)[2] = time.time()
def trigger_event(event_func, event_name): def trigger_event(event_func, event_name):
""" """
Update the last ran time and fire off the event. Update the last ran time and fire off the event.
event_func: (func_reference) Reference to the event function to fire. event_func: (func_reference) Reference to the event function to fire.
eventname: (string) The name of the event (as per schedule dict). eventname: (string) The name of the event (as per schedule dict).
""" """
event_func() event_func()
set_event_lastfired(event_name) set_event_lastfired(event_name)

View file

@ -15,54 +15,54 @@ interaction with actual script methods should happen via calls to Objects.
cached_scripts = {} cached_scripts = {}
def scriptlink(source_obj, scriptname): def scriptlink(source_obj, scriptname):
""" """
Each Object will refer to this function when trying to execute a function Each Object will refer to this function when trying to execute a function
contained within a scripted module. For the sake of ease of management, contained within a scripted module. For the sake of ease of management,
modules are cached and compiled as they are requested and stored in modules are cached and compiled as they are requested and stored in
the cached_scripts dictionary. the cached_scripts dictionary.
Returns a reference to an instance of the script's class as per it's Returns a reference to an instance of the script's class as per it's
class_factory() method. class_factory() method.
source_obj: (Object) A reference to the object being scripted. source_obj: (Object) A reference to the object being scripted.
scriptname: (str) Name of the module to load (minus 'scripts'). scriptname: (str) Name of the module to load (minus 'scripts').
""" """
# The module is already cached, just return it rather than re-load. # The module is already cached, just return it rather than re-load.
retval = cached_scripts.get(scriptname, False) retval = cached_scripts.get(scriptname, False)
if retval: if retval:
return retval.class_factory(source_obj) return retval.class_factory(source_obj)
## ##
## NOTE: Only go past here when the script isn't already cached. ## NOTE: Only go past here when the script isn't already cached.
## ##
# Split the script name up by periods to give us the directory we need # Split the script name up by periods to give us the directory we need
# to change to. I really wish we didn't have to do this, but there's some # to change to. I really wish we didn't have to do this, but there's some
# strange issue with __import__ and more than two directories worth of # strange issue with __import__ and more than two directories worth of
# nesting. # nesting.
path_split = scriptname.split('.') path_split = scriptname.split('.')
newpath_str = '/'.join(path_split[:-1]) newpath_str = '/'.join(path_split[:-1])
# Lop the module name off the end. # Lop the module name off the end.
modname = path_split[-1] modname = path_split[-1]
try: try:
# Change the working directory to the location of the script and import. # Change the working directory to the location of the script and import.
os.chdir('%s/%s/' % (settings.SCRIPT_ROOT, newpath_str)) os.chdir('%s/%s/' % (settings.SCRIPT_ROOT, newpath_str))
functions_general.log_infomsg("SCRIPT: Caching and importing %s." % (modname)) functions_general.log_infomsg("SCRIPT: Caching and importing %s." % (modname))
modreference = __import__(modname) modreference = __import__(modname)
# Store the module reference for later fast retrieval. # Store the module reference for later fast retrieval.
cached_scripts[scriptname] = modreference cached_scripts[scriptname] = modreference
except ImportError: except ImportError:
functions_general.log_infomsg('Error importing %s: %s' % (modname, format_exc())) functions_general.log_infomsg('Error importing %s: %s' % (modname, format_exc()))
os.chdir(settings.BASE_PATH) os.chdir(settings.BASE_PATH)
return return
except OSError: except OSError:
functions_general.log_infomsg('Invalid module path: %s' % (format_exc())) functions_general.log_infomsg('Invalid module path: %s' % (format_exc()))
os.chdir(settings.BASE_PATH) os.chdir(settings.BASE_PATH)
return return
# Change back to the original working directory. # Change back to the original working directory.
os.chdir(settings.BASE_PATH) os.chdir(settings.BASE_PATH)
# The new script module has been cached, return the reference. # The new script module has been cached, return the reference.
return modreference.class_factory(source_obj) return modreference.class_factory(source_obj)

164
server.py
View file

@ -21,102 +21,102 @@ import initial_setup
class EvenniaService(service.Service): class EvenniaService(service.Service):
def __init__(self, filename="blah"): def __init__(self, filename="blah"):
self.cmd_alias_list = {} self.cmd_alias_list = {}
self.game_running = True self.game_running = True
sys.path.append('.') sys.path.append('.')
# Database-specific startup optimizations. # Database-specific startup optimizations.
if settings.DATABASE_ENGINE == "sqlite3": if settings.DATABASE_ENGINE == "sqlite3":
self.sqlite3_prep() self.sqlite3_prep()
# Wipe our temporary flags on all of the objects. # Wipe our temporary flags on all of the objects.
cursor = connection.cursor() cursor = connection.cursor()
cursor.execute("UPDATE objects_object SET nosave_flags=''") cursor.execute("UPDATE objects_object SET nosave_flags=''")
print '-'*50 print '-'*50
# Load command aliases into memory for easy/quick access. # Load command aliases into memory for easy/quick access.
self.load_cmd_aliases() self.load_cmd_aliases()
if gameconf.get_configvalue('game_firstrun') == '1': if gameconf.get_configvalue('game_firstrun') == '1':
print ' Game started for the first time, setting defaults.' print ' Game started for the first time, setting defaults.'
initial_setup.handle_setup() initial_setup.handle_setup()
self.start_time = time.time() self.start_time = time.time()
print ' %s started on port(s):' % (gameconf.get_configvalue('site_name'),) print ' %s started on port(s):' % (gameconf.get_configvalue('site_name'),)
for port in settings.GAMEPORTS: for port in settings.GAMEPORTS:
print ' * %s' % (port) print ' * %s' % (port)
print '-'*50 print '-'*50
scheduler.start_events() scheduler.start_events()
""" """
BEGIN SERVER STARTUP METHODS BEGIN SERVER STARTUP METHODS
""" """
def load_cmd_aliases(self): def load_cmd_aliases(self):
""" """
Load up our command aliases. Load up our command aliases.
""" """
alias_list = CommandAlias.objects.all() alias_list = CommandAlias.objects.all()
for alias in alias_list: for alias in alias_list:
self.cmd_alias_list[alias.user_input] = alias.equiv_command self.cmd_alias_list[alias.user_input] = alias.equiv_command
print ' Command Aliases Loaded: %i' % (len(self.cmd_alias_list),) print ' Command Aliases Loaded: %i' % (len(self.cmd_alias_list),)
pass pass
def sqlite3_prep(self): def sqlite3_prep(self):
""" """
Optimize some SQLite stuff at startup since we can't save it to the Optimize some SQLite stuff at startup since we can't save it to the
database. database.
""" """
cursor = connection.cursor() cursor = connection.cursor()
cursor.execute("PRAGMA cache_size=10000") cursor.execute("PRAGMA cache_size=10000")
cursor.execute("PRAGMA synchronous=OFF") cursor.execute("PRAGMA synchronous=OFF")
cursor.execute("PRAGMA count_changes=OFF") cursor.execute("PRAGMA count_changes=OFF")
cursor.execute("PRAGMA temp_store=2") cursor.execute("PRAGMA temp_store=2")
""" """
BEGIN GENERAL METHODS BEGIN GENERAL METHODS
""" """
def shutdown(self, message='The server has been shutdown. Please check back soon.'): def shutdown(self, message='The server has been shutdown. Please check back soon.'):
functions_general.announce_all(message) functions_general.announce_all(message)
session_mgr.disconnect_all_sessions() session_mgr.disconnect_all_sessions()
reactor.callLater(0, reactor.stop) reactor.callLater(0, reactor.stop)
def command_list(self): def command_list(self):
""" """
Return a string representing the server's command list. Return a string representing the server's command list.
""" """
clist = cmdtable.ctable.keys() clist = cmdtable.ctable.keys()
clist.sort() clist.sort()
return clist return clist
def reload(self, session): def reload(self, session):
""" """
Reload modules that don't have any variables that can be reset. Reload modules that don't have any variables that can be reset.
For changes to the scheduler, server, or session_mgr modules, a cold For changes to the scheduler, server, or session_mgr modules, a cold
restart is needed. restart is needed.
""" """
reload_list = ['ansi', 'cmdhandler', 'commands.comsys', 'commands.general', reload_list = ['ansi', 'cmdhandler', 'commands.comsys', 'commands.general',
'commands.privileged', 'commands.unloggedin', 'defines_global', 'commands.privileged', 'commands.unloggedin', 'defines_global',
'events', 'functions_db', 'functions_general', 'functions_comsys', 'events', 'functions_db', 'functions_general', 'functions_comsys',
'functions_help', 'gameconf', 'session', 'apps.objects.models', 'functions_help', 'gameconf', 'session', 'apps.objects.models',
'apps.helpsys.models', 'apps.config.models'] 'apps.helpsys.models', 'apps.config.models']
for mod in reload_list: for mod in reload_list:
reload(sys.modules[mod]) reload(sys.modules[mod])
session.msg("Modules reloaded.") session.msg("Modules reloaded.")
functions_general.log_infomsg("Modules reloaded by %s." % (session,)) functions_general.log_infomsg("Modules reloaded by %s." % (session,))
def getEvenniaServiceFactory(self): def getEvenniaServiceFactory(self):
f = protocol.ServerFactory() f = protocol.ServerFactory()
f.protocol = SessionProtocol f.protocol = SessionProtocol
f.server = self f.server = self
return f return f
""" """
END Server CLASS END Server CLASS
""" """
application = service.Application('Evennia') application = service.Application('Evennia')
mud_service = EvenniaService('Evennia Server') mud_service = EvenniaService('Evennia Server')
@ -124,4 +124,4 @@ mud_service = EvenniaService('Evennia Server')
# Sheet sheet, fire ze missiles! # Sheet sheet, fire ze missiles!
serviceCollection = service.IServiceCollection(application) serviceCollection = service.IServiceCollection(application)
for port in settings.GAMEPORTS: for port in settings.GAMEPORTS:
internet.TCPServer(port, mud_service.getEvenniaServiceFactory()).setServiceParent(serviceCollection) internet.TCPServer(port, mud_service.getEvenniaServiceFactory()).setServiceParent(serviceCollection)

View file

@ -14,166 +14,166 @@ import ansi
import gameconf import gameconf
class SessionProtocol(StatefulTelnetProtocol): class SessionProtocol(StatefulTelnetProtocol):
""" """
This class represents a player's sesssion. From here we branch down into This class represents a player's sesssion. From here we branch down into
other various classes, please try to keep this one tidy! other various classes, please try to keep this one tidy!
""" """
def connectionMade(self): def connectionMade(self):
""" """
What to do when we get a connection. What to do when we get a connection.
""" """
self.prep_session() self.prep_session()
functions_general.log_infomsg('Connection: %s' % (self,)) functions_general.log_infomsg('Connection: %s' % (self,))
session_mgr.add_session(self) session_mgr.add_session(self)
self.game_connect_screen() self.game_connect_screen()
def getClientAddress(self): def getClientAddress(self):
""" """
Returns the client's address and port in a tuple. For example Returns the client's address and port in a tuple. For example
('127.0.0.1', 41917) ('127.0.0.1', 41917)
""" """
return self.transport.client return self.transport.client
def prep_session(self): def prep_session(self):
self.server = self.factory.server self.server = self.factory.server
self.address = self.getClientAddress() self.address = self.getClientAddress()
self.name = None self.name = None
self.uid = None self.uid = None
self.logged_in = False self.logged_in = False
# The time the user last issued a command. # The time the user last issued a command.
self.cmd_last = time.time() self.cmd_last = time.time()
# Player-visible idle time, excluding the IDLE command. # Player-visible idle time, excluding the IDLE command.
self.cmd_last_visible = time.time() self.cmd_last_visible = time.time()
# Total number of commands issued. # Total number of commands issued.
self.cmd_total = 0 self.cmd_total = 0
# The time when the user connected. # The time when the user connected.
self.conn_time = time.time() self.conn_time = time.time()
self.channels_subscribed = {} self.channels_subscribed = {}
def disconnectClient(self): def disconnectClient(self):
""" """
Manually disconnect the client. Manually disconnect the client.
""" """
self.transport.loseConnection() self.transport.loseConnection()
def connectionLost(self, reason): def connectionLost(self, reason):
""" """
Execute this when a client abruplty loses their connection. Execute this when a client abruplty loses their connection.
""" """
functions_general.log_infomsg('Disconnect: %s' % (self,)) functions_general.log_infomsg('Disconnect: %s' % (self,))
self.handle_close() self.handle_close()
def load_user_channels(self): def load_user_channels(self):
""" """
Un-pickle a user's channel list from their CHANLIST attribute. Un-pickle a user's channel list from their CHANLIST attribute.
""" """
chan_list = self.get_pobject().get_attribute_value("CHANLIST") chan_list = self.get_pobject().get_attribute_value("CHANLIST")
if chan_list: if chan_list:
self.channels_subscribed = pickle.loads(chan_list) self.channels_subscribed = pickle.loads(chan_list)
def lineReceived(self, data): def lineReceived(self, data):
""" """
Any line return indicates a command for the purpose of a MUD. So we take 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. the user input and pass it to our command handler.
""" """
line = (''.join(data)) line = (''.join(data))
line = line.strip('\r') line = line.strip('\r')
uinput = line uinput = line
# Stuff anything we need to pass in this dictionary. # Stuff anything we need to pass in this dictionary.
cdat = {"server": self.factory.server, "uinput": uinput, "session": self} cdat = {"server": self.factory.server, "uinput": uinput, "session": self}
cmdhandler.handle(cdat) cmdhandler.handle(cdat)
def execute_cmd(self, cmdstr): def execute_cmd(self, cmdstr):
"""
Executes a command as this session.
"""
self.lineReceived(data=cmdstr)
def handle_close(self):
""" """
Break the connection and do some accounting. Executes a command as this session.
""" """
pobject = self.get_pobject() self.lineReceived(data=cmdstr)
if pobject:
pobject.set_flag("CONNECTED", False) def handle_close(self):
pobject.get_location().emit_to_contents("%s has disconnected." % (pobject.get_name(show_dbref=False),), exclude=pobject) """
uaccount = pobject.get_user_account() Break the connection and do some accounting.
uaccount.last_login = datetime.now() """
uaccount.save() pobject = self.get_pobject()
if pobject:
self.disconnectClient() pobject.set_flag("CONNECTED", False)
self.logged_in = False pobject.get_location().emit_to_contents("%s has disconnected." % (pobject.get_name(show_dbref=False),), exclude=pobject)
session_mgr.remove_session(self) uaccount = pobject.get_user_account()
uaccount.last_login = datetime.now()
def get_pobject(self): uaccount.save()
"""
Returns the object associated with a session. self.disconnectClient()
""" self.logged_in = False
try: session_mgr.remove_session(self)
result = Object.objects.get(id=self.uid)
return result def get_pobject(self):
except: """
return False Returns the object associated with a session.
"""
def game_connect_screen(self): try:
""" result = Object.objects.get(id=self.uid)
Show the banner screen. Grab from the 'connect_screen' config directive. return result
""" except:
buffer = ansi.parse_ansi(gameconf.get_configvalue('connect_screen')) return False
self.msg(buffer)
def game_connect_screen(self):
"""
Show the banner screen. Grab from the 'connect_screen' config directive.
"""
buffer = ansi.parse_ansi(gameconf.get_configvalue('connect_screen'))
self.msg(buffer)
def is_loggedin(self): def is_loggedin(self):
""" """
Returns a boolean True if the session is logged in. Returns a boolean True if the session is logged in.
""" """
try: try:
return self.logged_in return self.logged_in
except: except:
return False return False
def login(self, user): def login(self, user):
""" """
After the user has authenticated, handle logging him in. After the user has authenticated, handle logging him in.
""" """
self.uid = user.id self.uid = user.id
self.name = user.username self.name = user.username
self.logged_in = True self.logged_in = True
self.conn_time = time.time() self.conn_time = time.time()
pobject = self.get_pobject() pobject = self.get_pobject()
session_mgr.disconnect_duplicate_session(self) session_mgr.disconnect_duplicate_session(self)
pobject.set_flag("CONNECTED", True) pobject.set_flag("CONNECTED", True)
self.msg("You are now logged in as %s." % (self.name,)) self.msg("You are now logged in as %s." % (self.name,))
pobject.get_location().emit_to_contents("%s has connected." % (pobject.get_name(show_dbref=False),), exclude=pobject) pobject.get_location().emit_to_contents("%s has connected." % (pobject.get_name(show_dbref=False),), exclude=pobject)
self.execute_cmd("look") self.execute_cmd("look")
functions_general.log_infomsg("Login: %s" % (self,)) functions_general.log_infomsg("Login: %s" % (self,))
# Update their account's last login time. # Update their account's last login time.
user.last_login = datetime.now() user.last_login = datetime.now()
user.save() user.save()
pobject.set_attribute("Last", "%s" % (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()),)) pobject.set_attribute("Last", "%s" % (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()),))
pobject.set_attribute("Lastsite", "%s" % (self.address[0],)) pobject.set_attribute("Lastsite", "%s" % (self.address[0],))
# Load their channel selection from a pickled attribute. # Load their channel selection from a pickled attribute.
self.load_user_channels() self.load_user_channels()
def msg(self, message): def msg(self, message):
""" """
Sends a message to the session. Sends a message to the session.
""" """
if isinstance(message, unicode): if isinstance(message, unicode):
message = message.encode("utf-8") message = message.encode("utf-8")
self.sendLine("%s" % (message,)) self.sendLine("%s" % (message,))
def __str__(self): def __str__(self):
""" """
String representation of the user session class. We use String representation of the user session class. We use
this a lot in the server logs and stuff. this a lot in the server logs and stuff.
""" """
if self.is_loggedin(): if self.is_loggedin():
symbol = '#' symbol = '#'
else: else:
symbol = '?' symbol = '?'
return "<%s> %s@%s" % (symbol, self.name, self.address,) return "<%s> %s@%s" % (symbol, self.name, self.address,)

View file

@ -9,94 +9,94 @@ Session manager, handles connected players.
session_list = [] session_list = []
def add_session(session): def add_session(session):
""" """
Adds a session to the session list. Adds a session to the session list.
""" """
session_list.insert(0, session) session_list.insert(0, session)
functions_general.log_infomsg('Sessions active: %d' % (len(get_session_list(return_unlogged=True),))) functions_general.log_infomsg('Sessions active: %d' % (len(get_session_list(return_unlogged=True),)))
def get_session_list(return_unlogged=False): def get_session_list(return_unlogged=False):
""" """
Lists the connected session objects. Lists the connected session objects.
""" """
if return_unlogged: if return_unlogged:
return session_list return session_list
else: else:
return [sess for sess in session_list if sess.is_loggedin()] return [sess for sess in session_list if sess.is_loggedin()]
def disconnect_all_sessions(): def disconnect_all_sessions():
""" """
Cleanly disconnect all of the connected sessions. Cleanly disconnect all of the connected sessions.
""" """
for sess in get_session_list(): for sess in get_session_list():
sess.handle_close() sess.handle_close()
def disconnect_duplicate_session(session): def disconnect_duplicate_session(session):
""" """
Disconnects any existing session under the same object. This is used in Disconnects any existing session under the same object. This is used in
connection recovery to help with record-keeping. connection recovery to help with record-keeping.
""" """
sess_list = get_session_list() sess_list = get_session_list()
new_pobj = session.get_pobject() new_pobj = session.get_pobject()
for sess in sess_list: for sess in sess_list:
if new_pobj == sess.get_pobject() and sess != session: if new_pobj == sess.get_pobject() and sess != session:
sess.msg("Your account has been logged in from elsewhere, disconnecting.") sess.msg("Your account has been logged in from elsewhere, disconnecting.")
sess.disconnectClient() sess.disconnectClient()
return True return True
return False return False
def check_all_sessions(): def check_all_sessions():
""" """
Check all currently connected sessions and see if any are dead. Check all currently connected sessions and see if any are dead.
""" """
idle_timeout = int(gameconf.get_configvalue('idle_timeout')) idle_timeout = int(gameconf.get_configvalue('idle_timeout'))
if len(session_list) <= 0: if len(session_list) <= 0:
return return
if idle_timeout <= 0: if idle_timeout <= 0:
return return
for sess in get_session_list(return_unlogged=True): for sess in get_session_list(return_unlogged=True):
if (time.time() - sess.cmd_last) > idle_timeout: if (time.time() - sess.cmd_last) > idle_timeout:
sess.msg("Idle timeout exceeded, disconnecting.") sess.msg("Idle timeout exceeded, disconnecting.")
sess.handle_close() sess.handle_close()
def remove_session(session): def remove_session(session):
""" """
Removes a session from the session list. Removes a session from the session list.
""" """
try: try:
session_list.remove(session) session_list.remove(session)
functions_general.log_infomsg('Sessions active: %d' % (len(get_session_list()),)) functions_general.log_infomsg('Sessions active: %d' % (len(get_session_list()),))
except: except:
#functions_general.log_errmsg("Unable to remove session: %s" % (session,)) #functions_general.log_errmsg("Unable to remove session: %s" % (session,))
pass pass
def session_from_object(targobject): def session_from_object(targobject):
""" """
Return the session object given a object (if there is one open). Return the session object given a object (if there is one open).
session_list: (list) The server's session_list attribute. session_list: (list) The server's session_list attribute.
targobject: (Object) The object to match. targobject: (Object) The object to match.
""" """
results = [prospect for prospect in session_list if prospect.get_pobject() == targobject] results = [prospect for prospect in session_list if prospect.get_pobject() == targobject]
if results: if results:
return results[0] return results[0]
else: else:
return False return False
def session_from_dbref(dbstring): def session_from_dbref(dbstring):
""" """
Return the session object given a dbref (if there is one open). Return the session object given a dbref (if there is one open).
dbstring: (int) The dbref number to match against. dbstring: (int) The dbref number to match against.
""" """
if is_dbref(dbstring): if is_dbref(dbstring):
results = [prospect for prospect in session_list if prospect.get_pobject().dbref_match(dbstring)] results = [prospect for prospect in session_list if prospect.get_pobject().dbref_match(dbstring)]
if results: if results:
return results[0] return results[0]
else: else:
return False return False

28
urls.py
View file

@ -10,21 +10,21 @@ from django.conf.urls.defaults import *
import settings import settings
urlpatterns = patterns('', urlpatterns = patterns('',
# User Authentication # User Authentication
(r'^accounts/login', 'django.contrib.auth.views.login'), (r'^accounts/login', 'django.contrib.auth.views.login'),
(r'^accounts/logout', 'django.contrib.auth.views.logout'), (r'^accounts/logout', 'django.contrib.auth.views.logout'),
# Admin interface # Admin interface
(r'^admin/', include('django.contrib.admin.urls')), (r'^admin/', include('django.contrib.admin.urls')),
# Front page # Front page
(r'^', include('apps.website.urls')), (r'^', include('apps.website.urls')),
# News stuff # News stuff
(r'^news/', include('apps.news.urls')), (r'^news/', include('apps.news.urls')),
# Page place-holder for things that aren't implemented yet. # Page place-holder for things that aren't implemented yet.
(r'^tbi/', 'apps.website.views.to_be_implemented'), (r'^tbi/', 'apps.website.views.to_be_implemented'),
) )
# If you'd like to serve media files via Django (strongly not recommended!), # If you'd like to serve media files via Django (strongly not recommended!),
@ -33,6 +33,6 @@ urlpatterns = patterns('',
# test server. Normally you want a webserver that is optimized for serving # test server. Normally you want a webserver that is optimized for serving
# static content to handle media files (apache, lighttpd). # static content to handle media files (apache, lighttpd).
if settings.SERVE_MEDIA: if settings.SERVE_MEDIA:
urlpatterns += patterns('', urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
) )