Procházet zdrojové kódy

Feat: cumulative update

dzp před 9 měsíci
rodič
revize
b978055138
23 změnil soubory, kde provedl 250 přidání a 171 odebrání
  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
 #showme $temp
 
 
 #nop -------------------------------------------------------------------------
 #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 -------------------------------------------------------------------------
 #nop -------------------------------------------------------------------------
 
 
 #alias {hpbar}
 #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.
 - 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
 - Add an example #edit script to SCRIPTS
 
 
@@ -24,6 +32,8 @@
 
 
 - comprehensive memory breakdown for variables/triggers/mapper/etc
 - 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
 - a better trigger stack debug buffer
 
 
 - Problem with restoring true color subs.
 - Problem with restoring true color subs.
@@ -51,6 +61,7 @@
 
 
 - Make #draw scroll grid table work properly.
 - Make #draw scroll grid table work properly.
 
 
+
 - update https://tintin.mudhalla.net/info/ansicolor/
 - update https://tintin.mudhalla.net/info/ansicolor/
 
 
 - Make sure #config compact also applies to the log file.
 - Make sure #config compact also applies to the log file.
@@ -63,7 +74,7 @@
 
 
 - catch event to handle #map global exceptions
 - catch event to handle #map global exceptions
 
 
-- switch to pcre2
+
 
 
 - Add routine to escape 0x00 in port.c RECEIVED DATA event.
 - 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
          3 - Yellow               8 - Skip
          4 - Blue                 9 - Default
          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
          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
          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
          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
 </span><span style='color:#AAA'>         The edit command can be used to turn the default line editor into a
          text editor.
          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:#AAA'>           Create an editor, initialize using the provided arguments.
 
 
          </span><span style='color:#FFF'>#edit load &lt;variable&gt;
          </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
 </span><span style='color:#AAA'>           Suspend editing, similar to pressing enter except that no
            events are triggered.
            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:#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>.
 </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>
 <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'>         </span><span style='color:#FFF'>CLASS_LOAD [CLASS]
 </span><span style='color:#AAA'>           %0 class name
 </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:#5F5'>GAG EVENTS
 
 
 </span><span style='color:#AAA'>         </span><span style='color:#FFF'>GAG &lt;EVENT&gt;
 </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:#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:#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
          </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'>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'>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:#5F5'>TELNET EVENTS
 
 
 </span><span style='color:#AAA'>         </span><span style='color:#FFF'>IAC &lt;EVENT&gt;
 </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:#0AA'>      ####################################################################
       #</span><span style='color:#AAA'>                                                                  </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'>                                                                  </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'>      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'>#
       #</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.
          settings, as well as the list names that you can ignore.
 
 
          If you for example use #IGNORE ACTIONS ON actions will no longer
          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>.
 </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>
 <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'>         </span><span style='color:#FFF'>#line background &lt;argument&gt;
 </span><span style='color:#AAA'>           Prevent new session activation.
 </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:#FFF'>#line capture &lt;variable&gt; &lt;argument&gt;
 </span><span style='color:#AAA'>           Argument is executed and output stored in &lt;variable&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
          #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
          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
          When inserting an item a positive index will prepend the item at the
          given index, while a negative index will append the item.
          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,
          The indexate option prepares a table or list table for order, sort,
          filter, refine, and find operations for the given key. It is similar
          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
          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[].
          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:#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:#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
 </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
          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
          #map goto 1. Once you are inside the map new rooms are automatically
          created as you move around. Movement commands are defined with the
          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.
          defined.
 
 
          </span><span style='color:#FFF'>#map map &lt;rows&gt; &lt;cols&gt; &lt;append|overwrite|list|variable&gt; &lt;name&gt;
          </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:#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
 </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;
          </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
          Available MSDP events can be queried using the MSDP protocol
          as described in the specification.
          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>.
 </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>
 <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
          you need to use &bsol;e]68;2;&bsol;a, and they instead trigger the SECURE LINK
          event.
          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'>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}
 </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;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;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;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
          &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
          </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
          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.
          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 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
 </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'>      %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 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'>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'>[ ] . + | ( ) ? * 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'>braces. Keep in mind that { } is replaced with ( ) automatically
 </span><span style='color:#FFF'>         </span><span style='color:#AAA'>unless %!{ } is used.
 </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 being used by utilizing the MTTS standard. The MTTS specification
          is available at:
          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
          With the screen reader mode enabled TinTin++ will try to remove or
          alter visual elements where possible.
          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
          underscores in order to be substituted.  If you do not meet these
          requirements do not panic, simply encapsulate the variable in braces:
          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!.
          #chat I was on &dollar;{cool website} yesterday!.
 
 
          Variables can be escaped by adding additional &dollar; signs.
          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
          3 - Yellow               8 - Skip
          4 - Blue                 9 - Default
          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
          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
          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
          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:#0AA'>      ####################################################################
       #</span><span style='color:#AAA'>                                                                  </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'>                                                                  </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'>      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'>#
       #</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
          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
          #map goto 1. Once you are inside the map new rooms are automatically
          created as you move around. Movement commands are defined with the
          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.
          defined.
 
 
          </span><span style='color:#FFF'>#map map &lt;rows&gt; &lt;cols&gt; &lt;append|overwrite|list|variable&gt; &lt;name&gt;
          </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:#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
 </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;
          </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
          Available MSDP events can be queried using the MSDP protocol
          as described in the specification.
          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>.
 </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>
 <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
          you need to use &bsol;e]68;2;&bsol;a, and they instead trigger the SECURE LINK
          event.
          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'>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}
 </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;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;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;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
          &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
          </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 being used by utilizing the MTTS standard. The MTTS specification
          is available at:
          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
          With the screen reader mode enabled TinTin++ will try to remove or
          alter visual elements where possible.
          alter visual elements where possible.

