Kaynağa Gözat

We have ANSI_CLS back again.

It uses the console terminal processor to figure
out what color is active at that point, so
we can reset it.  (NOTE:  You can't use ^CR
there, because we're at some point in time in the
buffer.)

We have ^G0x0y so you can goto XY positions on the screen.

NOTE: We probably need to make sure the Hahaha is in the
last_seen buffer, so it never shows it first -- the delays
could screw up Mystic's ANSI detection!
bugz 5 yıl önce
ebeveyn
işleme
e2e24d5937
1 değiştirilmiş dosya ile 145 ekleme ve 119 silme
  1. 145 119
      mystic.c

+ 145 - 119
mystic.c

@@ -9,7 +9,7 @@
 #include <sys/select.h>
 #include <sys/wait.h>
 
-#include <signal.h> // handle Ctrl-C/SIGINT
+// #include <signal.h> // handle Ctrl-C/SIGINT
 
 #include <strings.h> // strcasecmp
 #include <time.h>    // usleep(), nanonsleep() ?
@@ -20,8 +20,8 @@
 #include <regex.h>
 
 // LOGGING with file output
-
 #include "zf_log.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -57,29 +57,6 @@ that we'll be executing and mangling?
 // Size of our input and output buffers.
 #define BSIZE 128
 
