* mudpy.py (User.negotiate_telnet_options): Added support for RFC
1184 linemode and RFC 858 go ahead suppression. Automated end of
record/go ahead prompt terminator selection via Telnet option
negotiation. Added support for Telnet suboption negotiation. Fixed a
double-IAC escape matching error.
(User.send): Refactored away some spaghetti logic for better
readability.
(log): Added syslog support.
-[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.
+[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
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
+link_e = location:143
+link_n = location:128
+description_e = This is a simple merchant's booth.
+link_s = location:126
+name = South First Street
-[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.
+[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.
-link_e = location:119
-keywords_n = ['booth']
-description_n = This is a simple merchant's booth.
-link_w = location:116
-link_n = location:147
+name = The Corner of Fifth and Fourth
+link_w = location:119
+link_n = location:121
+
+[location:143]
+link_w = location:127
+terrain = inside
+name = New BuildWalk Room
+description = This unfinished room was created by Imp.
+
+[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
+link_n = location:133
+description_e = This is a simple merchant's booth.
+link_s = location:131
+name = North First Street
[location:159]
link_s = location:101
[location:159]
link_s = location:101
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?
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
+[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
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.
+link_e = location:150
+link_n = location:103
+description_e = This is the entrance to a shop.
+link_s = location:121
+name = South Fifth Street
[location:151]
terrain = inside
[location:151]
terrain = inside
description = This unfinished room was created by Imp.
[location:150]
description = This unfinished room was created by Imp.
[location:150]
name = New BuildWalk Room
description = This unfinished room was created by Imp.
[location:153]
name = New BuildWalk Room
description = This unfinished room was created by Imp.
[location:153]
-description = This unfinished room was created by Imp.
name = New BuildWalk Room
name = New BuildWalk Room
+description = This unfinished room was created by Imp.
name = New BuildWalk Room
description = This unfinished room was created by Imp.
[location:155]
name = New BuildWalk Room
description = This unfinished room was created by Imp.
[location:155]
name = New BuildWalk Room
description = This unfinished room was created by Imp.
name = New BuildWalk Room
description = This unfinished room was created by Imp.
description = This unfinished room was created by Imp.
[location:157]
description = This unfinished room was created by Imp.
[location:157]
-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.
+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.
[location:156]
terrain = inside
[location:156]
terrain = inside
[location:115]
link_n = location:114
[location:115]
link_n = location:114
+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.
-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
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.
+name = South Seventh Street
[location:114]
keywords_e = ['booth']
[location:114]
keywords_e = ['booth']
pickproof_e = yes
terrain = city
link_e = location:155
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
description_e = This is a simple merchant's booth.
link_s = location:115
+name = South Seventh Street
[location:117]
description_s = This gate leads from the market to the city proper.
[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
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
closeable_s = yes
keywords_s = ['gate']
link_s = location:0
pickproof_s = yes
+name = South Market Gate
[location:116]
link_n = location:115
[location:116]
link_n = location:115
+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.
terrain = city
link_e = location:118
terrain = city
link_e = location:118
-name = South Seventh and Fourth
link_s = location:117
link_w = location:123
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.
+name = South Seventh and Fourth
[location:111]
pickproof_n = yes
name = North Market Gate
closeable_n = yes
[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.
keywords_n = ['gate']
link_s = location:110
description_n = This gate leads from the market to the city proper.
keywords_n = ['gate']
link_s = location:110
description_n = 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 South, Seventh Street heads into the market while the rest of the city lies trough the gate to the North.
[location:110]
link_n = location:111
[location:110]
link_n = location:111
+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.
terrain = city
link_e = location:109
terrain = city
link_e = location:109
-name = North Seventh and Third
link_s = location:112
link_w = location:135
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.
+name = North Seventh and Third
[location:113]
link_n = location:112
[location:113]
link_n = location:112
+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.
-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
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.
+name = North Seventh Street
[location:112]
keywords_e = ['booth']
[location:112]
keywords_e = ['booth']
pickproof_e = yes
terrain = city
link_e = location:138
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
description_e = This is a simple merchant's booth.
link_s = location:113
+name = North Seventh Street
[location:137]
terrain = inside
[location:137]
terrain = inside
[location:136]
description_w = This gate leads from the market to the city proper.
[location:136]
description_w = 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 East, Sixth Avenue heads into the market while the rest of the city lies trough the gate to the West.
terrain = city
link_e = location:128
terrain = city
link_e = location:128
keywords_w = ['gate']
closeable_w = yes
pickproof_w = yes
link_w = location:0
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.
[location:135]
description_s = This is a simple merchant's booth.
pickproof_n = yes
name = West Third Avenue
closeable_n = yes
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
terrain = city
link_e = location:135
keywords_n = ['shop']
description_n = This is the entrance to a shop.
link_w = location:133
keywords_n = ['shop']
description_n = This is the entrance to a shop.
link_w = location:133
+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.
[location:119]
description_s = This is the entrance to a shop.
[location:119]
description_s = This is the entrance to a shop.
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.
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
+[location:118]
+pickproof_n = yes
+name = East Fourth Avenue
+closeable_n = yes
-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
+link_e = location:119
+link_n = location:147
+keywords_n = ['booth']
+description_n = This is a simple merchant's booth.
+link_w = location:116
+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.
[location:131]
link_n = location:132
[location:131]
link_n = 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. First Street runs North and South here while a storefront beckons to the West.
-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
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.
+name = North First Street
[location:130]
description_s = This is a simple merchant's booth.
[location:130]
description_s = This is a simple merchant's booth.
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.
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
+[location:123]
+description_s = This is the entrance to a shop.
+name = West Fourth Avenue
-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.
+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.
-description = This unfinished room was created by Imp.
name = New BuildWalk Room
name = New BuildWalk Room
+description = This unfinished room was created by Imp.
[location:149]
terrain = inside
[location:149]
terrain = inside
description = This unfinished room was created by Imp.
[location:146]
description = This unfinished room was created by Imp.
[location:146]
-description = This unfinished room was created by Imp.
name = New BuildWalk Room
name = New BuildWalk Room
+description = This unfinished room was created by Imp.
[location:147]
link_s = location:118
[location:147]
link_s = location:118
link_e = location:131
description = This unfinished room was created by Imp.
link_e = location:131
description = This unfinished room was created by Imp.
+[location:138]
+link_w = location:112
name = New BuildWalk Room
description = This unfinished room was created by Imp.
name = New BuildWalk Room
description = This unfinished room was created by Imp.
description = This unfinished room was created by Imp.
[location:141]
description = This unfinished room was created by Imp.
[location:141]
name = New BuildWalk Room
description = This unfinished room was created by Imp.
[location:160]
name = New BuildWalk Room
description = This unfinished room was created by Imp.
[location:160]
-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
name = Blacksmith's Booth
+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.
[location:161]
link_n = location:113
[location:161]
link_n = location:113
+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.
terrain = city
link_e = location:101
terrain = city
link_e = location:101
link_s = location:114
link_w = location:130
link_u = location:100
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.
[location:108]
description_s = This is a simple merchant's booth.
pickproof_n = yes
name = East Third Avenue
closeable_n = yes
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
terrain = city
link_e = location:108
keywords_n = ['shop']
description_n = This is the entrance to a shop.
link_w = location:110
keywords_n = ['shop']
description_n = This is the entrance to a shop.
link_w = location:110
+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.
[location:128]
link_n = location:131
[location:128]
link_n = location:131
+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.
terrain = city
link_e = location:129
terrain = city
link_e = location:129
-name = First and West Sixth
link_s = location:127
link_w = location:136
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.
+name = First and West Sixth
-description = This unfinished room was created by Imp.
name = New BuildWalk Room
name = New BuildWalk Room
+description = This unfinished room was created by Imp.
[location:102]
description_s = This is a simple merchant's booth.
[location:102]
description_s = This is a simple merchant's booth.
[location:103]
link_n = location:105
[location:103]
link_n = location:105
+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.
terrain = city
link_e = location:104
terrain = city
link_e = location:104
-name = Fifth and East Sixth
link_s = location:122
link_w = location:102
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.
+name = Fifth and East Sixth
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
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
-[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
+[location:101]
+pickproof_n = yes
+name = East Sixth Avenue
+closeable_n = yes
-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
+link_e = location:102
+link_n = location:159
+keywords_n = ['booth']
+description_n = This is a simple merchant's booth.
+link_w = location:161
+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.
-[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.
+[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
-name = The Corner of Fifth and Fourth
-link_w = location:119
-link_n = location:121
+link_e = location:152
+link_n = location:107
+description_e = This is the entrance to a shop.
+link_s = location:105
+name = North Fifth Street
[location:121]
link_n = location:122
[location:121]
link_n = location:122
+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.
-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
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.
+name = South Fifth Street
-[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.
+[location:104]
+keywords_e = ['gate']
+name = East Market Gate
closeable_e = yes
pickproof_e = yes
terrain = city
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
+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:123]
-description_s = This is the entrance to a shop.
-name = West Fourth Avenue
+[location:105]
+link_n = location:106
+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.
-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.
+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
+name = North Fifth Street
[location:124]
pickproof_n = yes
name = West Fourth Avenue
closeable_n = yes
[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
terrain = city
link_e = location:123
keywords_n = ['booth']
description_n = This is a simple merchant's booth.
link_w = location:125
keywords_n = ['booth']
description_n = This is a simple merchant's booth.
link_w = 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. Fourth Avenue runs East and West here while a merchant's booth lies to the North.
[location:133]
name = The Corner of First and Third
[location:133]
name = The Corner of First and Third
pickproof_n = yes
name = West Sixth Avenue
closeable_n = yes
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
terrain = city
link_e = location:130
keywords_n = ['booth']
description_n = This is a simple merchant's booth.
link_w = location:128
keywords_n = ['booth']
description_n = This is a simple merchant's booth.
link_w = location:128
+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.
-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
terrain = city
link_e = location:124
name = The Corner of First and Fourth
+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.
[location:107]
name = The Corner of Fifth and Third
[location:107]
name = The Corner of Fifth and Third
[location:126]
link_n = location:127
[location:126]
link_n = location:127
+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.
-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
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.
+name = South First Street
prompt = Enter a new password for "$(account)":
error_differs = The two passwords did not match. Try again...
prompt = Enter a new password for "$(account)":
error_differs = The two passwords did not match. Try again...
[menu:main_utility]
action_c = user.new_avatar()
branch_a = activate_avatar
[menu:main_utility]
action_c = user.new_avatar()
branch_a = activate_avatar
from random import choice, randrange
from socket import AF_INET, SO_REUSEADDR, SOCK_STREAM, SOL_SOCKET, socket
from stat import S_IMODE, ST_MODE
from random import choice, randrange
from socket import AF_INET, SO_REUSEADDR, SOCK_STREAM, SOL_SOCKET, socket
from stat import S_IMODE, ST_MODE
-from telnetlib import DO, DONT, ECHO, EOR, IAC, WILL, WONT
+from syslog import LOG_PID, LOG_INFO, LOG_DAEMON, closelog, openlog, syslog
+from telnetlib import DO, DONT, ECHO, EOR, GA, IAC, LINEMODE, SB, SE, SGA, WILL, WONT
from time import asctime, sleep
class Element:
from time import asctime, sleep
class Element:
self.connection = None
self.authenticated = False
self.password_tries = 0
self.connection = None
self.authenticated = False
self.password_tries = 0
- self.state = "entering_account_name"
self.menu_seen = False
self.error = ""
self.input_queue = []
self.output_queue = []
self.partial_input = ""
self.echoing = True
self.menu_seen = False
self.error = ""
self.input_queue = []
self.output_queue = []
self.partial_input = ""
self.echoing = True
+ self.terminator = IAC+GA
+ self.negotiation_pause = 0
self.avatar = None
self.account = None
self.avatar = None
self.account = None
"""Send the user their current menu."""
if not self.menu_seen:
self.menu_choices = get_menu_choices(self)
"""Send the user their current menu."""
if not self.menu_seen:
self.menu_choices = get_menu_choices(self)
- self.send(get_menu(self.state, self.error, self.echoing, self.menu_choices), "")
+ self.send(get_menu(self.state, self.error, self.echoing, self.terminator, self.menu_choices), "")
self.menu_seen = True
self.error = False
self.adjust_echoing()
self.menu_seen = True
self.error = False
self.adjust_echoing()
"""Remove a user from the list of connected users."""
universe.userlist.remove(self)
"""Remove a user from the list of connected users."""
universe.userlist.remove(self)
- def send(self, output, eol="$(eol)"):
+ def send(self, output, eol="$(eol)", raw=False):
"""Send arbitrary text to a connected user."""
"""Send arbitrary text to a connected user."""
- # start with a newline, append the message, then end
- # with the optional eol string passed to this function
- # and the ansi escape to return to normal text
- output = "\r\n" + output + eol + chr(27) + "[0m"
+ # unless raw mode is on, clean it up all nice and pretty
+ if not raw:
- # find and replace macros in the output
- output = replace_macros(self, output)
+ # we'll take out GA or EOR and add them back on the end
+ if output.endswith(IAC+GA) or output.endswith(IAC+EOR):
+ terminate = True
+ output = output[:-2]
+ else: terminate = False
- # wrap the text at 80 characters
- output = wrap_ansi_text(output, 80)
+ # start with a newline, append the message, then end
+ # with the optional eol string passed to this function
+ # and the ansi escape to return to normal text
+ output = "\r\n" + output + eol + chr(27) + "[0m"
- # drop the formatted output into the output queue
- self.output_queue.append(output)
+ # find and replace macros in the output
+ output = replace_macros(self, output)
- # try to send the last item in the queue and remove it
- try:
- self.connection.send(self.output_queue[0])
- del self.output_queue[0]
+ # wrap the text at 80 characters
+ output = wrap_ansi_text(output, 80)
- # but if we can't, that's okay too
- except:
- pass
+ # tack the terminator back on
+ if terminate: output += self.terminator
+
+ # drop the output into the user's output queue
+ self.output_queue.append(output)
def pulse(self):
"""All the things to do to the user per increment."""
def pulse(self):
"""All the things to do to the user per increment."""
self.state = "disconnecting"
self.menu_seen = False
self.state = "disconnecting"
self.menu_seen = False
+ # if output is paused, decrement the counter
+ if self.state == "initial":
+ if self.negotiation_pause: self.negotiation_pause -= 1
+ else: self.state = "entering_account_name"
+
# show the user a menu as needed
# show the user a menu as needed
# disconnect users with the appropriate state
if self.state == "disconnecting": self.quit()
# disconnect users with the appropriate state
if self.state == "disconnecting": self.quit()
# the user is unique and not flagged to disconnect
else:
# the user is unique and not flagged to disconnect
else:
+ # try to send the last item in the queue and remove it
+ if self.output_queue:
+ try:
+ self.connection.send(self.output_queue[0])
+ del self.output_queue[0]
+
+ # but if we can't, that's okay too
+ except:
+ pass
+
# check for input and add it to the queue
self.enqueue_input()
# check for input and add it to the queue
self.enqueue_input()
# if there wasn't an IAC in the input, skip to the end
if position < 0: position = len(text)
# if there wasn't an IAC in the input, skip to the end
if position < 0: position = len(text)
- # replace a double (literal) IAC and move on
+ # replace a double (literal) IAC if there's an LF later
elif len(text) > position+1 and text[position+1] == IAC:
elif len(text) > position+1 and text[position+1] == IAC:
- text = text.replace(IAC+IAC, IAC)
+ if text.find("\n", position) > 0: text = text.replace(IAC+IAC, IAC)
+ else: position += 1
position += 1
# this must be an option negotiation
elif len(text) > position+2 and text[position+1] in (DO, DONT, WILL, WONT):
position += 1
# this must be an option negotiation
elif len(text) > position+2 and text[position+1] in (DO, DONT, WILL, WONT):
+ negotiation = text[position+1:position+3]
+
# if we turned echo off, ignore the confirmation
# if we turned echo off, ignore the confirmation
- if not self.echoing and text[position+1:position+3] == DO+ECHO: pass
+ if not self.echoing and negotiation == DO+ECHO: pass
+
+ # allow LINEMODE
+ elif negotiation == WILL+LINEMODE: self.send(IAC+DO+LINEMODE, raw=True)
+
+ # if the client likes EOR instead of GA, make a note of it
+ elif negotiation == DO+EOR: self.terminator = IAC+EOR
+ elif negotiation == DONT+EOR and self.terminator == IAC+EOR:
+ self.terminator = IAC+GA
+
+ # if the client doesn't want GA, oblige
+ elif negotiation == DO+SGA and self.terminator == IAC+GA:
+ self.terminator = ""
+ self.send(IAC+WILL+SGA, raw=True)
# we don't want to allow anything else
# we don't want to allow anything else
- elif text[position+1] in (DO, WILL): self.send(IAC+WONT+text[position+2])
+ elif text[position+1] == DO: self.send(IAC+WONT+text[position+2], raw=True)
+ elif text[position+1] == WILL: self.send(IAC+DONT+text[position+2], raw=True)
# strip the negotiation from the input
text = text.replace(text[position:position+3], "")
# strip the negotiation from the input
text = text.replace(text[position:position+3], "")
+ # get rid of IAC SB .* IAC SE
+ elif len(text) > position+4 and text[position:position+2] == IAC+SB:
+ end_subnegotiation = text.find(IAC+SE, position)
+ if end_subnegotiation > 0: text = text[:position] + text[end_subnegotiation+2:]
+ else: position += 1
+
# otherwise, strip out a two-byte IAC command
# otherwise, strip out a two-byte IAC command
- else: text = text.replace(text[position:position+2], "")
+ elif len(text) > position+2: text = text.replace(text[position:position+2], "")
+
+ # and this means we got the begining of an IAC
+ else: position += 1
# replace the input with our cleaned-up text
self.partial_input = text
# replace the input with our cleaned-up text
self.partial_input = text
# send the timestamp and message to standard output
print(timestamp + " " + message)
# send the timestamp and message to standard output
print(timestamp + " " + message)
+ # send the message to the system log
+ openlog("mudpy", LOG_PID, LOG_INFO | LOG_DAEMON)
+ syslog(message)
+ closelog()
+
def wrap_ansi_text(text, width):
"""Wrap text with arbitrary width while ignoring ANSI colors."""
def wrap_ansi_text(text, width):
"""Wrap text with arbitrary width while ignoring ANSI colors."""
# set the user's ipa from the connection's ipa
user.address = address[0]
# set the user's ipa from the connection's ipa
user.address = address[0]
+ # let the client know we WILL EOR
+ user.send(IAC+WILL+EOR, raw=True)
+ user.negotiation_pause = 2
+
# return the new user object
return user
# return the new user object
return user
-def get_menu(state, error=None, echoing=True, choices={}):
+def get_menu(state, error=None, echoing=True, terminator="", choices=None):
"""Show the correct menu text to a user."""
"""Show the correct menu text to a user."""
+ # make sure we don't reuse a mutable sequence by default
+ if choices is None: choices = {}
+
# begin with a telnet echo command sequence if needed
message = get_echo_sequence(state, echoing)
# begin with a telnet echo command sequence if needed
message = get_echo_sequence(state, echoing)
# display a message indicating if echo is off
message += get_echo_message(state)
# display a message indicating if echo is off
message += get_echo_message(state)
- # tack on IAC EOR to indicate the prompt will not be followed by CRLF
- message += IAC+EOR
+ # tack on EOR or GA to indicate the prompt will not be followed by CRLF
+ message += terminator
# return the assembly of various strings defined above
return message
# return the assembly of various strings defined above
return message