+ 8 - 0
mods/igr.mods

@@ -1,5 +1,13 @@
+Jan 2025        2.02.50
+------------------------------------------------------------------------------
+
 Jan 2024        2.02.42
 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.
 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
 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)
 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_create(ses, "Lost Souls", arg1);
 
 
 	banner_desc(ses, "Lost Souls",
 	banner_desc(ses, "Lost Souls",
@@ -193,18 +219,6 @@ void banner_init(struct session *ses, char *arg1)
 	banner_expires(ses, "3Kingdoms", "2029", 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_create(ses, "Alter Aeon", arg1);
 
 
 	banner_desc(ses, "Alter Aeon",
 	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_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_create(ses, "Threshold RPG", arg1);
 
 
 	banner_desc(ses, "Threshold RPG",
 	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_expires(ses, "Realm of Utopian Dreams (RUD)", "2028", arg1);
 
 
 	banner_create(ses, "Primal Darkness", arg1);
 	banner_create(ses, "Primal Darkness", arg1);
-	
+
 	banner_desc(ses, "Primal Darkness",
 	banner_desc(ses, "Primal Darkness",
 		"Primal Darkness boasts twenty three start races, three quest races, five start\n"
 		"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"
 		"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;
 	int index;
 	struct listnode *node;
 	struct listnode *node;
 	char *name, *arg2;
 	char *name, *arg2;
-	
+
 	name = str_alloc_stack(0);
 	name = str_alloc_stack(0);
 	arg2 = str_alloc_stack(0);
 	arg2 = str_alloc_stack(0);
 
 
@@ -551,7 +564,7 @@ DO_COMMAND(do_banner)
 	else if (is_abbrev(arg1, "HELP"))
 	else if (is_abbrev(arg1, "HELP"))
 	{
 	{
 		tintin_printf2(ses, "#SYNTAX: #BANNER {GUI|INIT|LIST|RANDOM|SAVE|TEST}");
 		tintin_printf2(ses, "#SYNTAX: #BANNER {GUI|INIT|LIST|RANDOM|SAVE|TEST}");
-	}	
+	}
 	else
 	else
 	{
 	{
 		banner_list(ses, arg1);
 		banner_list(ses, arg1);

+ 7 - 11
src/buffer.c

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

+ 1 - 3
src/chat.c

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

+ 1 - 3
src/daemon.c

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

+ 4 - 2
src/data.c

@@ -1422,18 +1422,20 @@ DO_COMMAND(do_info)
 			case CTRL_A:
 			case CTRL_A:
 				if (is_abbrev(arg1, "ARGUMENTS"))
 				if (is_abbrev(arg1, "ARGUMENTS"))
 				{
 				{
+					int vars = atoi(arg2) ? atoi(arg2) : gtd->varc;
+
 					if (is_abbrev(arg2, "SAVE"))
 					if (is_abbrev(arg2, "SAVE"))
 					{
 					{
 						set_nest_node_ses(ses, "info[ARGUMENTS]", "");
 						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]);
 							add_nest_node_ses(ses, "info[ARGUMENTS]", "{%d}{%s}", index, gtd->vars[index]);
 						}
 						}
 					}
 					}
 					else
 					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]);
 							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)
 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))
 	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)
 DO_DRAW(draw_line_horizontal)
 {
 {
-	int col, corner, ins_len;
+	int col, ins_len;
+	long long corner;
 	char *line;
 	char *line;
 
 
 	if (!HAS_BIT(flags, DRAW_FLAG_VER))
 	if (!HAS_BIT(flags, DRAW_FLAG_VER))
@@ -1645,7 +1647,8 @@ DO_DRAW(draw_line_horizontal)
 
 
 DO_DRAW(draw_line_vertical)
 DO_DRAW(draw_line_vertical)
 {
 {
-	int row, corner;
+	int row;
+	long long corner;
 
 
 	if (!HAS_BIT(flags, DRAW_FLAG_HOR))
 	if (!HAS_BIT(flags, DRAW_FLAG_HOR))
 	{
 	{
@@ -2198,7 +2201,8 @@ DO_DRAW(draw_square)
 DO_DRAW(draw_table_grid)
 DO_DRAW(draw_table_grid)
 {
 {
 	char buf1[BUFFER_SIZE], *str, buf2[BUFFER_SIZE], buf3[BUFFER_SIZE], row_color[COLOR_SIZE];
 	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);
 	row = cnt_arg_all(ses, arg, GET_ALL);
 
 
@@ -2696,7 +2700,8 @@ DO_DRAW(draw_text)
 
 
 DO_DRAW(draw_top_side)
 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);
 	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>         3 - Yellow               8 - Skip\n"
 		"<278>         4 - Blue                 9 - Default\n"
 		"<278>         4 - Blue                 9 - Default\n"
 		"\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>         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>         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"
 		"<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"
 		"<278>           %0 old vnum  %1 new vnum  %2 exit name\n"
 		"\n"
 		"\n"
 		"<278>         <178>MAP REGION <MOUSE>, MAP ROOM <MOUSE>\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"
 		"\n"
 		"<278>         <128>MOUSE EVENTS\n"
 		"<278>         <128>MOUSE EVENTS\n"
 		"\n"
 		"\n"
@@ -2648,7 +2650,7 @@ struct help_type help_table[] =
 		"\n"
 		"\n"
 		"<278>         The indexate option prepares a table or list table for order, sort,\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>         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"
 		"\n"
 		"<278>         A size of 0 is returned for an empty or non-existent list. You can\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"
 		"<278>         directly access the size of a list using &var[].\n"
@@ -3017,6 +3019,9 @@ struct help_type help_table[] =
 		"\n"
 		"\n"
 		"<278>         The log command allows logging session output to file.\n"
 		"<278>         The log command allows logging session output to file.\n"
 		"\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>         <178>#config log_mode <html|plain|raw>\n"
 		"<278>           Set the log's data type to either html, plain, or raw.\n"
 		"<278>           Set the log's data type to either html, plain, or raw.\n"
 		"\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>         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"
 		"<278>         possible to place text on your split lines using #show.\n"
 		"\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"
 		"<178>Comment<278>: See <178>#help split<278> for more information on split mode.\n"
 		"\n"
 		"\n"
 		"<178>Comment<278>: See <178>#help substitute<278> for more information on text\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)
 	if (*arg1 == 0)
 	{
 	{
-		info:
-
 		tintin_header(ses, 80, " HISTORY COMMANDS ");
 		tintin_header(ses, 80, " HISTORY COMMANDS ");
 
 
 		for (cnt = 0 ; *history_table[cnt].name != 0 ; cnt++)
 		for (cnt = 0 ; *history_table[cnt].name != 0 ; cnt++)
@@ -58,7 +56,7 @@ DO_COMMAND(do_history)
 		return ses;
 		return ses;
 	}
 	}
 
 
-	goto info;
+	show_error(ses, LIST_COMMAND, "#ERROR: #HISTORY {%s}: INVALID HISTORY OPTION.", arg1);
 
 
 	return ses;
 	return ses;
 }
 }

+ 1 - 3
src/line.c

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

+ 41 - 18
src/list.c

@@ -104,8 +104,6 @@ DO_COMMAND(do_list)
 
 
 	if (*arg1 == 0)
 	if (*arg1 == 0)
 	{
 	{
-		info:
-
 		tintin_header(ses, 80, " LIST OPTIONS ");
 		tintin_header(ses, 80, " LIST OPTIONS ");
 
 
 		for (index = 0 ; *array_table[index].fun ; index++)
 		for (index = 0 ; *array_table[index].fun ; index++)
@@ -133,23 +131,23 @@ DO_COMMAND(do_list)
 
 
 		if (*array_table[cnt].name == 0)
 		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;
 	return ses;
 }
 }
@@ -293,7 +291,7 @@ DO_ARRAY(array_copy)
 	if ((from = search_nest_node_ses(ses, arg1)) == NULL)
 	if ((from = search_nest_node_ses(ses, arg1)) == NULL)
 	{
 	{
 		show_error(ses, LIST_VARIABLE, "#LIST COPY: VARIABLE {%s} NOT FOUND.", arg1);
 		show_error(ses, LIST_VARIABLE, "#LIST COPY: VARIABLE {%s} NOT FOUND.", arg1);
-		
+
 		return ses;
 		return ses;
 	}
 	}
 
 
@@ -575,7 +573,7 @@ DO_ARRAY(array_get)
 	if (*arg2 == 0)
 	if (*arg2 == 0)
 	{
 	{
 		show_error(ses, LIST_VARIABLE, "#SYNTAX: #LIST <VARIABLE> GET <INDEX> <VARIABLE>");
 		show_error(ses, LIST_VARIABLE, "#SYNTAX: #LIST <VARIABLE> GET <INDEX> <VARIABLE>");
-		
+
 		return ses;
 		return ses;
 	}
 	}
 
 
@@ -597,7 +595,7 @@ DO_ARRAY(array_get)
 
 
 DO_ARRAY(array_indexate)
 DO_ARRAY(array_indexate)
 {
 {
-	int cnt;
+	int cnt, index;
 
 
 	arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
 	arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
 
 
@@ -625,6 +623,30 @@ DO_ARRAY(array_indexate)
 		return ses;
 		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)
 	if (list->root->used)
 	{
 	{
 		int index = search_index_list(list->root->list[0]->root, arg1, "");
 		int index = search_index_list(list->root->list[0]->root, arg1, "");
@@ -649,6 +671,7 @@ DO_ARRAY(array_indexate)
 			}
 			}
 		}
 		}
 	}
 	}
+#endif
 	return ses;
 	return ses;
 }
 }
 
 
