Migration needed. Changed how connection screens are defined, rather than being a database model, they are created on-the fly. I didn't migrate over the screen data into the new module file though, so if you had custom connection screens, you need to manually add them to the new module in gamesrc/world/connection_screen.py.

This commit is contained in:
Griatch 2011-04-10 14:21:41 +00:00
parent 52785e8f3e
commit 2ee54678ae
12 changed files with 110 additions and 174 deletions

View file

View file

@ -0,0 +1,28 @@
#
# This module holds textual connection screen definitions. All global
# string variables (only) in this module are read by Evennia and
# assumed to define a Connection screen.
#
# The names of the string variables doesn't matter (except they
# shouldn't start with _), but each should hold a string defining a
# connection screen - as seen when first connecting to the game
# (before having logged in). If there are more than one string
# variable defined, a random one is picked.
#
# After adding new connection screens to this module you must
# either reboot or reload the server to make them available.
#
from src.utils import utils
DEFAULT_SCREEN = \
"""{b=============================================================={n
Welcome to {gEvennia{n, version %s!
If you have an existing account, connect to it by typing:
{wconnect <email> <password>{n
If you need to create an account, type (without the <>'s):
{wcreate \"<username>\" <email> <password>{n
Enter {whelp{n for more info. {wlook{n will re-load this screen.
{b=============================================================={n""" % utils.get_evennia_version()

View file

View file

