//------------------------------------------------------------------------------------- void TelnetHandler::sendNewLine() { std::string startstr = getInputStartString(); pEndPoint_->send(startstr.c_str(), startstr.size()); resetStartPosition(); currPos_ = 0; }
//------------------------------------------------------------------------------------- void TelnetHandler::sendDelChar() { if(command_.size() > 0) { if(currPos_ > 0) { command_.erase(currPos_ - 1, 1); currPos_--; pEndPoint_->send(TELNET_CMD_DEL, strlen(TELNET_CMD_DEL)); } } else { resetStartPosition(); } }
//------------------------------------------------------------------------------------- bool TelnetHandler::checkUDLR(const std::string &cmd) { if (cmd.find(TELNET_CMD_UP) != std::string::npos) // 上 { pEndPoint_->send(TELNET_CMD_MOVE_FOCUS_LEFT_MAX, strlen(TELNET_CMD_MOVE_FOCUS_LEFT_MAX)); sendDelChar(); std::string startstr = getInputStartString(); pEndPoint_->send(startstr.c_str(), startstr.size()); resetStartPosition(); if(!getingHistroyCmd_) { ++historyCommandIndex_; getingHistroyCmd_ = true; } std::string s = getHistoryCommand(false); pEndPoint_->send(s.c_str(), s.size()); command_ = s; currPos_ = s.size(); return true; } else if (cmd.find(TELNET_CMD_DOWN) != std::string::npos) // 下 { pEndPoint_->send(TELNET_CMD_MOVE_FOCUS_LEFT_MAX, strlen(TELNET_CMD_MOVE_FOCUS_LEFT_MAX)); sendDelChar(); std::string startstr = getInputStartString(); pEndPoint_->send(startstr.c_str(), startstr.size()); resetStartPosition(); if(!getingHistroyCmd_) { --historyCommandIndex_; getingHistroyCmd_ = true; } std::string s = getHistoryCommand(true); pEndPoint_->send(s.c_str(), s.size()); command_ = s; currPos_ = s.size(); return true; } else if (cmd.find(TELNET_CMD_RIGHT) != std::string::npos) // 右 { int cmdlen = strlen(TELNET_CMD_RIGHT); if(currPos_ < (int)command_.size()) { currPos_++; pEndPoint_->send(TELNET_CMD_RIGHT, cmdlen); } return true; } else if (cmd.find(TELNET_CMD_LEFT) != std::string::npos) // 左 { int cmdlen = strlen(TELNET_CMD_LEFT); if(currPos_ > 0) { currPos_--; pEndPoint_->send(TELNET_CMD_LEFT, cmdlen); } return true; } else if (cmd.find(TELNET_CMD_HOME) != std::string::npos) // 移动到行首 { if (currPos_ > 0) { std::string cmdstr = fmt::format("\033[{}D", currPos_); pEndPoint_->send(cmdstr.c_str(), cmdstr.length()); currPos_ = 0; } return true; } else if (cmd.find(TELNET_CMD_END) != std::string::npos) // 移动到行尾 { if (currPos_ != (int32)command_.length()) { std::string cmdstr = fmt::format("\033[{}C", command_.length() - currPos_); pEndPoint_->send(cmdstr.c_str(), cmdstr.length()); currPos_ = command_.length(); } return true; } return false; }
//------------------------------------------------------------------------------------- void TelnetHandler::onRecvInput(const char *buffer, int size) { int idx = 0; while (idx < size) { char c = buffer[idx++]; switch(c) { case '\r': getingHistroyCmd_ = false; if (idx < size) { int cc = buffer[idx++]; if(cc == '\n') { if(!processCommand()) return; } } break; case 8: // 退格 if (currPos_ == 0) { resetStartPosition(); } else { sendDelChar(); checkAfterStr(); } break; case 27: // vt100命令码: 0x1b { std::string s = ""; std::string vt100cmd(s + c); bool shouldBeContinue = true; while (shouldBeContinue && idx < size) { if (buffer[idx] == '\r') break; c = buffer[idx++]; vt100cmd.append(s + c); switch (c) { case 'A': // 光标上移n行 case 'B': // 光标下移n行 case 'C': // 光标右移n列 case 'D': // 光标左移n列 case '~': // home、end等 shouldBeContinue = false; break; case 'm': // 颜色等属性或命令 case 'J': // 清屏 case 'K': // 清除从光标到行尾的内容 case 's': // 保存光标位置 case 'u': // 恢复光标位置 case 'l': // 隐藏光标 case 'h': // 显示光标 case 'H': // 设置光标位置 default: break; } } if (!checkUDLR(vt100cmd)) { // 把不认识的命令原样输出,但会把命令符改成“^” // 以避免客户端触发命令操作 vt100cmd[0] = '^'; command_.insert(currPos_, vt100cmd); currPos_ += vt100cmd.length(); if (currPos_ == (int32)command_.length()) { pEndPoint_->send(vt100cmd.c_str(), vt100cmd.size()); } else { std::string s = command_.substr(currPos_ - vt100cmd.length(), command_.size() - currPos_ + vt100cmd.length()); s += fmt::format("\33[{}D", command_.size() - currPos_); pEndPoint_->send(s.c_str(), s.size()); } } break; } case 0x7f: // delete if (currPos_ < (int32)command_.length()) { command_.erase(currPos_, 1); pEndPoint_->send(TELNET_CMD_DEL, strlen(TELNET_CMD_DEL)); checkAfterStr(); } break; default: { std::string s = ""; s += c; command_.insert(currPos_, s); currPos_++; checkAfterStr(); break; } }; } }
//------------------------------------------------------------------------------------- bool TelnetHandler::checkUDLR() { if(command_.find(TELNET_CMD_UP) != std::string::npos) // 上 { pEndPoint_->send(TELNET_CMD_MOVE_FOCUS_LEFT_MAX, strlen(TELNET_CMD_MOVE_FOCUS_LEFT_MAX)); sendDelChar(); std::string startstr = getInputStartString(); pEndPoint_->send(startstr.c_str(), startstr.size()); resetStartPosition(); if(!getingHistroyCmd_) { ++historyCommandIndex_; getingHistroyCmd_ = true; } std::string s = getHistoryCommand(false); pEndPoint_->send(s.c_str(), s.size()); command_ = s; buffer_.clear(); currPos_ = s.size(); return true; } else if(command_.find(TELNET_CMD_DOWN) != std::string::npos) // 下 { pEndPoint_->send(TELNET_CMD_MOVE_FOCUS_LEFT_MAX, strlen(TELNET_CMD_MOVE_FOCUS_LEFT_MAX)); sendDelChar(); std::string startstr = getInputStartString(); pEndPoint_->send(startstr.c_str(), startstr.size()); resetStartPosition(); if(!getingHistroyCmd_) { --historyCommandIndex_; getingHistroyCmd_ = true; } std::string s = getHistoryCommand(true); pEndPoint_->send(s.c_str(), s.size()); command_ = s; buffer_.clear(); currPos_ = s.size(); return true; } else if(command_.find(TELNET_CMD_RIGHT) != std::string::npos) // 右 { int cmdlen = strlen(TELNET_CMD_RIGHT); currPos_-= cmdlen; command_.erase(command_.find(TELNET_CMD_RIGHT), cmdlen); if(currPos_ < (int)command_.size()) { currPos_++; pEndPoint_->send(TELNET_CMD_RIGHT, cmdlen); } return true; } else if(command_.find(TELNET_CMD_LEFT) != std::string::npos) // 左 { int cmdlen = strlen(TELNET_CMD_LEFT); currPos_-= (int)(cmdlen + 1); if(currPos_ < 0) { currPos_ = 0; } else { pEndPoint_->send(TELNET_CMD_LEFT, cmdlen); } command_.erase(command_.find(TELNET_CMD_LEFT), cmdlen); return true; } return false; }