49 return COLOR_PAIR(1 + (int(fg) * NUM_COLORS) + int(bg)); |
49 return COLOR_PAIR(1 + (int(fg) * NUM_COLORS) + int(bg)); |
50 } |
50 } |
51 |
51 |
52 // ------------------------------------------------------------------------------------------------- |
52 // ------------------------------------------------------------------------------------------------- |
53 // |
53 // |
54 const String& Interface::getCurrentInput() |
54 const std::string& Interface::getCurrentInput() |
55 { |
55 { |
56 return m_inputHistory[m_inputCursor]; |
56 return m_inputHistory[m_inputCursor]; |
57 } |
57 } |
58 |
58 |
59 // ------------------------------------------------------------------------------------------------- |
59 // ------------------------------------------------------------------------------------------------- |
99 } |
99 } |
100 } |
100 } |
101 |
101 |
102 // ------------------------------------------------------------------------------------------------- |
102 // ------------------------------------------------------------------------------------------------- |
103 // |
103 // |
104 String Interface::getPromptString() |
104 std::string Interface::getPromptString() |
105 { |
105 { |
106 String prompt; |
106 std::string prompt; |
107 |
107 |
108 switch (m_inputState) |
108 switch (m_inputState) |
109 { |
109 { |
110 case INPUTSTATE_NORMAL: prompt = ">"; break; |
110 case INPUTSTATE_NORMAL: prompt = ">"; break; |
111 case INPUTSTATE_ADDRESS: prompt = "address:"; break; |
111 case INPUTSTATE_ADDRESS: prompt = "address:"; break; |
415 attroff(promptColor); |
415 attroff(promptColor); |
416 m_needRefresh = true; |
416 m_needRefresh = true; |
417 return; |
417 return; |
418 } |
418 } |
419 |
419 |
420 String prompt = getPromptString(); |
420 std::string prompt = getPromptString(); |
421 int displayLength = COLS - prompt.length() - 2; |
421 int displayLength = COLS - prompt.length() - 2; |
422 String displayString = getCurrentInput(); |
422 std::string displayString = getCurrentInput(); |
423 int y = LINES - 2; |
423 int y = LINES - 2; |
424 |
424 |
425 // If we're inputting a password, replace it with asterisks |
425 // If we're inputting a password, replace it with asterisks |
426 if (m_inputState == INPUTSTATE_PASSWORD) |
426 if (m_inputState == INPUTSTATE_PASSWORD) |
427 { |
427 { |
476 |
476 |
477 // ------------------------------------------------------------------------------------------------- |
477 // ------------------------------------------------------------------------------------------------- |
478 // |
478 // |
479 void Interface::updateStatusBar() |
479 void Interface::updateStatusBar() |
480 { |
480 { |
481 String text; |
481 std::string text; |
482 |
482 |
483 switch (m_session.getState()) |
483 switch (m_session.getState()) |
484 { |
484 { |
485 case RCON_DISCONNECTED: |
485 case RCON_DISCONNECTED: |
486 text = "Disconnected."; |
486 text = "Disconnected."; |
556 |
556 |
557 // ------------------------------------------------------------------------------------------------- |
557 // ------------------------------------------------------------------------------------------------- |
558 // |
558 // |
559 int Interface::findPreviousWord() |
559 int Interface::findPreviousWord() |
560 { |
560 { |
561 const String& input = getCurrentInput(); |
561 const std::string& input = getCurrentInput(); |
562 int pos = m_cursorPosition; |
562 int pos = m_cursorPosition; |
563 |
563 |
564 // Move past whitespace |
564 // Move past whitespace |
565 while (pos > 0 and isspace(input[pos - 1])) |
565 while (pos > 0 and isspace(input[pos - 1])) |
566 pos--; |
566 pos--; |
574 |
574 |
575 // ------------------------------------------------------------------------------------------------- |
575 // ------------------------------------------------------------------------------------------------- |
576 // |
576 // |
577 int Interface::findNextWord() |
577 int Interface::findNextWord() |
578 { |
578 { |
579 const String& input = getCurrentInput(); |
579 const std::string& input = getCurrentInput(); |
580 int pos = m_cursorPosition; |
580 int pos = m_cursorPosition; |
581 |
581 |
582 // Move past current whitespace |
582 // Move past current whitespace |
583 while (pos < static_cast<signed>(input.length()) and isspace(input[pos])) |
583 while (pos < static_cast<signed>(input.length()) and isspace(input[pos])) |
584 pos++; |
584 pos++; |
598 return; |
598 return; |
599 |
599 |
600 if (m_cursorPosition > a and m_cursorPosition <= b) |
600 if (m_cursorPosition > a and m_cursorPosition <= b) |
601 m_cursorPosition = a; |
601 m_cursorPosition = a; |
602 |
602 |
603 String& input = getEditableInput(); |
603 std::string& input = getEditableInput(); |
604 m_pasteBuffer = mid(input, a, b); |
604 m_pasteBuffer = mid(input, a, b); |
605 input = remove_range(input, a, b - a); |
605 input = remove_range(input, a, b - a); |
606 m_needInputRender = true; |
606 m_needInputRender = true; |
607 } |
607 } |
608 |
608 |
717 |
717 |
718 case KEY_BACKSPACE: |
718 case KEY_BACKSPACE: |
719 case '\b': |
719 case '\b': |
720 if (m_cursorPosition > 0) |
720 if (m_cursorPosition > 0) |
721 { |
721 { |
722 String& input = getEditableInput(); |
722 std::string& input = getEditableInput(); |
723 input.erase(input.begin() + m_cursorPosition); |
723 input.erase(input.begin() + m_cursorPosition); |
724 m_cursorPosition -= 1; |
724 m_cursorPosition -= 1; |
725 m_needInputRender = true; |
725 m_needInputRender = true; |
726 } |
726 } |
727 break; |
727 break; |
728 |
728 |
729 case KEY_DC: |
729 case KEY_DC: |
730 case 'D' - 'A' + 1: // readline ^D |
730 case 'D' - 'A' + 1: // readline ^D |
731 if (m_cursorPosition < static_cast<signed>(getCurrentInput().length())) |
731 if (m_cursorPosition < static_cast<signed>(getCurrentInput().length())) |
732 { |
732 { |
733 String& input = getEditableInput(); |
733 std::string& input = getEditableInput(); |
734 input.erase(input.begin() + m_cursorPosition); |
734 input.erase(input.begin() + m_cursorPosition); |
735 m_needInputRender = true; |
735 m_needInputRender = true; |
736 } |
736 } |
737 break; |
737 break; |
738 |
738 |
777 |
777 |
778 if (m_inputState == INPUTSTATE_NORMAL |
778 if (m_inputState == INPUTSTATE_NORMAL |
779 and m_cursorPosition > 0 |
779 and m_cursorPosition > 0 |
780 and(space == -1 or space >= m_cursorPosition)) |
780 and(space == -1 or space >= m_cursorPosition)) |
781 { |
781 { |
782 String start = mid(getCurrentInput(), 0, m_cursorPosition); |
782 std::string start = mid(getCurrentInput(), 0, m_cursorPosition); |
783 m_session.requestTabCompletion(start); |
783 m_session.requestTabCompletion(start); |
784 } |
784 } |
785 } |
785 } |
786 break; |
786 break; |
787 |
787 |
906 |
906 |
907 // ------------------------------------------------------------------------------------------------- |
907 // ------------------------------------------------------------------------------------------------- |
908 // |
908 // |
909 void Interface::vprint(const char* fmtstr, va_list args) |
909 void Interface::vprint(const char* fmtstr, va_list args) |
910 { |
910 { |
911 String message; |
911 std::string message; |
912 message = vsprintf(fmtstr, args); |
912 message = vsprintf(fmtstr, args); |
913 printToConsole(message); |
913 printToConsole(message); |
914 } |
914 } |
915 |
915 |
916 // ------------------------------------------------------------------------------------------------- |
916 // ------------------------------------------------------------------------------------------------- |
956 va_end(args); |
956 va_end(args); |
957 } |
957 } |
958 |
958 |
959 // ------------------------------------------------------------------------------------------------- |
959 // ------------------------------------------------------------------------------------------------- |
960 // |
960 // |
961 void Interface::printToConsole(String message) |
961 void Interface::printToConsole(std::string message) |
962 { |
962 { |
963 // Zandronum sometimes sends color codes as "\\c" and sometimes as "\x1C". |
963 // Zandronum sometimes sends color codes as "\\c" and sometimes as "\x1C". |
964 // Let's correct that on our end and hope this won't cause conflicts. |
964 // Let's correct that on our end and hope this won't cause conflicts. |
965 replace_all(message, "\\c", "\x1C"); |
965 replace_all(message, "\\c", "\x1C"); |
966 |
966 |
978 time_t now; |
978 time_t now; |
979 time(&now); |
979 time(&now); |
980 char timestamp[32]; |
980 char timestamp[32]; |
981 strftime(timestamp, sizeof timestamp, "[%H:%M:%S] ", localtime(&now)); |
981 strftime(timestamp, sizeof timestamp, "[%H:%M:%S] ", localtime(&now)); |
982 |
982 |
983 for (char ch : String(timestamp)) |
983 for (char ch : std::string(timestamp)) |
984 zfc::last(m_outputLines).addChar(ch); |
984 zfc::last(m_outputLines).addChar(ch); |
985 } |
985 } |
986 |
986 |
987 // Remove some lines if there's too many of them. 20,000 should be enough, I hope. |
987 // Remove some lines if there's too many of them. 20,000 should be enough, I hope. |
988 while (m_outputLines.size() > 20000) |
988 while (m_outputLines.size() > 20000) |
994 m_needOutputRender = true; |
994 m_needOutputRender = true; |
995 } |
995 } |
996 |
996 |
997 // ------------------------------------------------------------------------------------------------- |
997 // ------------------------------------------------------------------------------------------------- |
998 // |
998 // |
999 void Interface::connect(String address, String password) |
999 void Interface::connect(std::string address, std::string password) |
1000 { |
1000 { |
1001 try |
1001 try |
1002 { |
1002 { |
1003 m_remoteAddress = IPAddress::from_string(address); |
1003 m_remoteAddress = IPAddress::from_string(address); |
1004 } |
1004 } |
1016 m_session.connect(m_remoteAddress); |
1016 m_session.connect(m_remoteAddress); |
1017 } |
1017 } |
1018 |
1018 |
1019 // ------------------------------------------------------------------------------------------------- |
1019 // ------------------------------------------------------------------------------------------------- |
1020 // |
1020 // |
1021 void Interface::setPlayerNames(const StringList& names) |
1021 void Interface::setPlayerNames(const std::vector<std::string>& names) |
1022 { |
1022 { |
1023 m_playerNames.clear(); |
1023 m_playerNames.clear(); |
1024 |
1024 |
1025 for (const String& name : names) |
1025 for (const std::string& name : names) |
1026 { |
1026 { |
1027 ColoredLine coloredname; |
1027 ColoredLine coloredname; |
1028 coloredname.addString(name); |
1028 coloredname.addString(name); |
1029 coloredname.finalize(); |
1029 coloredname.finalize(); |
1030 m_playerNames.push_back(coloredname); |
1030 m_playerNames.push_back(coloredname); |
1033 m_needNicklistRender = true; |
1033 m_needNicklistRender = true; |
1034 } |
1034 } |
1035 |
1035 |
1036 // ------------------------------------------------------------------------------------------------- |
1036 // ------------------------------------------------------------------------------------------------- |
1037 // |
1037 // |
1038 void Interface::tabComplete(const String& part, String complete) |
1038 void Interface::tabComplete(const std::string& part, std::string complete) |
1039 { |
1039 { |
1040 String& input = getEditableInput(); |
1040 std::string& input = getEditableInput(); |
1041 |
1041 |
1042 if (starts_with(input, part)) |
1042 if (starts_with(input, part)) |
1043 { |
1043 { |
1044 if (input[part.length()] != ' ') |
1044 if (input[part.length()] != ' ') |
1045 complete += ' '; |
1045 complete += ' '; |
1050 } |
1050 } |
1051 } |
1051 } |
1052 |
1052 |
1053 // ------------------------------------------------------------------------------------------------- |
1053 // ------------------------------------------------------------------------------------------------- |
1054 // |
1054 // |
1055 void Interface::handleCommand(const String& input) |
1055 void Interface::handleCommand(const std::string& input) |
1056 { |
1056 { |
1057 if (input[0] != '/') |
1057 if (input[0] != '/') |
1058 return; |
1058 return; |
1059 |
1059 |
1060 StringList args = split(right(input, input.length() - 1), " "); |
1060 std::vector<std::string> args = split(right(input, input.length() - 1), " "); |
1061 String command = to_lowercase(args[0]); |
1061 std::string command = to_lowercase(args[0]); |
1062 args.erase(args.begin()); |
1062 args.erase(args.begin()); |
1063 |
1063 |
1064 if (command == "connect") |
1064 if (command == "connect") |
1065 { |
1065 { |
1066 if (args.size() != 2) |
1066 if (args.size() != 2) |