diff --git a/src/client.h b/src/client.h index dc87397..8182326 100644 --- a/src/client.h +++ b/src/client.h @@ -1,5 +1,6 @@ #ifndef H_CLIENT #define H_CLIENT +#include #include "drone.h" #define SERVERADDR "209.240.84.122" @@ -20,17 +21,21 @@ char* avatars = "1024"; char* room = "GroundZero#Reception"; char* dimension = "dimension-1"; uint16_t roomID = 1; -char username[128]; -char password[128]; + +char login_username[128]; +char login_password[128]; uint16_t xPos = 0; uint16_t yPos = 0; uint16_t zPos = 0; uint16_t rot = 0; -std::map properties = {}; -std::map objects = {}; -std::map rooms = {}; +std::map properties; +std::map objects; +std::map rooms; + +std::vector friends; +std::vector mutes; static char* trim(char *str); char* zero(int size); diff --git a/src/main.cpp b/src/main.cpp index 57a243d..7c82caf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,9 @@ #include -#include #include #include -#include #include #include +#include #include #include #include @@ -36,7 +35,7 @@ int main(int argc, char const* argv[]) { int status, valread, autosock, roomsock; struct sockaddr_in serv_addr; - std::cout << "Username: "; std::cin >> username; + std::cout << "Username: "; std::cin >> login_username; initscr(); cbreak(); @@ -44,7 +43,7 @@ int main(int argc, char const* argv[]) { refresh(); printf("*Password: "); - std::cin >> password; + std::cin >> login_password; wlog = newwin(LINES-1, COLS, 0, 0); wmove(wlog, LINES-2, 0); @@ -101,7 +100,10 @@ int main(int argc, char const* argv[]) { int msglen = 0; if ((msglen = strlen(inmsg)) > 0) { if (inmsg[0] == '.' && msglen > 1) { // Starting a command. + std::ifstream srcFile; + int srcLine = -1; int msgoff = 1; + ccmd_parse: char cmd[16] = {0}; char s; int j = 0; while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { cmd[j++] = s; @@ -109,18 +111,35 @@ int main(int argc, char const* argv[]) { cmd[j++] = 0; if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0) { wprintw(wlog, "\n*Command help: "); - wprintw(wlog, "\n* .h Show this."); + wprintw(wlog, "\n* .h Show this"); wprintw(wlog, "\n* .help"); - wprintw(wlog, "\n* .w Whisper a message to a user."); + wprintw(wlog, "\n* .login Login as a user"); + wprintw(wlog, "\n* .source Run commands from a text file"); + wprintw(wlog, "\n* .f [user] Modify friends list"); + wprintw(wlog, "\n* .friends [user]"); + wprintw(wlog, "\n* .mute [user] Mute users"); + wprintw(wlog, "\n* .w Whisper a message to a user"); wprintw(wlog, "\n* .whisper "); - wprintw(wlog, "\n* .status Watch for user to come online"); wprintw(wlog, "\n* .avatar Change avatar"); - wprintw(wlog, "\n* .teleport [#] Teleport to coordinates."); + wprintw(wlog, "\n* .teleport [#] Teleport to coordinates"); wprintw(wlog, "\n* .dimension Change dimension"); wprintw(wlog, "\n* .list Show room users"); wprintw(wlog, "\n* .clear Clear chat log"); + wprintw(wlog, "\n* .logout Logs out of current user"); wprintw(wlog, "\n* .q Quit"); - } else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "whisper") == 0) { + } else if (strcmp(cmd, "source") == 0) { + char file[32] = {0}; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + file[j++] = s; + } + file[j++] = 0; + srcFile.open(file); + if (srcFile.is_open()) { + wprintw(wlog, "\n*Sourcing from file %s", file); + inmsg = new char[256]; + srcLine = 0; + } + } else if ((strcmp(cmd, "w") == 0 || strcmp(cmd, "whisper") == 0) && srcLine < 0) { int k = 1; bufout[k++] = 0; @@ -148,24 +167,135 @@ int main(int argc, char const* argv[]) { bufout[0] = k; wprintw(wlog, "\n <- [%s] %s", username, message); wsend(roomsock, bufout, 0); - } else if (strcmp(cmd, "status") == 0) { - char username[32] = {0}; int j = 0; - while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { - username[j++] = s; - } - username[j] = 0; - if (strlen(username) == 0) { wprintw(wlog, "\n*.status "); continue; } + } else if (strcmp(cmd, "f") == 0 || strcmp(cmd, "friends") == 0) { - int k = 0; - bufout[k++] = j+5; - bufout[k++] = 0x01; - bufout[k++] = CMD_BUDDYUPD; - bufout[k++] = j; - for(int l = 0; l < j; l++) - bufout[k++] = username[l]; - bufout[k++] = 0x01; - bufout[k] = 0; - wsend(roomsock, bufout, 0); + char subcmd[4] = {0}; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + subcmd[j++] = s; + } + subcmd[j++] = 0; + + if (strcmp(subcmd, "add") == 0) { + char *username = new char[16]; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x00) { + username[j++] = s; + } + username[j] = 0; + + bool already_exists = false; + for (std::vector::iterator v = friends.begin(); v != friends.end(); ++v) + if (strcmp(username, *v) == 0) { + already_exists = true; + break; + } + if (!already_exists) { + friends.push_back(username); + + int k = 0; + bufout[k++] = j+5; + bufout[k++] = 0x01; + bufout[k++] = CMD_BUDDYUPD; + bufout[k++] = j; + for(int l = 0; l < j; l++) + bufout[k++] = username[l]; + bufout[k++] = 0x01; + bufout[k] = 0; + wprintw(wlog, "\n*%s added to friendslist.", username); + wsend(roomsock, bufout, 0); + } else { + wprintw(wlog, "\n*%s is already your friend!", username); + } + } else if (strcmp(subcmd, "del") == 0) { + char *username = new char[16]; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x00) { + username[j++] = s; + } + username[j] = 0; + + bool existed = false; + for (std::vector::iterator v = friends.begin(); v != friends.end(); ++v) + if (strcmp(username, *v) == 0) { + existed = true; + friends.erase(v); + break; + } + + if (existed) { + int k = 0; + bufout[k++] = j+5; + bufout[k++] = 0x01; + bufout[k++] = CMD_BUDDYUPD; + bufout[k++] = j; + for(int l = 0; l < j; l++) + bufout[k++] = username[l]; + bufout[k++] = 0x00; + bufout[k] = 0; + wprintw(wlog, "\n*%s removed from friendslist.", username); + wsend(roomsock, bufout, 0); + } else { + wprintw(wlog, "\n*%s isn't on your friendslist.", username); + } + } else if (strcmp(subcmd, "list") == 0) { + wprintw(wlog, "\n*Friendslist:"); + for (std::vector::iterator v = friends.begin(); v != friends.end(); ++v) + wprintw(wlog, "%s %s", v==friends.begin()?",":"", *v); + } else { + wprintw(wlog, "\n.friend [user]"); + } + } else if (strcmp(cmd, "mute") == 0) { + + char subcmd[4] = {0}; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + subcmd[j++] = s; + } + subcmd[j++] = 0; + + if (strcmp(subcmd, "add") == 0) { + char *username = new char[16]; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x00) { + username[j++] = s; + } + username[j] = 0; + + bool already_exists = false; + for (std::vector::iterator v = mutes.begin(); v != mutes.end(); ++v) + if (strcmp(username, *v) == 0) { + already_exists = true; + break; + } + if (!already_exists) { + mutes.push_back(username); + wprintw(wlog, "\n*%s added to mutelist.", username); + } else { + wprintw(wlog, "\n*%s is already muted.", username); + } + } else if (strcmp(subcmd, "del") == 0) { + char *username = new char[16]; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x00) { + username[j++] = s; + } + username[j] = 0; + + bool existed = false; + for (std::vector::iterator v = mutes.begin(); v != mutes.end(); ++v) + if (strcmp(username, *v) == 0) { + existed = true; + mutes.erase(v); + break; + } + + if (existed) { + wprintw(wlog, "\n*%s removed from mutelist.", username); + } else { + wprintw(wlog, "\n*%s isn't muted.", username); + } + } else if (strcmp(subcmd, "list") == 0) { + wprintw(wlog, "\n*Mutelist:"); + for (std::vector::iterator v = mutes.begin(); v != mutes.end(); ++v) + wprintw(wlog, "%s %s", v==mutes.begin()?",":"", *v); + } else { + wprintw(wlog, "\n.mute [user]"); + } } else if (strcmp(cmd, "avatar") == 0) { char avatar[32] = {0}; int j = 0; while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { @@ -232,16 +362,27 @@ int main(int argc, char const* argv[]) { wclear(wlog); wmove(wlog, LINES-2, 0); } else if (strcmp(cmd, "list") == 0) { - wprintw(wlog, "\n*Users in room: "); + bool _f = false; + wprintw(wlog, "\n*Users in room:"); for (const auto& [key, value] : objects) { - wprintw(wlog, "%s, ", value.name); + wprintw(wlog, "%s %s", _f?",":"", value.name); + _f=true; } - wprintw(wlog, "and you."); } else if (strcmp(cmd, "q") == 0) { goto quit; } else { wprintw(wlog, "\n*Unknown command: \"%s\"", cmd); } + + if (srcLine >= 0 && srcFile.getline(inmsg, 255)) { + srcLine++; + wprintw(wlog, "\n#%s", inmsg); + msgoff = 0; + goto ccmd_parse; + } else { + srcLine = -1; + srcFile.close(); + } } else { int k = 1; bufout[k++] = 1; @@ -289,7 +430,7 @@ int main(int argc, char const* argv[]) { void autoInit(int sock_fd) { wsend(sock_fd, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 0); sleep(1); - sessInit(sock_fd, username, password); + sessInit(sock_fd, login_username, login_password); sleep(1); setAvatar(sock_fd, default_avatar); roomIDReq(sock_fd, room); @@ -303,7 +444,7 @@ void autoInit(int sock_fd) { void roomInit(int sock_fd) { wsend(sock_fd, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 0); sleep(1); - sessInit(sock_fd, username, password); + sessInit(sock_fd, login_username, login_password); setAvatar(sock_fd, default_avatar); while (true) { teleport(sock_fd, xPos, yPos, zPos, rot); @@ -323,6 +464,7 @@ void reciever(int sock_fd) { if (bufin[p+2] == CMD_PROPUPD && bufin[p+1] == 0xff) { readPropertyList(bufin); } else if (bufin[p+2] == CMD_CHATMSG && bufin[p+1] == 0x01) { + bool muted = false; char *username = new char[16]; char *message = new char[250]; int offs = p+3; @@ -330,14 +472,19 @@ void reciever(int sock_fd) { int username_len = bufin[offs++]; memcpy(username, &bufin[offs], username_len); username[username_len+1] = 0; - offs+=username_len; - int message_len = bufin[offs++]; - memcpy(message, &bufin[offs++], message_len); - message[message_len+1] = 0; - if (!(message[0] == '&' && message[1] == '|' && message[2] == '+')) - wprintw(wlog, "\n %s> %s", username, message); - wrefresh(wlog); + for (std::vector::iterator v = mutes.begin(); v != mutes.end(); ++v) + if (strcmp(username, *v) == 0) { muted = true; break; } + if (!muted) { + offs+=username_len; + int message_len = bufin[offs++]; + memcpy(message, &bufin[offs++], message_len); + message[message_len+1] = 0; + if (!(message[0] == '&' && message[1] == '|' && message[2] == '+')) + wprintw(wlog, "\n %s> %s", username, message); + wrefresh(wlog); + } } else if (bufin[p+2] == CMD_WHISPER && bufin[p+1] == 0x01) { + int muted = false; char *username = new char[16]; char *message; int offs = p+3; @@ -345,12 +492,16 @@ void reciever(int sock_fd) { int username_len = bufin[offs++]; memcpy(username, &bufin[offs], username_len); username[username_len] = 0; - offs+=username_len; - message = new char[250-username_len]; - int message_len = bufin[offs++]; - memcpy(message, &bufin[offs++], message_len); - message[message_len] = 0; - wprintw(wlog, "\n [%s] -> %s", username, message); + for (std::vector::iterator v = mutes.begin(); v != mutes.end(); ++v) + if (strcmp(username, *v) == 0) { muted = true; break; } + if (!muted) { + offs+=username_len; + message = new char[250-username_len]; + int message_len = bufin[offs++]; + memcpy(message, &bufin[offs++], message_len); + message[message_len] = 0; + wprintw(wlog, "\n [%s] -> %s", username, message); + } } else if (bufin[p+2] == CMD_ACTOR_DISAPPR && bufin[p+1] == 0xfe) { for (int t = 3; t < buflen; t++) { userExit(bufin[p+t]); @@ -399,17 +550,6 @@ void reciever(int sock_fd) { offs+=username_len; bool status = (bufin[offs++] == 1); wprintw(wlog, "\n*%s is %s", username, status?"ONLINE":"OFFLINE"); - - int k = 0; - bufout[k++] = username_len+5; - bufout[k++] = 0x01; - bufout[k++] = 0x1D; - bufout[k++] = username_len; - for(int l = 0; l < username_len; l++) - bufout[k++] = username[l]; - bufout[k++] = 0x00; - bufout[k] = 0; - wsend(sock_fd, bufout, 0); } else if (bufin[p+2] == CMD_TELEPORT && bufin[p+1] == 0xfe) { int offs = p+3; int objID = bufin[offs++]; @@ -441,7 +581,7 @@ void reciever(int sock_fd) { } } -void sessInit(int sock_fd, char* username, char* password) { +void sessInit(int sock_fd, char* name, char* pass) { unsigned char bufout[BUFFERSIZE] = {0}; bufout[1] = 0x01; bufout[2] = CMD_SESSINIT; @@ -449,15 +589,15 @@ void sessInit(int sock_fd, char* username, char* password) { // Username bufout[l++] = 2; - bufout[l++] = strlen(username); - for (int c = 0; c < strlen(username); c++) - bufout[l++] = username[c]; + bufout[l++] = strlen(name); + for (int c = 0; c < strlen(name); c++) + bufout[l++] = name[c]; // Password bufout[l++] = 6; - bufout[l++] = strlen(password); - for (int c = 0; c < strlen(password); c++) - bufout[l++] = password[c]; + bufout[l++] = strlen(pass); + for (int c = 0; c < strlen(pass); c++) + bufout[l++] = pass[c]; // Protocol bufout[l++] = 3;