123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- #include "images.h"
- #include "lastseen.h"
- #include "render.h"
- #include "terminal.h"
- #include "utils.h"
- #include <iomanip>
- #include <sstream>
- #include <string.h>
- #include <string>
- #include <vector>
- #include "charman.h"
- #include "zf_log.h"
- #include <unistd.h> // write
- extern struct console_details console;
- #define BSIZE 512
- void harry_idle_event(int fd) {
-
- std::ostringstream buffer;
- int r;
-
-
- const char *phrases[] = {"Hahaha", "Snicker, snicker", "Boo!",
- "MeOW", "I see U", "Arrooo!",
- "Ahh-wooo!", "Aaaooo!"};
- static LastSeen last_seen_harry_event(2);
- do {
- r = randint((sizeof(phrases) / sizeof(char *)));
- } while (last_seen_harry_event.seen_before(r));
- int color = random() % 15 + 1;
-
- buffer << "^S2^C" << std::setfill('0') << std::setw(2) << color << phrases[r]
- << "^P2^CR^D" << std::setw(2) << strlen(phrases[r]);
-
- std::string str = buffer.str();
- ZF_LOGD("harry_event: render(%d, \"%s\")", fd, str.c_str());
- render(fd, str);
- }
- void init_harry() {
-
-
-
- console_init(&console);
- }
- int mangle_clrscr(std::string &buffer, std::string &work, size_t pos) {
- static int ANSI_CLS_count = 0;
- ZF_LOGI("seen: ANSI_CLS");
- ANSI_CLS_count++;
- if (ANSI_CLS_count > 1) {
-
- struct console_details temp_console;
- memcpy(&temp_console, &console, sizeof(console));
- console_receive(&temp_console, buffer.substr(0, pos));
- std::string restore_color;
- restore_color.assign(color_restore(&temp_console));
- if (random_activate(3)) {
- std::ostringstream display;
- int needs_cls = 0;
- struct image {
- const char **lines;
- int size;
- int cls;
- int width;
- } images[] = {{ghost, sizeof(ghost) / sizeof(char *), 1, 0},
- {ghead, sizeof(ghead) / sizeof(char *), 1, 0},
- {wolf, sizeof(wolf) / sizeof(char *), 1, 0},
- {panther, sizeof(panther) / sizeof(char *), 1, 0},
- {bat, sizeof(bat) / sizeof(char *), 1, 0},
- {icu, sizeof(icu) / sizeof(char *), 0, 20},
- {skull, sizeof(skull) / sizeof(char *), 0, 19},
- {skullblink, sizeof(skullblink) / sizeof(char *), 0, 19}};
- static LastSeen last_files(2);
- int r;
- do {
- r = randint((sizeof(images) / sizeof(image)));
- } while (last_files.seen_before(r));
- std::string fgoto;
- if (!images[r].cls) {
- int x = 0, y = 0;
- x = randint(79 - images[r].width) + 1;
- y = randint(24 - images[r].size) + 1;
- display << "^f" << std::setfill('0') << std::setw(2) << x
- << std::setw(2) << y << "\x1b[1;1H";
- fgoto = display.str();
-
- display.str(std::string());
- display.clear();
-
-
- } else {
- fgoto.assign("^F");
- }
- needs_cls = images[r].cls;
-
-
-
-
-
-
-
- render_image(images[r].lines, images[r].size);
- display << (needs_cls ? "\x1b[2J" : "") << fgoto << restore_color
- << "^P3";
-
-
- std::string display_output = display.str();
- ZF_LOGI("mangle(ANSI_CLS): %d file inserted %s", r,
- repr(display_output.c_str()));
-
- buffer.insert(pos, display_output);
- work.insert(pos, std::string(display_output.size(), ' '));
- return 1;
- } else {
- if (random_activate(4)) {
- int r;
- std::ostringstream display;
- const char *phrasing[] = {
- "^R1Haha^P1ha^P1ha", "Poof!", "Got U", "Anyone there?",
- "^R1Knock, ^P1Knock",
-
- "^G0101^C07^S9Segmentation fault (core dumped)^P2"};
- static LastSeen last_phrasing(2);
- ZF_LOGI("mangle(ANSI_CLS)");
- do {
- r = randint(sizeof(phrasing) / sizeof(char *));
- } while (last_phrasing.seen_before(r));
- int color = randint(14) + 1;
- int x = randint(30) + 1;
- int y = randint(15) + 1;
-
- if (strncmp(phrasing[r], "^G", 2) == 0) {
- display << "^S3^P1" << phrasing[r] << "^S0^R0" << restore_color
- << "^P1^G0101";
-
-
-
-
- } else {
- display << "^G" << std::setw(2) << std::setfill('0') << x
- << std::setw(2) << y << "^S3^C" << std::setw(2) << color
- << "^P1" << phrasing[r] << "^S0^R0" << restore_color
- << "^P1^G0101";
-
-
-
- };
- std::string display_output = display.str();
-
-
-
-
- ZF_LOGD("mangle(ANSI_CLS): Inserted color=%02d r=%d phrase='%s'", color,
- r, phrasing[r]);
- ZF_LOGI("mangle(ANSI_CLS): %d %s", r, repr(display_output.c_str()));
-
- buffer.insert(pos, display_output);
- work.insert(pos, std::string(display_output.size(), ' '));
- return 1;
- }
- }
- }
- }
- int mangle(int fd, std::string &buffer) {
-
- ZF_LOGV_MEM(buffer.data(), buffer.size(), "mangle(%d): %lu bytes", fd,
- buffer.size());
- int need_render = 0;
- int mangled = 0;
- int mangled_chars = 0;
- static std::string work;
- static size_t work_size = 0;
- work.assign(buffer);
-
- if (work.capacity() != work_size) {
- ZF_LOGD("work cap %lu -> %lu", work_size, work.capacity());
- work_size = work.capacity();
- }
- const char *ANSI_CLS = "\x1b[2J";
- size_t pos = buffer.find(ANSI_CLS);
- if (pos != std::string::npos) {
- if (mangle_clrscr(buffer, work, pos)) {
- need_render = 1;
- }
- }
-
- static std::string text;
- static std::vector<int> text_offsets;
- size_t stri;
- text.clear();
- text_offsets.clear();
- for (stri = 0; stri < buffer.size(); ++stri) {
-
-
- termchar tc = console_char(&console, work[stri]);
- if (tc.in_ansi) {
- if (tc.ansi != START) {
-
-
- switch (tc.ansi) {
- case CURSOR:
- case CLEAR:
- case OTHER:
- text.append(1, '.');
- text_offsets.push_back(-1);
- break;
- case COLOR:
-
-
-
- break;
- }
- }
- } else {
-
- if (text.size() != text_offsets.size()) {
- ZF_LOGE("Error: text != text_offsets %lu != %lu", text.size(),
- text_offsets.size());
- }
- text.append(1, work[stri]);
- text_offsets.push_back(stri);
- }
- }
- 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());
-
- oss.str(std::string());
- oss.clear();
- comma = 0;
- }
- }
- std::string vector_output = oss.str();
- ZF_LOGV("Vector: %s", vector_output.c_str());
-
- oss.str(std::string());
- oss.clear();
-
- {
- ZF_LOGD("CharMan");
- CharMan cm(buffer, work, text, text_offsets);
- ZF_LOGD("CharMan %d, %d chars", cm.mangle_count, cm.mangle_chars);
- };
- if (need_render) {
- render(fd, buffer);
- } else {
- write(fd, buffer.data(), buffer.size());
- }
- return need_render;
- }
|