-/*
-  // Don't need this,  zf_log does date/time stamps on output.
-
-const char * it_is_now(void) {
-    static char buffer[100];
-    time_t timer;
-    struct tm* tm_info;
-
-    timer = time(NULL);
-    tm_info = localtime(&timer);
-    strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info);
-    return buffer;
-}
-
-void slow_write(int fd, int speed, char * buffer, int len) {
-    int x;
-    for( x = 0; x < len; x++) {
-        usleep(speed);
-        write( fd, &buffer[x], 1);
-    }
-}
-*/
-
 /**
  * Display a repr of the given string.
  *
@@ -157,6 +134,25 @@ const char *repr(const char *data) {
   return buffer;
 }
 
+/*
+ * string_insert()
+ * Inserts a string into a given position.
+ * This safely checks to make sure the buffer isn't overrun.
+ */
+int string_insert( char * buffer, int max_length, int pos, const char * insert ) {
+    if (strlen(buffer) + strlen(insert) >= max_length) {
+      ZF_LOGD("string_insert() failed inserting [%s]", repr(insert));
+      return 0;
+    }
+    memmove(buffer + pos + strlen(insert), buffer + pos, strlen(buffer + pos) + 1 ); 
+    // cp + strlen(display), cp, strlen(cp) + 1);
+    strncpy(buffer+pos, insert, strlen(insert));
+    // (cp, display, strlen(display));
+    return 1; // success
+}
+
+// Should this be passed around to the functions that use it?
+
 struct render {
   int speed;
   int effect;
@@ -196,6 +192,10 @@ void render_sleep(void) {
 
 /*
 Terminal tracking
+
+Actually, I believe I only really need to track the color information.
+Everything else, I'm not sure I really care about.
+
  */
 
 struct console_details {
@@ -214,50 +214,50 @@ void console_init(struct console_details *cdp) {
   cdp->savedx = 0;
   cdp->savedy = 0;
   cdp->in_ansi = 0;
-  cdp->fgcolor = 0;
+  cdp->fgcolor = 7;
   cdp->bgcolor = 0;
   cdp->status = 0;
 }
 
-void ansi_color(int color) {
+void ansi_color(struct console_details *cdp, int color) {
   ZF_LOGD("ansi_color(%d)", color);
   if (color == 0) {
-    console.status = 0;
-    console.fgcolor = 0;
-    console.bgcolor = 0;
+    cdp->status = 0;
+    cdp->fgcolor = 7;
+    cdp->bgcolor = 0;
     return;
   }
   if (color == 1) {
-    console.status = 1;
+    cdp->status = 1;
     return;
   }
   if (color == 5) {
-    console.status = 5;
+    cdp->status = 5;
     return;
   }
   if ((color >= 30) && (color <= 37)) {
-    console.fgcolor = color - 30;
+    cdp->fgcolor = color - 30;
     return;
   }
   if ((color >= 40) && (color <= 47)) {
-    console.bgcolor = color - 40;
+    cdp->bgcolor = color - 40;
     return;
   }
   ZF_LOGD("ansi_color( %d ) is unknown to me.", color);
 }
 
-const char *color_restore() {
+const char *color_restore(struct console_details *cdp) {
   static char buffer[30];
-  if (console.status == 0) {
-    sprintf(buffer, "\x1b[0;3%d;4%dm", console.fgcolor, console.bgcolor);
+  if (cdp->status == 0) {
+    sprintf(buffer, "\x1b[0;3%d;4%dm", cdp->fgcolor, cdp->bgcolor);
   } else {
-    sprintf(buffer, "\x1b[0;%d;3%d;4%dm", console.status, console.fgcolor,
-            console.bgcolor);
+    sprintf(buffer, "\x1b[0;%d;3%d;4%dm", cdp->status, cdp->fgcolor,
+            cdp->bgcolor);
   };
   return buffer;
 }
 
-void console_ansi(const char *ansi) {
+void console_ansi(struct console_details *cdp, const char *ansi) {
   int understood = 0;
   const char *cp = ansi;
   const char *last = ansi + strlen(ansi) - 1;
@@ -284,9 +284,9 @@ void console_ansi(const char *ansi) {
             number = 1;
           }
         };
-        console.posy -= number;
-        if (console.posy < 0) {
-          console.posy = 0;
+        cdp->posy -= number;
+        if (cdp->posy < 0) {
+          cdp->posy = 0;
           ZF_LOGD(
               "console_ansi( %s ): attempt to move above top of screen (%d)",
               repr(ansi), number);
@@ -305,7 +305,7 @@ void console_ansi(const char *ansi) {
             number = 1;
           }
         };
-        console.posy += number;
+        cdp->posy += number;
         // check range/"scroll"
         understood = 1;
         return;
@@ -322,16 +322,16 @@ void console_ansi(const char *ansi) {
             number = 1;
           }
         };
-        console.posx += number;
+        cdp->posx += number;
 
         // Well.  According to the "spec", the screen limits are hard
         // If the cursor is already at the edge of the screen, this has no
         // effect. ^ This is *NOT* how any ANSI BBS terminal program acts!
 
-        while (console.posx > 79) {
-          console.posy++;
+        while (cdp->posx > 79) {
+          cdp->posy++;
           // check range/"scroll"
-          console.posx -= 79;
+          cdp->posx -= 79;
         }
         understood = 1;
         return;
@@ -345,21 +345,21 @@ void console_ansi(const char *ansi) {
           if (number < 1) {
             ZF_LOGD("console_ansi( %s ): number error (%d)", repr(ansi),
                     number);
-            number = 1;
+            number = 0;
           }
         };
-        console.posx -= number;
+        cdp->posx -= number;
 
         // Well.  According to the "spec", the screen limits are hard
         // If the cursor is already at the edge of the screen, this has no
         // effect. ^ This is *NOT* how any ANSI BBS terminal program acts!
 
-        while (console.posx < 0) {
-          console.posy--;
-          if (console.posy < 0) {
-            console.posy = 0;
+        while (cdp->posx < 0) {
+          cdp->posy--;
+          if (cdp->posy < 0) {
+            cdp->posy = 0;
           }
-          console.posx += 79;
+          cdp->posx += 79;
         }
         understood = 1;
         return;
@@ -397,8 +397,8 @@ void console_ansi(const char *ansi) {
         }
 
         // Our positions start at zero, not one.
-        console.posx = number - 1;
-        console.posy = number2 - 1;
+        cdp->posx = number - 1;
+        cdp->posy = number2 - 1;
 
         understood = 1;
         break;
@@ -413,8 +413,8 @@ void console_ansi(const char *ansi) {
 
         // clears ... part of the screen.
         if (number == 2) {
-          console.posx = 0;
-          console.posy = 0;
+          cdp->posx = 0;
+          cdp->posy = 0;
         };
         understood = 1;
         break;
@@ -424,11 +424,11 @@ void console_ansi(const char *ansi) {
         if (cp == last) {
           // nothing given, default to 0.
           number = 0;
-          ansi_color(number);
+          ansi_color(cdp, number);
         } else {
           while (cp != last) {
             number = atoi(cp);
-            ansi_color(number);
+            ansi_color(cdp, number);
             cp++;
 
             while ((cp != last) && (isdigit(*cp))) {
@@ -471,54 +471,54 @@ void console_ansi(const char *ansi) {
  * console_char()
  *  return whether or not we are still in_ansi
  */
-int console_char(char ch) {
+int console_char(struct console_details *cdp, char ch) {
   char *cp;
 
-  if (console.in_ansi) {
+  if (cdp->in_ansi) {
     // Ok, append this char
-    cp = console.ansi + strlen(console.ansi);
+    cp = cdp->ansi + strlen(cdp->ansi);
     *cp = ch;
     cp++;
     *cp = 0;
     if (isalpha(ch)) {
       // Ok!
-      console_ansi(console.ansi);
-      console.in_ansi = 0;
-      console.ansi[0] = 0;
+      console_ansi(cdp, cdp->ansi);
+      cdp->in_ansi = 0;
+      cdp->ansi[0] = 0;
       return 1;
     }
     return 1;
   } else {
     if (ch == '\x1b') {
-      cp = console.ansi;
+      cp = cdp->ansi;
       *cp = ch;
       cp++;
       *cp = 0;
-      console.in_ansi = 1;
+      cdp->in_ansi = 1;
       return 1;
     }
     if (ch == '\r') {
       // Carriage return
-      console.posx = 0;
+      cdp->posx = 0;
       return 0;
     }
     if (ch == '\n') {
-      console.posy++;
+      cdp->posy++;
       // check range/"scroll"
       return 0;
     }
     if (ch == '\b') {
       // Backspace.
-      if (console.posx > 0) {
-        console.posx--;
+      if (cdp->posx > 0) {
+        cdp->posx--;
       }
       return 0;
     }
     if (ch == '\f') {
       // form feed
       // treat as clear screen
-      console.posx = 0;
-      console.posy = 0;
+      cdp->posx = 0;
+      cdp->posy = 0;
       return 0;
     }
 
@@ -527,29 +527,29 @@ int console_char(char ch) {
       actual printable character.  So!
     */
 
-    console.posx++;
+    cdp->posx++;
 
-    if (console.posx > 79) {
-      console.posx = 0;
-      console.posy++;
+    if (cdp->posx > 79) {
+      cdp->posx = 0;
+      cdp->posy++;
       // check range/"scroll"
     }
     return 0;
   }
 }
 
-void console_string(const char *chars) {
+void console_string(struct console_details *cdp, const char *chars) {
   int x;
   for (x = 0; x < strlen(chars); x++) {
-    console_char(chars[x]);
+    console_char(cdp, chars[x]);
   }
 }
 
-void console_receive(const char *chars, int len) {
+void console_receive(struct console_details *cdp, const char *chars, int len) {
   int x;
 
   for (x = 0; x < len; x++) {
-    console_char(chars[x]);
+    console_char(cdp, chars[x]);
   }
 }
 
@@ -618,7 +618,7 @@ const int MYSTIC[] = {0, 4, 2, 6, 1, 5, 3, 7};
 // ANSI_color = MYSTIC[ odd_mystic_color % 8 ]
 
 void write_color(int fd, int color) {
-  char buffer[10];
+  char buffer[12];
 
   switch (color) {
   case 0:
@@ -710,7 +710,7 @@ const char *process_trigger(int fd, const char *cp) {
     i = 0;
     if (*cp == 'R') {
       cp++;
-      const char *restore = color_restore();
+      const char *restore = color_restore(&console);
       write(fd, restore, strlen(restore));
       break;
     }
@@ -747,6 +747,10 @@ const char *process_trigger(int fd, const char *cp) {
       y += (*cp) - '0';
       cp++;
     };
+    char buffer[20];  // row ; column H
+    ZF_LOGD("GOTO (%d,%d)", x, y);
+    sprintf(buffer, "\x1b[%d;%dH", y, x);
+    write(fd, buffer, strlen(buffer));
     break;
 
   case 'R':
@@ -967,7 +971,7 @@ const char *random_phrase(const char *words, int len, int last_seen) {
 }
 #endif
 
-void harry_event(int fd) {
+void harry_idle_event(int fd) {
   // Make something happen
   char buffer[100];
   int r;
@@ -990,7 +994,8 @@ void harry_event(int fd) {
   int color = random() % 16;
   if (color == 0) {
     color++;
-  } // If it's 0 let's make it 1.
+  } // If it's 0 let's make it 1.   // color = (random() % 15) + 1
+
   sprintf(buffer, "^S2^C%02d%s^P2^CR^D%02d", color, cp, (int)strlen(cp));
 
   ZF_LOGD("harry_event: render(%d, \"%s\")", fd, buffer);
@@ -1202,7 +1207,6 @@ int word_state(const char *buffer, int len) {
 
   // ZF_LOGD("So far %d with %f %%", ret, pct);
 
-  // They must be > 75%, otherwise return "mixed".
   if (pct < 40.0) {
     return ret;
   }
@@ -1223,7 +1227,6 @@ int word_mangler(char *buffer, int len) {
   int p;
   int count = 0;
   int state;
-  char c;
 
   state = word_state(buffer, len);
   // ZF_LOGD("word_state(%.*s) %d", len, buffer, state);
@@ -1231,7 +1234,7 @@ int word_mangler(char *buffer, int len) {
   // TODO:  Transposer
 
   for (p = 0; p < len; p++) {
-    c = buffer[p];
+    char c = buffer[p];
 
     switch (state) {
     case -1:
@@ -1293,8 +1296,6 @@ int mangle(int fd, char *buffer) {
   process.
   */
 
-#ifdef NO_NOT_YET
-
   /*
    (random) Look for ANSI CLS and:
 
@@ -1308,17 +1309,26 @@ int mangle(int fd, char *buffer) {
   if (cp != NULL) {
     ZF_LOGI("seen: ANSI_CLS");
 
-    if (random_activate(9)) {
+    if (random_activate(4)) {
       int r;
-      int color;
       char display[100] = "";
       const char *phrasing[] = {
-          "HeHeHe",
+          "^R1Haha^P1ha^P1ha",
           "Poof!",
           "Got U",
           "Anyone there?",
+          "^R1Knock, ^P1Knock"
       };
 
+      // import magic
+      struct console_details temp_console;
+      // Make exact copy of our current console state.
+      memcpy(&temp_console, &console, sizeof(console));
+      // Play the buffer into the console
+      console_receive(&temp_console, buffer, cp - buffer);
+      char restore_color[30];  // ansi color
+      strcpy( restore_color, color_restore(&temp_console));
+
       ZF_LOGI("mangle(ANSI_CLS)");
       // sprintf( display, "^P2...");
       // This string actually screws up ANSI detection (takes too long)
@@ -1326,25 +1336,41 @@ int mangle(int fd, char *buffer) {
 
       // strcpy(display, "^P2^S301234^P15^S0^P2");
 
-      r = random() % 10;
-      if (r == 8) {
-        // Add in random text, plus color!
-        r = random() % ((sizeof(phrasing) / sizeof(char *)) - 1);
-        color = random() % 16;
-        if (color == 0) {
-          color++;
-        }
-        sprintf(display, "^P1^S3^C%02d%s^S0^P1", color, phrasing[r]);
-        ZF_LOGI("mangle(ANSI_CLS): Inserted (%02d) %s", color, phrasing[r]);
+      // Add in random text, plus color!
+      r = random() % ((sizeof(phrasing) / sizeof(char *)) - 1);
+      int color = random() % 15 + 1;
+      int x = random() % 30 + 1;
+      int y = random() % 15 + 1;
+
+      /* 
+      Don't have it pause there before moving the cursor.
+
+      Move the cursor, get the color changed, THEN pause.
+      Then act all crazy.
+
+      NOTE:  Make sure if you use any ^R Render effects, turn them off before
+      trying to display the restore_color.  :P   ^R0
+      Also, make sure you re-home the cursor ^G0101 because that's where they
+      are expecting the cursor to be!  (At least it's how Mystic does it.)
+
+      HOME, CLS, HOME, ...  Not sure what others do there.  We'll see.
+      */
+
+      sprintf(display, "^G%02d%02d^S3^C%02d^P1%s^S0^R0%s^P1^G0101", x, y, color, phrasing[r], restore_color);
+
+      //sprintf(display, "^P1^S3^C%02d%s^S0^R0%s^P1", color, phrasing[r], restore_color);
+      ZF_LOGI("mangle(ANSI_CLS): Inserted (%02d) %s", color, phrasing[r]);
+
+      // Move the buffer so there's room for the display string.
+      if ( string_insert(buffer, BSIZE * 4, cp - buffer, display)) {
+        ZF_LOGI("mangle(ANSI_CLS): [%s]", repr(buffer));
+        need_render = 1;
       } else {
-        ZF_LOGI("mangle(ANSI_CLS): Inserted Nothing");
+        ZF_LOGD("insert failed [%s].", repr(display));
       }
 
-      // Move the buffer so there's room for the display string.
-      memmove(cp + strlen(display), cp, strlen(cp) + 1);
-      strncpy(cp, display, strlen(display));
-      ZF_LOGI("mangle(ANSI_CLS): [%s]", repr(buffer));
-      need_render = 1;
+      // memmove(cp + strlen(display), cp, strlen(cp) + 1);
+      // strncpy(cp, display, strlen(display));
 
       /*
       Copy the new buffer over, but hide our "render" code
@@ -1358,14 +1384,14 @@ int mangle(int fd, char *buffer) {
     };
   }
 
-#endif
 
   strcpy(work, buffer); // sure.
 
+  const char replace_with = ' ';
   for (x = 0; x < strlen(buffer); x++) {
-    int ansi = console_char(buffer[x]);
+    int ansi = console_char(&console, buffer[x]);
     if (ansi) {
-      work[x] = ' ';
+      work[x] = replace_with;
     }
   }
 
@@ -1375,7 +1401,7 @@ int mangle(int fd, char *buffer) {
 
   /* work -- clear out ANSI so we don't mangle ANSI codes. */
   x = rx_match(&ANSI, work);
-  char replace_with = ' ';
+
   if (x > 0) {
     ZF_LOGD("found %d ANSI", x);
     for (i = 0; i < x; i++) {
@@ -1484,16 +1510,16 @@ int main(int argc, char *argv[]) {
   // ./mystic -TID7 -IP192.168.0.1 -HOSTUnknown -ML0 -SL0 -ST0 -CUnknown
 
   // ./mystic -TID7 -IP192.168.0.1 -HOSTUnknown -ML1 -SL0 -ST2 -CUnknown -Ubugz
-  // -PUP2LAT3
+  // -PUWISH
   // ./mystic -TID7 -IP192.168.0.1 -HOSTUnknown -ML0 -SL0 -ST0 -CUnknown
 
   // ./mystic -TID7 -IP192.168.0.1 -HOSTUnknown -ML0 -SL0 -ST0 -CUnknown
   // ./mystic -TID9 -IP192.168.0.1 -HOSTUnknown -ML0 -SL1 -ST0 -CUnknown
 
   // ./mystic -TID7 -IP192.168.0.1 -HOSTUnknown -ML1 -SL0 -ST2 -CUnknown -Ubugz
-  // -PUP2LAT3
+  // -PDUMBWAYTODOTHIS
   // ./mystic -TID9 -IP192.168.0.1 -HOSTUnknown -ML1 -SL1 -ST2 -CUnknown -Ubugz
-  // -PUP2LAT3
+  // -PIDONTUSEPASCAL
 
   // SSH:  -ML1 -ST2
   // Telnet: -ML0 -ST0
@@ -1603,7 +1629,7 @@ int main(int argc, char *argv[]) {
       if (select(master + 1, &read_fd, &write_fd, &except_fd, &timeout) == 0) {
         // This means timeout!
         ZF_LOGI("TIMEOUT");
-        harry_event(STDOUT_FILENO);
+        harry_idle_event(STDOUT_FILENO);
       }
 
       char input[BSIZE + 1];