diff --git a/conf.examples/attentions.messages b/conf.examples/attentions.messages deleted file mode 100644 index b32d74d..0000000 --- a/conf.examples/attentions.messages +++ /dev/null @@ -1,7 +0,0 @@ -hey pengo -hey p3ng0 -p3ng0 -yo pengo -yo p3ng0 -hello p3ng0 -aloha p3ng0 diff --git a/conf.examples/pengobot.conf b/conf.examples/bot.conf similarity index 53% rename from conf.examples/pengobot.conf rename to conf.examples/bot.conf index e6043c6..e6dbe6d 100644 --- a/conf.examples/pengobot.conf +++ b/conf.examples/bot.conf @@ -1,5 +1,12 @@ # This is the configuration file for PengoBot. +# Handles every message group. +messages=conf/messages.list +# Handles single messages to single phrases. +replyfile=conf/replies.conf +# Handles worlds and their names. +worldfile=conf/worldlist.conf + # The username you log in as. Account must be registered on worlds servers. username=Clem @@ -15,6 +22,9 @@ help_url= # Bot avatar. Must be VIP for articulated to show up. avatar=http://files.worlio.com/users/wirlaburla/avatars/pengobot.mov +# Room to appear in. +room=GroundZero#Reception + # The position in the world that the bot will sit. xpos=0 ypos=0 @@ -28,21 +38,17 @@ spin=0 katime=5 # The time between random messages. The wait period is between minRandomMsgTime and maxRandomMsgTime. Setting these to 0 will disable. -msg_random=conf/randoms.messages minRandomMsgTime=300 maxRandomMsgTime=900 -# Local database of worlds and their names. -msg_whereis=conf/whereis.messages -worldfile=conf/worlds.conf - -# Simple responses to simple phrases. -responsefile=conf/responses.conf - -# Other responses. -msg_attention=conf/attentions.messages -msg_startup=conf/startups.messages -msg_greet=conf/greets.messages -msg_goodbye=conf/goodbyes.messages -msg_unknowncmd=conf/unknowncmd.messages -msg_whoami=conf/whoami.messages +# Here are all single-definition messages. For anything that isn't picked in a list, it's here. +help_msg=You can find more information here: %s +coinflip_msg=%s flipped %s. +help_whisper_message=%s, you have been whispered with more information. +time_msg=It is %s. +roll_msg=%s rolled a %i. +world_not_found_msg=Sorry, I don't know that one. +roomusers_msg=There are %i users in this room. +conf_reload_msg=My configuration has been reloaded. +ping_msg=Response recieved in %ims. +pong_msg=Pong! diff --git a/conf.examples/goodbyes.messages b/conf.examples/goodbyes.messages deleted file mode 100644 index 4ff1126..0000000 --- a/conf.examples/goodbyes.messages +++ /dev/null @@ -1 +0,0 @@ -Goodbye! \ No newline at end of file diff --git a/conf.examples/greets.messages b/conf.examples/greets.messages deleted file mode 100644 index f583ea1..0000000 --- a/conf.examples/greets.messages +++ /dev/null @@ -1,9 +0,0 @@ -Hi. -Hi %s. -Aloha %s. -Nice to meet you %s. -Hope all is well! -Howdy! -Salutations %s. -Acknowledged. -Add '%s' to database. \ No newline at end of file diff --git a/conf.examples/messages.list b/conf.examples/messages.list new file mode 100644 index 0000000..fb980e3 --- /dev/null +++ b/conf.examples/messages.list @@ -0,0 +1,39 @@ +[startup] +Hi, I'm P3NG0, your friendly Worlds bot. +My initialization is complete. +[attention] +hey pengo +hey p3ng0 +p3ng0 +yo pengo +yo p3ng0 +hello p3ng0 +aloha p3ng0 +[greets] +Hi. +Hi %s. +Aloha %s. +Nice to meet you %s. +Hope all is well! +Howdy! +Salutations %s. +Acknowledged. +Added '%s' to database. +[goodbye] +Goodbye! +[unknown] +Sorry, I don't know what you're asking. +I am unsure of your request. +ERROR: DIVISION BY ZERO +Need something? +[random] +Beep boop! +[jokes] +Why did the chicken cross the road? To escape my deadly lasers, of course! +[world] +It's right here: %s +%s +Here is your mark: %s +[whoami] +Hi, I'm P3NG0. I'm a friendly bot. +I am here to annihilate the human race. \ No newline at end of file diff --git a/conf.examples/randoms.messages b/conf.examples/randoms.messages deleted file mode 100644 index 5631c41..0000000 --- a/conf.examples/randoms.messages +++ /dev/null @@ -1,2 +0,0 @@ -kiwi -mongolia diff --git a/conf.examples/responses.conf b/conf.examples/replies.conf similarity index 100% rename from conf.examples/responses.conf rename to conf.examples/replies.conf diff --git a/conf.examples/startups.messages b/conf.examples/startups.messages deleted file mode 100644 index c4eae6e..0000000 --- a/conf.examples/startups.messages +++ /dev/null @@ -1,3 +0,0 @@ -Hi, I'm P3NG0, your friendly Worlds bot. -My initialization is complete. -Beep boop! diff --git a/conf.examples/unknowncmd.messages b/conf.examples/unknowncmd.messages deleted file mode 100644 index ef27f59..0000000 --- a/conf.examples/unknowncmd.messages +++ /dev/null @@ -1,4 +0,0 @@ -Sorry, I don't know what you're asking. -I am unsure of your request. -ERROR: DIVISION BY ZERO -Need something? diff --git a/conf.examples/whereis.messages b/conf.examples/whereis.messages deleted file mode 100644 index 37eeee9..0000000 --- a/conf.examples/whereis.messages +++ /dev/null @@ -1,4 +0,0 @@ -It's right here: %s -%s -Here is your mark: %s -Found it! %s diff --git a/conf.examples/whoami.messages b/conf.examples/whoami.messages deleted file mode 100644 index 59c95fe..0000000 --- a/conf.examples/whoami.messages +++ /dev/null @@ -1,2 +0,0 @@ -Hi, I'm P3NG0. I'm a friendly bot. -I am here to annihilate the human race. diff --git a/conf.examples/worlds.conf b/conf.examples/worldlist.conf similarity index 100% rename from conf.examples/worlds.conf rename to conf.examples/worldlist.conf diff --git a/src/acfile.h b/src/acfile.h new file mode 100644 index 0000000..eca96af --- /dev/null +++ b/src/acfile.h @@ -0,0 +1,119 @@ +#ifndef ACF_H +#define ACF_H +#include +#include +#include + +// Another Configuration File +class ACFile { +public: + ACFile() {}; + ACFile(const ACFile &other) { + this->conf = other.conf; + for (auto const& c : this->conf) { + printf("processed: (%s),(%s)\n", c.first.c_str(), c.second.c_str()); + } + } + ACFile(const char* path) { + std::ifstream infile(path); + + std::string line; + while (std::getline(infile, line)) { + if (line.length() == 0) continue; + // Check if line is a comment line. + if (line.rfind("#", 0) != 0) { + std::string name = line.substr(0, line.find("=")); + std::string value = line.substr(line.find("=")+1, line.length()); + std::cout << name << ": \"" << value << "\"" << std::endl; + conf[name] = value; + } + } + } + + std::map get() { + for (auto const& c : this->conf) { + printf("info: (%s),(%s)\n", c.first.c_str(), c.second.c_str()); + } + return this->conf; + } + + std::vector getKeyValues() { + std::vector values; + for (auto const& c : conf) { + values.push_back(c.first); + } + return values; + } + + std::string getValue(std::string name, std::string def) { + if (conf.find(name) != conf.end()) return conf[name]; + else return def; + } + + int getInt(std::string name, int def) { + if (conf.find(name) != conf.end()) return std::stoi(conf[name]); + else return def; + } + + void setValue(std::string name, std::string value) { + conf[name] = value; + } + + void setInt(std::string name, int value) { + conf[name] = std::to_string(value); + } +private: + std::map conf; +}; + +// Another Message File +class AMFile { +public: + AMFile() {}; + AMFile(const AMFile &other) { + this->messages = other.messages; + } + AMFile(const char* path) { + this->rng = std::mt19937(rd()); + + std::ifstream infile(path); + + std::string line; std::string group; + while (std::getline(infile, line)) { + if (line.length() == 0) continue; + // Check if line is a group defining line. + if (line.rfind("[", 0) == 0) { + group = line.substr(1, line.find("]")-1); + messages[group] = {}; + } else if (line.rfind("#", 0) != 0) { + if (line.rfind("\\", 0) == 0) { + line = line.substr(1, line.length()); + } // For \[text] messages. + messages[group].push_back(line); + std::cout << "[" << group << "]=" << line << std::endl; + } + } + } + + std::map> get() { + return messages; + } + + std::string getMessage(std::string group) { + if (messages.find(group) == messages.end() || messages[group].size() == 0) return ""; + std::uniform_int_distribution rno(0,(messages[group]).size()-1); + return (messages[group])[rno(rng)]; + } + + std::vector getMessages(std::string group) { + if (messages.find(group) == messages.end()) return {}; + return messages[group]; + } +private: + std::map> messages; + std::random_device rd; + std::mt19937 rng; +}; + +#endif + diff --git a/src/client.h b/src/client.h index d54c8a4..17087d1 100644 --- a/src/client.h +++ b/src/client.h @@ -5,122 +5,17 @@ #include #include #include "drone.h" +#include "acfile.h" + bool debug = false; std::random_device rd; std::mt19937 rng(rd()); -class PengoConfig { -public: - PengoConfig() { - std::ifstream mconf("conf/pengobot.conf"); - - std::string line; - while (std::getline(mconf, line)) { - // Check if line is a comment line. - if (line.rfind("#", 0) != 0) { - std::string name = line.substr(0, line.find("=")); - std::string value = line.substr(line.find("=")+1, line.length()); - if (debug) std::cout << name << ": \"" << value << "\"" << std::endl; - conf[name] = value; - } - } - - for (auto const& mc : conf) { - std::string msgName; - if ((mc.first.substr(0, mc.first.find("_"))) == "msg") { - msgName = mc.first.substr(mc.first.find("_")+1, mc.first.length()); - std::ifstream msglines(mc.second); - std::string line; - std::vector lines; - while (std::getline(msglines, line)) { - if (line.rfind("#", 0) != 0) { - lines.push_back(line); - if (debug) std::cout << msgName << "=" << line << std::endl; - } - } - messages[msgName] = lines; - } - } - - if ((conf["worldfile"]).length() > 0) { - std::ifstream wrlds(conf["worldfile"]); - std::string wline; - while (std::getline(wrlds, wline)) { - if (wline.rfind("#", 0) != 0) { - std::string name = wline.substr(0, wline.find("=")); - std::string value = wline.substr(wline.find("=")+1, wline.length()); - if (debug) std::cout << name << ": \"" << value << "\"" << std::endl; - worlds[name] = value; - } - } - } - - if ((conf["responsefile"]).length() > 0) { - std::ifstream rspn(conf["responsefile"]); - std::string rline; - while (std::getline(rspn, rline)) { - if (rline.rfind("#", 0) != 0) { - std::string name = rline.substr(0, rline.find("=")); - std::string value = rline.substr(rline.find("=")+1, rline.length()); - if (debug) std::cout << name << ": \"" << value << "\"" << std::endl; - responses[name] = value; - } - } - } - } - PengoConfig operator = (PengoConfig *pc) { return *pc; }; - - std::string getValue(std::string name, std::string def) { - if (((std::string)conf[name]).length() > 0) return conf[name]; - else return def; - } - - int getInt(std::string name, int def) { - if (((std::string)conf[name]).length() > 0) return std::stoi(conf[name]); - else return def; - } - - void setValue(std::string name, std::string value) { - conf[name] = value; - } - - void setInt(std::string name, int value) { - conf[name] = std::to_string(value); - } - - std::string getMessage(std::string type) { - std::uniform_int_distribution rno(0,(messages[type]).size()-1); - return (messages[type])[rno(rng)]; - } - - std::vector getMessages(std::string type) { - return messages[type]; - } - - std::string getWorld(std::string name) { - return worlds[name]; - } - - std::map getWorlds() { - return worlds; - } - - std::string getReply(std::string name) { - return responses[name]; - } - - std::map getResponses() { - return responses; - } - -private: - std::map conf; - std::map worlds; - std::map responses; - std::map> messages; -}; - -PengoConfig conf; +std::string confFile = "conf/bot.conf"; +ACFile* mainConf; +ACFile* worldlist; +ACFile* replylist; +AMFile* messages; #define BUFFERSIZE 65535 diff --git a/src/main.cpp b/src/main.cpp index b214d9d..c6e06cb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,7 +23,7 @@ #include "strutils.h" #include "client.h" -#include "verrors.h.h" +#include "verrors.h" #include "cmds.h" #include "props.h" @@ -58,7 +58,14 @@ static char* trim(char *str) { int main(int argc, char const* argv[]) { // Setting config values. + if (argc > 1) { + confFile = std::string(argv[1]); + printf("info: primary conf file set to \"%s\"\n", confFile.c_str()); + } loadConfig(); + /*for (auto const& c : mainConf->get()) { + printf("info: (%s),(%s)\n", c.first.c_str(), c.second.c_str()); + }*/ autoInit(); while (autoOnline) { while (!roomOnline) {} @@ -68,22 +75,25 @@ int main(int argc, char const* argv[]) { } void loadConfig() { - conf = new PengoConfig(); - login_username = (conf.getValue("username", "")); - login_password = (conf.getValue("password", "")); - room = (conf.getValue("room", "GroundZero#Reception")); - avatar = (conf.getValue("avatar", "avatar:pengo.mov")); - xPos = conf.getInt("xpos", 0); - yPos = conf.getInt("ypos", 0); - zPos = conf.getInt("zpos", 0); - direction = conf.getInt("direction", 0); - spin = conf.getInt("spin", 45); - keepAliveTime = conf.getInt("katime", 15); - debug = conf.getInt("debug", 0) == 1; + mainConf = new ACFile(confFile.c_str()); + worldlist = new ACFile(mainConf->getValue("worldfile", "conf/worldlist.conf").c_str()); + replylist = new ACFile(mainConf->getValue("replyfile", "conf/replies.conf").c_str()); + messages = new AMFile(mainConf->getValue("messages", "conf/messages.list").c_str()); + login_username = mainConf->getValue("username", ""); + login_password = mainConf->getValue("password", ""); + room = mainConf->getValue("room", "GroundZero#Reception"); + avatar = mainConf->getValue("avatar", "avatar:pengo.mov"); + xPos = mainConf->getInt("xpos", 0); + yPos = mainConf->getInt("ypos", 0); + zPos = mainConf->getInt("zpos", 0); + direction = mainConf->getInt("direction", 0); + spin = mainConf->getInt("spin", 0); + keepAliveTime = mainConf->getInt("katime", 15); + debug = mainConf->getInt("debug", 0) == 1; } int deinit(int response) { - sendChatMessage(&roomsock, conf.getMessage("goodbye")); + sendChatMessage(&roomsock, messages->getMessage("goodbye")); if (roomOnline) sessExit(&roomsock); roomOnline = false; if (autoOnline) sessExit(&autosock); @@ -148,15 +158,15 @@ void roomKeepAlive() { } void autoRandMessage() { - int minTime = conf.getInt("minRandomMsgTime", 0); - int maxTime = conf.getInt("maxRandomMsgTime", 0); + int minTime = mainConf->getInt("minRandomMsgTime", 0); + int maxTime = mainConf->getInt("maxRandomMsgTime", 0); int wait = 0; sleep(2); - sendChatMessage(&roomsock, conf.getMessage("startup")); + sendChatMessage(&roomsock, messages->getMessage("startup")); if (minTime != 0) { while (roomOnline) { if (wait != 0) { - std::string newMsg = conf.getMessage("random"); + std::string newMsg = messages->getMessage("random"); if (debug) printf("debug: automsg: \"%s\"\n", newMsg.c_str()); sendChatMessage(&roomsock, newMsg); } @@ -509,13 +519,11 @@ std::string getResponse(std::map responselist, std::st char* handleCommand(std::string from, std::string message) { char *msgout = new char[255]; - if (strcontains("hi", message)) { - snprintf(msgout, 255, conf.getMessage("greet").c_str(), from.c_str()); - } else if (strcontains("flip a coin", message)) { + if (strcontains("flip a coin", message)) { std::uniform_int_distribution rno(0,1); bool heads = rno(rng) == 1; - snprintf(msgout, 255, "%s", heads?"Heads":"Tails"); + snprintf(msgout, 255, mainConf->getValue("coinflip_msg", "%s flipped %s.").c_str(), heads?"heads":"tails"); } else if (strcontains("time", message)) { @@ -525,7 +533,7 @@ char* handleCommand(std::string from, std::string message) { nowStream << std::put_time(localtime(&nowTime), "%A %b %d, %Y at %I:%M %p %Z"); std::string curTime = nowStream.str(); - snprintf(msgout, 255, "It is %s.", curTime.c_str()); + snprintf(msgout, 255, mainConf->getValue("time_msg", "It is %s.").c_str(), curTime.c_str()); } else if (strcontains("roll", message)) { @@ -540,42 +548,50 @@ char* handleCommand(std::string from, std::string message) { dice = 6; } - std::uniform_int_distribution rno(1,dice); int roll = rno(rng); - snprintf(msgout, 255, "%s rolled a %i.", from.c_str(), roll); + snprintf(msgout, 255, mainConf->getValue("roll_msg", "%s rolled a %i.").c_str(), from.c_str(), roll); } else if (strcontains("where is", message) || strcontains("where", message) || strcontains("mark to", message) || strcontains("show me", message)) { - std::string mark = getContainedWorld(conf.getWorlds(), message); + std::string mark = getContainedWorld(worldlist->get(), message); if (mark.length() > 0) { - snprintf(msgout, 255, conf.getMessage("whereis").c_str(), mark.c_str()); + snprintf(msgout, 255, messages->getMessage("world").c_str(), mark.c_str()); } else { - snprintf(msgout, 255, "Sorry! Not a clue."); + snprintf(msgout, 255, mainConf->getValue("world_not_found_msg", "Sorry, I don't know that one.").c_str()); } - } else if (strcontains("many users", message) || strcontains("whos online", message) || strcontains("who is online", message) || strcontains("many online", message)) { + } else if (((strcontains("many", message) || strcontains("count", message)) && (strcontains("users", message) || strcontains("people", message))) || (strcontains("online", message) && (strcontains("who", message) || strcontains("how many", message) || strcontains("who is", message)))) { - snprintf(msgout, 255, "There are %i users in this room.", objects.size()); + snprintf(msgout, 255, mainConf->getValue("roomusers_msg", "There are %i users in this room.").c_str(), objects.size()); + + } else if ((strcontains("joke", message) && strcontains("tell", message)) || (strcontains("make", message) && strcontains("laugh", message))) { + + snprintf(msgout, 255, messages->getMessage("jokes").c_str()); } else if ((strcontains("what", message) || strcontains("who", message)) && strcontains("are you", message)) { - snprintf(msgout, 255, "%s", conf.getMessage("whoami").c_str()); + snprintf(msgout, 255, messages->getMessage("whoami").c_str()); - } else if (strcontains("shutdown", message) && from == conf.getValue("owner", "")) { + } else if (strcontains("shutdown", message) && from == mainConf->getValue("owner", "")) { exit(deinit(0)); - } else if (strcontains("reload", message) && from == conf.getValue("owner", "")) { + } else if (strcontains("reload", message) && from == mainConf->getValue("owner", "")) { loadConfig(); - snprintf(msgout, 255, "My configurations have been reloaded."); + snprintf(msgout, 255, mainConf->getValue("conf_reload_msg", "My configurations have been reloaded.").c_str()); + + } else if (strcontains(" hi", message) || strcontains("hello", message) || strcontains(" hey", message) || strcontains(" yo", message)) { + // Prefix small ones with spaces so they don't get mixed up easily in other words. "this" -> hi, "you" -> yo, "they" -> hey + + snprintf(msgout, 255, messages->getMessage("greets").c_str(), from.c_str()); } else { std::string response; - if ((response = getResponse(conf.getResponses(), message)).length() > 0) { - snprintf(msgout, 255, "%s", response.c_str()); + if ((response = getResponse(replylist->get(), message)).length() > 0) { + snprintf(msgout, 255, response.c_str()); } } @@ -591,7 +607,7 @@ void processText(int *sock, std::string username, std::string message) { int alen = 0; // Someone has requested P3NG0s attention. // We'll accept some variations. - if ((alen = vstrcontains(message, conf.getMessages("attention"))) > 0) { + if ((alen = vstrcontains(message, messages->getMessages("attention"))) > 0) { // Strip out the attention. We got it. message = message.substr(alen+1, message.length()); msgout = handleCommand(username, message); @@ -599,12 +615,12 @@ void processText(int *sock, std::string username, std::string message) { else if (strcontains("your commands", message) || strcontains("can you do", message)) { char *whisout = new char[255]; - snprintf(whisout, 255, "Check this out: %s", conf.getValue("help_url", "").c_str()); + snprintf(whisout, 255, mainConf->getValue("help_msg", "You can find more information here: %s").c_str(), mainConf->getValue("help_url", "").c_str()); sendWhisperMessage(&roomsock, username, whisout); - snprintf(msgout, 255, "You have been whispered with a link that will help you."); + snprintf(msgout, 255, mainConf->getValue("help_whisper_message", "%s, you have been whispered with more information.").c_str(), username.c_str()); sendChatMessage(sock, msgout); - } else if (strcontains("test ping", message)) { + } else if (strcontains("ping test", message)) { pingStart = std::chrono::system_clock::now(); snprintf(msgout, 255, "Ping!"); @@ -612,14 +628,14 @@ void processText(int *sock, std::string username, std::string message) { } } else if (message == "ping") { // We'll accept a simple ping to pong. - sendChatMessage(sock, "Pong!"); + sendChatMessage(sock, mainConf->getValue("pong_msg", "Pong!")); } } else { if (debug) printf("debug: processing own message: %s\n", message.c_str()); if (message.compare("Ping!") == 0) { pingEnd = std::chrono::system_clock::now(); std::chrono::duration ping = pingEnd - pingStart; - snprintf(msgout, 255, "Response received in %ims.", ping.count()); + snprintf(msgout, 255, mainConf->getValue("ping_msg", "Response recieved in %ims.").c_str(), ping.count()); sendChatMessage(sock, msgout); } } @@ -631,49 +647,57 @@ void processWhisper(int *sock, std::string username, std::string message) { message = toLower(message); if (message == "ping") { - sendWhisperMessage(sock, username, "Pong"); + sendWhisperMessage(sock, username, mainConf->getValue("pong_msg", "Pong!")); } else { msgout = handleCommand(username, message); if (strlen(msgout) > 0) sendWhisperMessage(sock, username, msgout); + else { + snprintf(msgout, 255, messages->getMessage("unknown").c_str()); + sendWhisperMessage(sock, username, msgout); + } } } void sendChatMessage(int *sock, std::string msg) { - unsigned char msgout[255] = {0}; - int msglen = msg.length(); - int k = 1; - msgout[k++] = 1; - msgout[k++] = CMD_CHATMSG; - msgout[k++] = 0; bufout[k++] = 0; - msgout[k++] = msglen; - for(int l = 0; l < msglen; l++) - msgout[k++] = msg[l]; - msgout[k] = 0; - msgout[0] = k; - wsend(&roomsock, msgout, 0); + if (msg.length() > 0) { + unsigned char msgout[255] = {0}; + int msglen = msg.length(); + int k = 1; + msgout[k++] = 1; + msgout[k++] = CMD_CHATMSG; + msgout[k++] = 0; bufout[k++] = 0; + msgout[k++] = msglen; + for(int l = 0; l < msglen; l++) + msgout[k++] = msg[l]; + msgout[k] = 0; + msgout[0] = k; + wsend(&roomsock, msgout, 0); + } } void sendWhisperMessage(int *sock, std::string to, std::string msg) { - whisper_repeat: - unsigned char msgout[255] = {0}; - int k = 1; - msgout[k++] = 0; - msgout[k++] = to.length(); - for(int l = 0; l < to.length(); l++) - msgout[k++] = to[l]; - msgout[k++] = CMD_WHISPER; - msgout[k++] = 0; bufout[k++] = 0; - int msglen = std::min((int)msg.length(), 226); - msgout[k++] = msglen; - for(int l = 0; l < msglen; l++) - msgout[k++] = msg[l]; - msgout[k] = 0; - msgout[0] = k; - wsend(&roomsock, msgout, 0); - // Check if the length is higher. - if (msg.length() > 226) { - msg = msg.substr(226, -1); - goto whisper_repeat; + if (msg.length() > 0 && to.length() > 0) { + whisper_repeat: + unsigned char msgout[255] = {0}; + int k = 1; + msgout[k++] = 0; + msgout[k++] = to.length(); + for(int l = 0; l < to.length(); l++) + msgout[k++] = to[l]; + msgout[k++] = CMD_WHISPER; + msgout[k++] = 0; bufout[k++] = 0; + int msglen = std::min((int)msg.length(), 226); + msgout[k++] = msglen; + for(int l = 0; l < msglen; l++) + msgout[k++] = msg[l]; + msgout[k] = 0; + msgout[0] = k; + wsend(&roomsock, msgout, 0); + // Check if the length is higher. + if (msg.length() > 226) { + msg = msg.substr(226, -1); + goto whisper_repeat; + } } } diff --git a/src/verrors.h.h b/src/verrors.h similarity index 100% rename from src/verrors.h.h rename to src/verrors.h