[control]
read_only = yes
-[command:quit]
-action = command_quit(user, command, parameters)
-description = Leave Example.
-help = This will save your account and disconnect your client connection.
+[command:create]
+action = command_create(user, parameters)
+administrative = yes
+description = Create a new element in the universe.
+help = Ways to create an element:$(eol)$(eol) create actor:fred$(eol) create other:garply foo/bar/baz
+
+[command:delete]
+action = command_delete(user, parameters)
+administrative = yes
+description = Delete an existing facet from an element.
+help = You can delete any facet of an element as follows:$(eol)$(eol) delete location:boardroom terrain
+
+[command:destroy]
+action = command_destroy(user, parameters)
+administrative = yes
+description = Destroy an existing element in the universe.
+help = You can destroy any element in the universe as follows:$(eol)$(eol) destroy prop:dagger
[command:halt]
-action = command_halt(user, command, parameters)
+action = command_halt(user, parameters)
+administrative = yes
description = Shut down the world.
help = This will save all active accounts, disconnect all clients and stop the entire program.
[command:help]
-action = command_help(user, command, parameters)
+action = command_help(user, parameters)
description = List commands or get help on one.
help = This will list all comand words available to you along with a brief description or, alternatively, give you detailed information on one command.
-[command:show]
-action = command_show(user, command, parameters)
-description = Show program data.
-help = For now, this is used to show things like "avatars", "time" and "universe".
+[command:quit]
+action = user.state = "main_utility"
+description = Leave Example.
+help = This will save your account and disconnect your client connection.
[command:reload]
-action = command_reload(user, command, parameters)
+action = command_reload(user)
+administrative = yes
description = Reload code modules and data.
help = This will reload all python code modules, reload configuration files and re-read data files.
[command:say]
-action = command_say(user, command, parameters)
+action = command_say(user, parameters)
description = State something out loud.
help = This allows you to speak to other characters within the same room. If you end your sentence with specific punctuation, the aparent speech action (ask, exclaim, et cetera) will be adapted accordingly. It will also add punctuation and capitalize your message where needed.
+[command:set]
+action = command_set(user, parameters)
+administrative = yes
+description = Set a facet of an element.
+help = Invoke it like this:$(eol)$(eol) set actor:dominique description You see nothing special.
+
+[command:show]
+action = command_show(user, parameters)
+administrative = yes
+description = Show element data.
+help = Here are the possible incantations:$(eol)$(eol) show categories$(eol) show category actor$(eol) show element location:1:2:3:4$(eol) show files$(eol) show time
+
--- /dev/null
+[location:101]
+pickproof_n = yes
+name = East Sixth Avenue
+closeable_n = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Sixth Avenue runs East and West here while a merchant's booth lies to the North.
+terrain = city
+link_e = location:102
+keywords_n = ['booth']
+description_n = This is a simple merchant's booth.
+link_w = location:161
+link_n = location:159
+
+[location:106]
+keywords_e = ['shop']
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Fifth Street runs North and South here while a storefront beckons to the East.
+closeable_e = yes
+pickproof_e = yes
+terrain = city
+link_e = location:152
+name = North Fifth Street
+description_e = This is the entrance to a shop.
+link_s = location:105
+link_n = location:107
+
+[location:118]
+pickproof_n = yes
+name = East Fourth Avenue
+closeable_n = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Fourth Avenue runs East and West here while a merchant's booth lies to the North.
+terrain = city
+link_e = location:119
+keywords_n = ['booth']
+description_n = This is a simple merchant's booth.
+link_w = location:116
+link_n = location:147
+
+[location:159]
+link_s = location:101
+terrain = inside
+name = Tanner's Booth
+description = The smell of leather goods fills your nostrils. Tanned, finished and embroidered leather is hung and piled everywhere.
+
+[location:158]
+name = Cobbler's Booth
+terrain = inside
+closeable_s = yes
+keywords_s = ['booth']
+link_s = location:129
+pickproof_s = yes
+description = Shoes, shoes and more shoes... You need footwear, we have footwear. Look around, see what you like. Best prices in town! So you gonna buy something, stranger?
+
+[location:104]
+keywords_e = ['gate']
+name = East Market Gate
+closeable_e = yes
+pickproof_e = yes
+terrain = city
+link_e = location:0
+description_e = This gate leads from the market to the city proper.
+link_w = location:103
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the West, Sixth Avenue heads into the market while the rest of the city lies trough the gate to the East.
+
+[location:151]
+terrain = inside
+name = New BuildWalk Room
+link_e = location:105
+description = This unfinished room was created by Imp.
+
+[location:150]
+terrain = inside
+link_w = location:122
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[location:153]
+link_n = location:108
+terrain = inside
+description = This unfinished room was created by Imp.
+name = New BuildWalk Room
+
+[location:152]
+terrain = inside
+link_w = location:106
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[location:155]
+terrain = inside
+link_w = location:114
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[location:154]
+link_s = location:109
+terrain = inside
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[location:157]
+link_n = location:130
+terrain = inside
+description = This booth sells cloth garments of every description. Fine silks and linens line the walls, draped from every protrusion and stacked on every surface.
+name = Tailor's Booth
+
+[location:156]
+terrain = inside
+name = New BuildWalk Room
+link_e = location:115
+description = This unfinished room was created by Imp.
+
+[location:115]
+link_n = location:114
+terrain = city
+name = South Seventh Street
+keywords_w = ['booth']
+closeable_w = yes
+description_w = This is a simple merchant's booth.
+link_s = location:116
+pickproof_w = yes
+link_w = location:156
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Seventh Street runs North and South here while a merchant's booth lies to the West.
+
+[location:114]
+keywords_e = ['booth']
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Seventh Street runs North and South here while a merchant's booth lies to the East.
+closeable_e = yes
+pickproof_e = yes
+terrain = city
+link_e = location:155
+name = South Seventh Street
+description_e = This is a simple merchant's booth.
+link_s = location:115
+link_n = location:161
+
+[location:117]
+description_s = This gate leads from the market to the city proper.
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the North, Seventh Street heads into the market while the rest of the city lies trough the gate to the South.
+terrain = city
+name = South Market Gate
+closeable_s = yes
+keywords_s = ['gate']
+link_s = location:0
+pickproof_s = yes
+link_n = location:116
+
+[location:116]
+link_n = location:115
+terrain = city
+link_e = location:118
+name = South Seventh and Fourth
+link_s = location:117
+link_w = location:123
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the East and West lies Fourth Avenue while Seventh Street runs North and South.
+
+[location:111]
+pickproof_n = yes
+name = North Market Gate
+closeable_n = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the South, Seventh Street heads into the market while the rest of the city lies trough the gate to the North.
+terrain = city
+keywords_n = ['gate']
+link_s = location:110
+description_n = This gate leads from the market to the city proper.
+link_n = location:0
+
+[location:110]
+link_n = location:111
+terrain = city
+link_e = location:109
+name = North Seventh and Third
+link_s = location:112
+link_w = location:135
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the East and West lies Third Avenue while Seventh Street runs North and South.
+
+[location:113]
+link_n = location:112
+terrain = city
+name = North Seventh Street
+keywords_w = ['booth']
+closeable_w = yes
+description_w = This is a simple merchant's booth.
+link_s = location:161
+pickproof_w = yes
+link_w = location:137
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Seventh Street runs North and South here while a merchant's booth lies to the West.
+
+[location:112]
+keywords_e = ['booth']
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Seventh Street runs North and South here while a merchant's booth lies to the East.
+closeable_e = yes
+pickproof_e = yes
+terrain = city
+link_e = location:138
+name = North Seventh Street
+description_e = This is a simple merchant's booth.
+link_s = location:113
+link_n = location:110
+
+[location:137]
+terrain = inside
+name = New BuildWalk Room
+link_e = location:113
+description = This unfinished room was created by Imp.
+
+[location:136]
+description_w = This gate leads from the market to the city proper.
+terrain = city
+link_e = location:128
+name = West Market Gate
+keywords_w = ['gate']
+closeable_w = yes
+pickproof_w = yes
+link_w = location:0
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the East, Sixth Avenue heads into the market while the rest of the city lies trough the gate to the West.
+
+[location:135]
+description_s = This is a simple merchant's booth.
+name = West Third Avenue
+terrain = city
+link_e = location:110
+closeable_s = yes
+keywords_s = ['booth']
+link_s = location:139
+link_w = location:134
+pickproof_s = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Third Avenue runs East and West here while a merchant's booth lies to the South.
+
+[location:134]
+pickproof_n = yes
+name = West Third Avenue
+closeable_n = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Third Avenue runs East and West here while a storefront beckons to the North.
+terrain = city
+link_e = location:135
+keywords_n = ['shop']
+description_n = This is the entrance to a shop.
+link_w = location:133
+link_n = location:140
+
+[location:119]
+description_s = This is the entrance to a shop.
+name = East Fourth Avenue
+terrain = city
+link_e = location:120
+closeable_s = yes
+keywords_s = ['shop']
+link_s = location:148
+link_w = location:118
+pickproof_s = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Fourth Avenue runs East and West here while a storefront beckons to the South.
+
+[location:132]
+keywords_e = ['booth']
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. First Street runs North and South here while a merchant's booth lies to the East.
+closeable_e = yes
+pickproof_e = yes
+terrain = city
+link_e = location:141
+name = North First Street
+description_e = This is a simple merchant's booth.
+link_s = location:131
+link_n = location:133
+
+[location:131]
+link_n = location:132
+terrain = city
+name = North First Street
+keywords_w = ['shop']
+closeable_w = yes
+description_w = This is the entrance to a shop.
+link_s = location:128
+pickproof_w = yes
+link_w = location:142
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. First Street runs North and South here while a storefront beckons to the West.
+
+[location:130]
+description_s = This is a simple merchant's booth.
+name = West Sixth Avenue
+terrain = city
+link_e = location:161
+closeable_s = yes
+keywords_s = ['booth']
+link_s = location:157
+link_w = location:129
+pickproof_s = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Sixth Avenue runs East and West here while a merchant's booth lies to the South.
+
+[location:105]
+link_n = location:106
+terrain = city
+name = North Fifth Street
+keywords_w = ['booth']
+closeable_w = yes
+description_w = This is a simple merchant's booth.
+link_s = location:103
+pickproof_w = yes
+link_w = location:151
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Fifth Street runs North and South here while a merchant's booth lies to the West.
+
+[location:138]
+terrain = inside
+link_w = location:112
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[location:148]
+link_n = location:119
+terrain = inside
+description = This unfinished room was created by Imp.
+name = New BuildWalk Room
+
+[location:149]
+terrain = inside
+name = New BuildWalk Room
+link_e = location:121
+description = This unfinished room was created by Imp.
+
+[location:146]
+link_n = location:123
+terrain = inside
+description = This unfinished room was created by Imp.
+name = New BuildWalk Room
+
+[location:147]
+link_s = location:118
+terrain = inside
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[location:144]
+terrain = inside
+name = New BuildWalk Room
+link_e = location:126
+description = This unfinished room was created by Imp.
+
+[location:145]
+link_s = location:124
+terrain = inside
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[location:142]
+terrain = inside
+name = New BuildWalk Room
+link_e = location:131
+description = This unfinished room was created by Imp.
+
+[location:143]
+terrain = inside
+link_w = location:127
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[location:140]
+link_s = location:134
+terrain = inside
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[location:141]
+terrain = inside
+link_w = location:132
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[location:160]
+link_n = location:102
+terrain = inside
+description = You find yourself amidst cold, hard steel and iron equipment of every possible description. A slight breeze brings tinkle and clank sounds from all around you.
+name = Blacksmith's Booth
+
+[location:161]
+link_n = location:113
+terrain = city
+link_e = location:101
+name = Second Square
+link_s = location:114
+link_w = location:130
+link_u = location:100
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the East and West lies Sixth Avenue while Seventh Street runs North and South. A short flight of stairs leads up to the bandstand.
+
+[location:108]
+description_s = This is a simple merchant's booth.
+name = East Third Avenue
+terrain = city
+link_e = location:107
+closeable_s = yes
+keywords_s = ['booth']
+link_s = location:153
+link_w = location:109
+pickproof_s = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Third Avenue runs East and West here while a merchant's booth lies to the South.
+
+[location:109]
+pickproof_n = yes
+name = East Third Avenue
+closeable_n = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Third Avenue runs East and West here while a storefront beckons to the North.
+terrain = city
+link_e = location:108
+keywords_n = ['shop']
+description_n = This is the entrance to a shop.
+link_w = location:110
+link_n = location:154
+
+[location:128]
+link_n = location:131
+terrain = city
+link_e = location:129
+name = First and West Sixth
+link_s = location:127
+link_w = location:136
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the East and West lies Sixth Avenue while First Street runs North and South.
+
+[location:139]
+link_n = location:135
+terrain = inside
+description = This unfinished room was created by Imp.
+name = New BuildWalk Room
+
+[location:102]
+description_s = This is a simple merchant's booth.
+name = East Sixth Avenue
+terrain = city
+link_e = location:103
+closeable_s = yes
+keywords_s = ['booth']
+link_s = location:160
+link_w = location:101
+pickproof_s = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Sixth Avenue runs East and West here while a merchant's booth lies to the South.
+
+[location:103]
+link_n = location:105
+terrain = city
+link_e = location:104
+name = Fifth and East Sixth
+link_s = location:122
+link_w = location:102
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the East and West lies Sixth Avenue while Fifth Street runs North and South.
+
+[location:100]
+terrain = inside
+description = The stand is currently not in use for a performance, but shoppers gather here to rest and chat with one another. A pleasantly cool breeze coupled with a nice view of the market make this a good place to relax and recover energy.
+name = The Bandstand
+link_d = location:161
+
+[location:127]
+keywords_e = ['booth']
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. First Street runs North and South here while a merchant's booth lies to the East.
+closeable_e = yes
+pickproof_e = yes
+terrain = city
+link_e = location:143
+name = South First Street
+description_e = This is a simple merchant's booth.
+link_s = location:126
+link_n = location:128
+
+[location:120]
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the West lies Fourth Avenue while Fifth Street leads North.
+terrain = city
+name = The Corner of Fifth and Fourth
+link_w = location:119
+link_n = location:121
+
+[location:121]
+link_n = location:122
+terrain = city
+name = South Fifth Street
+keywords_w = ['booth']
+closeable_w = yes
+description_w = This is a simple merchant's booth.
+link_s = location:120
+pickproof_w = yes
+link_w = location:149
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Fifth Street runs North and South here while a merchant's booth lies to the West.
+
+[location:122]
+keywords_e = ['shop']
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Fifth Street runs North and South here while a storefront beckons to the East.
+closeable_e = yes
+pickproof_e = yes
+terrain = city
+link_e = location:150
+name = South Fifth Street
+description_e = This is the entrance to a shop.
+link_s = location:121
+link_n = location:103
+
+[location:123]
+description_s = This is the entrance to a shop.
+name = West Fourth Avenue
+terrain = city
+link_e = location:116
+closeable_s = yes
+keywords_s = ['shop']
+link_s = location:146
+link_w = location:124
+pickproof_s = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Fourth Avenue runs East and West here while a storefront beckons to the South.
+
+[location:124]
+pickproof_n = yes
+name = West Fourth Avenue
+closeable_n = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Fourth Avenue runs East and West here while a merchant's booth lies to the North.
+terrain = city
+link_e = location:123
+keywords_n = ['booth']
+description_n = This is a simple merchant's booth.
+link_w = location:125
+link_n = location:145
+
+[location:133]
+name = The Corner of First and Third
+terrain = city
+link_e = location:134
+link_s = location:132
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the East lies Third Avenue while First Street leads South.
+
+[location:129]
+pickproof_n = yes
+name = West Sixth Avenue
+closeable_n = yes
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. Sixth Avenue runs East and West here while a merchant's booth lies to the North.
+terrain = city
+link_e = location:130
+keywords_n = ['booth']
+description_n = This is a simple merchant's booth.
+link_w = location:128
+link_n = location:158
+
+[location:125]
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the East lies Fourth Avenue while First Street leads North.
+terrain = city
+link_e = location:124
+name = The Corner of First and Fourth
+link_n = location:126
+
+[location:107]
+name = The Corner of Fifth and Third
+terrain = city
+link_s = location:106
+link_w = location:108
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. To the West lies Third Avenue while Fifth Street leads South.
+
+[location:126]
+link_n = location:127
+terrain = city
+name = South First Street
+keywords_w = ['shop']
+closeable_w = yes
+description_w = This is the entrance to a shop.
+link_s = location:125
+pickproof_w = yes
+link_w = location:144
+description = You find the hustle and bustle of this place remarkably distracting. The streets are filled with people of all races, buying and selling goods of every variety. First Street runs North and South here while a storefront beckons to the West.
+
prompt = >
[menu:checking_new_account_name]
-action_d = user.account.delete()
-action_g = user.account.delete()
+action_d = user.account.destroy()
+action_g = user.account.destroy()
branch_d = disconnecting
branch_g = entering_account_name
branch_n = entering_new_password
prompt = Choose a name for $(tpop):
[menu:delete_account]
-action_y = user.delete()
+action_y = user.destroy()
branch_n = main_utility
branch_y = disconnecting
choice_n = no, don't delete my account
[control]
default_files = {"account": "account", "actor": "actor", "command": "command", "internal": "internal", "location": "location", "menu": "menu", "other": "other" }
+include_files = example
private_files = account
read_only = yes
DataFile(self.origin, universe)
if not universe.files[self.origin].data.has_section(self.key):
universe.files[self.origin].data.add_section(self.key)
- def delete(self):
- log("Deleting: " + self.key + ".")
+ def destroy(self):
+ """Remove an element from the universe and destroy it."""
+ log("Destroying: " + self.key + ".")
universe.files[self.origin].data.remove_section(self.key)
del universe.categories[self.category][self.subkey]
del universe.contents[self.key]
del self
+ def delete(self, facet):
+ """Delete a facet from the element."""
+ if universe.files[self.origin].data.has_option(self.key, facet):
+ universe.files[self.origin].data.remove_option(self.key, facet)
def facets(self):
"""Return a list of facets for this element."""
return universe.files[self.origin].data.options(self.key)
DataFile(include_file, universe)
def save(self):
if ( self.data.sections() or exists(self.filename) ) and not ( self.data.has_option("control", "read_only") and self.data.getboolean("control", "read_only") ):
- if not exists(dirname(self.filename)): makedirs(dirname)
+ if not exists(dirname(self.filename)): makedirs(dirname(self.filename))
file_descriptor = file(self.filename, "w")
if self.filename in universe.private_files and oct(S_IMODE(stat(self.filename)[ST_MODE])) != 0600:
chmod(self.filename, 0600)
# put on the end of the queue
self.input_queue.append(line)
+ def can_run(self, command):
+ """Check if the user can run this command object."""
+
+ # has to be in the commands category
+ if command not in universe.categories["command"].values(): result = False
+
+ # administrators can run any command
+ elif self.account.getboolean("administrator"): result = True
+
+ # everyone can run non-administrative commands
+ elif not command.getboolean("administrative"): result = True
+
+ # otherwise the command cannot be run by this user
+ else: result = False
+
+ # pass back the result
+ return result
+
def new_avatar(self):
"""Instantiate a new, unconfigured avatar for this user."""
counter = 0
def delete_avatar(self, avatar):
"""Remove an avatar from the world and from the user's list."""
if self.avatar is universe.contents[avatar]: self.avatar = None
- universe.contents[avatar].delete()
+ universe.contents[avatar].destroy()
avatars = self.account.getlist("avatars")
avatars.remove(avatar)
self.account.set("avatars", avatars)
- def delete(self):
- """Delete the user and associated avatars."""
+ def destroy(self):
+ """Destroy the user and associated avatars."""
for avatar in self.account.getlist("avatars"): self.delete_avatar(avatar)
- self.account.delete()
+ self.account.destroy()
def list_avatar_names(self):
"""List names of assigned avatars."""
return text
+def escape_macros(text):
+ """Escapes replacement macros in text."""
+ return text.replace("$(", "$_(")
+
def check_time(frequency):
"""Check for a factor of the current increment count."""
if type(frequency) is str:
# too many tries, so adios
else:
user.send("$(eol)$(red)Too many failed password attempts...$(nrm)$(eol)")
- user.account.delete()
+ user.account.destroy()
user.state = "disconnecting"
def handler_verifying_new_password(user):
# otherwise, sayonara
else:
user.send("$(eol)$(red)Too many failed password attempts...$(nrm)$(eol)")
- user.account.delete()
+ user.account.destroy()
user.state = "disconnecting"
def handler_active(user):
# split out the command (first word) and parameters (everything else)
if input_data.find(" ") > 0:
- command, parameters = input_data.split(" ", 1)
+ command_name, parameters = input_data.split(" ", 1)
else:
- command = input_data
+ command_name = input_data
parameters = ""
# lowercase the command
- command = command.lower()
+ command_name = command_name.lower()
# the command matches a command word for which we have data
- if command in universe.categories["command"]:
- exec(universe.categories["command"][command].get("action"))
+ if command_name in universe.categories["command"]:
+ command = universe.categories["command"][command_name]
+ else: command = None
- # no data matching the entered command word
- elif command: command_error(user, command, parameters)
+ # if it's allowed, do it
+ if user.can_run(command): exec(command.get("action"))
-def command_halt(user, command="", parameters=""):
+ # otherwise, give an error
+ elif command_name: command_error(user, input_data)
+
+def command_halt(user, parameters):
"""Halt the world."""
# see if there's a message or use a generic one
# set a flag to terminate the world
universe.terminate_world = True
-def command_reload(user, command="", parameters=""):
+def command_reload(user):
"""Reload all code modules, configs and data."""
# let the user know and log
# set a flag to reload
universe.reload_modules = True
-def command_quit(user, command="", parameters=""):
- """Quit the world."""
- user.state = "main_utility"
-
-def command_help(user, command="", parameters=""):
+def command_help(user, parameters):
"""List available commands and provide help for commands."""
# did the user ask for help on a specific command word?
# is the command word one for which we have data?
if parameters in universe.categories["command"]:
+ command = universe.categories["command"][parameters]
+ else: command = None
+
+ # only for allowed commands
+ if user.can_run(command):
# add a description if provided
- description = universe.categories["command"][parameters].get("description")
+ description = command.get("description")
if not description:
description = "(no short description provided)"
- output = "$(grn)" + parameters + "$(nrm) - " + description + "$(eol)$(eol)"
+ if command.getboolean("administrative"): output = "$(red)"
+ else: output = "$(grn)"
+ output += parameters + "$(nrm) - " + description + "$(eol)$(eol)"
# add the help text if provided
- help_text = universe.categories["command"][parameters].get("help")
+ help_text = command.get("help")
if not help_text:
help_text = "No help is provided for this command."
output += help_text
sorted_commands = universe.categories["command"].keys()
sorted_commands.sort()
for item in sorted_commands:
- description = universe.categories["command"][item].get("description")
- if not description:
- description = "(no short description provided)"
- output += " $(grn)" + item + "$(nrm) - " + description + "$(eol)"
+ command = universe.categories["command"][item]
+ if user.can_run(command):
+ description = command.get("description")
+ if not description:
+ description = "(no short description provided)"
+ if command.getboolean("administrative"): output += " $(red)"
+ else: output += " $(grn)"
+ output += item + "$(nrm) - " + description + "$(eol)"
output += "$(eol)Enter \"help COMMAND\" for help on a command named \"COMMAND\"."
# send the accumulated output to the user
user.send(output)
-def command_say(user, command="", parameters=""):
+def command_say(user, parameters):
"""Speak to others in the same room."""
# check for replacement macros
# tell the room
# TODO: we won't be using broadcast once there are actual rooms
- broadcast(user.account.get("name") + " " + action + "s, \"" + message + "\"")
+ broadcast(user.avatar.get("name") + " " + action + "s, \"" + message + "\"")
# there was no message
else:
user.send("What do you want to say?")
-def command_show(user, command="", parameters=""):
+def command_show(user, parameters):
"""Show program data."""
- if parameters == "avatars":
- message = "These are the avatars managed by your account:$(eol)"
- avatars = user.list_avatar_names()
- avatars.sort()
- for avatar in avatars: message += "$(eol) $(grn)" + avatar + "$(nrm)"
- elif parameters == "files":
- message = "These are the current files containing the universe:$(eol)"
- keys = universe.files.keys()
- keys.sort()
- for key in keys: message += "$(eol) $(grn)" + key + "$(nrm)"
- elif parameters == "universe":
- message = "These are the current elements in the universe:$(eol)"
- keys = universe.contents.keys()
- keys.sort()
- for key in keys: message += "$(eol) $(grn)" + key + "$(nrm)"
- elif parameters == "time":
- message = universe.categories["internal"]["counters"].get("elapsed") + " increments elapsed since the world was created."
- elif parameters: message = "I don't know what \"" + parameters + "\" is."
- else: message = "What do you want to show?"
+ message = ""
+ if parameters.find(" ") < 1:
+ if parameters == "time":
+ message = universe.categories["internal"]["counters"].get("elapsed") + " increments elapsed since the world was created."
+ elif parameters == "categories":
+ message = "These are the element categories:$(eol)"
+ categories = universe.categories.keys()
+ categories.sort()
+ for category in categories: message += "$(eol) $(grn)" + category + "$(nrm)"
+ elif parameters == "files":
+ message = "These are the current files containing the universe:$(eol)"
+ filenames = universe.files.keys()
+ filenames.sort()
+ for filename in filenames: message += "$(eol) $(grn)" + filename + "$(nrm)"
+ else: message = ""
+ else:
+ arguments = parameters.split()
+ if arguments[0] == "category":
+ if arguments[1] in universe.categories:
+ message = "These are the elements in the \"" + arguments[1] + "\" category:$(eol)"
+ elements = universe.categories[arguments[1]].keys()
+ elements.sort()
+ for element in elements:
+ message += "$(eol) $(grn)" + universe.categories[arguments[1]][element].key + "$(nrm)"
+ elif arguments[0] == "element":
+ if arguments[1] in universe.contents:
+ message = "These are the properties of the \"" + arguments[1] + "\" element:$(eol)"
+ element = universe.contents[arguments[1]]
+ facets = element.facets()
+ facets.sort()
+ for facet in facets:
+ message += "$(eol) $(grn)" + facet + ": $(red)" + escape_macros(element.get(facet)) + "$(nrm)"
+ if not message:
+ if parameters: message = "I don't know what \"" + parameters + "\" is."
+ else: message = "What do you want to show?"
+ user.send(message)
+
+def command_create(user, parameters):
+ """Create an element if it does not exist."""
+ if not parameters: message = "You must at least specify an element to create."
+ else:
+ arguments = parameters.split()
+ if len(arguments) == 1: arguments.append("")
+ if len(arguments) == 2:
+ element, filename = arguments
+ if element in universe.contents: message = "The \"" + element + "\" element already exists."
+ else:
+ message = "You create \"" + element + "\" within the universe."
+ logline = user.account.get("name") + " created an element: " + element
+ if filename:
+ logline += " in file " + filename
+ if filename not in universe.files:
+ message += " Warning: \"" + filename + "\" is not yet included in any other file and will not be read on startup unless this is remedied."
+ Element(element, universe, filename)
+ log(logline)
+ elif len(arguments) > 2: message = "You can only specify an element and a filename."
+ user.send(message)
+
+def command_destroy(user, parameters):
+ """Destroy an element if it exists."""
+ if not parameters: message = "You must specify an element to destroy."
+ else:
+ if parameters not in universe.contents: message = "The \"" + parameters + "\" element does not exist."
+ else:
+ universe.contents[parameters].destroy()
+ message = "You destroy \"" + parameters + "\" within the universe."
+ log(user.account.get("name") + " destroyed an element: " + parameters)
+ user.send(message)
+
+def command_set(user, parameters):
+ """Set a facet of an element."""
+ if not parameters: message = "You must specify an element, a facet and a value."
+ else:
+ arguments = parameters.split(" ", 2)
+ if len(arguments) == 1: message = "What facet of element \"" + arguments[0] + "\" would you like to set?"
+ elif len(arguments) == 2: message = "What value would you like to set for the \"" + arguments[1] + "\" facet of the \"" + arguments[0] + "\" element?"
+ else:
+ element, facet, value = arguments
+ if element not in universe.contents: message = "The \"" + element + "\" element does not exist."
+ else:
+ universe.contents[element].set(facet, value)
+ message = "You have successfully (re)set the \"" + facet + "\" facet of element \"" + element + "\". Try \"show element " + element + "\" for verification."
+ user.send(message)
+
+def command_delete(user, parameters):
+ """Delete a facet from an element."""
+ if not parameters: message = "You must specify an element and a facet."
+ else:
+ arguments = parameters.split(" ")
+ if len(arguments) == 1: message = "What facet of element \"" + arguments[0] + "\" would you like to delete?"
+ elif len(arguments) != 2: message = "You may only specify an element and a facet."
+ else:
+ element, facet = arguments
+ if element not in universe.contents: message = "The \"" + element + "\" element does not exist."
+ elif facet not in universe.contents[element].facets(): message = "The \"" + element + "\" element has no \"" + facet + "\" facet."
+ else:
+ universe.contents[element].delete(facet)
+ message = "You have successfully deleted the \"" + facet + "\" facet of element \"" + element + "\". Try \"show element " + element + "\" for verification."
user.send(message)
-def command_error(user, command="", parameters=""):
+def command_error(user, input_data):
"""Generic error for an unrecognized command word."""
# 90% of the time use a generic error
if randrange(10):
- message = "I'm not sure what \"" + command
- if parameters:
- message += " " + parameters
- message += "\" means..."
+ message = "I'm not sure what \"" + input_data + "\" means..."
# 10% of the time use the classic diku error
else: