Browse Source

Ok, there's lots of changes here.

Deep debugging is still enabled.
But, charman is now valid again!

Our insert is working correctly.
The buffers aren't getting corrupted.

BUG:  Mystic BBS v1.11 for Linux Node 1
^ THIS is the OLD version.

A54 HAS:
Mystic BBS Version 1.12 A45

This screwed up my regex.  Fixed,
and we use our modified OLD version.
Steve Thielemann 4 years ago
parent
commit
5f226410a7
5 changed files with 206 additions and 68 deletions
  1. 113 10
      charman.cpp
  2. 8 4
      charman.h
  3. 6 2
      render.cpp
  4. 12 6
      utils.cpp
  5. 67 46
      wordplay.cpp

+ 113 - 10
charman.cpp

@@ -27,12 +27,44 @@ void CharMan::validate(void) {
   }
   if (!valid) {
     ZF_LOGE("* NOT VALID*  Somethings hosed.");
+    diagnostics();
   }
 }
 
+void CharMan::diagnostics(void) {
+  ZF_LOGV_MEM(buffer.data(), buffer.size(), "Buffer:");
+  ZF_LOGV_MEM(work.data(), work.size(), "Work:");
+  ZF_LOGV_MEM(text.data(), text.size(), "Text Buffer:");
+
+  std::ostringstream oss;
+  int comma = 0;
+  for (auto it = std::begin(text_offsets); it != std::end(text_offsets); ++it) {
+    if (comma) {
+      oss << ", ";
+    };
+    comma++;
+    oss << *it;
+    if (comma == 30) {
+      std::string temp_output = oss.str();
+      ZF_LOGV("Vector: %s", temp_output.c_str());
+      // reset ostringstream
+      oss.str(std::string());
+      oss.clear();
+      comma = 0;
+    }
+  }
+  std::string vector_output = oss.str();
+  ZF_LOGV("Vector: %s", vector_output.c_str());
+
+  // reset oss (if we need it)
+  oss.str(std::string());
+  oss.clear();
+}
+
 void CharMan::regular_expressions(void) {
   static std::regex words("[a-zA-Z'-]+([ ]{1,2}[a-zA-Z&'-]+)+");
   // I need position and length.
+  pos_len.clear();
 
   for (auto it =
            std::sregex_iterator(this->text.begin(), this->text.end(), words);
@@ -55,6 +87,32 @@ void CharMan::set(int pos, char ch) {
   }
 }
 
+void CharMan::insert(int pos, std::string str) {
+  int len = str.size();
+  int idx = this->text_offsets[pos];
+  ZF_LOGE("insert( POS %d, LEN %d, IDX %d, %s)", pos, len, idx, str.c_str());
+  diagnostics();
+  std::string blank(len, ' ');
+  // Don't insert into text.
+  // Insert blank into work.
+  // Update indexes >= idx
+
+  if (idx >= 0) {
+    this->buffer.insert(idx, str);
+    this->work.insert(idx, blank);
+
+    // UPDATE indexes!
+    for (auto it = std::begin(this->text_offsets);
+         it != std::end(this->text_offsets); ++it) {
+      if (*it >= idx) {
+        *it += len;
+      }
+    }
+    ZF_LOGE("Indexes updated... check your work");
+    diagnostics();
+  }
+}
+
 int CharMan::word_mangler(std::pair<int, int> pos_len) {
   int pos = pos_len.first;
   int state = randrange(-1, 1);
@@ -124,6 +182,47 @@ int CharMan::word_wrangler(std::pair<int, int> pos_len) {
   return count;
 }
 
+/*
+  Display up to certain point.
+  Print some characters slowly.  Delay.
+ */
+int CharMan::word_tangler(std::pair<int, int> pos_len) {
+  int count = 0;
+  int p;
+  int len;
+
+  std::string part = this->text.substr(pos_len.first, pos_len.second);
+  ZF_LOGE("tangler [%s]", logrepr(part.c_str()));
+
+  if (pos_len.second < 4)
+    return 0;
+
+  /* p = randint(pos_len.second - 4);
+  len = randint(pos_len.second - p); */
+  p = pos_len.first;
+  len = pos_len.second;
+
+  if (len >= 2) {
+    ZF_LOGD("Tangler: %d, %d", p, len);
+    this->validate();
+    std::ostringstream buffer;
+    std::string tangle;
+    int r = 1; // randint(2) + 1;
+
+    buffer << "^P1^R" << r;
+    r = randint(4) + 1;
+    buffer << "^S" << r;
+    tangle = buffer.str();
+    std::string reset = "^R0^S0";
+    this->insert(p + len, reset);
+    this->validate();
+    this->insert(p, tangle);
+    this->validate();
+    return 1;
+  }
+  return 0;
+}
+
 CharMan::CharMan(std::string &buffer, std::string &work, std::string &text,
                  std::vector<int> &text_offsets)
     : buffer(buffer), work(work), text(text), text_offsets(text_offsets) {
@@ -135,6 +234,7 @@ this->text_offsets = text_offsets;
 */
   this->mangle_count = 0;
   this->mangle_chars = 0;
+  this->need_render = 0;
 
   this->level = harry_level();
   if (!this->level)
@@ -145,27 +245,30 @@ this->text_offsets = text_offsets;
   ZF_LOGD("Found %d word groups", (int)pos_len.size());
   if (pos_len.size() > 0) {
     for (int i = 0; i < pos_len.size(); ++i) {
-      if (random_activate(8)) {
+      int active = 0;
+      if (random_activate(level * 2)) { // 8
         int c = word_mangler(pos_len[i]);
         if (c) {
+          active = 1;
           this->mangle_count++;
           this->mangle_chars += c;
         }
       }
 
-      if (random_activate(4)) {
-        if (word_wrangler(pos_len[i]))
+      if (random_activate(level)) { // 4
+        if (word_wrangler(pos_len[i])) {
           this->mangle_count++;
+          active = 1;
+        }
+      }
+
+      if (!active && random_activate(level)) {
+        if (word_tangler(pos_len[i])) {
+          this->need_render = 1;
+        }
       }
     }
   }
-
-  /*
-    Display up to certain point.
-    Print some characters slowly.  Delay.
-
-    ** This would require "need_render" **
-   */
 };
 
 CharMan::~CharMan() {

+ 8 - 4
charman.h

@@ -16,19 +16,23 @@ private:
   void validate(void);
   void regular_expressions();
   char get(int);
-  void set(int,char);
+  void set(int, char);
+  void insert(int, std::string);
 
-  int word_mangler(std::pair<int,int> pos_len);
-  int word_wrangler(std::pair<int,int> pos_len);
+  int word_mangler(std::pair<int, int> pos_len);
+  int word_wrangler(std::pair<int, int> pos_len);
+  int word_tangler(std::pair<int, int> pos_len);
   int level;
-  
+
 public:
   int mangle_count;
   int mangle_chars;
+  int need_render;
 
   CharMan(std::string &buffer, std::string &work, std::string &text,
           std::vector<int> &text_offsets);
   ~CharMan();
+  void diagnostics(void);
 };
 
 #endif

+ 6 - 2
render.cpp

@@ -549,6 +549,7 @@ const char *process_trigger(int fd, const char *cp) {
       ZF_LOGI("RENDER %d", i);
       current_render.effect = i;
     } else {
+      ZF_LOGI("RENDER OFF");
       current_render.effect = 0;
     }
   } break;
@@ -562,6 +563,7 @@ const char *process_trigger(int fd, const char *cp) {
       ZF_LOGI("SPEED %d", i);
       current_render.speed = i;
     } else {
+      ZF_LOGI("SPEED OFF");
       current_render.speed = 0;
     }
   } break;
@@ -617,13 +619,15 @@ void render_effect(int fd, char ch) {
     break;
   case 2:
     // CHAR + 8 spaces + 8 BS
+    // This might be too much.
+#define MOVE 4
     render_sleep();
     write(fd, &ch, 1);
-    for (l = 0; l < 8; l++) {
+    for (l = 0; l < MOVE; l++) {
       render_sleep();
       write(fd, &space, 1);
     }
-    for (l = 0; l < 8; l++) {
+    for (l = 0; l < MOVE; l++) {
       render_sleep();
       write(fd, &bs, 1);
     }

+ 12 - 6
utils.cpp

@@ -333,12 +333,12 @@ std::map<std::string, std::string> read_configfile(std::string filename) {
   return config;
 }
 
-bool replace(std::string& str, const std::string& from, const std::string& to) {
-    size_t start_pos = str.find(from);
-    if(start_pos == std::string::npos)
-        return false;
-    str.replace(start_pos, from.length(), to);
-    return true;
+bool replace(std::string &str, const std::string &from, const std::string &to) {
+  size_t start_pos = str.find(from);
+  if (start_pos == std::string::npos)
+    return false;
+  str.replace(start_pos, from.length(), to);
+  return true;
 }
 
 IConv::IConv(const char *to, const char *from) : ic(iconv_open(to, from)) {}
@@ -377,6 +377,12 @@ int harry_level(void) {
   auto search = CONFIG.find("LEVEL");
   if (search != CONFIG.end()) {
     last = stoi(search->second);
+    if (last > 4) {
+      last = 4;
+    }
+    if (last < 0) {
+      last = 0;
+    }
     return last;
   }
 

+ 67 - 46
wordplay.cpp

@@ -262,67 +262,88 @@ int mangle(int fd, std::string &buffer) {
   }
 
   int level = harry_level();
+  std::ostringstream new_buffer;
+  std::smatch match;
 
-  if (level > 2) {
+  if (level) {
     // Strings are good, but Regex is better
     // Mystic BBS v1.12 A43 for Linux Node 1
-    static std::regex bbs("Mystic BBS v[0-9.]+ A[0-9]+ for Linux Node [0-9]+");
-    std::smatch match;
-
-    if (std::regex_search(buffer, match, bbs)) {
-      // We have a match
-      std::string old_string =
-          buffer.substr(match.position(0), match.length(0));
-
-      // Build a new and better string
-      std::ostringstream new_buffer;
-      std::string new_string;
-      const char *bbs_systems[] = {"Haunted BBS", "Harry's BBS",
-                                   "Scary BBS Software", "Screaming BBS"};
-      const char *operating_systems[] = {
-          "OS/360",     "CP/M",       "OS/9",     "Xenix",          "MS-DOS",
-          "PC-DOS",     "DR-DOS",     "QNX",      "Novell Netware", "AmigaOS",
-          "Windows NT", "Windows CE", "AIX",      "OS/2",           "OS/400",
-          "NeXTSTEP",   "MINIX",      "Solaris",  "Plan 9",         "FreeBSD",
-          "Windows 95", "Palm OS",    "Mac OS X", "Windows XP"};
-
-      int r = randint(sizeof(bbs_systems) / sizeof(char *));
-      new_buffer << bbs_systems[r] << " v" << randint(10) << "." << randint(80);
-      new_buffer << " for ";
-
-      r = randint(sizeof(operating_systems) / sizeof(char *));
-      new_buffer << operating_systems[r] << " Node " << randint(100 * level);
-      new_string = new_buffer.str();
-      // reset buffer
-      new_buffer.str(std::string());
-      new_buffer.clear();
-
-      replace(buffer, old_string, new_string);
-      replace(work, old_string, new_string);
-      level = 0; // turn off the manglers!  ;)
+    // Mystic BBS Version 1.12 A45
+    static int bbs_match = 0;
+
+    if (!bbs_match) {
+      std::regex bbs_what("Mystic BBS Version [0-9.]+ A[0-9]+");
+      // Mystic BBS v[0-9.]+ A[0-9]+ for Linux Node [0-9]+
+
+      if (std::regex_search(buffer, match, bbs_what)) {
+        // We have a match
+        ZF_LOGD("bbs_seen");
+        bbs_match = 1;
+        std::string old_string =
+            buffer.substr(match.position(0), match.length(0));
+
+        // Build a new and better string
+        std::string new_string;
+        const char *bbs_systems[] = {
+            "Haunted BBS",   "Harry's BBS", "Scary BBS Software",
+            "Screaming BBS", "Fright BBS",  "Gravestone BBS",
+        };
+        const char *operating_systems[] = {
+            "OS/360",   "CP/M",       "OS/9",
+            "Xenix",    "MS-DOS",     "PC-DOS",
+            "DR-DOS",   "QNX",        "Novell Netware",
+            "AmigaOS",  "Windows NT", "Windows CE",
+            "AIX",      "OS/2",       "OS/400",
+            "NeXTSTEP", "MINIX",      "Solaris",
+            "Plan 9",   "FreeBSD",    "Windows 95",
+            "Palm OS",  "Mac OS X",   "Windows XP",
+            "DESQview",
+        };
 
+        int r = randint(sizeof(bbs_systems) / sizeof(char *));
+        new_buffer << bbs_systems[r] << " v" << randint(10) << "."
+                   << randint(80);
+        new_buffer << " for ";
+
+        r = randint(sizeof(operating_systems) / sizeof(char *));
+        new_buffer << operating_systems[r] << " Node " << randint(150 * level);
+        new_string = new_buffer.str();
+        // reset buffer
+        new_buffer.str(std::string());
+        new_buffer.clear();
+
+        replace(buffer, old_string, new_string);
+        replace(work, old_string, new_string);
+        level = 0; // turn off the manglers!  ;)
+      }
+    }
+
+    static int author_match = 0;
+
+    if (!author_match) {
       static std::regex author("Copyright \\(C\\) [0-9-]+ By James Coyle");
-      std::smatch match;
 
       if (std::regex_search(buffer, match, author)) {
         // We have a match
+        ZF_LOGD("author seen");
+        author_match = 1;
         std::string old_author =
             buffer.substr(match.position(0), match.length(0));
 
         // Build a new and better string
-        std::string new_author;
         const char *coder_names[] = {"Horrible Harry", "Ghost Writer",
                                      "Sands of Time", "Spector Software",
                                      "Creepy Coder"};
-        if (randint(10) < 4)
-          new_buffer << "Copywrong ";
+        if (randint(10) < 5)
+          new_buffer << "Copyfright ";
         else
           new_buffer << "Copyright ";
+
         new_buffer << "(C) " << 1000 + randint(999) << "-" << randint(24000)
                    << " By ";
         int r = randint(sizeof(coder_names) / sizeof(char *));
         new_buffer << coder_names[r];
-        new_author = new_buffer.str();
+        std::string new_author = new_buffer.str();
 
         replace(buffer, old_author, new_author);
         replace(work, old_author, new_author);
@@ -341,7 +362,6 @@ int mangle(int fd, std::string &buffer) {
       }
   }
 
-  // Ok, maybe the work string was a bad idea?
   static std::string text;
   static std::vector<int> text_offsets;
   size_t stri;
@@ -350,8 +370,6 @@ int mangle(int fd, std::string &buffer) {
   text_offsets.clear();
 
   for (stri = 0; stri < buffer.size(); ++stri) {
-    // why wasn't \x1b[?1000h   handled by console_char?
-    // what happened to \x0c ?   It is there.
     termchar tc = console_char(&console, work[stri]);
 
     if (tc.in_ansi) {
@@ -385,11 +403,11 @@ int mangle(int fd, std::string &buffer) {
   }
 
   ZF_LOGV("Buffer: %s", logrepr(buffer.c_str()));
+  ZF_LOGV("Work: %s", logrepr(work.c_str()));
+  ZF_LOGV("Text: %s", logrepr(text.c_str()));
   // ZF_LOGV_MEM(buffer.data(), buffer.size(), "Buffer:");
   // ZF_LOGV_MEM(work.data(), work.size(), "Work:");
-  ZF_LOGV("Work: %s", logrepr(work.c_str()));
   // ZF_LOGV_MEM(text.data(), text.size(), "Text Buffer:");
-  ZF_LOGV("Text: %s", logrepr(text.c_str()));
 
   // Output vector contents
   std::ostringstream oss;
@@ -420,7 +438,10 @@ int mangle(int fd, std::string &buffer) {
   if (level) {
     ZF_LOGD("CharMan");
     CharMan cm(buffer, work, text, text_offsets);
-    ZF_LOGD("CharMan %d, %d chars", cm.mangle_count, cm.mangle_chars);
+    ZF_LOGD("CharMan %d, %d chars, render %d", cm.mangle_count, cm.mangle_chars,
+            cm.need_render);
+    if (cm.need_render)
+      need_render = 1;
   };
 
   if (need_render) {