diff --git a/CMakeLists.txt b/CMakeLists.txt index eb823bb..fb2cd74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,5 +4,6 @@ SET(CMAKE_CXX_STANDARD 17) SET(CMAKE_CXX_STANDARD_REQUIRED True) SET(CMAKE_CXX_FLAGS "-O3") find_package(CURL REQUIRED) +find_package(nlohmann_json 3.2.0 REQUIRED) add_subdirectory(src) install(TARGETS p3ng0 RUNTIME DESTINATION bin) diff --git a/src/main.cpp b/src/main.cpp index 17fe510..8873abe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,8 @@ #include #include +#include + #define CURL_STATICLIB #include @@ -210,7 +212,7 @@ void reciever(int *sock, uint16_t port, bool* status) { int message_len = bufin[offs++]; memcpy(message, &bufin[offs++], message_len); message[message_len] = 0; - processText(sock, std::string(username), std::string(message)); + try { processText(sock, std::string(username), std::string(message)); } catch (...) { }; } else if (bufin[p+2] == CMD_WHISPER && bufin[p+1] == 0x01) { char *username = new char[32]; char *message = new char[250]; @@ -224,7 +226,7 @@ void reciever(int *sock, uint16_t port, bool* status) { int message_len = bufin[offs++]; memcpy(message, &bufin[offs++], message_len); message[message_len] = 0; - processWhisper(sock, std::string(username), std::string(message)); + try { processWhisper(sock, std::string(username), std::string(message)); } catch (...) { }; } else if (bufin[p+2] == CMD_REGOBJID && bufin[p+1] == 0xff) { char *longID = new char[32]; int shortID; @@ -591,14 +593,6 @@ bool handleCommand(char* buffer, std::string from, std::string message) { for (int d = 0; d < dice; d++) roll+=rno(rng); sprintf(buffer, mainConf->getValue("roll_msg", "%s rolled a %i.").c_str(), from.c_str(), roll); return true; - } else if ((args[0] == "where" || args[0] == "whereis") && args.size() > 1) { - std::string mark = getValueOfIncludedName(worldlist->get(), strcombine(args, 1, args.size(), ' ')); - if (mark.length() > 0) { - sprintf(buffer, messages->getMessage("world").c_str(), mark.c_str()); - } else { - sprintf(buffer, mainConf->getValue("world_not_found_msg", "Sorry, I don't know that one.").c_str()); - } - return true; } else if (args[0] == "help") { char *whisout = new char[255]; sprintf(whisout, mainConf->getValue("help_msg", "You can find more information here: %s").c_str(), mainConf->getValue("help_url", "").c_str()); @@ -620,6 +614,67 @@ bool handleCommand(char* buffer, std::string from, std::string message) { } else if (args[0] == "stats" || args[0] == "status") { sprintf(buffer, mainConf->getValue("roomusers_msg", "There are %i users in this room.").c_str(), objects.size()); return true; + } else if (args[0] == "translate") { + std::string source = "auto"; // Automatically + std::string target = "en"; // Assume target is English if not specified + if (args.size() > 2) { + try { + int spos = args[1].find(">"); + if (spos != args[1].npos) { + if (spos > 0) source = args[1].substr(0, spos); + if (spos < args[1].length()) target = args[1].substr(spos+1, args[1].length()); + } + } catch (...) { } + nlohmann::json input = { + {"q", strcombine(args, 2, args.size(), ' ')}, + {"source", source}, + {"target", target}, + }; + std::string newmsg; + if (debug) printf("debug: attempting to translate from %s to %s: \"%s\"\n", source.c_str(), target.c_str(), strcombine(args, 2, args.size(), ' ').c_str()); + curl_global_init(CURL_GLOBAL_ALL); + if(CURL* curl = curl_easy_init()) { + std::string postData = input.dump(); + std::string httpContents; + long httpCode; + + struct curl_slist *list = NULL; + list = curl_slist_append(list, "Content-Type: application/json"); + + + curl_easy_setopt(curl, CURLOPT_URL, (mainConf->getValue("translator", "http://localhost;5010/")+"translate").c_str()); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str()); + curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &httpContents); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); + + CURLcode res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); + if (debug) printf("debug: translator recieved: %i \"%s\"\n", httpCode, httpContents.c_str()); + if(res != CURLE_OK) { + fprintf(stderr, "Error: curl_easy_perform() failed > %s\n", curl_easy_strerror(res)); + sprintf(buffer, "I cannot translate that."); + } else { + nlohmann::json output = nlohmann::json::parse(httpContents); + std::string fromLang = source; + if (fromLang == "auto") { + fromLang = output["detectedLanguage"]["language"]; + } + newmsg = output["translatedText"]; + sprintf(buffer, "[%s] %s->%s: %s", from.c_str(), fromLang.c_str(), target.c_str(), filter(filth->getLines(), newmsg).c_str()); + } + curl_easy_cleanup(curl); + curl_slist_free_all(list); + } + } else { + sprintf(buffer, "I cannot process those arguments. Use the command like this: 'translate src>trg message'"); + } + return true; } else if (args[0] == "reload" && from == mainConf->getValue("owner", "")) { loadConfig(); setAvatar(&roomsock, avatar); @@ -703,27 +758,27 @@ bool handleGroups(char* buffer, std::string from, std::string message) { bool handlePhrase(char* buffer, std::string from, std::string message) { std::vector args = split(message, ' '); if (strcontains("flip a coin", message)) { - std::uniform_int_distribution rno(0,1); bool heads = rno(rng) == 1; sprintf(buffer, mainConf->getValue("coinflip_msg", "%s flipped %s.").c_str(), from.c_str(), heads?"heads":"tails"); return true; - } else if ((strcontains("joke", message) && strcontains("tell", message)) || (strcontains("make", message) && strcontains("laugh", message))) { - sprintf(buffer, messages->getMessage("jokes").c_str()); return true; - } else if ((strcontains("what", message) || strcontains("who", message)) && strcontains("are you", message)) { - sprintf(buffer, messages->getMessage("whoami").c_str()); return true; - } else if (vfind(args, "hi") || vfind(args, "hello") || vfind(args, "hey") || vfind(args, "yo")) { - sprintf(buffer, messages->getMessage("greets").c_str(), from.c_str()); return true; - + } else if (strcontains("where", message)) { + std::string mark = getValueOfIncludedName(worldlist->get(), message); + if (mark.length() > 0) { + sprintf(buffer, messages->getMessage("world").c_str(), mark.c_str()); + } else { + sprintf(buffer, mainConf->getValue("world_not_found_msg", "Sorry, I don't know that one.").c_str()); + } + return true; } return false; }