Răsfoiți Sursa

Feat: cumulative update

dzp 9 luni în urmă
părinte
comite
b978055138
23 a modificat fișierele cu 250 adăugiri și 171 ștergeri
  1. 1 1
      SCRIPTS
  2. 13 2
      TODO
  3. 44 20
      docs/help.html
  4. 15 7
      docs/tutorial.html
  5. 8 0
      mods/igr.mods
  6. 55 42
      src/banner.c
  7. 7 11
      src/buffer.c
  8. 1 3
      src/chat.c
  9. 1 3
      src/daemon.c
  10. 4 2
      src/data.c
  11. 10 5
      src/draw.c
  12. 12 2
      src/help.c
  13. 1 3
      src/history.c
  14. 1 3
      src/line.c
  15. 41 18
      src/list.c
  16. 9 16
      src/log.c
  17. 10 7
      src/mapper.c
  18. 1 3
      src/path.c
  19. 1 3
      src/port.c
  20. 1 1
      src/ssl.c
  21. 1 1
      src/tintin.h
  22. 12 17
      src/tokenize.c
  23. 1 1
      src/trigger.c

+ 1 - 1
SCRIPTS

@@ -270,7 +270,7 @@
 #showme $temp
 
 #nop -------------------------------------------------------------------------
-#nop Draw a health bar. Alternatively: #draw bar -2 1 -2 20 {%1;%2<faa><afa>}
+#nop Draw a health bar. Alternatively: #draw bar -2 1 -2 20 {%1;%2;<faa><afa>}
 #nop -------------------------------------------------------------------------
 
 #alias {hpbar}

+ 13 - 2
TODO

@@ -1,6 +1,14 @@
+- switch to pcre2
+
+- #alias test {#if {1} {%1}} gives an error on an empty input.
+
+- check if #scan file is escaping braces
+
+- If I set #config log_level low then it ignores #log timestamp {%Y-%m-%d-%H:%M:%S}
+
 - Update script's --time-style=full-iso doesn't work on Mac.
 
-- Investigate: #var bla {{test};{tost};{tust}};#showme {--$bla[t%*]}
+- Investigate: EVENT_FLAG_UPDATE running as gtd->level->quiet++ in check_all_events
 
 - Add an example #edit script to SCRIPTS
 
@@ -24,6 +32,8 @@
 
 - comprehensive memory breakdown for variables/triggers/mapper/etc
 
+- #draw calign grid table {2} {2} {8} {42} {n;s;w;e} {n;s;w;e}; doesn't work properly.
+
 - a better trigger stack debug buffer
 
 - Problem with restoring true color subs.
@@ -51,6 +61,7 @@
 
 - Make #draw scroll grid table work properly.
 
+
 - update https://tintin.mudhalla.net/info/ansicolor/
 
 - Make sure #config compact also applies to the log file.
@@ -63,7 +74,7 @@
 
 - catch event to handle #map global exceptions
 
-- switch to pcre2
+
 
 - Add routine to escape 0x00 in port.c RECEIVED DATA event.
 

+ 44 - 20
docs/help.html

@@ -544,6 +544,8 @@ Related</span><span style='color:#AAA'>: <a href='#PORT'>port</a>
          3 - Yellow               8 - Skip
          4 - Blue                 9 - Default
 
+</span><span style='color:#FFF'>Example</span><span style='color:#AAA'>: #show &lt;125&gt;Bold green on a magenta background.
+
          For xterm 256 colors support use &lt;aaa&gt; to &lt;fff&gt; for RGB foreground
          colors and &lt;AAA&gt; to &lt;FFF&gt; for RGB background colors. For the grayscale
          foreground colors use &lt;g00&gt; to &lt;g23&gt;, for grayscale background colors
@@ -924,7 +926,7 @@ Command</span><span style='color:#AAA'>: #delay </span><span style='color:#FFF'>
 </span><span style='color:#AAA'>         The edit command can be used to turn the default line editor into a
          text editor.
 
-         </span><span style='color:#FFF'>#edit create &lt;arguments&gt;
+         </span><span style='color:#FFF'>#edit create [filename] [arguments]
 </span><span style='color:#AAA'>           Create an editor, initialize using the provided arguments.
 
          </span><span style='color:#FFF'>#edit load &lt;variable&gt;
@@ -943,10 +945,10 @@ Command</span><span style='color:#AAA'>: #delay </span><span style='color:#FFF'>
 </span><span style='color:#AAA'>           Suspend editing, similar to pressing enter except that no
            events are triggered.
 
-         </span><span style='color:#FFF'>#edit write &lt;filename
+         </span><span style='color:#FFF'>#edit write [filename]
 </span><span style='color:#AAA'>           Write the editor content to file.
 
-</span><span style='color:#FFF'>Example</span><span style='color:#AAA'>: #edit create {bli}{bla}{blo}
+</span><span style='color:#FFF'>Example</span><span style='color:#AAA'>: #edit create {bla.txt} {line 1} {line 2}
 
 </span><span style='color:#FFF'>Related</span><span style='color:#AAA'>: <a href='#CURSOR'>cursor</a> and <a href='#MACRO'>macro</a>.
 <a name='EDITING'></a>
@@ -1160,6 +1162,10 @@ Command</span><span style='color:#AAA'>: #delay </span><span style='color:#FFF'>
 </span><span style='color:#AAA'>         </span><span style='color:#FFF'>CLASS_LOAD [CLASS]
 </span><span style='color:#AAA'>           %0 class name
 
+         </span><span style='color:#5F5'>FORMAT EVENTS
+
+</span><span style='color:#AAA'>         </span><span style='color:#FFF'>REFORMAT &lt;MESSAGE&gt;     </span><span style='color:#AAA'>Use #return to change MESSAGE
+
          </span><span style='color:#5F5'>GAG EVENTS
 
 </span><span style='color:#AAA'>         </span><span style='color:#FFF'>GAG &lt;EVENT&gt;
@@ -1211,7 +1217,7 @@ Command</span><span style='color:#AAA'>: #delay </span><span style='color:#FFF'>
 </span><span style='color:#AAA'>           %0 old vnum  %1 new vnum  %2 exit name
 
          </span><span style='color:#FFF'>MAP REGION &lt;MOUSE&gt;, MAP ROOM &lt;MOUSE&gt;
-</span><span style='color:#AAA'>           %0 row  %1 col  %2 -row  %3 -col  %5 vnum  %6 info
+</span><span style='color:#AAA'>           %0 row  %1 col  %2 -row  %3 -col  %4 vnum  %5 info
 
          </span><span style='color:#5F5'>MOUSE EVENTS
 
@@ -1305,8 +1311,6 @@ Command</span><span style='color:#AAA'>: #delay </span><span style='color:#FFF'>
          </span><span style='color:#FFF'>UNKNOWN COMMAND        </span><span style='color:#AAA'>%0 raw text
          </span><span style='color:#FFF'>SIGUSR                 </span><span style='color:#AAA'>%0 signal
 
-         </span><span style='color:#FFF'>REFORMAT &lt;MESSAGE&gt;     </span><span style='color:#AAA'>Use #return to change MESSAGE
-
          </span><span style='color:#5F5'>TELNET EVENTS
 
 </span><span style='color:#AAA'>         </span><span style='color:#FFF'>IAC &lt;EVENT&gt;
@@ -1463,7 +1467,7 @@ Command</span><span style='color:#AAA'>: #delay </span><span style='color:#FFF'>
 
 </span><span style='color:#0AA'>      ####################################################################
       #</span><span style='color:#AAA'>                                                                  </span><span style='color:#0AA'>#
-      #</span><span style='color:#AAA'>                    T I N T I N + +   2.02.41b                    </span><span style='color:#0AA'>#
+      #</span><span style='color:#AAA'>                    T I N T I N + +   2.02.42                     </span><span style='color:#0AA'>#
       #</span><span style='color:#AAA'>                                                                  </span><span style='color:#0AA'>#
       #</span><span style='color:#AAA'>      Code by Peter Unold, Bill Reis, and Igor van den Hoven      </span><span style='color:#0AA'>#
       #</span><span style='color:#AAA'>                                                                  </span><span style='color:#0AA'>#
@@ -1640,7 +1644,7 @@ Command</span><span style='color:#AAA'>: #delay </span><span style='color:#FFF'>
          settings, as well as the list names that you can ignore.
 
          If you for example use #IGNORE ACTIONS ON actions will no longer
-         triger. Not every list can be ignored.
+         trigger. Not every list can be ignored.
 
 </span><span style='color:#FFF'>Related</span><span style='color:#AAA'>: <a href='#CLASS'>class</a>, <a href='#DEBUG'>debug</a>, <a href='#INFO'>info</a>, <a href='#KILL'>kill</a> and <a href='#MESSAGE'>message</a>.
 <a name='INDEX'></a>
@@ -2065,6 +2069,9 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
 </span><span style='color:#AAA'>         </span><span style='color:#FFF'>#line background &lt;argument&gt;
 </span><span style='color:#AAA'>           Prevent new session activation.
 
+         </span><span style='color:#FFF'>#line benchmark &lt;argument&gt;
+</span><span style='color:#AAA'>           Argument is executed and the elapsed time is reported after.
+
          </span><span style='color:#FFF'>#line capture &lt;variable&gt; &lt;argument&gt;
 </span><span style='color:#AAA'>           Argument is executed and output stored in &lt;variable&gt;.
 
@@ -2154,8 +2161,8 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          #list {var} {tokenize} &lt;string&gt;        Create a character list
 
          The index should be between +1 and the list's size. You can also give
-         a negative value, in which case -1 equals the last item in the list, -2
-         the second last, etc.
+         a negative value, in which case -1 equals the last item in the list,
+         -2 the second last, etc.
 
          When inserting an item a positive index will prepend the item at the
          given index, while a negative index will append the item.
@@ -2173,7 +2180,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
 
          The indexate option prepares a table or list table for order, sort,
          filter, refine, and find operations for the given key. It is similar
-         to the SELECT option in SQL.
+         to the SELECT option in SQL. All entries must contain the given key.
 
          A size of 0 is returned for an empty or non-existent list. You can
          directly access the size of a list using &amp;var[].
@@ -2537,8 +2544,13 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
 
 </span><span style='color:#FFF'>Command</span><span style='color:#AAA'>: #log </span><span style='color:#FFF'>{</span><span style='color:#AAA'>option</span><span style='color:#FFF'>} {</span><span style='color:#AAA'>argument</span><span style='color:#FFF'>}
 
-</span><span style='color:#AAA'>         The log command allows logging session output to file. You can set the
-         data type to either plain, raw, or html with the config command.
+</span><span style='color:#AAA'>         The log command allows logging session output to file.
+
+         </span><span style='color:#FFF'>#config log_level &lt;low|high&gt;
+</span><span style='color:#AAA'>           Default is high. Low, logs server output before triggers.
+
+         </span><span style='color:#FFF'>#config log_mode &lt;html|plain|raw&gt;
+</span><span style='color:#AAA'>           Set the log's data type to either html, plain, or raw.
 
          </span><span style='color:#FFF'>#log append &lt;filename&gt;
 </span><span style='color:#AAA'>           Start logging to the given file, if the file already exists it won't
@@ -2972,7 +2984,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          default room number (vnum) 1 is created, so you can go to it using
          #map goto 1. Once you are inside the map new rooms are automatically
          created as you move around. Movement commands are defined with the
-         pathdir command. By default n, ne, e, se, s, sw, w, nw, u, d are
+         #pathdir command. By default n, ne, e, se, s, sw, w, nw, u, d are
          defined.
 
          </span><span style='color:#FFF'>#map map &lt;rows&gt; &lt;cols&gt; &lt;append|overwrite|list|variable&gt; &lt;name&gt;
@@ -3017,7 +3029,9 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          </span><span style='color:#FFF'>#map write &lt;filename&gt;
 
 </span><span style='color:#AAA'>         You can save your map using #map write, to load a map you can use
-         #map read &lt;filename&gt;.
+         #map read &lt;filename&gt;. You can return to the room you were in when
+         the map was last saved by using #map return. You can use #event to
+         automatically read and write the map on session start and end.
 
          </span><span style='color:#FFF'>#map set &lt;option&gt; &lt;value&gt;
 
@@ -3268,7 +3282,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          Available MSDP events can be queried using the MSDP protocol
          as described in the specification.
 
-         </span><span style='color:#5FF'>https://tintin.sourceforge.io/protocols/msdp
+         </span><span style='color:#5FF'>https://tintin.mudhalla.net/protocols/msdp
 
 </span><span style='color:#FFF'>Related</span><span style='color:#AAA'>: <a href='#EVENT'>event</a> and <a href='#PORT'>port</a>.
 <a name='MSLP'></a>
@@ -3319,7 +3333,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          you need to use &bsol;e]68;2;&bsol;a, and they instead trigger the SECURE LINK
          event.
 
-         To creae a link that is not undelined, use &bsol;e]4;24m text &bsol;e]24m.
+         To create a link that is not underlined, use &bsol;e]4;24m text &bsol;e]24m.
 
 </span><span style='color:#FFF'>Example</span><span style='color:#AAA'>: #sub {%* tells %*} {&bsol;e]68;2;EXEC;#cursor set tell %1 &bsol;a&bsol;e[4;24m%0&bsol;e[24m}
 </span><span style='color:#FFF'>       </span><span style='color:#AAA'>  #event {PRESSED SECURE LINK EXEC MOUSE BUTTON ONE} {%4}
@@ -3607,9 +3621,13 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
 </span><span style='color:#FFF'>      &bsol;W </span><span style='color:#AAA'>Match non-letters, numbers, and underscores    [^A-Za-z0-9_]
 </span><span style='color:#FFF'>      &bsol;x </span><span style='color:#AAA'>Insert hex character                           &bsol;x
 </span><span style='color:#FFF'>      &bsol;Z </span><span style='color:#AAA'>Match end of string                            &dollar;
+</span><span style='color:#FFF'>      &bsol;&bsol; </span><span style='color:#AAA'>Match a backslash                              &bsol;&bsol;
 
          &bsol;s matches one space, &bsol;s+ matches one or multiple spaces, the use
-         of {&bsol;s+} is required for this sequence to work in tintin, &bsol;s by         itself will work outside of a set of braces.
+         of {&bsol;s+} is required for this sequence to work in tintin, &bsol;s by
+         itself will work outside of a set of braces.
+
+         Use &bsol;% to forcibly match a literal % character.
 
          </span><span style='color:#5F5'>Color triggers
 
@@ -3711,6 +3729,11 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          The #show command takes a row and col argument as well so it's also
          possible to place text on your split lines using #show.
 
+</span><span style='color:#FFF'>Example</span><span style='color:#AAA'>: #prompt {[%*] %* (%*) &gt; } {[%1] %2 (%3)}
+</span><span style='color:#FFF'>Example</span><span style='color:#AAA'>: #prompt {[%*] %* (%*) &gt; } {} {-2}
+         If the &lt;new text&gt; argument is left empty the original text is used,
+         including colors. Use {&bsol;} for a blank line.
+
 </span><span style='color:#FFF'>Comment</span><span style='color:#AAA'>: See </span><span style='color:#FFF'>#help split</span><span style='color:#AAA'> for more information on split mode.
 
 </span><span style='color:#FFF'>Comment</span><span style='color:#AAA'>: See </span><span style='color:#FFF'>#help substitute</span><span style='color:#AAA'> for more information on text
@@ -3760,6 +3783,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
 </span><span style='color:#FFF'>      %0 </span><span style='color:#AAA'>should be avoided in triggers, and if left alone lists all matches.
 </span><span style='color:#FFF'>     { } </span><span style='color:#AAA'>embed a raw regular expression, matches are stored to %1-%99.
 </span><span style='color:#FFF'>   %!{ } </span><span style='color:#AAA'>embed a raw regular expression, matches are not stored.
+
 </span><span style='color:#FFF'>         </span><span style='color:#AAA'>[ ] . + | ( ) ? * are treated as normal text unlessed used within
 </span><span style='color:#FFF'>         </span><span style='color:#AAA'>braces. Keep in mind that { } is replaced with ( ) automatically
 </span><span style='color:#FFF'>         </span><span style='color:#AAA'>unless %!{ } is used.
@@ -4003,7 +4027,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          is being used by utilizing the MTTS standard. The MTTS specification
          is available at:
 
-         http://tintin.sourceforge.net/protocols/mtts
+         https://tintin.mudhalla.net/protocols/mtts
 
          With the screen reader mode enabled TinTin++ will try to remove or
          alter visual elements where possible.
@@ -4648,7 +4672,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          underscores in order to be substituted.  If you do not meet these
          requirements do not panic, simply encapsulate the variable in braces:
 
-</span><span style='color:#FFF'>Example</span><span style='color:#AAA'>: #variable {cool website} {http://tintin.sourceforge.net}
+</span><span style='color:#FFF'>Example</span><span style='color:#AAA'>: #variable {cool website} {https://tintin.mudhalla.net}
          #chat I was on &dollar;{cool website} yesterday!.
 
          Variables can be escaped by adding additional &dollar; signs.

+ 15 - 7
docs/tutorial.html

@@ -398,6 +398,8 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          3 - Yellow               8 - Skip
          4 - Blue                 9 - Default
 
+</span><span style='color:#FFF'>Example</span><span style='color:#AAA'>: #show &lt;125&gt;Bold green on a magenta background.
+
          For xterm 256 colors support use &lt;aaa&gt; to &lt;fff&gt; for RGB foreground
          colors and &lt;AAA&gt; to &lt;FFF&gt; for RGB background colors. For the grayscale
          foreground colors use &lt;g00&gt; to &lt;g23&gt;, for grayscale background colors
@@ -612,7 +614,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
 
 </span><span style='color:#0AA'>      ####################################################################
       #</span><span style='color:#AAA'>                                                                  </span><span style='color:#0AA'>#
-      #</span><span style='color:#AAA'>                    T I N T I N + +   2.02.41b                    </span><span style='color:#0AA'>#
+      #</span><span style='color:#AAA'>                    T I N T I N + +   2.02.42                     </span><span style='color:#0AA'>#
       #</span><span style='color:#AAA'>                                                                  </span><span style='color:#0AA'>#
       #</span><span style='color:#AAA'>      Code by Peter Unold, Bill Reis, and Igor van den Hoven      </span><span style='color:#0AA'>#
       #</span><span style='color:#AAA'>                                                                  </span><span style='color:#0AA'>#
@@ -1012,7 +1014,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          default room number (vnum) 1 is created, so you can go to it using
          #map goto 1. Once you are inside the map new rooms are automatically
          created as you move around. Movement commands are defined with the
-         pathdir command. By default n, ne, e, se, s, sw, w, nw, u, d are
+         #pathdir command. By default n, ne, e, se, s, sw, w, nw, u, d are
          defined.
 
          </span><span style='color:#FFF'>#map map &lt;rows&gt; &lt;cols&gt; &lt;append|overwrite|list|variable&gt; &lt;name&gt;
@@ -1057,7 +1059,9 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          </span><span style='color:#FFF'>#map write &lt;filename&gt;
 
 </span><span style='color:#AAA'>         You can save your map using #map write, to load a map you can use
-         #map read &lt;filename&gt;.
+         #map read &lt;filename&gt;. You can return to the room you were in when
+         the map was last saved by using #map return. You can use #event to
+         automatically read and write the map on session start and end.
 
          </span><span style='color:#FFF'>#map set &lt;option&gt; &lt;value&gt;
 
@@ -1226,7 +1230,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          Available MSDP events can be queried using the MSDP protocol
          as described in the specification.
 
-         </span><span style='color:#5FF'>https://tintin.sourceforge.io/protocols/msdp
+         </span><span style='color:#5FF'>https://tintin.mudhalla.net/protocols/msdp
 
 </span><span style='color:#FFF'>Related</span><span style='color:#AAA'>: <a href='help.html#EVENT'>event</a> and <a href='help.html#PORT'>port</a>.
 <a name='MSLP'></a>
@@ -1277,7 +1281,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          you need to use &bsol;e]68;2;&bsol;a, and they instead trigger the SECURE LINK
          event.
 
-         To creae a link that is not undelined, use &bsol;e]4;24m text &bsol;e]24m.
+         To create a link that is not underlined, use &bsol;e]4;24m text &bsol;e]24m.
 
 </span><span style='color:#FFF'>Example</span><span style='color:#AAA'>: #sub {%* tells %*} {&bsol;e]68;2;EXEC;#cursor set tell %1 &bsol;a&bsol;e[4;24m%0&bsol;e[24m}
 </span><span style='color:#FFF'>       </span><span style='color:#AAA'>  #event {PRESSED SECURE LINK EXEC MOUSE BUTTON ONE} {%4}
@@ -1472,9 +1476,13 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
 </span><span style='color:#FFF'>      &bsol;W </span><span style='color:#AAA'>Match non-letters, numbers, and underscores    [^A-Za-z0-9_]
 </span><span style='color:#FFF'>      &bsol;x </span><span style='color:#AAA'>Insert hex character                           &bsol;x
 </span><span style='color:#FFF'>      &bsol;Z </span><span style='color:#AAA'>Match end of string                            &dollar;
