queue system, better command systsem, whispers/messages now can get split if too long
This commit is contained in:
parent
74d14372ec
commit
fb666f1d92
|
@ -24,7 +24,6 @@ public:
|
||||||
if (line.rfind("#", 0) != 0) {
|
if (line.rfind("#", 0) != 0) {
|
||||||
std::string name = line.substr(0, line.find("="));
|
std::string name = line.substr(0, line.find("="));
|
||||||
std::string value = line.substr(line.find("=")+1, line.length());
|
std::string value = line.substr(line.find("=")+1, line.length());
|
||||||
std::cout << name << ": \"" << value << "\"" << std::endl;
|
|
||||||
conf[name] = value;
|
conf[name] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +89,6 @@ public:
|
||||||
line = line.substr(1, line.length());
|
line = line.substr(1, line.length());
|
||||||
} // For \[text] messages.
|
} // For \[text] messages.
|
||||||
messages[group].push_back(line);
|
messages[group].push_back(line);
|
||||||
std::cout << "[" << group << "]=" << line << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
src/client.h
13
src/client.h
|
@ -60,9 +60,6 @@ uint16_t spin = 0;
|
||||||
std::map<char, char*> properties;
|
std::map<char, char*> properties;
|
||||||
std::map<char, Drone> objects;
|
std::map<char, Drone> objects;
|
||||||
|
|
||||||
static char* toLower(char* str);
|
|
||||||
static std::string toLower(std::string str);
|
|
||||||
static char* trim(char *str);
|
|
||||||
void loadConfig();
|
void loadConfig();
|
||||||
int deinit(int response);
|
int deinit(int response);
|
||||||
void autoInit();
|
void autoInit();
|
||||||
|
@ -78,17 +75,15 @@ std::map<char, char*> readOldPropertyList(unsigned char* in);
|
||||||
void setAvatar(int *sock, std::string avstr);
|
void setAvatar(int *sock, std::string avstr);
|
||||||
void roomIDReq(int *sock, std::string room);
|
void roomIDReq(int *sock, std::string room);
|
||||||
void teleport(int *sock, int x, int y, int z, int rot);
|
void teleport(int *sock, int x, int y, int z, int rot);
|
||||||
|
void longloc(int *sock, int x, int y, int z, int rot);
|
||||||
void userEnter(char id);
|
void userEnter(char id);
|
||||||
void userExit(char id);
|
void userExit(char id);
|
||||||
bool strcontains(std::string needle, std::string haystack);
|
bool handleCommand(char* buffer, std::string from, std::string message);
|
||||||
int vstrcontains(std::string needle, std::vector<std::string> haystack);
|
bool handlePhrase(char* buffer, std::string from, std::string message);
|
||||||
std::string getContainedWorld(std::map<std::string, std::string> worldlist, std::string input);
|
|
||||||
std::string getResponse(std::map<std::string, std::string> responselist, std::string input);
|
|
||||||
char* handleCommand(std::string from, std::string message);
|
|
||||||
void processText(int *sock, std::string username, std::string message);
|
void processText(int *sock, std::string username, std::string message);
|
||||||
void processWhisper(int *sock, std::string username, std::string message);
|
void processWhisper(int *sock, std::string username, std::string message);
|
||||||
void sendChatMessage(int *sock, std::string msg);
|
void sendChatMessage(int *sock, std::string msg);
|
||||||
void sendWhisperMessage(int *sock, std::string to, std::string msg);
|
void sendWhisperMessage(int *sock, std::string to, std::string msg);
|
||||||
int wsend(int *sock, unsigned char str[], int flags);
|
void qsend(int *sock, unsigned char str[], bool queue);
|
||||||
|
|
||||||
#endif
|
#endif
|
33
src/group.h
Normal file
33
src/group.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef GROUP_H
|
||||||
|
#define GROUP_H
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class Group {
|
||||||
|
public:
|
||||||
|
Group() {};
|
||||||
|
Group(const Group &other) {
|
||||||
|
this->owner = other.owner;
|
||||||
|
this->members = other.members;
|
||||||
|
}
|
||||||
|
Group(std::string owner) {
|
||||||
|
this->owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addMember(std::string name) {
|
||||||
|
members.push_back(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delMember(std::string name) {
|
||||||
|
members.erase(std::find(members.begin(), members.end(), name));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string owner;
|
||||||
|
std::vector<std::string> members;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Group> groups;
|
||||||
|
std::map<std::string, Group*> groupmap;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
392
src/main.cpp
392
src/main.cpp
|
@ -21,40 +21,34 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "strutils.h"
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "verrors.h"
|
#include "verrors.h"
|
||||||
#include "cmds.h"
|
#include "cmds.h"
|
||||||
#include "props.h"
|
#include "props.h"
|
||||||
|
#include "group.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
std::chrono::time_point<std::chrono::system_clock> pingStart;
|
class QueuedPacket {
|
||||||
std::chrono::time_point<std::chrono::system_clock> pingEnd;
|
public:
|
||||||
|
QueuedPacket() {};
|
||||||
static char* toLower(char* str) {
|
QueuedPacket(const QueuedPacket &other) {
|
||||||
for(int i = 0; str[i]; i++){
|
this->sock = other.sock;
|
||||||
str[i] = std::tolower(str[i]);
|
memcpy(this->buf, other.buf, 255);
|
||||||
}
|
}
|
||||||
return str;
|
QueuedPacket(int *sock, unsigned char str[]) {
|
||||||
}
|
this->sock = *sock;
|
||||||
|
memcpy(this->buf, str, 255);
|
||||||
|
};
|
||||||
|
|
||||||
static std::string toLower(std::string str) {
|
int flush(int flags) {
|
||||||
std::transform(str.begin(), str.end(), str.begin(),
|
return send(this->sock, this->buf, this->buf[0], flags);
|
||||||
[](unsigned char c){ return std::tolower(c); });
|
}
|
||||||
return str;
|
private:
|
||||||
}
|
int sock;
|
||||||
|
unsigned char buf[255] = {};
|
||||||
|
};
|
||||||
|
|
||||||
static char* trim(char *str) {
|
std::vector<QueuedPacket> bufferQueue;
|
||||||
char *end;
|
|
||||||
while(isspace(*str))
|
|
||||||
str++;
|
|
||||||
if(*str == 0)
|
|
||||||
return str;
|
|
||||||
end = str + strnlen(str, 128) - 1;
|
|
||||||
while(end > str && isspace(*end))
|
|
||||||
end--;
|
|
||||||
*(end+1) = '\0';
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char const* argv[]) {
|
int main(int argc, char const* argv[]) {
|
||||||
// Setting config values.
|
// Setting config values.
|
||||||
|
@ -70,6 +64,15 @@ int main(int argc, char const* argv[]) {
|
||||||
while (autoOnline) {
|
while (autoOnline) {
|
||||||
while (!roomOnline) {}
|
while (!roomOnline) {}
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
if (bufferQueue.size() > 0) {
|
||||||
|
if (debug) printf("debug: flushing buffer queue (%i packets)\n", bufferQueue.size());
|
||||||
|
for (QueuedPacket qp : bufferQueue) {
|
||||||
|
qp.flush(MSG_MORE);
|
||||||
|
}
|
||||||
|
send(autosock, new unsigned char[]{}, 0, 0);
|
||||||
|
send(roomsock, new unsigned char[]{}, 0, 0);
|
||||||
|
bufferQueue.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return deinit(0);
|
return deinit(0);
|
||||||
}
|
}
|
||||||
|
@ -119,7 +122,7 @@ void autoInit() {
|
||||||
perror("AutoServ connection failed");
|
perror("AutoServ connection failed");
|
||||||
|
|
||||||
aRecv_t = std::thread(reciever, &autosock, autoport);
|
aRecv_t = std::thread(reciever, &autosock, autoport);
|
||||||
wsend(&autosock, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 0);
|
send(autosock, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 3, 0);
|
||||||
printf("info: Connected to AutoServer: %i.%i.%i.%i:%i\n", autoserver[1], autoserver[1], autoserver[2], autoserver[3], autoport);
|
printf("info: Connected to AutoServer: %i.%i.%i.%i:%i\n", autoserver[1], autoserver[1], autoserver[2], autoserver[3], autoport);
|
||||||
sessInit(&autosock, login_username, login_password);
|
sessInit(&autosock, login_username, login_password);
|
||||||
autoOnline = true;
|
autoOnline = true;
|
||||||
|
@ -137,22 +140,25 @@ void roomInit() {
|
||||||
if ((connect(roomsock, (struct sockaddr*)&room_addr, sizeof(room_addr))) < 0)
|
if ((connect(roomsock, (struct sockaddr*)&room_addr, sizeof(room_addr))) < 0)
|
||||||
perror("RoomServ connection failed");
|
perror("RoomServ connection failed");
|
||||||
|
|
||||||
wsend(&autosock, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 0);
|
send(autosock, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 3, 0);
|
||||||
printf("info: Connected to RoomServer: %i.%i.%i.%i:%i\n", roomserver[1], roomserver[1], roomserver[2], roomserver[3], roomport);
|
printf("info: Connected to RoomServer: %i.%i.%i.%i:%i\n", roomserver[1], roomserver[1], roomserver[2], roomserver[3], roomport);
|
||||||
roomOnline = true;
|
roomOnline = true;
|
||||||
rRecv_t = std::thread(reciever, &roomsock, roomport);
|
rRecv_t = std::thread(reciever, &roomsock, roomport);
|
||||||
sessInit(&roomsock, login_username, login_password);
|
sessInit(&roomsock, login_username, login_password);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
rKeepAlive_t = std::thread(roomKeepAlive);
|
rKeepAlive_t = std::thread(roomKeepAlive);
|
||||||
|
sleep(1);
|
||||||
rAutoMsg_t = std::thread(autoRandMessage);
|
rAutoMsg_t = std::thread(autoRandMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void roomKeepAlive() {
|
void roomKeepAlive() {
|
||||||
|
sleep(1);
|
||||||
|
teleport(&roomsock, xPos, yPos, zPos, direction);
|
||||||
while (roomOnline) {
|
while (roomOnline) {
|
||||||
if (direction >= 360) direction = 0;
|
if (direction >= 360) direction += (spin - 360);
|
||||||
else direction+=spin;
|
else direction+=spin;
|
||||||
teleport(&roomsock, xPos, yPos, zPos, direction);
|
longloc(&roomsock, xPos, yPos, zPos, direction);
|
||||||
sleep(keepAliveTime); // So we don't auto-disconnect.
|
sleep(keepAliveTime);
|
||||||
}
|
}
|
||||||
printf("warning: room keep alive disconnected!\n");
|
printf("warning: room keep alive disconnected!\n");
|
||||||
}
|
}
|
||||||
|
@ -161,7 +167,6 @@ void autoRandMessage() {
|
||||||
int minTime = mainConf->getInt("minRandomMsgTime", 0);
|
int minTime = mainConf->getInt("minRandomMsgTime", 0);
|
||||||
int maxTime = mainConf->getInt("maxRandomMsgTime", 0);
|
int maxTime = mainConf->getInt("maxRandomMsgTime", 0);
|
||||||
int wait = 0;
|
int wait = 0;
|
||||||
sleep(2);
|
|
||||||
sendChatMessage(&roomsock, messages->getMessage("startup"));
|
sendChatMessage(&roomsock, messages->getMessage("startup"));
|
||||||
if (minTime != 0) {
|
if (minTime != 0) {
|
||||||
while (roomOnline) {
|
while (roomOnline) {
|
||||||
|
@ -315,7 +320,7 @@ void reciever(int *sock, uint16_t port) {
|
||||||
p += bufin[p];
|
p += bufin[p];
|
||||||
goto more_in_buffer;
|
goto more_in_buffer;
|
||||||
}
|
}
|
||||||
memset(&(bufin[0]), 0, sizeof(bufin));
|
memset(&bufin[0], 0, sizeof(bufin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,14 +370,14 @@ void sessInit(int *sock, std::string username, std::string password) {
|
||||||
|
|
||||||
bufout[0] = l;
|
bufout[0] = l;
|
||||||
bufout[l+1] = 0;
|
bufout[l+1] = 0;
|
||||||
wsend(sock, bufout, 0);
|
qsend(sock, bufout, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sessExit(int *sock) {
|
void sessExit(int *sock) {
|
||||||
bufout[0] = 0x03;
|
bufout[0] = 0x03;
|
||||||
bufout[1] = 0x01;
|
bufout[1] = 0x01;
|
||||||
bufout[2] = CMD_SESSEXIT;
|
bufout[2] = CMD_SESSEXIT;
|
||||||
wsend(sock, bufout, 0);
|
qsend(sock, bufout, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void constructPropertyList(int type, std::map<int, char*> props, unsigned char* snd) {
|
void constructPropertyList(int type, std::map<int, char*> props, unsigned char* snd) {
|
||||||
|
@ -434,7 +439,7 @@ void setAvatar(int *sock, std::string avstr) {
|
||||||
|
|
||||||
bufav[0] = l;
|
bufav[0] = l;
|
||||||
bufav[l+1] = 0;
|
bufav[l+1] = 0;
|
||||||
wsend(sock, bufav, 0);
|
qsend(sock, bufav, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void roomIDReq(int *sock, std::string room) {
|
void roomIDReq(int *sock, std::string room) {
|
||||||
|
@ -447,7 +452,7 @@ void roomIDReq(int *sock, std::string room) {
|
||||||
bufrm[x++] = room[z];
|
bufrm[x++] = room[z];
|
||||||
bufrm[x++] = 0;
|
bufrm[x++] = 0;
|
||||||
bufrm[0] = x;
|
bufrm[0] = x;
|
||||||
wsend(sock, bufrm, 0);
|
qsend(sock, bufrm, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void teleport(int *sock, int x, int y, int z, int rot) {
|
void teleport(int *sock, int x, int y, int z, int rot) {
|
||||||
|
@ -468,12 +473,34 @@ void teleport(int *sock, int x, int y, int z, int rot) {
|
||||||
buftp[2] = CMD_TELEPORT;
|
buftp[2] = CMD_TELEPORT;
|
||||||
buftp[4] = _roomID[0]; buftp[3] = _roomID[1];
|
buftp[4] = _roomID[0]; buftp[3] = _roomID[1];
|
||||||
buftp[5] = 0x00; buftp[6] = 0x01;
|
buftp[5] = 0x00; buftp[6] = 0x01;
|
||||||
buftp[8] = _x[0]; buftp[7] = _x[1];
|
buftp[8] = _x[1]; buftp[7] = _x[0];
|
||||||
buftp[10] = _y[0]; buftp[9] = _y[1];
|
buftp[10] = _y[1]; buftp[9] = _y[0];
|
||||||
buftp[12] = _z[0]; buftp[11] = _z[1];
|
buftp[12] = _z[1]; buftp[11] = _z[0];
|
||||||
buftp[14] = _rot[0]; buftp[13] = _rot[1];
|
buftp[14] = _rot[1]; buftp[13] = _rot[0];
|
||||||
|
|
||||||
wsend(sock, buftp, 0);
|
qsend(sock, buftp, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void longloc(int *sock, int x, int y, int z, int rot) {
|
||||||
|
unsigned char buftp[11] = {0};
|
||||||
|
uint8_t _x[2];
|
||||||
|
uint8_t _y[2];
|
||||||
|
uint8_t _z[2];
|
||||||
|
uint8_t _rot[2];
|
||||||
|
memcpy(_x, &x, sizeof(_x));
|
||||||
|
memcpy(_y, &y, sizeof(_y));
|
||||||
|
memcpy(_z, &z, sizeof(_z));
|
||||||
|
memcpy(_rot, &rot, sizeof(_rot));
|
||||||
|
|
||||||
|
buftp[0] = 0x0b;
|
||||||
|
buftp[1] = 0x01;
|
||||||
|
buftp[2] = CMD_LONGLOC;
|
||||||
|
buftp[3] = _x[1]; buftp[4] = _x[0];
|
||||||
|
buftp[5] = _y[1]; buftp[6] = _y[0];
|
||||||
|
buftp[7] = _z[1]; buftp[8] = _z[0];
|
||||||
|
buftp[9] = _rot[1]; buftp[10] = _rot[0];
|
||||||
|
|
||||||
|
qsend(sock, buftp, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void userEnter(char id) {
|
void userEnter(char id) {
|
||||||
|
@ -488,120 +515,106 @@ void userExit(char id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool handleCommand(char* buffer, std::string from, std::string message) {
|
||||||
|
std::vector<std::string> args = split(message, ' ');
|
||||||
|
if (args.size() > 0) {
|
||||||
|
if (args[0] == "roll" && args.size() > 1) {
|
||||||
|
int dice = 1; int sides = 6; int roll = 0;
|
||||||
|
if (args.size() > 1) {
|
||||||
|
try {
|
||||||
|
int dinx = args[1].find("d");
|
||||||
|
if (dinx > 0) {
|
||||||
|
dice = std::stoi(args[1].substr(0, dinx));
|
||||||
|
}
|
||||||
|
sides = std::stoi(args[1].substr(dinx+1, args[1].length()));
|
||||||
|
} catch (const std::out_of_range& e) { }
|
||||||
|
}
|
||||||
|
|
||||||
bool strcontains(std::string needle, std::string haystack) {
|
std::uniform_int_distribution<int> rno(1,sides);
|
||||||
bool found = haystack.find(needle) != std::string::npos;
|
for (int d = 0; d < dice; d++) roll+=rno(rng);
|
||||||
if (debug) printf("debug: %s =?= %s == %i\n", needle.c_str(), haystack.c_str(), found?1:0);
|
sprintf(buffer, mainConf->getValue("roll_msg", "%s rolled a %i.").c_str(), from.c_str(), roll);
|
||||||
return found;
|
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());
|
||||||
|
sendWhisperMessage(&roomsock, from, whisout);
|
||||||
|
sprintf(buffer, mainConf->getValue("help_whisper_message", "%s, you have been whispered with more information.").c_str(), from.c_str());
|
||||||
|
return true;
|
||||||
|
} else if (args[0] == "ping") {
|
||||||
|
sprintf(buffer, mainConf->getValue("pong_msg", "Pong!").c_str());
|
||||||
|
return true;
|
||||||
|
} else if (args[0] == "time") {
|
||||||
|
std::ostringstream nowStream;
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
std::time_t nowTime = std::chrono::system_clock::to_time_t(now);
|
||||||
|
nowStream << std::put_time(localtime(&nowTime), "%A %b %d, %Y at %I:%M %p %Z");
|
||||||
|
std::string curTime = nowStream.str();
|
||||||
|
|
||||||
int vstrcontains(std::string needle, std::vector<std::string> haystack) {
|
sprintf(buffer, mainConf->getValue("time_msg", "It is %s.").c_str(), curTime.c_str());
|
||||||
for (std::string str : haystack) {
|
return true;
|
||||||
if (needle.rfind(str, 0) == 0) return str.length();
|
} 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] == "reload" && from == mainConf->getValue("owner", "")) {
|
||||||
|
loadConfig();
|
||||||
|
setAvatar(&roomsock, avatar);
|
||||||
|
sprintf(buffer, mainConf->getValue("conf_reload_msg", "My configurations have been reloaded.").c_str());
|
||||||
|
return true;
|
||||||
|
} else if ((args[0] == "shutdown" || args[0] == "kill") && from == mainConf->getValue("owner", "")) {
|
||||||
|
exit(deinit(0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getContainedWorld(std::map<std::string, std::string> worldlist, std::string input) {
|
bool handlePhrase(char* buffer, std::string from, std::string message) {
|
||||||
for (auto world : worldlist) {
|
std::vector<std::string> args = split(message, ' ');
|
||||||
if (strcontains(world.first, input)) return world.second;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getResponse(std::map<std::string, std::string> responselist, std::string input) {
|
|
||||||
for (auto resp : responselist) {
|
|
||||||
if (strcontains(resp.first, input)) return resp.second;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
char* handleCommand(std::string from, std::string message) {
|
|
||||||
char *msgout = new char[255];
|
|
||||||
|
|
||||||
if (strcontains("flip a coin", message)) {
|
if (strcontains("flip a coin", message)) {
|
||||||
|
|
||||||
std::uniform_int_distribution<int> rno(0,1);
|
std::uniform_int_distribution<int> rno(0,1);
|
||||||
bool heads = rno(rng) == 1;
|
bool heads = rno(rng) == 1;
|
||||||
snprintf(msgout, 255, mainConf->getValue("coinflip_msg", "%s flipped %s.").c_str(), heads?"heads":"tails");
|
sprintf(buffer, mainConf->getValue("coinflip_msg", "%s flipped %s.").c_str(), from.c_str(), heads?"heads":"tails");
|
||||||
|
return true;
|
||||||
} else if (strcontains("time", message)) {
|
|
||||||
|
|
||||||
std::ostringstream nowStream;
|
|
||||||
auto now = std::chrono::system_clock::now();
|
|
||||||
std::time_t nowTime = std::chrono::system_clock::to_time_t(now);
|
|
||||||
nowStream << std::put_time(localtime(&nowTime), "%A %b %d, %Y at %I:%M %p %Z");
|
|
||||||
std::string curTime = nowStream.str();
|
|
||||||
|
|
||||||
snprintf(msgout, 255, mainConf->getValue("time_msg", "It is %s.").c_str(), curTime.c_str());
|
|
||||||
|
|
||||||
} else if (strcontains("roll", message)) {
|
|
||||||
|
|
||||||
int dice = 6; int dstr;
|
|
||||||
try {
|
|
||||||
if ((dstr = message.find(" d")) != std::string::npos) {
|
|
||||||
std::string dino = message.substr(dstr+2, message.length());
|
|
||||||
if (debug) printf("debug: setting die to d%s\n", dino.c_str());
|
|
||||||
dice = std::stoi(dino);
|
|
||||||
}
|
|
||||||
} catch (const std::out_of_range& e) {
|
|
||||||
dice = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uniform_int_distribution<int> rno(1,dice);
|
|
||||||
int roll = rno(rng);
|
|
||||||
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(worldlist->get(), message);
|
|
||||||
if (mark.length() > 0) {
|
|
||||||
snprintf(msgout, 255, messages->getMessage("world").c_str(), mark.c_str());
|
|
||||||
} else {
|
|
||||||
snprintf(msgout, 255, mainConf->getValue("world_not_found_msg", "Sorry, I don't know that one.").c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
} 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, 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))) {
|
} else if ((strcontains("joke", message) && strcontains("tell", message)) || (strcontains("make", message) && strcontains("laugh", message))) {
|
||||||
|
|
||||||
snprintf(msgout, 255, messages->getMessage("jokes").c_str());
|
sprintf(buffer, messages->getMessage("jokes").c_str());
|
||||||
|
return true;
|
||||||
|
|
||||||
} else if ((strcontains("what", message) || strcontains("who", message)) && strcontains("are you", message)) {
|
} else if ((strcontains("what", message) || strcontains("who", message)) && strcontains("are you", message)) {
|
||||||
|
|
||||||
snprintf(msgout, 255, messages->getMessage("whoami").c_str());
|
sprintf(buffer, messages->getMessage("whoami").c_str());
|
||||||
|
return true;
|
||||||
|
|
||||||
} else if (strcontains("shutdown", message) && from == mainConf->getValue("owner", "")) {
|
} else if (vfind(args, "hi") || vfind(args, "hello") || vfind(args, "hey") || vfind(args, "yo")) {
|
||||||
|
|
||||||
exit(deinit(0));
|
sprintf(buffer, messages->getMessage("greets").c_str(), from.c_str());
|
||||||
|
return true;
|
||||||
} else if (strcontains("reload", message) && from == mainConf->getValue("owner", "")) {
|
|
||||||
|
|
||||||
loadConfig();
|
|
||||||
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 {
|
} else {
|
||||||
|
|
||||||
std::string response;
|
std::string response;
|
||||||
if ((response = getResponse(replylist->get(), message)).length() > 0) {
|
if ((response = getValueOfIncludedName(replylist->get(), message)).length() > 0) {
|
||||||
snprintf(msgout, 255, response.c_str());
|
sprintf(buffer, response.c_str());
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
return msgout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void processText(int *sock, std::string username, std::string message) {
|
void processText(int *sock, std::string username, std::string message) {
|
||||||
printf("info: received text from %s: \"%s\"\n", username.c_str(), message.c_str());
|
if (debug) printf("debug: received text from %s: \"%s\"\n", username.c_str(), message.c_str());
|
||||||
char *msgout = new char[255];
|
char *msgout = new char[BUFFERSIZE];
|
||||||
if (username.compare(login_username) != 0) {
|
if (username.compare(login_username) != 0) {
|
||||||
message = toLower(message); // Make it a lowercase string so we can work with it.
|
message = toLower(message); // Make it a lowercase string so we can work with it.
|
||||||
int alen = 0;
|
int alen = 0;
|
||||||
|
@ -610,98 +623,91 @@ void processText(int *sock, std::string username, std::string message) {
|
||||||
if ((alen = vstrcontains(message, messages->getMessages("attention"))) > 0) {
|
if ((alen = vstrcontains(message, messages->getMessages("attention"))) > 0) {
|
||||||
// Strip out the attention. We got it.
|
// Strip out the attention. We got it.
|
||||||
message = message.substr(alen+1, message.length());
|
message = message.substr(alen+1, message.length());
|
||||||
msgout = handleCommand(username, message);
|
if (handleCommand(msgout, username, message)) {
|
||||||
if (strlen(msgout) > 1) sendChatMessage(sock, std::string(msgout));
|
printf("info: processed command\n");
|
||||||
else if (strcontains("your commands", message) || strcontains("can you do", message)) {
|
} else if (handlePhrase(msgout, username, message)) {
|
||||||
|
printf("info: processed phrase\n");
|
||||||
char *whisout = new char[255];
|
|
||||||
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, mainConf->getValue("help_whisper_message", "%s, you have been whispered with more information.").c_str(), username.c_str());
|
|
||||||
sendChatMessage(sock, msgout);
|
|
||||||
|
|
||||||
} else if (strcontains("ping test", message)) {
|
|
||||||
|
|
||||||
pingStart = std::chrono::system_clock::now();
|
|
||||||
snprintf(msgout, 255, "Ping!");
|
|
||||||
sendChatMessage(sock, msgout);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (message == "ping") { // We'll accept a simple ping to pong.
|
sendChatMessage(sock, std::string(msgout));
|
||||||
sendChatMessage(sock, mainConf->getValue("pong_msg", "Pong!"));
|
} else if (message == "ping") {
|
||||||
}
|
sprintf(msgout, mainConf->getValue("pong_msg", "Pong!").c_str());
|
||||||
} else {
|
sendChatMessage(sock, std::string(msgout));
|
||||||
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<double, std::milli> ping = pingEnd - pingStart;
|
|
||||||
snprintf(msgout, 255, mainConf->getValue("ping_msg", "Response recieved in %ims.").c_str(), ping.count());
|
|
||||||
sendChatMessage(sock, msgout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void processWhisper(int *sock, std::string username, std::string message) {
|
void processWhisper(int *sock, std::string username, std::string message) {
|
||||||
printf("info: received whisper from %s: \"%s\"\n", username.c_str(), message.c_str());
|
if (debug) printf("debug: received whisper from %s: \"%s\"\n", username.c_str(), message.c_str());
|
||||||
char *msgout = new char[255];
|
char *msgout = new char[255];
|
||||||
message = toLower(message);
|
message = toLower(message);
|
||||||
|
|
||||||
if (message == "ping") {
|
if (message == "ping") {
|
||||||
sendWhisperMessage(sock, username, mainConf->getValue("pong_msg", "Pong!"));
|
sendWhisperMessage(sock, username, mainConf->getValue("pong_msg", "Pong!"));
|
||||||
} else {
|
} else {
|
||||||
msgout = handleCommand(username, message);
|
if (handleCommand(msgout, username, message)) {
|
||||||
if (strlen(msgout) > 0) sendWhisperMessage(sock, username, msgout);
|
printf("info: processed command\n");
|
||||||
else {
|
} else if (handlePhrase(msgout, username, message)) {
|
||||||
|
printf("info: processed phrase\n");
|
||||||
|
} else {
|
||||||
snprintf(msgout, 255, messages->getMessage("unknown").c_str());
|
snprintf(msgout, 255, messages->getMessage("unknown").c_str());
|
||||||
sendWhisperMessage(sock, username, msgout);
|
|
||||||
}
|
}
|
||||||
|
sendWhisperMessage(sock, username, msgout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendChatMessage(int *sock, std::string msg) {
|
void sendChatMessage(int *sock, std::string msg) {
|
||||||
if (msg.length() > 0) {
|
if (msg.length() > 0) {
|
||||||
unsigned char msgout[255] = {0};
|
unsigned char msgout[255] = {0};
|
||||||
int msglen = msg.length();
|
for (size_t i = 0; i < msg.size(); i += 226) {
|
||||||
int k = 1;
|
const std::string line = msg.substr(i, 226);
|
||||||
msgout[k++] = 1;
|
int k = 1;
|
||||||
msgout[k++] = CMD_CHATMSG;
|
msgout[k++] = 1;
|
||||||
msgout[k++] = 0; bufout[k++] = 0;
|
msgout[k++] = CMD_CHATMSG;
|
||||||
msgout[k++] = msglen;
|
msgout[k++] = 0; bufout[k++] = 0;
|
||||||
for(int l = 0; l < msglen; l++)
|
uint8_t msglen = line.length();
|
||||||
msgout[k++] = msg[l];
|
msgout[k++] = msglen;
|
||||||
msgout[k] = 0;
|
for(int l = 0; l < msglen; l++)
|
||||||
msgout[0] = k;
|
msgout[k++] = line[l];
|
||||||
wsend(&roomsock, msgout, 0);
|
msgout[k] = 0;
|
||||||
|
msgout[0] = k;
|
||||||
|
if(debug) printf("debug: sending text \"%s\"\n", line.c_str());
|
||||||
|
unsigned char bufmsg[255];
|
||||||
|
for(int l = 0; l < sizeof(msgout); l++)
|
||||||
|
bufmsg[l] = msgout[l];
|
||||||
|
qsend(sock, bufmsg, true);
|
||||||
|
memset(&msgout[0], 0, sizeof(msgout));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendWhisperMessage(int *sock, std::string to, std::string msg) {
|
void sendWhisperMessage(int *sock, std::string to, std::string msg) {
|
||||||
if (msg.length() > 0 && to.length() > 0) {
|
if (msg.length() > 0 && to.length() > 0) {
|
||||||
whisper_repeat:
|
|
||||||
unsigned char msgout[255] = {0};
|
unsigned char msgout[255] = {0};
|
||||||
int k = 1;
|
for (size_t i = 0; i < msg.size(); i += 226) {
|
||||||
msgout[k++] = 0;
|
const std::string line = msg.substr(i, 226);
|
||||||
msgout[k++] = to.length();
|
int k = 1;
|
||||||
for(int l = 0; l < to.length(); l++)
|
msgout[k++] = 0;
|
||||||
msgout[k++] = to[l];
|
msgout[k++] = to.length();
|
||||||
msgout[k++] = CMD_WHISPER;
|
for(int l = 0; l < to.length(); l++)
|
||||||
msgout[k++] = 0; bufout[k++] = 0;
|
msgout[k++] = to[l];
|
||||||
int msglen = std::min((int)msg.length(), 226);
|
msgout[k++] = CMD_WHISPER;
|
||||||
msgout[k++] = msglen;
|
msgout[k++] = 0; bufout[k++] = 0;
|
||||||
for(int l = 0; l < msglen; l++)
|
uint8_t msglen = line.length();
|
||||||
msgout[k++] = msg[l];
|
msgout[k++] = msglen;
|
||||||
msgout[k] = 0;
|
for(int l = 0; l < msglen; l++)
|
||||||
msgout[0] = k;
|
msgout[k++] = line[l];
|
||||||
wsend(&roomsock, msgout, 0);
|
msgout[k] = 0;
|
||||||
// Check if the length is higher.
|
msgout[0] = k;
|
||||||
if (msg.length() > 226) {
|
if(debug) printf("debug: sending whisper \"%s\"\n", line.c_str());
|
||||||
msg = msg.substr(226, -1);
|
qsend(sock, *(&msgout), true);
|
||||||
goto whisper_repeat;
|
memset(&msgout[0], 0, sizeof(msgout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int wsend(int *sock, unsigned char str[], int flags) {
|
void qsend(int *sock, unsigned char str[], bool queue) {
|
||||||
if (debug) printf("debug: sending new packet of type %i and length %i.\n", str[2], str[0]);
|
if (debug) printf("debug: queuing packet type %i with length %i.\n", str[2], str[0]);
|
||||||
return send(*sock, str, str[0], flags);
|
QueuedPacket* qp = new QueuedPacket(sock, str);
|
||||||
|
if (queue) bufferQueue.push_back(*qp);
|
||||||
|
else qp->flush(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
#ifndef STRUTILS_H
|
|
||||||
#define STRUTILS_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <vector>
|
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
template <typename Out>
|
|
||||||
void split(const std::string &s, char delim, Out result) {
|
|
||||||
std::istringstream iss(s);
|
|
||||||
std::string item;
|
|
||||||
while (std::getline(iss, item, delim)) {
|
|
||||||
*result++ = item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> split(const std::string &s, char delim) {
|
|
||||||
std::vector<std::string> elems;
|
|
||||||
split(s, delim, std::back_inserter(elems));
|
|
||||||
return elems;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
84
src/utils.h
Normal file
84
src/utils.h
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#ifndef UTILS_H
|
||||||
|
#define UTILS_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <iterator>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
template <typename Out>
|
||||||
|
void split(const std::string &s, char delim, Out result) {
|
||||||
|
std::istringstream iss(s);
|
||||||
|
std::string item;
|
||||||
|
while (std::getline(iss, item, delim)) {
|
||||||
|
*result++ = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split(const std::string &s, char delim) {
|
||||||
|
std::vector<std::string> elems;
|
||||||
|
split(s, delim, std::back_inserter(elems));
|
||||||
|
return elems;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool strcontains(std::string needle, std::string haystack) {
|
||||||
|
bool found = haystack.find(needle) != std::string::npos;
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfind(std::vector<std::string> v, std::string i) {
|
||||||
|
return std::find(v.begin(), v.end(), i) != v.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
int vstrcontains(std::string needle, std::vector<std::string> haystack) {
|
||||||
|
for (std::string str : haystack) {
|
||||||
|
if (needle.rfind(str, 0) == 0) return str.length();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getValueOfIncludedName(std::map<std::string, std::string> list, std::string input) {
|
||||||
|
for (auto v : list) {
|
||||||
|
if (strcontains(v.first, input)) return v.second;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string strcombine(std::vector<std::string> args, int start, int end, char pad) {
|
||||||
|
std::string output = args[start];
|
||||||
|
for (int c = start+1; c < end; c++) {
|
||||||
|
output+=(pad+args[c]);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* toLower(char* str) {
|
||||||
|
for(int i = 0; str[i]; i++){
|
||||||
|
str[i] = std::tolower(str[i]);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string toLower(std::string str) {
|
||||||
|
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c){ return std::tolower(c); });
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* trim(char *str) {
|
||||||
|
char *end;
|
||||||
|
while(isspace(*str))
|
||||||
|
str++;
|
||||||
|
if(*str == 0)
|
||||||
|
return str;
|
||||||
|
end = str + strnlen(str, 128) - 1;
|
||||||
|
while(end > str && isspace(*end))
|
||||||
|
end--;
|
||||||
|
*(end+1) = '\0';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user