@ -2,18 +2,19 @@
Commands that are available from the connect screen.
"""
import traceback
#from django.contrib.auth.models import User
from django.conf import settings
from django.contrib.auth.models import User
from src.server import sessionhandler
from src.players.models import PlayerDB
from src.objects.models import ObjectDB
from src.config.models import ConfigValue, ConnectScreen
from src.config.models import ConfigValue
from src.comms.models import Channel
from src.utils import create, logger, utils, ansi
from src.commands.default.muxcommand import MuxCommand
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
class CmdConnect(MuxCommand):
"""
Connect to the game.
@ -252,8 +253,8 @@ class CmdUnconnectedLook(MuxCommand):
def func(self):
"Show the connect screen."
try:
screen = ConnectScreen.objects.get_random_connect_screen()
string = ansi.parse_ansi(screen.text)
screen = utils.string_from_module(CONNECTION_SCREEN_MODULE)
string = ansi.parse_ansi(screen)
self.caller.msg(string)
except Exception, e:
self.caller.msg(e)
@ -272,35 +273,30 @@ class CmdUnconnectedHelp(MuxCommand):
"Shows help"
string = \
"""Welcome to Evennia!
Commands available at this point:
create - create a new account
connect - login with an existing account
look - re-show the connect screen
help - this help
quit - leave
"""
You are not yet logged into the game. Commands available at this point:
{wcreate, connect, look, help, quit{n
To login to the system, you need to do one of the following:
1) If you have no previous account, you need to use the 'create'
{w1){n If you have no previous account, you need to use the 'create'
command like this:
> create "Anna the Barbarian" anna@myemail.com c67jHL8p
{wcreate "Anna the Barbarian" anna@myemail.com c67jHL8p{n
It's always a good idea (not only here, but everywhere on the net)
to not use a regular word for your password. Make it longer than
3 characters (ideally 6 or more) and mix numbers and capitalization
into it.
2) If you have an account already, either because you just created
one in 1) above or you are returning, use the 'connect' command:
{w2){n If you have an account already, either because you just created
one in {w1){n above or you are returning, use the 'connect' command:
> connect anna@myemail.com c67jHL8p
{wconnect anna@myemail.com c67jHL8p{n
This should log you in. Run 'help' again once you're logged in
This should log you in. Run {whelp{n again once you're logged in
to get more aid. Hope you enjoy your stay!
You can use the 'look' command if you want to see the connect screen again.
You can use the {wlook{n command if you want to see the connect screen again.
"""
self.caller.msg(string)

View file

@ -65,27 +65,3 @@ class ConfigValueManager(models.Manager):
self.set_configvalue(db_key, db_value)
else:
return self.get_configvalue(db_key, default=default)
class ConnectScreenManager(models.Manager):
"""
This handles the random initial login screen system.
"""
def get_random_connect_screen(self):
"""
Returns a random active connect screen.
"""
try:
return self.filter(db_is_active=True).order_by('?')[0]
except IndexError:
ConnectScreen = ContentType.objects.get(app_label="config",
model="connectscreen").model_class()
text = "This is a placeholder connect screen. "
text += "Remind your admin to edit it."
new_screen = ConnectScreen(db_key='Default',
db_text=text,
db_is_active=True)
new_screen.save()
return new_screen

View file

@ -0,0 +1,35 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
from src.utils import utils
class Migration(SchemaMigration):
def forwards(self, orm):
# Deleting model 'ConnectScreen'
db.delete_table('config_connectscreen')
def backwards(self, orm):
# Adding model 'ConnectScreen'
db.create_table('config_connectscreen', (
('db_key', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('db_is_active', self.gf('django.db.models.fields.BooleanField')(default=True)),
('db_text', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal('config', ['ConnectScreen'])
models = {
'config.configvalue': {
'Meta': {'object_name': 'ConfigValue'},
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'db_value': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
}
}
complete_apps = ['config']

View file

@ -9,7 +9,6 @@ ConnectScreen model - cycling connect screens
from django.db import models
from src.utils.idmapper.models import SharedMemoryModel
from src.config.manager import ConfigValueManager
from src.config.manager import ConnectScreenManager
#------------------------------------------------------------
#
@ -93,99 +92,3 @@ class ConfigValue(SharedMemoryModel):
def __unicode__(self):
return "%s" % self.key
#------------------------------------------------------------
## ConnectScreen
#
#------------------------------------------------------------
class ConnectScreen(SharedMemoryModel):
"""
Stores connect screens. The admins may have only one or multiple, which
will cycle randomly.
Properties on ConnectScreen:
key - optional identifier
text - the text to show
is_active - if the screen is in rotation
"""
#
# ConnectScreen database model setup
#
# These database fields are all set using their corresponding properties,
# named same as the field, but withtout the db_* prefix.
#
# optional identifier
db_key = models.CharField(max_length=255, blank=True)
# connect screen text (ansi may be used)
db_text = models.TextField()
# if this screen should be used in rotation
db_is_active = models.BooleanField(default=True)
# Database manager
objects = ConnectScreenManager()
# Wrapper properties to easily set database fields. These are
# @property decorators that allows to access these fields using
# normal python operations (without having to remember to save()
# etc). So e.g. a property 'attr' has a get/set/del decorator
# defined that allows the user to do self.attr = value,
# value = self.attr and del self.attr respectively (where self
# is the object in question).
# key property (wraps db_key)
#@property
def key_get(self):
"Getter. Allows for value = self.key"
return self.db_key
#@key.setter
def key_set(self, value):
"Setter. Allows for self.key = value"
self.db_key = value
self.save()
#@key.deleter
def key_del(self):
"Deleter. Allows for del self.key. Deletes entry."
self.delete()
key = property(key_get, key_set, key_del)
# text property (wraps db_text)
#@property
def text_get(self):
"Getter. Allows for value = self.text"
return self.db_text
#@text.setter
def text_set(self, value):
"Setter. Allows for self.text = value"
self.db_text = value
self.save()
#@text.deleter
def text_del(self):
"Deleter. Allows for del self.text."
raise Exception("You can't delete the text of the connect screen!")
text = property(text_get, text_set, text_del)
# is_active property (wraps db_is_active)
#@property
def is_active_get(self):
"Getter. Allows for value = self.is_active"
return self.db_is_active
#@is_active.setter
def is_active_set(self, value):
"Setter. Allows for self.is_active = value"
self.db_is_active = value
self.save()
#@is_active.deleter
def is_active_del(self):
"Deleter. Allows for del self.is_active."
self.db_is_active = False
self.save()
is_active = property(is_active_get, is_active_set, is_active_del)
class Meta:
"Define Django meta options"
verbose_name = "Connect Screen"
verbose_name_plural = "Connect Screens"

View file

@ -21,23 +21,6 @@ def create_config_values():
ConfigValue.objects.conf("site_name", settings.SERVERNAME)
ConfigValue.objects.conf("idle_timeout", settings.IDLE_TIMEOUT)
def create_connect_screens():
"""
Creates the default connect screen(s).
"""
print " Creating startup screen(s) ..."
text = "{b=================================================================={n"
text += "\r\n Welcome to {wEvennia{n! Please type one of the following to begin:\r\n"
text += "\r\n If you have an existing account, connect to it by typing:\r\n "
text += "{wconnect <email> <password>{n\r\n If you need to create an account, "
text += "type (without the <>'s):\r\n "
text += "{wcreate \"<username>\" <email> <password>{n\r\n"
text += "\r\n Enter {whelp{n for more info. {wlook{n will re-show this screen.\r\n"
text += "{b=================================================================={n\r\n"
ConnectScreen(db_key="Default", db_text=text, db_is_active=True).save()
def get_god_user():
"""
Returns the initially created 'god' User object.
@ -203,7 +186,6 @@ def handle_setup(last_step):
# setting up the list of functions to run
setup_queue = [
create_config_values,
create_connect_screens,
create_objects,
create_channels,
create_system_scripts,

View file

@ -79,16 +79,11 @@ class TelnetProtocol(StatefulTelnetProtocol, session.Session):
def at_connect(self):
"""
Show the banner screen. Grab from the 'connect_screen'
config directive. If more than one connect screen is
defined in the ConnectScreen attribute, it will be
random which screen is used.
Show the banner screen.
"""
self.telnet_markup = True
# show screen
screen = ConnectScreen.objects.get_random_connect_screen()
string = ansi.parse_ansi(screen.text)
self.at_data_out(string)
# show connection screen
self.execute_cmd('look')
def at_login(self, player):
"""

View file

@ -221,15 +221,10 @@ class WebClientSession(session.Session):
def at_connect(self):
"""
Show the banner screen. Grab from the 'connect_screen'
config directive. If more than one connect screen is
defined in the ConnectScreen attribute, it will be
random which screen is used.
Show the banner screen.
"""
# show screen
screen = ConnectScreen.objects.get_random_connect_screen()
#string = parse_html(screen.text)
self.at_data_out(screen.text)
self.execute_cmd('look')
def at_login(self, player):
"""

View file

@ -96,7 +96,10 @@ IDLE_COMMAND = "idle"
# Add sets for languages/regions your players are likely to use.
# (see http://en.wikipedia.org/wiki/Character_encoding)
ENCODINGS = ["utf-8", "latin-1", "ISO-8859-1"]
# The module holding text strings for the connection screen.
# This module should contain one ore more variables
# with strings defining the look of the screen.
CONNECTION_SCREEN_MODULE = "game.gamesrc.world.connection_screens"
###################################################
# Evennia Database config

View file

@ -7,6 +7,7 @@ be of use when designing your own game.
import os, sys, imp
import textwrap
import datetime
import random
from twisted.internet import threads
from django.conf import settings
from src.utils import ansi
@ -479,6 +480,7 @@ def mod_import(mod_path):
result = imp.find_module(modname, [path])
except ImportError:
log_trace("Could not find module '%s' (%s.py) at path '%s'" % (modname, modname, path))
return
try:
mod = imp.load_module(modname, *result)
except ImportError:
@ -487,3 +489,24 @@ def mod_import(mod_path):
# we have to close the file handle manually
result[0].close()
return mod
def string_from_module(modpath, variable=None):
"""
This obtains a string from a given module python path.
The variable must be global within that module - that is, defined in
the outermost scope of the module. The value of the
variable will be returned. If not found (or if it's not a string),
None is returned.
This is useful primarily for storing various game strings
in a module and extract them by name or randomly.
"""
mod = __import__(modpath, fromlist=[None])
if variable:
return mod.__dict__.get(variable, None)
else:
mvars = [val for key, val in mod.__dict__.items()
if not key.startswith('_') and isinstance(val, basestring)]
if not mvars:
return None
return mvars[random.randint(0, len(mvars)-1)]