+</span><span style='color:#FFF'>      &bsol;&bsol; </span><span style='color:#AAA'>Match a backslash                              &bsol;&bsol;
 
          &bsol;s matches one space, &bsol;s+ matches one or multiple spaces, the use
-         of {&bsol;s+} is required for this sequence to work in tintin, &bsol;s by         itself will work outside of a set of braces.
+         of {&bsol;s+} is required for this sequence to work in tintin, &bsol;s by
+         itself will work outside of a set of braces.
+
+         Use &bsol;% to forcibly match a literal % character.
 
          </span><span style='color:#5F5'>Color triggers
 
@@ -1517,7 +1525,7 @@ Example</span><span style='color:#AAA'>: #high </span><span style='color:#FFF'>{
          is being used by utilizing the MTTS standard. The MTTS specification
          is available at:
 
-         http://tintin.sourceforge.net/protocols/mtts
+         https://tintin.mudhalla.net/protocols/mtts
 
          With the screen reader mode enabled TinTin++ will try to remove or
          alter visual elements where possible.

+ 8 - 0
mods/igr.mods

@@ -1,5 +1,13 @@
+Jan 2025        2.02.50
+------------------------------------------------------------------------------
+
 Jan 2024        2.02.42
 ------------------------------------------------------------------------------
+map.c           Fixed #map move not working with nofollow flag set.
+
+list.c          Made #list indexate no longer require a uniform key layout,
+                but the indexation key must be present in all list entries.
+
 chat.c          Increased to timeout for the handshake from 5 to 30 seconds.
 
 substitute.c    %%%s would get escaped to %%s in aliases and actions. This was

+ 55 - 42
src/banner.c

