123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- #include "utils.h"
- #include <regex>
- #include <string>
- #include <vector>
- #include <exception>
- #include <chrono>
- /**
- * Clean up the trailing ../ in __FILE__
- *
- * This is used by the logging macro.
- *
- * @param filepath
- * @return const char*
- */
- const char *trim_path(const char *filepath) {
- if (strncmp(filepath, "../", 3) == 0) {
- filepath += 3;
- }
- return filepath;
- }
- #include <fstream>
- bool file_exists(const std::string &name) {
- std::ifstream f(name.c_str());
- return f.good();
- }
- 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;
- do {
- str.replace(start_pos, from.length(), to);
- } while ((start_pos = str.find(from)) != std::string::npos);
- return true;
- }
- bool replace(std::string &str, const char *from, const char *to) {
- size_t start_pos = str.find(from);
- if (start_pos == std::string::npos) return false;
- do {
- str.replace(start_pos, strlen(from), to);
- } while ((start_pos = str.find(from)) != std::string::npos);
- return true;
- }
- void ansi_clean(std::string &str) {
- static std::regex ansi_cleaner("\x1b\[[0-9;]*[A-Zmh]",
- std::regex_constants::ECMAScript);
- str = std::regex_replace(str, ansi_cleaner, "");
- }
- void high_ascii(std::string &str) {
- // the + replaces all of them into one. I want each high ascii replaced with
- // #.
- static std::regex high_cleaner("[\x80-\xff]",
- std::regex_constants::ECMAScript);
- str = std::regex_replace(str, high_cleaner, "#");
- }
- std::smatch ansi_newline(const std::string &str) {
- static std::regex ansi_nl("\x1b\[[0-9;]*[JK]",
- std::regex_constants::ECMAScript);
- std::smatch m;
- std::regex_search(str, m, ansi_nl);
- return m;
- }
- std::string repr(const std::string &source) {
- std::string output = source;
- replace(output, "\n", "\\n");
- replace(output, "\r", "\\r");
- replace(output, "\b", "\\b");
- replace(output, "\x1b", "\\[");
- high_ascii(output);
- return output;
- }
- std::string clean_string(const std::string &source) {
- std::string clean = source;
- /*
- replace(clean, "\n", "\\n");
- replace(clean, "\r", "\\r");
- replace(clean, "\b", "\\b");
- replace(clean, "\x1b", "\\[");
- */
- replace(clean, "\n", "");
- replace(clean, "\r", "");
- // ANSI too
- ansi_clean(clean);
- // BUGZ_LOG(error) << "cleaned: " << clean;
- high_ascii(clean);
- // replace(clean, "\x1b", "^");
- return clean;
- }
- std::vector<std::string> split(const std::string &line) {
- static std::regex rx_split("[^\\s]+");
- std::vector<std::string> results;
- for (auto it = std::sregex_iterator(line.begin(), line.end(), rx_split);
- it != std::sregex_iterator(); ++it) {
- results.push_back(it->str());
- }
- return results;
- }
- std::vector<std::string> split(const std::string &line, const std::string &by) {
- std::string work = line;
- std::vector<std::string> results;
- size_t pos;
- while ((pos = work.find(by)) != std::string::npos) {
- results.push_back(work.substr(0, pos));
- work.erase(0, pos + by.length());
- }
- if (!work.empty()) results.push_back(work);
- return results;
- }
- bool in(const std::string &line, const std::string &has) {
- return (line.find(has) != std::string::npos);
- }
- bool startswith(const std::string &line, const std::string &has) {
- return (line.substr(0, has.length()) == has);
- }
- bool endswith(const std::string &line, const std::string &has) {
- if (line.length() < has.length()) return false;
- return (line.substr(line.length() - has.length()) == has);
- }
- /**
- * Trim leading and trailing spaces from str.
- *
- * @param str
- */
- void trim(std::string &str) {
- while (str.substr(0, 1) == " ") str.erase(0, 1);
- while (str.substr(str.length() - 1) == " ") str.erase(str.length() - 1);
- }
- bool at_command_prompt(const std::string &prompt) {
- if (startswith(prompt, "Command ["))
- if (endswith(prompt, "] (?=Help)? : ")) return true;
- return false;
- }
- bool at_computer_prompt(const std::string &prompt) {
- if (startswith(prompt, "Computer command ["))
- if (endswith(prompt, "] (?=Help)? ")) return true;
- return false;
- }
- bool at_planet_prompt(const std::string &prompt) {
- if (startswith(prompt, "Planet command (?=Help)"))
- if (endswith(prompt, " [D] ")) return true;
- return false;
- }
- bool density_clear(int sector, int density, int navhaz) {
- if (sector == 0) return false;
- // if(anomoly) return false;
- /*
- http://wiki.classictw.com/index.php?title=Gypsy%27s_Big_Dummy%27s_Guide_to_TradeWars_Text#Trader_Information
- Density Readings:
- 0 = Empty Sector or Ferrengi Dreadanought
- 1 = Marker Beacon
- 2 = Limpet Type 2 Tracking Mine
- 5 = Fighter (per Fighter)
- 10 = Armid Type 1 Mine
- 21 = Navigation Hazard (Per 1 Percent)
- 21 = Destroyed Ship (Due to 1 Percent Nav-Haz)
- 38 = Unmanned Ship
- 40 = Manned Ship, Alien or Ferrengi Assault Trader
- 50 = Destroyed Starport (After 25 Percent Nav-Haz Clears)
- 100 = Starport or Ferrengi Battle Cruiser
- 210 = Destroyed Planet (Due to 10 Percent Nav-Haz)
- 462 = Federation Starship under Admiral Nelson
- 489 = Federation Starship under Captain Zyrain
- 500 = Planet
- 512 = Federation Starship under Admiral Clausewitz
- 575 = Destroyed Port (Before 25% Nav-Haz Clears)
- */
- int dense = density;
- if ((navhaz != 0) && (navhaz <= 5)) {
- // Adjust density by upto 5% navhaz, exlude greather than 5%
- dense -= navhaz * 21;
- }
- if (navhaz > 5) return false;
- switch (dense) {
- case 0:
- case 1:
- case 100:
- case 101:
- return true;
- }
- // Special case for Sector 001.
- if ((sector == 1) && (dense == 601)) return true;
- return false;
- }
- #include <algorithm>
- #include <cctype>
- void str_toupper(std::string &str) {
- std::transform(str.begin(), str.end(), str.begin(), ::toupper);
- }
- void str_tolower(std::string &str) {
- std::transform(str.begin(), str.end(), str.begin(), ::tolower);
- }
- void remove_telnet_commands(std::string &text) {
- size_t pos;
- while ((pos = text.find('\xff')) != std::string::npos) {
- text.erase(pos, pos + 3);
- }
- }
- int sstoi(const std::string &text, int failure) {
- int result;
- try {
- result = stoi(text);
- } catch (const std::invalid_argument &e) {
- // BUGZ_LOG(fatal) << e.what();
- return failure;
- } catch (const std::out_of_range &e) {
- // BUGZ_LOG(fatal) << e.what();
- return failure;
- }
- return result;
- }
- time_t time_t_now(void) {
- return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
- }
- // json support functions
- bool json_bool(json j) {
- if (j.is_boolean()) {
- return j.get<bool>();
- }
- if (j.is_number_integer()) {
- return j.get<int>() == 1;
- }
- if (j.is_string()) {
- std::string temp = j.get<std::string>();
- char c = toupper(temp[0]);
- return ((c == 'Y') || (c == 'T'));
- }
- std::string error = "json_bool from ";
- error += j.type_name();
- throw std::range_error(error);
- }
- std::string json_str(json j) {
- if (j.is_string()) return j.get<std::string>();
- if (j.is_number_integer()) {
- return std::to_string(j.get<int>());
- }
- std::string error = "json_str from ";
- error += j.type_name();
- throw std::range_error(error);
- }
- int json_int(json j) {
- if (j.is_number_integer()) return j.get<int>();
- if (j.is_string()) return sstoi(j.get<std::string>());
- std::string error = "json_int from ";
- error += j.type_name();
- throw std::range_error(error);
- }
|