@@ -910,7 +933,7 @@ DO_ARRAY(array_size)
 	if (*arg1 == 0)
 	if (*arg1 == 0)
 	{
 	{
 		show_error(ses, LIST_VARIABLE, "#SYNTAX: #LIST <VARIABLE> SIZE <VARIABLE>");
 		show_error(ses, LIST_VARIABLE, "#SYNTAX: #LIST <VARIABLE> SIZE <VARIABLE>");
-		
+
 		return ses;
 		return ses;
 	}
 	}
 
 

+ 9 - 16
src/log.c

@@ -69,8 +69,6 @@ DO_COMMAND(do_log)
 
 
 	if (*arg1 == 0)
 	if (*arg1 == 0)
 	{
 	{
-		info:
-
 		tintin_header(ses, 80, " LOG OPTIONS ");
 		tintin_header(ses, 80, " LOG OPTIONS ");
 
 
 		for (cnt = 0 ; *log_table[cnt].fun != NULL ; cnt++)
 		for (cnt = 0 ; *log_table[cnt].fun != NULL ; cnt++)
@@ -83,25 +81,19 @@ DO_COMMAND(do_log)
 		pop_call();
 		pop_call();
 		return ses;
 		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);
 			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();
 	pop_call();
 	return ses;
 	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: 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: 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: 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)
 DO_LOG(log_make)

