CViewer::CViewer(const std::string &p_fileName): CWindow(), m_fileName(p_fileName), m_firstLine(0), m_image(NULL), m_font(CResourceManager::instance().getFont()) { // Init clip rect m_clip.x = 0; m_clip.y = 0; m_clip.w = SCREEN_WIDTH - 2 * VIEWER_MARGIN; // Create background image m_image = SDL_utils::createImage(SCREEN_WIDTH, SCREEN_HEIGHT, SDL_MapRGB(Globals::g_screen->format, COLOR_BG_1)); { SDL_Rect l_rect; l_rect.x = 0; l_rect.y = 0; l_rect.w = SCREEN_WIDTH; l_rect.h = Y_LIST; SDL_FillRect(m_image, &l_rect, SDL_MapRGB(m_image->format, COLOR_BORDER)); } // Print title SDL_Surface *l_surfaceTmp = SDL_utils::renderText(m_font, m_fileName, Globals::g_colorTextTitle); if (l_surfaceTmp->w > m_image->w - 2 * VIEWER_MARGIN) { SDL_Rect l_rect; l_rect.x = l_surfaceTmp->w - (m_image->w - 2 * VIEWER_MARGIN); l_rect.y = 0; l_rect.w = m_image->w - 2 * VIEWER_MARGIN; l_rect.h = l_surfaceTmp->h; SDL_utils::applySurface(VIEWER_MARGIN, Y_HEADER, l_surfaceTmp, m_image, &l_rect); } else { SDL_utils::applySurface(VIEWER_MARGIN, Y_HEADER, l_surfaceTmp, m_image); } m_clip.h = l_surfaceTmp->h; SDL_FreeSurface(l_surfaceTmp); // Read file #ifdef ZIPIT_Z2 extern int readtextfile(std::string filename, std::vector<std::string> &txtman); if (!readtextfile(m_fileName, m_lines)) #else std::ifstream l_file(m_fileName.c_str()); if (l_file.is_open()) { std::string l_line(""); while (!l_file.eof()) { std::getline(l_file, l_line); m_lines.push_back(l_line); } l_file.close(); } else #endif std::cerr << "Error: unable to open file " << m_fileName << std::endl; INHIBIT(std::cout << "CViewer: " << m_lines.size() << " lines read" << std::endl;) }
void tree_Node_::draw_tree_buffer( TextBuffer * b) { draw(); int last = f_line(); tree_Node sub = NULL; for ( int i = 0 ; i < (int)subNodes.size(); i++ ) { // glPushMatrix(); switch ( i % 3 ) { case 0 : glColor3d ( 0.5,0,0 ); break; case 1 : glColor3d ( 0,0.5,0 ); break; case 2 : glColor3d ( 0,0,0.5 ); break; } sub = subNodes[i]; if ( sub && ( multiline() || sub->multiline() ) ) { drawTextRange(b, last, sub->f_line() - 1 ); sub->draw_tree_buffer(b); last = sub->l_line() + 1; } // glPopMatrix(); } drawTextRange(b, last, l_line()); }
void tree_Node_::draw_tree() { glPushMatrix(); draw(); glPushName(structID); double top = f_line() - 1.0 ; double bottom = l_line(); double midpoint = 0.5 * (top + bottom); if ( subNodes.size() > 1 ) { // glBegin(GL_LINE_STRIP); // glVertex2d( 0, top ); // glVertex2d(-1, top ); // glVertex2d(-0.8, midpoint ); // glVertex2d( 0, bottom ); // glEnd(); glBegin(GL_QUADS); glVertex2d(-1.0, top ); glVertex2d( 0.0, top ); glVertex2d( 0.0, bottom ); glVertex2d(-1.0, bottom ); glEnd(); glPushName ( boxID ); glPushMatrix(); glTranslated(-1, top , 0 ); glScaled ( 0.3, 0.3, 1 ); glBegin(GL_QUADS); glColor3d ( 1.0 , 0.0 , 0.0 ); if ( open ) glColor3d ( 0.0 , 1.0, 0.0 ); glVertex2d ( 1.0 , 1.0 ); glVertex2d ( -1.0 , 1.0 ); glVertex2d ( -1.0 , -1.0 ); glVertex2d ( 1.0 , -1.0 ); glEnd(); glPopMatrix(); glPopName(); glTranslated ( 1.0, 0.0, 0.0 ); } else if ( open && subNodes.size() == 1 ) { if ( subNodes[0]->firstline != firstline || subNodes[0]->lastline != lastline ) { //glBegin(GL_LINE_STRIP); //glVertex2d( 0, top ); //glVertex2d(-1, top); //glVertex2d( 0, bottom ); //glEnd(); glBegin(GL_QUADS); glVertex2d(-1.0, top ); glVertex2d( 0.0, subNodes[0]->f_line() - 1.0 ); glVertex2d( 0.0, subNodes[0]->l_line()); glVertex2d(-1.0, bottom ); glEnd(); glTranslated ( 1.0, 0.0, 0.0 ); } } if ( open ) { for ( int i = 0 ; i < (int)subNodes.size(); i++ ) { switch ( i % 3 ) { case 0 : glColor4d ( 1,0,0,0.2 ); break; case 1 : glColor4d ( 0,1,0,0.2 ); break; case 2 : glColor4d ( 0,0,1,0.2 ); break; } if ( subNodes[i] ) { // glBegin(GL_LINES); // glVertex2d(-1.0, top); // glVertex2d(0.0, subNodes[i]->f_line() - 1.0); // glEnd(); subNodes[i]->draw_tree(); } } } glPopName(); glPopMatrix(); }
/* for use from fish_inject.dll */ EXPORT_SIG(__declspec(dllexport) char*) _OnIncomingIRCLine(HANDLE a_socket, const char* a_line, size_t a_len) { if(!a_socket || !a_line || a_len < 1 || *a_line != ':') return NULL; if(strstr(a_line, " ") == strstr(a_line, " 005 ")) { std::string l_line(a_line, a_len); std::string::size_type l_pos = l_line.find(" NETWORK="); if(l_pos != std::string::npos) { l_pos += 9; // strlen(" NETWORK=") std::string::size_type l_endPos = l_line.find(" ", l_pos); if(l_endPos == std::string::npos) l_endPos = l_line.size(); ::EnterCriticalSection(&s_socketMapLock); // allow overwriting network names for dis/re-connecting BNCs and such: s_socketMap[a_socket] = l_line.substr(l_pos, l_endPos - l_pos); ::LeaveCriticalSection(&s_socketMapLock); return NULL; } } // quick exit to save some CPU cycles: if(!strstr(a_line, "+OK ") && !strstr(a_line, "mcps ")) return NULL; auto l_ini = GetBlowIni(); if(!l_ini->GetBool(L"process_incoming", true)) return NULL; /** list of stuff we possibly need to decrypt: ** :nick!ident@host PRIVMSG #chan :+OK 2T5zD0mPgMn :nick!ident@host PRIVMSG #chan :\x01ACTION +OK 2T5zD0mPgMn\x01 :nick!ident@host PRIVMSG ownNick :+OK 2T5zD0mPgMn :nick!ident@host PRIVMSG ownNick :\x01ACTION +OK 2T5zD0mPgMn\x01 :nick!ident@host NOTICE ownNick :+OK 2T5zD0mPgMn :nick!ident@host NOTICE #chan :+OK 2T5zD0mPgMn :nick!ident@host NOTICE @#chan :+OK 2T5zD0mPgMn :nick!ident@host NOTICE ~#chan :+OK 2T5zD0mPgMn (topic) :irc.tld 332 nick #chan :+OK hqnSD1kaIaE00uei/.3LjAO1Den3t/iMNsc1 :nick!ident@host TOPIC #chan :+OK JRFEAKWS (topic /list) :irc.tld 322 nick #chan 2 :[+snt] +OK BLAH */ std::string l_line(a_line, a_len); std::string l_cmd, l_contact, l_message; std::string::size_type l_cmdPos, l_tmpPos, l_targetPos, l_msgPos; StrTrimRight(l_line); l_cmdPos = l_line.find(' '); if(l_cmdPos != std::string::npos) { while(l_line[l_cmdPos] == ' ') l_cmdPos++; l_tmpPos = l_line.find(' ', l_cmdPos); if(l_tmpPos != std::string::npos) { while(l_line[l_tmpPos + 1] == ' ') l_tmpPos++; l_cmd = l_line.substr(l_cmdPos, l_tmpPos - l_cmdPos); l_msgPos = l_line.find(" :", l_tmpPos + 1); if(l_msgPos != std::string::npos) { l_msgPos += 2; l_message = l_line.substr(l_msgPos); } } } if(l_cmd.empty() || l_message.empty()) return NULL; // check if +OK is in the message part of the line: if(l_message.find("+OK ") == std::string::npos && l_message.find("mcps ") == std::string::npos) return NULL; enum { CMD_PRIVMSG = 1, CMD_ACTION, CMD_NOTICE, CMD_N332, // 332 channel :topic CMD_TOPIC, CMD_N322 // 322 channel users :topic } l_cmd_type; if(!_stricmp(l_cmd.c_str(), "PRIVMSG")) l_cmd_type = CMD_PRIVMSG; else if(!_stricmp(l_cmd.c_str(), "NOTICE")) l_cmd_type = CMD_NOTICE; else if(!strcmp(l_cmd.c_str(), "332")) l_cmd_type = CMD_N332; else if(!_stricmp(l_cmd.c_str(), "TOPIC")) l_cmd_type = CMD_TOPIC; else if(!strcmp(l_cmd.c_str(), "322")) l_cmd_type = CMD_N322; else return NULL; std::string l_leading, l_trailing; if(l_cmd_type == CMD_N322 || l_cmd_type == CMD_N332 || l_cmd_type == CMD_TOPIC) { l_targetPos = l_line.rfind(" #", l_msgPos); if(l_targetPos != std::string::npos && l_targetPos >= l_cmdPos + l_cmd.size()) /* >= because of the leading space in the find string */ { l_targetPos++; // skip the leading space l_tmpPos = l_line.find(' ', l_targetPos + 1); if(l_tmpPos != std::string::npos) { l_contact = l_line.substr(l_targetPos, l_tmpPos - l_targetPos); } } if(l_cmd_type == CMD_N322 && !l_message.empty()) { // account for channel modes in /list, like "[+nts] +OK BLAH" if(l_message[0] == '[') { l_tmpPos = l_message.find("] +OK "); if(l_tmpPos != std::string::npos) { l_leading = l_message.substr(0, l_tmpPos + 2); l_message.erase(0, l_tmpPos + 2); } } } } else { l_contact = l_line.substr(l_tmpPos + 1, l_msgPos - 2 - l_tmpPos - 1); if(!l_contact.empty()) { switch(l_contact[0]) { case '#': case '&': // channel, l_contact = channel name, all is fine. break; case '@': case '+': case '%': // onotice or something like that. l_contact.erase(0, 1); // left in l_contact is the channel name. break; default: // probably a query message. Need to make l_contact the nick name: { l_tmpPos = l_line.find('!'); if(l_tmpPos != std::string::npos) { l_contact = l_line.substr(1, l_tmpPos - 1); } else { l_contact.clear(); } } // :TODO: for future versions: keep track of local nickname and use that to determine channel/query. } } } if(l_contact.empty()) return NULL; if(l_cmd_type == CMD_PRIVMSG && l_message.find("\x01""ACTION ") == 0) { l_message.erase(0, 8); if(l_message.size() > 0 && l_message[l_message.size() - 1] == 0x01) l_message.erase(l_message.size() - 1); l_cmd_type = CMD_ACTION; } if(l_message.find("+OK ") == 0) l_message.erase(0, 4); else if(l_message.find("mcps ") == 0) l_message.erase(0, 5); else return NULL; // something must have gone awry. // account for stuff like trailing time stamps from BNCs: if((l_tmpPos = l_message.find(' ')) != std::string::npos) { l_trailing = l_message.substr(l_tmpPos); l_message.erase(l_tmpPos); } // get blowfish key... bool l_cbc; std::string l_blowKey, l_networkName; ::EnterCriticalSection(&s_socketMapLock); l_networkName = s_socketMap[a_socket]; ::LeaveCriticalSection(&s_socketMapLock); l_blowKey = l_ini->GetBlowKey(l_networkName, l_contact, l_cbc); if(l_blowKey.empty()) return NULL; // put together new message: std::string l_newMsg; if(l_cbc && !l_message.empty() && l_message[0] != '*') { // silent fallback to old style l_cbc = false; } else if(!l_cbc && !l_message.empty() && l_message[0] == '*') { // auto-enable new style even for non-prefixed keys l_cbc = true; } if(l_cbc && !l_message.empty() && l_message[0] == '*') { // strip asterisk l_message.erase(0, 1); } int l_decryptionResult = blowfish_decrypt_auto(l_cbc, l_message, l_newMsg, l_blowKey); if(l_decryptionResult == 0) { // compatibility fix // (we only encode the actual MSG part of CTCP ACTIONs, but the old FiSH.dll and some scripts etc. // encode the whole thing including \x01 and so on) if(l_cmd_type == CMD_PRIVMSG && l_newMsg.find("\x01""ACTION ") == 0) { l_newMsg.erase(0, 8); if(l_newMsg.size() > 0 && l_newMsg[l_newMsg.size() - 1] == 0x01) l_newMsg.erase(l_newMsg.size() - 1); l_cmd_type = CMD_ACTION; } // this obviously needs to be done before appending the crypt mark... fixed 2011-11. } switch(l_decryptionResult) { case -1: l_newMsg = l_message + "=[FiSH: DECRYPTION FAILED!]="; break; case 1: l_newMsg += "\x02&\x02"; /* fall through */ case 0: l_newMsg += l_trailing; if(l_ini->GetSectionBool(l_networkName, l_contact, L"mark_encrypted", !l_ini->GetStringW(L"mark_encrypted", L"").empty())) { // try local setting and use global setting as default ^^ int l_markPos = l_ini->GetInt(L"mark_position"); // 1 = append, 2 = prepend, 0 = disabled if(l_markPos > 0 && l_markPos <= 2) { const std::wstring l_markWide = l_ini->GetStringW(L"mark_encrypted"); std::string l_mark; if(l_ini->NoLegacy()) { std::string l_markDumb; // if the .ini file is UTF-8 encoded, UnicodeToCp would double-encode // the characters, so try this dumbfolded approach of conversion. for each(wchar_t ch in l_markWide) { if(ch && ch <= std::numeric_limits<unsigned char>::max()) l_markDumb += (unsigned char)ch; } if(l_markDumb.empty() || !Utf8Validate(l_markDumb.c_str())) { l_mark = UnicodeToCp(CP_UTF8, l_markWide); } else { l_mark = l_markDumb; } } else { l_mark = UnicodeToCp(CP_UTF8, l_markWide); } l_mark = SimpleMIRCParser(l_mark); #if 0 bool l_msgValid = Utf8Validate(l_newMsg.c_str(); bool l_markValid = Utf8Validate(l_mark.c_str()); if(!l_msgValid && l_markValid) { // prevent total message corruption by using // "neutral" crypt-mark l_mark = " \x0315*\x03"; } #endif if(l_markPos == 1) l_newMsg.append(l_mark); else l_newMsg.insert(0, l_mark); }