@@ -103,23 +103,49 @@ void banner_expires(struct session *ses, char *name, char *arg, char *arg1)
 
 void banner_init(struct session *ses, char *arg1)
 {
-	banner_create(ses, "Armageddon", arg1);
+	banner_create(ses, "RetroMUD", arg1);
 
-	banner_desc(ses, "Armageddon",
-		"Armageddon MUD is set in the brutal post-apocalyptic world of Zalanthas.\n"
-		"Emphasizing roleplay over combat, the game offers a rich, immersive experience.\n"
-		"Zalanthas is ruled by sorcerer-kings and their powerful Templarate, dominating\n"
-		"the twin cities of Allanak and Tuluk. Magic not sanctioned by these rulers is\n"
-		"feared and often met with fatal consequences. Survival is a constant struggle\n"
-		"in this harsh environment, and death is permanent. Armageddon MUD delivers a\n"
-		"distinctive roleplaying adventure, with a dedicated community of players and\n"
-		"staff actively shaping the ongoing Zalanthan narrative for over three decades.", arg1);
+	banner_desc(ses, "RetroMUD",
+		"RetroMUD features over 100 levels of play, a huge array of character advancement\n"
+		"options, and dozens of quests across six different worlds. It's like six games\n"
+		"in one.", arg1);
 
-	banner_website(ses, "Armageddon", "https://armageddon.org", arg1);
-	banner_address(ses, "Armageddon", "arm armageddon.org 4050", arg1);
-	banner_expires(ses, "Armageddon", "2030", arg1);
+	banner_website(ses, "RetroMUD", "http://www.retromud.org", arg1);
+	banner_address(ses, "RetroMUD", "rm 96.126.116.118 3000", arg1);
+	banner_expires(ses, "RetroMUD", "2032", arg1);
 
 
+	banner_create(ses, "New Worlds Ateraan", arg1);
+
+	banner_desc(ses, "New Worlds Ateraan",
+		"Ateraan is a world of Intensive Roleplaying offering many unique and powerful\n"
+		"guilds, races, politics, religion, justice, economy, and a storyline that is\n"
+		"dominantly player controlled and based on a novel. The game is based on a\n"
+		"Kingdom with knights, merchants, mages, and thieves, and a fierce southern\n"
+		"state that has warriors, shaman, slaves, and servants. Ships rule the seas and\n"
+		"caravans travel the lands. With 100's of players and features like invasions,\n"
+		"ship creation, house building, clans, theaters, leatherball fields, and massive\n"
+		"events, the game is incredibly robust and diverse.", arg1);
+
+	banner_website(ses, "New Worlds Ateraan", "http://www.ateraan.com", arg1);
+	banner_address(ses, "New Worlds Ateraan", "nwa ateraan.com 4002", arg1);
+	banner_expires(ses, "New Worlds Ateraan", "2029", arg1);
+
+
+	banner_create(ses, "Untold Dawn", arg1);
+
+	banner_desc(ses, "Untold Dawn",
+		"Untold Dawn is an early access post-cyberpunk permadeath text-based roleplay\n"
+		"required multiplayer game. The game aims to redefine the RPI genre with a focus\n"
+		"on building a positive community, innovative features and a fresh look on game\n"
+		"rules. The game was developed from scratch using Rust and Bevy, a project which\n"
+		"began in January of 2024.\n", arg1);
+
+	banner_website(ses, "Untold Dawn", "https://blog.untold-dawn.com", arg1);
+	banner_address(ses, "Untold Dawn", "ud www.untold-dawn.com 4000", arg1);
+	banner_expires(ses, "Untold Dawn", "2030", arg1);
+
+/*
 	banner_create(ses, "Lost Souls", arg1);
 
 	banner_desc(ses, "Lost Souls",
@@ -193,18 +219,6 @@ void banner_init(struct session *ses, char *arg1)
 	banner_expires(ses, "3Kingdoms", "2029", arg1);
 
 
-	banner_create(ses, "RetroMUD", arg1);
-
-	banner_desc(ses, "RetroMUD",
-		"RetroMUD features over 100 levels of play, a huge array of character advancement\n"
-		"options, and dozens of quests across six different worlds. It's like six games\n"
-		"in one.", arg1);
-
-	banner_website(ses, "RetroMUD", "http://www.retromud.org", arg1);
-	banner_address(ses, "RetroMUD", "rm 96.126.116.118 3000", arg1);
-	banner_expires(ses, "RetroMUD", "2032", arg1);
-
-
 	banner_create(ses, "Alter Aeon", arg1);
 
 	banner_desc(ses, "Alter Aeon",
@@ -221,23 +235,22 @@ void banner_init(struct session *ses, char *arg1)
 	banner_expires(ses, "Alter Aeon", "2029", arg1);
 
 
-	banner_create(ses, "New Worlds Ateraan", arg1);
+	banner_create(ses, "Armageddon", arg1);
 
-	banner_desc(ses, "New Worlds Ateraan",
-		"Ateraan is a world of Intensive Roleplaying offering many unique and powerful\n"
-		"guilds, races, politics, religion, justice, economy, and a storyline that is\n"
-		"dominantly player controlled and based on a novel. The game is based on a\n"
-		"Kingdom with knights, merchants, mages, and thieves, and a fierce southern\n"
-		"state that has warriors, shaman, slaves, and servants. Ships rule the seas and\n"
-		"caravans travel the lands. With 100's of players and features like invasions,\n"
-		"ship creation, house building, clans, theaters, leatherball fields, and massive\n"
-		"events, the game is incredibly robust and diverse.", arg1);
+	banner_desc(ses, "Armageddon",
+		"Armageddon MUD is set in the brutal post-apocalyptic world of Zalanthas.\n"
+		"Emphasizing roleplay over combat, the game offers a rich, immersive experience.\n"
+		"Zalanthas is ruled by sorcerer-kings and their powerful Templarate, dominating\n"
+		"the twin cities of Allanak and Tuluk. Magic not sanctioned by these rulers is\n"
+		"feared and often met with fatal consequences. Survival is a constant struggle\n"
+		"in this harsh environment, and death is permanent. Armageddon MUD delivers a\n"
+		"distinctive roleplaying adventure, with a dedicated community of players and\n"
+		"staff actively shaping the ongoing Zalanthan narrative for over three decades.", arg1);
 
-	banner_website(ses, "New Worlds Ateraan", "http://www.ateraan.com", arg1);
-	banner_address(ses, "New Worlds Ateraan", "nwa ateraan.com 4002", arg1);
-	banner_expires(ses, "New Worlds Ateraan", "2029", arg1);
+	banner_website(ses, "Armageddon", "https://armageddon.org", arg1);
+	banner_address(ses, "Armageddon", "arm armageddon.org 4050", arg1);
+	banner_expires(ses, "Armageddon", "2030", arg1);
 
-/*
 	banner_create(ses, "Threshold RPG", arg1);
 
 	banner_desc(ses, "Threshold RPG",
@@ -269,7 +282,7 @@ void banner_init(struct session *ses, char *arg1)
 	banner_expires(ses, "Realm of Utopian Dreams (RUD)", "2028", arg1);
 
 	banner_create(ses, "Primal Darkness", arg1);
-	
+
 	banner_desc(ses, "Primal Darkness",
 		"Primal Darkness boasts twenty three start races, three quest races, five start\n"
 		"classes and twenty one subclasses to suit your adventuring needs, and a custom\n"
@@ -408,7 +421,7 @@ void banner_save(struct session *ses, char *arg1)
 	int index;
 	struct listnode *node;
 	char *name, *arg2;
-	
+
 	name = str_alloc_stack(0);
 	arg2 = str_alloc_stack(0);
 
@@ -551,7 +564,7 @@ DO_COMMAND(do_banner)
 	else if (is_abbrev(arg1, "HELP"))
 	{
 		tintin_printf2(ses, "#SYNTAX: #BANNER {GUI|INIT|LIST|RANDOM|SAVE|TEST}");
-	}	
+	}
 	else
 	{
 		banner_list(ses, arg1);

+ 7 - 11
src/buffer.c

@@ -638,8 +638,6 @@ DO_COMMAND(do_buffer)
 
 	if (*arg1 == 0)
 	{
-		info:
-
 		tintin_header(ses, 80, " BUFFER OPTIONS ");
 
 		for (cnt = 0 ; *buffer_table[cnt].name != 0 ; cnt++)
@@ -663,7 +661,7 @@ DO_COMMAND(do_buffer)
 		return ses;
 	}
 
-	goto info;
+	show_error(ses, LIST_COMMAND, "#ERROR: #BUFFER {%s}: INVALID BUFFER OPTION.", arg1);
 
 	return ses;
 }
@@ -1235,9 +1233,9 @@ DO_COMMAND(do_grep)
 	{
 		page = get_number(ses, arg1);
 
-		arg = get_arg_in_braces(ses, arg, arg2, GET_ALL);
+		arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
 
-		if (*arg2 == 0)
+		if (*arg1 == 0)
 		{
 			show_error(ses, LIST_COMMAND, "#SYNTAX: #GREP {%s} <SEARCH TEXT>", arg1);
 
@@ -1247,8 +1245,6 @@ DO_COMMAND(do_grep)
 	else
 	{
 		page = 1;
-
-		strcpy(arg2, arg1);
 	}
 
 	if (page > 0)
@@ -1264,7 +1260,7 @@ DO_COMMAND(do_grep)
 
 	gtd->level->grep++;
 
-	tintin_header(ses, 80, " GREPPING PAGE %d FOR %s ", page, arg2);
+	tintin_header(ses, 80, " GREPPING PAGE %d FOR %s ", page, arg1);
 
 	if (page > 0)
 	{
@@ -1275,7 +1271,7 @@ DO_COMMAND(do_grep)
 				continue;
 			}
 
-			if (find(ses, ses->scroll->buffer[scroll_cnt]->str, arg2, SUB_NONE, REGEX_FLAG_NONE))
+			if (find(ses, ses->scroll->buffer[scroll_cnt]->str, arg1, SUB_NONE, REGEX_FLAG_NONE))
 			{
 				grep_add = ses->scroll->buffer[scroll_cnt]->height;
 
@@ -1304,7 +1300,7 @@ DO_COMMAND(do_grep)
 				continue;
 			}
 
-			if (find(ses, ses->scroll->buffer[scroll_cnt]->str, arg2, SUB_NONE, REGEX_FLAG_NONE))
+			if (find(ses, ses->scroll->buffer[scroll_cnt]->str, arg1, SUB_NONE, REGEX_FLAG_NONE))
 			{
 				grep_add = ses->scroll->buffer[scroll_cnt]->height;
 
@@ -1328,7 +1324,7 @@ DO_COMMAND(do_grep)
 				continue;
 			}
 
-			if (find(ses, ses->scroll->buffer[scroll_cnt]->str, arg2, SUB_NONE, REGEX_FLAG_NONE))
+			if (find(ses, ses->scroll->buffer[scroll_cnt]->str, arg1, SUB_NONE, REGEX_FLAG_NONE))
 			{
 				grep_add = ses->scroll->buffer[scroll_cnt]->height;
 

+ 1 - 3
src/chat.c

@@ -79,8 +79,6 @@ DO_COMMAND(do_chat)
 
 	if (*cmd == 0)
 	{
-		info:
-
 		tintin_header(ses, 80, " CHAT OPTIONS ");
 
 		for (cnt = 0 ; *chat_table[cnt].name != 0 ; cnt++)
@@ -114,7 +112,7 @@ DO_COMMAND(do_chat)
 		return ses;
 	}
 
-	goto info;
+	show_error(ses, LIST_COMMAND, "#ERROR: #CHAT {%s}: INVALID CHAT OPTION.", cmd);
 
 	return ses;
 }

+ 1 - 3
src/daemon.c

@@ -49,8 +49,6 @@ DO_COMMAND(do_daemon)
 
 	if (*arg1 == 0)
 	{
-		info:
-
 		tintin_header(ses, 80, " DAEMON OPTIONS ");
 
 		for (cnt = 0 ; *daemon_table[cnt].fun != NULL ; cnt++)
@@ -76,7 +74,7 @@ DO_COMMAND(do_daemon)
 
 		if (*daemon_table[cnt].name == 0)
 		{
-			goto info;
+			show_error(ses, LIST_COMMAND, "#ERROR: #DAEMON {%s}: INVALID DAEMON OPTION.", arg1);
 		}
 		else
 		{

+ 4 - 2
src/data.c

@@ -1422,18 +1422,20 @@ DO_COMMAND(do_info)
 			case CTRL_A:
 				if (is_abbrev(arg1, "ARGUMENTS"))
 				{
+					int vars = atoi(arg2) ? atoi(arg2) : gtd->varc;
+
 					if (is_abbrev(arg2, "SAVE"))
 					{
 						set_nest_node_ses(ses, "info[ARGUMENTS]", "");
 
-						for (index = 0 ; index < gtd->varc ; index++)
+						for (index = 0 ; index < vars ; index++)
 						{
 							add_nest_node_ses(ses, "info[ARGUMENTS]", "{%d}{%s}", index, gtd->vars[index]);
 						}
 					}
 					else
 					{
-						for (index = 0 ; index < gtd->varc ; index++)
+						for (index = 0 ; index < vars ; index++)
 						{
 							tintin_printf2(ses, "#INFO ARGUMENTS: %2d: %s", index, gtd->vars[index]);
 						}

+ 10 - 5
src/draw.c

@@ -1389,7 +1389,8 @@ char *draw_vertical(long long flags, char *str)
 
 DO_DRAW(draw_bot_side)
 {
-	int col, corner;
+	int col;
+	long long corner;
 
 	if (!HAS_BIT(flags, DRAW_FLAG_LEFT) && !HAS_BIT(flags, DRAW_FLAG_RIGHT) && !HAS_BIT(flags, DRAW_FLAG_BOT))
 	{
@@ -1549,7 +1550,8 @@ DO_DRAW(draw_corner)
 
 DO_DRAW(draw_line_horizontal)
 {
-	int col, corner, ins_len;
+	int col, ins_len;
+	long long corner;
 	char *line;
 
 	if (!HAS_BIT(flags, DRAW_FLAG_VER))
@@ -1645,7 +1647,8 @@ DO_DRAW(draw_line_horizontal)
 
 DO_DRAW(draw_line_vertical)
 {
-	int row, corner;
+	int row;
+	long long corner;
 
 	if (!HAS_BIT(flags, DRAW_FLAG_HOR))
 	{
@@ -2198,7 +2201,8 @@ DO_DRAW(draw_square)
 DO_DRAW(draw_table_grid)
 {
 	char buf1[BUFFER_SIZE], *str, buf2[BUFFER_SIZE], buf3[BUFFER_SIZE], row_color[COLOR_SIZE];
-	int corner, blank, row, col, max_r, max_c, r, c, top_r, top_c, bot_r, bot_c, tot_r, tot_c;
+	int blank, row, col, max_r, max_c, r, c, top_r, top_c, bot_r, bot_c, tot_r, tot_c;
+	long long corner;
 
 	row = cnt_arg_all(ses, arg, GET_ALL);
 
@@ -2696,7 +2700,8 @@ DO_DRAW(draw_text)
 
 DO_DRAW(draw_top_side)
 {
-	int col, corner;
+	int col;
+	long long corner;
 
 	SET_BIT(flags, HAS_BIT(flags, DRAW_FLAG_VER) ? DRAW_FLAG_VER : DRAW_FLAG_HOR);
 

+ 12 - 2
src/help.c

@@ -996,6 +996,8 @@ struct help_type help_table[] =
 		"<278>         3 - Yellow               8 - Skip\n"
 		"<278>         4 - Blue                 9 - Default\n"
 		"\n"
+		"<178>Example<278>: #show <<888>125>Bold green on a magenta background.\n"
+		"\n"
 		"<278>         For xterm 256 colors support use <<888>aaa> to <<888>fff> for RGB foreground\n"
 		"<278>         colors and <<888>AAA> to <<888>FFF> for RGB background colors. For the grayscale\n"
 		"<278>         foreground colors use <<888>g00> to <<888>g23>, for grayscale background colors\n"
@@ -1680,7 +1682,7 @@ struct help_type help_table[] =
 		"<278>           %0 old vnum  %1 new vnum  %2 exit name\n"
 		"\n"
 		"<278>         <178>MAP REGION <MOUSE>, MAP ROOM <MOUSE>\n"
-		"<278>           %0 row  %1 col  %2 -row  %3 -col  %5 vnum  %6 info\n"
+		"<278>           %0 row  %1 col  %2 -row  %3 -col  %4 vnum  %5 info\n"
 		"\n"
 		"<278>         <128>MOUSE EVENTS\n"
 		"\n"
@@ -2648,7 +2650,7 @@ struct help_type help_table[] =
 		"\n"
 		"<278>         The indexate option prepares a table or list table for order, sort,\n"
 		"<278>         filter, refine, and find operations for the given key. It is similar\n"
-		"<278>         to the SELECT option in SQL. The table must have a uniform key layout.\n"
+		"<278>         to the SELECT option in SQL. All entries must contain the given key.\n"
 		"\n"
 		"<278>         A size of 0 is returned for an empty or non-existent list. You can\n"
 		"<278>         directly access the size of a list using &var[].\n"
@@ -3017,6 +3019,9 @@ struct help_type help_table[] =
 		"\n"
 		"<278>         The log command allows logging session output to file.\n"
 		"\n"
+		"<278>         <178>#config log_level <low|high>\n"
+		"<278>           Default is high. Low, logs server output before triggers.\n"
+		"\n"
 		"<278>         <178>#config log_mode <html|plain|raw>\n"
 		"<278>           Set the log's data type to either html, plain, or raw.\n"
 		"\n"
@@ -4221,6 +4226,11 @@ struct help_type help_table[] =
 		"<278>         The #show command takes a row and col argument as well so it's also\n"
 		"<278>         possible to place text on your split lines using #show.\n"
 		"\n"
+		"<178>Example<278>: #prompt {[%*] %* (%*) > } {[%1] %2 (%3)}\n"
+		"<178>Example<278>: #prompt {[%*] %* (%*) > } {} {-2}\n"
+		"<278>         If the <new text> argument is left empty the original text is used,\n"
+		"<278>         including colors. Use {\\} for a blank line.\n"
+		"\n"
 		"<178>Comment<278>: See <178>#help split<278> for more information on split mode.\n"
 		"\n"
 		"<178>Comment<278>: See <178>#help substitute<278> for more information on text\n"

+ 1 - 3
src/history.c

@@ -33,8 +33,6 @@ DO_COMMAND(do_history)
 
 	if (*arg1 == 0)
 	{
-		info:
-
 		tintin_header(ses, 80, " HISTORY COMMANDS ");
 
 		for (cnt = 0 ; *history_table[cnt].name != 0 ; cnt++)
@@ -58,7 +56,7 @@ DO_COMMAND(do_history)
 		return ses;
 	}
 
-	goto info;
+	show_error(ses, LIST_COMMAND, "#ERROR: #HISTORY {%s}: INVALID HISTORY OPTION.", arg1);
 
 	return ses;
 }

+ 1 - 3
src/line.c

@@ -65,8 +65,6 @@ DO_COMMAND(do_line)
 
 	if (*arg1 == 0)
 	{
-		info:
-
 		tintin_header(ses, 80, " LINE OPTIONS ");
 
 		for (cnt = 0 ; *line_table[cnt].fun != NULL ; cnt++)
@@ -92,7 +90,7 @@ DO_COMMAND(do_line)
 
 		if (*line_table[cnt].name == 0)
 		{
-			goto info;
+			show_error(ses, LIST_COMMAND, "#ERROR: #LINE {%s}: INVALID LINE OPTION.", arg1);
 		}
 		else
 		{

+ 41 - 18
src/list.c

@@ -104,8 +104,6 @@ DO_COMMAND(do_list)
 
 	if (*arg1 == 0)
 	{
-		info:
-
 		tintin_header(ses, 80, " LIST OPTIONS ");
 
 		for (index = 0 ; *array_table[index].fun ; index++)
@@ -133,23 +131,23 @@ DO_COMMAND(do_list)
 
 		if (*array_table[cnt].name == 0)
 		{
-			goto info;
+			show_error(ses, LIST_VARIABLE, "#ERROR: #LIST {%s} {%s}: INVALID LIST OPTION.", arg1, arg2);
+
+			return ses;
 		}
-		else
+
+		if (!valid_variable(ses, arg1))
 		{
-			if (!valid_variable(ses, arg1))
-			{
-				show_error(ses, LIST_VARIABLE, "#LIST: INVALID VARIABLE NAME {%s}.", arg1);
+			show_error(ses, LIST_VARIABLE, "#ERROR: #LIST {%s} {%s}: INVALID VARIABLE NAME.", arg1, arg2);
 
-				return ses;
-			}
+			return ses;
+		}
 
-			if ((node = search_nest_node_ses(ses, arg1)) == NULL)
-			{
-				node = set_nest_node_ses(ses, arg1, "");
-			}
-			array_table[cnt].fun(ses, node, arg, arg1, arg2, arg3);
+		if ((node = search_nest_node_ses(ses, arg1)) == NULL)
+		{
+			node = set_nest_node_ses(ses, arg1, "");
 		}
+		array_table[cnt].fun(ses, node, arg, arg1, arg2, arg3);
 	}
 	return ses;
 }
@@ -293,7 +291,7 @@ DO_ARRAY(array_copy)
 	if ((from = search_nest_node_ses(ses, arg1)) == NULL)
 	{
 		show_error(ses, LIST_VARIABLE, "#LIST COPY: VARIABLE {%s} NOT FOUND.", arg1);
-		
+
 		return ses;
 	}
 
@@ -575,7 +573,7 @@ DO_ARRAY(array_get)
 	if (*arg2 == 0)
 	{
 		show_error(ses, LIST_VARIABLE, "#SYNTAX: #LIST <VARIABLE> GET <INDEX> <VARIABLE>");
-		
+
 		return ses;
 	}
 
@@ -597,7 +595,7 @@ DO_ARRAY(array_get)
 
 DO_ARRAY(array_indexate)
 {
-	int cnt;
+	int cnt, index;
 
 	arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
 
@@ -625,6 +623,30 @@ DO_ARRAY(array_indexate)
 		return ses;
 	}
 
+#if 1
+	if (list->root->used)
+	{
+		for (cnt = 0 ; cnt < list->root->used ; cnt++)
+		{
+			if (list->root->list[cnt]->root == NULL)
+			{
+				show_error(ses, LIST_COMMAND, "#ERROR: #LIST %s[%s] INDEXATE: FAILED TO FIND NEST {%s}.", var, list->root->list[cnt]->arg1, arg1);
+
+				return ses;
+			}
+
+			index = search_index_list(list->root->list[cnt]->root, arg1, "");
+
+			if (index == -1)
+			{
+				show_error(ses, LIST_COMMAND, "#ERROR: #LIST %s[%s] INDEXATE: FAILED TO FIND NEST {%s}.", var, list->root->list[cnt]->arg1, arg1);
+
+				return ses;
+			}
+			str_cpy(&list->root->list[cnt]->arg2, list->root->list[cnt]->root->list[index]->arg2);
+		}
+	}
+#else
 	if (list->root->used)
 	{
 		int index = search_index_list(list->root->list[0]->root, arg1, "");
@@ -649,6 +671,7 @@ DO_ARRAY(array_indexate)
 			}
 		}
 	}
+#endif
 	return ses;
 }
 
@@ -910,7 +933,7 @@ DO_ARRAY(array_size)
 	if (*arg1 == 0)
 	{
 		show_error(ses, LIST_VARIABLE, "#SYNTAX: #LIST <VARIABLE> SIZE <VARIABLE>");
-		
+
 		return ses;
 	}
 

+ 9 - 16
src/log.c

@@ -69,8 +69,6 @@ DO_COMMAND(do_log)
 
 	if (*arg1 == 0)
 	{
-		info:
-
 		tintin_header(ses, 80, " LOG OPTIONS ");
 
 		for (cnt = 0 ; *log_table[cnt].fun != NULL ; cnt++)
@@ -83,25 +81,19 @@ DO_COMMAND(do_log)
 		pop_call();
 		return ses;
 	}
-	else
-	{
-		for (cnt = 0 ; *log_table[cnt].name ; cnt++)
-		{
-			if (is_abbrev(arg1, log_table[cnt].name))
-			{
-				break;
-			}
-		}
 
-		if (*log_table[cnt].name == 0)
-		{
-			goto info;
-		}
-		else
+	for (cnt = 0 ; *log_table[cnt].name ; cnt++)
+	{
+		if (is_abbrev(arg1, log_table[cnt].name))
 		{
 			log_table[cnt].fun(ses, arg, arg1, arg2);
+
+			pop_call();
+			return ses;
 		}
 	}
+	show_error(ses, LIST_COMMAND, "#ERROR: #LOG {%s}: INVALID LOG OPTION.", arg1);
+
 	pop_call();
 	return ses;
 }
@@ -136,6 +128,7 @@ DO_LOG(log_info)
 	tintin_printf2(ses, "#LOG INFO: MODE  = %s", HAS_BIT(ses->log->mode, LOG_FLAG_HTML) ? "HTML" : HAS_BIT(ses->log->mode, LOG_FLAG_PLAIN) ? "PLAIN" : HAS_BIT(ses->log->mode, LOG_FLAG_RAW) ? "RAW" : "UNSET");
 	tintin_printf2(ses, "#LOG INFO: LINE  = %s", ses->log->line_file ? ses->log->line_name : "");
 	tintin_printf2(ses, "#LOG INFO: NEXT  = %s", ses->log->next_file ? ses->log->next_name : "");
+	tintin_printf2(ses, "#LOG INFO: STAMP = %s", ses->log->stamp_strf);
 }
 
 DO_LOG(log_make)

+ 10 - 7
src/mapper.c

@@ -83,8 +83,6 @@ DO_COMMAND(do_map)
 
 	if (*arg1 == 0)
 	{
-		info:
-
 		tintin_header(ses, 80, " MAP OPTIONS ");
 
 		for (cnt = 0 ; *map_table[cnt].fun != NULL ; cnt++)
@@ -136,8 +134,7 @@ DO_COMMAND(do_map)
 				return ses;
 			}
 		}
-
-		goto info;
+		show_error(ses, LIST_COMMAND, "#ERROR: #MAP {%s}: INVALID MAP OPTION.", arg1);
 	}
 	pop_call();
 	return ses;
@@ -1828,7 +1825,7 @@ int follow_map(struct session *ses, char *argument)
 
 	room = ses->map->room_list[ses->map->in_room];
 
-	if (HAS_BIT(ses->map->flags, MAP_FLAG_NOFOLLOW))
+	if (HAS_BIT(ses->map->flags, MAP_FLAG_NOFOLLOW) && ses->map->nofollow == 0)
 	{
 		if (check_global(ses, room->vnum) && find_exit(ses, ses->map->global_vnum, argument))
 		{
@@ -1874,8 +1871,14 @@ int follow_map(struct session *ses, char *argument)
 		{
 			if (HAS_BIT(exit->flags, EXIT_FLAG_BLOCK) || HAS_BIT(ses->map->room_list[vnum]->flags, ROOM_FLAG_BLOCK))
 			{
-				show_error(ses, LIST_COMMAND, "#MAP FOLLOW: %s {%d} HAS THE BLOCK FLAG SET.", HAS_BIT(exit->flags, EXIT_FLAG_BLOCK) ? "EXIT" : "ROOM", vnum);
-
+				if (HAS_BIT(exit->flags, EXIT_FLAG_BLOCK))
+				{
+					show_error(ses, LIST_COMMAND, "#MAP FOLLOW: EXIT {%s} HAS THE BLOCK FLAG SET.", exit->name);
+				}
+				else
+				{
+					show_error(ses, LIST_COMMAND, "#MAP FOLLOW: ROOM {%d} HAS THE BLOCK FLAG SET.", vnum);
+				}
 				pop_call();
 				return 1;
 			}

+ 1 - 3
src/path.c

@@ -36,8 +36,6 @@ DO_COMMAND(do_path)
 
 	if (*arg1 == 0)
 	{
-		info:
-
 		tintin_header(ses, 80, " PATH OPTIONS ");
 
 		for (cnt = 0 ; *path_table[cnt].fun != NULL ; cnt++)
@@ -63,7 +61,7 @@ DO_COMMAND(do_path)
 
 		if (*path_table[cnt].name == 0)
 		{
-			goto info;
+			show_error(ses, LIST_COMMAND, "#ERROR: #PATH {%s}: INVALID PATH OPTION.", arg1);
 		}
 		else
 		{

+ 1 - 3
src/port.c

@@ -43,8 +43,6 @@ DO_COMMAND(do_port)
 
 	if (*cmd == 0)
 	{
-		info:
-
 		tintin_header(ses, 80, " PORT OPTIONS ");
 
 		for (cnt = 0 ; *port_table[cnt].name != 0 ; cnt++)
@@ -79,7 +77,7 @@ DO_COMMAND(do_port)
 		return ses;
 	}
 
-	goto info;
+	show_error(ses, LIST_COMMAND, "#ERROR: #PORT {%s}: INVALID PORT OPTION.", cmd);
 
 	return ses;
 }

+ 1 - 1
src/ssl.c

@@ -312,7 +312,7 @@ static int ssl_check_cert(struct session *ses, gnutls_session_t ssl_ses)
 	{
 		t -= gnutls_x509_crt_get_expiration_time(oldcert);
 
-		if (err || t < -7*24*3600)
+		if (err || t < -31*24*3600)
 		{
 			if (err)
 			{

+ 1 - 1
src/tintin.h

@@ -212,7 +212,7 @@
 
 
 #define CLIENT_NAME              "TinTin++"
-#define CLIENT_VERSION           "2.02.42b"
+#define CLIENT_VERSION           "2.02.50b"
 
 
 #define XT_E                            0x27

+ 12 - 17
src/tokenize.c

@@ -589,13 +589,14 @@ void tokenize_script(struct scriptroot *root, int lvl, char *str)
 						str = get_arg_in_braces(root->ses, arg, line, GET_ONE);
 						addtoken(root, lvl++, TOKEN_TYPE_CASE, cmd, line);
 
-						str = get_arg_in_braces(root->ses, str, line, GET_ALL);
-						tokenize_script(root, lvl--, line);
-
 						if (*line == 0)
 						{
 							show_error(root->ses, LIST_COMMAND, "#SYNTAX: #CASE <CONDITIONAL> <COMMANDS>");
 						}
+
+						str = get_arg_in_braces(root->ses, str, line, GET_ALL);
+						tokenize_script(root, lvl--, line);
+
 						addtoken(root, lvl, TOKEN_TYPE_END, -1, "endcase");
 						break;
 
@@ -610,10 +611,6 @@ void tokenize_script(struct scriptroot *root, int lvl, char *str)
 						str = get_arg_in_braces(root->ses, arg, line, GET_ALL);
 						tokenize_script(root, lvl--, line);
 
-						if (*line == 0)
-						{
-							show_error(root->ses, LIST_COMMAND, "#SYNTAX: #DEFAULT <COMMANDS>");
-						}
 						addtoken(root, lvl, TOKEN_TYPE_END, -1, "enddefault");
 						break;
 
@@ -623,10 +620,6 @@ void tokenize_script(struct scriptroot *root, int lvl, char *str)
 						str = get_arg_in_braces(root->ses, arg, line, GET_ALL);
 						tokenize_script(root, lvl--, line);
 
-						if (*line == 0)
-						{
-							show_error(root->ses, LIST_COMMAND, "#SYNTAX: #ELSE <COMMANDS>");
-						}
 						addtoken(root, lvl, TOKEN_TYPE_END, -1, "endelse");
 						break;
 
@@ -634,13 +627,14 @@ void tokenize_script(struct scriptroot *root, int lvl, char *str)
 						str = get_arg_in_braces(root->ses, arg, line, GET_ONE);
 						addtoken(root, lvl++, TOKEN_TYPE_ELSEIF, cmd, line);
 
-						str = get_arg_in_braces(root->ses, str, line, GET_ALL);
-						tokenize_script(root, lvl--, line);
-
 						if (*line == 0)
 						{
 							show_error(root->ses, LIST_COMMAND, "#SYNTAX: #ELSEIF <CONDITIONAL> <COMMANDS>");
 						}
+
+						str = get_arg_in_braces(root->ses, str, line, GET_ALL);
+						tokenize_script(root, lvl--, line);
+
 						addtoken(root, lvl, TOKEN_TYPE_END, -1, "endelseif");
 						break;
 
@@ -661,13 +655,14 @@ void tokenize_script(struct scriptroot *root, int lvl, char *str)
 						str = get_arg_in_braces(root->ses, arg, line, GET_ONE);
 						addtoken(root, lvl++, TOKEN_TYPE_IF, cmd, line);
 
-						str = get_arg_in_braces(root->ses, str, line, GET_ALL);
-						tokenize_script(root, lvl--, line);
-
 						if (*line == 0)
 						{
 							show_error(root->ses, LIST_COMMAND, "#SYNTAX: #IF <CONDITIONAL> <TRUE> [FALSE]");
 						}
+
+						str = get_arg_in_braces(root->ses, str, line, GET_ALL);
+						tokenize_script(root, lvl--, line);
+
 						addtoken(root, lvl, TOKEN_TYPE_END, -1, "endif");
 
 						str = space_out(str);

+ 1 - 1
src/trigger.c

@@ -820,7 +820,7 @@ DO_COMMAND(do_prompt)
 	{
 		show_list(ses->list[LIST_PROMPT], 0);
 	}
-	else if (*arg1 && *arg2 == 0)
+	else if (*arg1 && *arg2 == 0 && *arg == 0)
 	{
 		if (show_node_with_wild(ses, arg1, ses->list[LIST_PROMPT]) == FALSE)
 		{