+ 10 - 7
src/mapper.c

@@ -83,8 +83,6 @@ DO_COMMAND(do_map)
 
 
 	if (*arg1 == 0)
 	if (*arg1 == 0)
 	{
 	{
-		info:
-
 		tintin_header(ses, 80, " MAP OPTIONS ");
 		tintin_header(ses, 80, " MAP OPTIONS ");
 
 
 		for (cnt = 0 ; *map_table[cnt].fun != NULL ; cnt++)
 		for (cnt = 0 ; *map_table[cnt].fun != NULL ; cnt++)
@@ -136,8 +134,7 @@ DO_COMMAND(do_map)
 				return ses;
 				return ses;
 			}
 			}
 		}
 		}
-
-		goto info;
+		show_error(ses, LIST_COMMAND, "#ERROR: #MAP {%s}: INVALID MAP OPTION.", arg1);
 	}
 	}
 	pop_call();
 	pop_call();
 	return ses;
 	return ses;
@@ -1828,7 +1825,7 @@ int follow_map(struct session *ses, char *argument)
 
 
 	room = ses->map->room_list[ses->map->in_room];
 	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))
 		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))
 			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();
 				pop_call();
 				return 1;
 				return 1;
 			}
 			}

+ 1 - 3
src/path.c

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

+ 1 - 3
src/port.c

@@ -43,8 +43,6 @@ DO_COMMAND(do_port)
 
 
 	if (*cmd == 0)
 	if (*cmd == 0)
 	{
 	{
-		info:
-
 		tintin_header(ses, 80, " PORT OPTIONS ");
 		tintin_header(ses, 80, " PORT OPTIONS ");
 
 
 		for (cnt = 0 ; *port_table[cnt].name != 0 ; cnt++)
 		for (cnt = 0 ; *port_table[cnt].name != 0 ; cnt++)
@@ -79,7 +77,7 @@ DO_COMMAND(do_port)
 		return ses;
 		return ses;
 	}
 	}
 
 
-	goto info;
+	show_error(ses, LIST_COMMAND, "#ERROR: #PORT {%s}: INVALID PORT OPTION.", cmd);
 
 
 	return ses;
 	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);
 		t -= gnutls_x509_crt_get_expiration_time(oldcert);
 
 
-		if (err || t < -7*24*3600)
+		if (err || t < -31*24*3600)
 		{
 		{
 			if (err)
 			if (err)
 			{
 			{

+ 1 - 1
src/tintin.h

@@ -212,7 +212,7 @@
 
 
 
 
 #define CLIENT_NAME              "TinTin++"
 #define CLIENT_NAME              "TinTin++"
-#define CLIENT_VERSION           "2.02.42b"
+#define CLIENT_VERSION           "2.02.50b"
 
 
 
 
 #define XT_E                            0x27
 #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);
 						str = get_arg_in_braces(root->ses, arg, line, GET_ONE);
 						addtoken(root, lvl++, TOKEN_TYPE_CASE, cmd, line);
 						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)
 						if (*line == 0)
 						{
 						{
 							show_error(root->ses, LIST_COMMAND, "#SYNTAX: #CASE <CONDITIONAL> <COMMANDS>");
 							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");
 						addtoken(root, lvl, TOKEN_TYPE_END, -1, "endcase");
 						break;
 						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);
 						str = get_arg_in_braces(root->ses, arg, line, GET_ALL);
 						tokenize_script(root, lvl--, line);
 						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");
 						addtoken(root, lvl, TOKEN_TYPE_END, -1, "enddefault");
 						break;
 						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);
 						str = get_arg_in_braces(root->ses, arg, line, GET_ALL);
 						tokenize_script(root, lvl--, line);
 						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");
 						addtoken(root, lvl, TOKEN_TYPE_END, -1, "endelse");
 						break;
 						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);
 						str = get_arg_in_braces(root->ses, arg, line, GET_ONE);
 						addtoken(root, lvl++, TOKEN_TYPE_ELSEIF, cmd, line);
 						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)
 						if (*line == 0)
 						{
 						{
 							show_error(root->ses, LIST_COMMAND, "#SYNTAX: #ELSEIF <CONDITIONAL> <COMMANDS>");
 							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");
 						addtoken(root, lvl, TOKEN_TYPE_END, -1, "endelseif");
 						break;
 						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);
 						str = get_arg_in_braces(root->ses, arg, line, GET_ONE);
 						addtoken(root, lvl++, TOKEN_TYPE_IF, cmd, line);
 						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)
 						if (*line == 0)
 						{
 						{
 							show_error(root->ses, LIST_COMMAND, "#SYNTAX: #IF <CONDITIONAL> <TRUE> [FALSE]");
 							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");
 						addtoken(root, lvl, TOKEN_TYPE_END, -1, "endif");
 
 
 						str = space_out(str);
 						str = space_out(str);

+ 1 - 1
src/trigger.c

@@ -820,7 +820,7 @@ DO_COMMAND(do_prompt)
 	{
 	{
 		show_list(ses->list[LIST_PROMPT], 0);
 		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)
 		if (show_node_with_wild(ses, arg1, ses->list[LIST_PROMPT]) == FALSE)
 		{
 		{