commit 9e0e9ad789f55705ad673e08ac01680fa3360fcc Author: Wirlaburla Date: Fri Sep 22 16:28:35 2023 -0500 Initial release diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..59f05c6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +nbproject/ +build/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..59ed08a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.5) +project(worldsterm) +SET(CMAKE_CXX_STANDARD 17) +SET(CMAKE_CXX_STANDARD_REQUIRED True) +SET(CMAKE_CXX_FLAGS "-O3") +include_directories(${CMAKE_BINARY_DIR}) +find_package(Curses REQUIRED) +include_directories(${CURSES_INCLUDE_DIRS}) +add_subdirectory(src) +install(TARGETS worldsterm RUNTIME DESTINATION bin) diff --git a/README.md b/README.md new file mode 100644 index 0000000..9dc20c6 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Worlds Terminal +A simple terminal-based chat for Worlds.com, without the 3D. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..1136ce2 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(worldsterm + main.cpp +) +target_link_libraries(worldsterm ${CURSES_LIBRARIES}) diff --git a/src/client.h b/src/client.h new file mode 100644 index 0000000..dc87397 --- /dev/null +++ b/src/client.h @@ -0,0 +1,52 @@ +#ifndef H_CLIENT +#define H_CLIENT +#include "drone.h" + +#define SERVERADDR "209.240.84.122" +#define AUTOSERVER 6650 +#define ROOMSERVER 5672 +// This should be your MTU, but I don't have a method for auto-detecting that. +#define BUFFERSIZE 1440 + +WINDOW* wlog; +WINDOW* wform; +FORM *form; +FIELD *entries[1]; + +char* protocol = "24"; +char* version = "0000000000"; +char* default_avatar = "avatar:pengo.mov"; +char* avatars = "1024"; +char* room = "GroundZero#Reception"; +char* dimension = "dimension-1"; +uint16_t roomID = 1; +char username[128]; +char 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 = {}; + +static char* trim(char *str); +char* zero(int size); +unsigned char* uzero(int size); +void autoInit(int sock_fd); +void roomInit(int sock_fd); +void reciever(int sock_fd); +void sessInit(int sock_fd, char* username, char* password); +void sessExit(int sock_fd); +void readPropertyList(unsigned char* in); +void setAvatar(int sock_fd, char* avatar); +void roomIDReq(int sock_fd, char* room); +void teleport(int sock_fd, int x, int y, int z, int rot); +char* dimAdd(char* room); +void userEnter(char id); +void userExit(char id); +int wsend(int sock_fd, unsigned char str[], int flags); + +#endif \ No newline at end of file diff --git a/src/cmds.h b/src/cmds.h new file mode 100644 index 0000000..9e23bf7 --- /dev/null +++ b/src/cmds.h @@ -0,0 +1,34 @@ +#ifndef H_CMDS +#define H_CMDS + +#define CMD_LONGLOC 1 +#define CMD_STATE 2 +#define CMD_PROP 3 +#define CMD_SHORTLOC 4 +#define CMD_ROOMCHANGE 5 +#define CMD_SESSINIT 6 +#define CMD_SESSEXIT 7 +#define CMD_APPINIT 9 +#define CMD_PROPREQ 10 +#define CMD_ACTOR_DISAPPR 11 +#define CMD_ACTOR_APPR 12 +#define CMD_REGOBJID 13 +#define CMD_CHATMSG 14 +#define CMD_PROPSET 15 +#define CMD_PROPUPD 16 +#define CMD_WHISPER 17 +#define CMD_TELEPORT 18 +#define CMD_ROOMIDREQ 20 +#define CMD_ROOMID 21 +#define CMD_SUBSCRIBE 22 +#define CMD_UNSUBSCRIBE 23 +#define CMD_SUBDIST 24 +#define CMD_REDIRECT 25 +#define CMD_REDIRID 26 +#define CMD_FINGREQ 27 +#define CMD_FINGREP 28 +#define CMD_BUDDYUPD 29 +#define CMD_BUDDYNTF 30 +#define CMD_CHANNEL 31 + +#endif diff --git a/src/drone.h b/src/drone.h new file mode 100644 index 0000000..332f76a --- /dev/null +++ b/src/drone.h @@ -0,0 +1,15 @@ +#ifndef H_DRONE +#define H_DRONE + +class Drone { +public: + bool droneActive = false; + char* name = new char[24]; + + Drone() { }; + Drone(char* &_name) : name{ _name } { }; + bool operator != (Drone &d) { return strcmp(this->name, d.name) != 0; }; + Drone operator = (Drone *d) { return *d; }; +}; + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..57a243d --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,635 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "client.h" +#include "var_error.h" +#include "cmds.h" + +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; +} + +int main(int argc, char const* argv[]) { + unsigned char bufout[BUFFERSIZE] = {0}; + int status, valread, autosock, roomsock; + struct sockaddr_in serv_addr; + + std::cout << "Username: "; std::cin >> username; + + initscr(); + cbreak(); + noecho(); + refresh(); + + printf("*Password: "); + std::cin >> password; + + wlog = newwin(LINES-1, COLS, 0, 0); + wmove(wlog, LINES-2, 0); + scrollok(wlog, true); + wprintw(wlog, "\n*Connecting to Worlds.com. Enter '.help' for a list of commands."); + + wform = newwin(1, COLS, LINES-1, 0); + wmove(wform, 0, 0); + scrollok(wform, true); + keypad(wform, TRUE); + + entries[0] = new_field(1, COLS, LINES-1, 0, 0, 0); + set_field_buffer(entries[0], 0, ""); + set_field_opts(entries[0], O_VISIBLE | O_PUBLIC | O_EDIT | O_ACTIVE); + field_opts_off(entries[0], O_AUTOSKIP); + + form = new_form(entries); + set_form_win(form, wform); + post_form(form); + + set_current_field(form, entries[0]); + + if ((autosock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + perror("Socket creation error."); + + serv_addr.sin_family = AF_INET; + inet_pton(AF_INET, SERVERADDR, &serv_addr.sin_addr); + serv_addr.sin_port = htons(AUTOSERVER); + + if ((status = connect(autosock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) < 0) + perror("AutoServ connection failed."); + + // Initialize connection. + std::thread aRecv_t(reciever, autosock); + autoInit(autosock); + + serv_addr.sin_port = htons(ROOMSERVER); + close(autosock); + if ((roomsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + perror("Socket creation error."); + + if ((status = connect(roomsock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) < 0) + perror("RoomServ connection failed"); + + std::thread rRecv_t(reciever, roomsock); + std::thread rInit_t(roomInit, roomsock); + + int key = 0; + while ((key = wgetch(wform))) { + memset(&(bufout[0]), 0, sizeof(bufout)); + if (key == 10) { + form_driver(form, REQ_VALIDATION); + char* inmsg = trim(field_buffer(entries[0], 0)); + int msglen = 0; + if ((msglen = strlen(inmsg)) > 0) { + if (inmsg[0] == '.' && msglen > 1) { // Starting a command. + int msgoff = 1; + char cmd[16] = {0}; char s; int j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + cmd[j++] = s; + } + 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* .help"); + 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* .dimension Change dimension"); + wprintw(wlog, "\n* .list Show room users"); + wprintw(wlog, "\n* .clear Clear chat log"); + wprintw(wlog, "\n* .q Quit"); + } else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "whisper") == 0) { + int k = 1; + bufout[k++] = 0; + + char username[32] = {0}; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + username[j++] = s; + } + username[j++] = 0; + char message[255] = {0}; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x00) { + message[j++] = s; + } + message[j++] = 0; + if (strlen(username) == 0 || strlen(message) == 0) { wprintw(wlog, "\n*.whisper "); continue; } + + bufout[k++] = strlen(username); + for(int l = 0; l < strlen(username); l++) + bufout[k++] = username[l]; + bufout[k++] = CMD_WHISPER; + bufout[k++] = 0; bufout[k++] = 0; + bufout[k++] = strlen(message); + for(int l = 0; l < strlen(message); l++) + bufout[k++] = message[l]; + bufout[k] = 0; + 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; } + + 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); + } else if (strcmp(cmd, "avatar") == 0) { + char avatar[32] = {0}; int j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + avatar[j++] = s; + } + avatar[j] = 0; + if (strlen(avatar) == 0) { wprintw(wlog, "\n*.avatar "); continue; } + wprintw(wlog, "\n*Avatar set to: %s", avatar); + setAvatar(roomsock, avatar); + } else if (strcmp(cmd, "teleport") == 0) { + char _x[6] = {0}; int j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + _x[j++] = s; + } + _x[j] = 0; + xPos = atoi(_x); + + char _y[6] = {0}; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + _y[j++] = s; + } + _y[j] = 0; + yPos = atoi(_y); + + char _z[6] = {0}; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + _z[j++] = s; + } + _z[j] = 0; + zPos = atoi(_z); + + char _r[6] = {0}; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + _r[j++] = s; + } + _r[j] = 0; + rot = atoi(_r); + + + char _room[32] = {0}; j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x00) { + _room[j++] = s; + } + _room[j] = 0; + if (strlen(_room) == 0) { + teleport(roomsock, xPos, yPos, zPos, rot); + wprintw(wlog, "\n*Teleported to [%u,%u,%u,%u]", xPos, yPos, zPos, rot); + } else { + room = _room; + wprintw(wlog, "\n*Teleporting to %s [%u,%u,%u,%u]", room, xPos, yPos, zPos, rot); + roomIDReq(roomsock, room); + } + } else if (strcmp(cmd, "dimension") == 0) { + char dim[32] = {0}; int j = 0; + while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) { + dim[j++] = s; + } + dim[j] = 0; + if (strlen(dim) == 0) { wprintw(wlog, "\n*.dimension "); continue; } + wprintw(wlog, "\n*Changing dimension: %s", dim); + dimension = dim; + roomIDReq(roomsock, room); + } else if (strcmp(cmd, "clear") == 0) { + wclear(wlog); + wmove(wlog, LINES-2, 0); + } else if (strcmp(cmd, "list") == 0) { + wprintw(wlog, "\n*Users in room: "); + for (const auto& [key, value] : objects) { + wprintw(wlog, "%s, ", value.name); + } + wprintw(wlog, "and you."); + } else if (strcmp(cmd, "q") == 0) { + goto quit; + } else { + wprintw(wlog, "\n*Unknown command: \"%s\"", cmd); + } + } else { + int k = 1; + bufout[k++] = 1; + bufout[k++] = CMD_CHATMSG; + bufout[k++] = 0; bufout[k++] = 0; + bufout[k++] = msglen; + for(int l = 0; l < msglen; l++) + bufout[k++] = inmsg[l]; + bufout[k] = 0; + bufout[0] = k; + wsend(roomsock, bufout, 0); + } + bufout[0] = 0; + set_field_buffer(entries[0], 0, ""); + } + } else if (key == KEY_LEFT) { + form_driver(form, REQ_PREV_CHAR); + } else if (key == KEY_RIGHT) { + form_driver(form, REQ_NEXT_CHAR); + } else if (key == KEY_BACKSPACE || key == 127) { + form_driver(form, REQ_DEL_PREV); + } else if (key == KEY_DC) { + form_driver(form, REQ_DEL_CHAR); + } else if (key == KEY_HOME) { + form_driver(form, REQ_BEG_LINE); + } else if (key == KEY_END) { + form_driver(form, REQ_END_LINE); + } else { + form_driver(form, key); + } + pos_form_cursor(form); + wrefresh(wform); + wrefresh(wlog); + refresh(); + } + quit: + unpost_form(form); + free_form(form); + free_field(entries[0]); + endwin(); + close(roomsock); + return 0; +} + +void autoInit(int sock_fd) { + wsend(sock_fd, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 0); + sleep(1); + sessInit(sock_fd, username, password); + sleep(1); + setAvatar(sock_fd, default_avatar); + roomIDReq(sock_fd, room); + + pos_form_cursor(form); + wrefresh(wform); + wrefresh(wlog); + refresh(); +} + +void roomInit(int sock_fd) { + wsend(sock_fd, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 0); + sleep(1); + sessInit(sock_fd, username, password); + setAvatar(sock_fd, default_avatar); + while (true) { + teleport(sock_fd, xPos, yPos, zPos, rot); + sleep(15); + } +} + +void reciever(int sock_fd) { + unsigned char bufin[BUFFERSIZE] = {}; + unsigned char bufout[BUFFERSIZE] = {}; + while (read(sock_fd, bufin, sizeof(bufin)) > 0) { + int p = 0; + more_in_buffer: + int buflen = bufin[p]; + if (buflen == 0x00) continue; + memset(&(bufout[0]), 0, sizeof(bufout)); + if (bufin[p+2] == CMD_PROPUPD && bufin[p+1] == 0xff) { + readPropertyList(bufin); + } else if (bufin[p+2] == CMD_CHATMSG && bufin[p+1] == 0x01) { + char *username = new char[16]; + char *message = new char[250]; + int offs = p+3; + offs++; // Ignore empty byte + 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); + } else if (bufin[p+2] == CMD_WHISPER && bufin[p+1] == 0x01) { + char *username = new char[16]; + char *message; + int offs = p+3; + offs++; // Ignore empty byte + 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); + } else if (bufin[p+2] == CMD_ACTOR_DISAPPR && bufin[p+1] == 0xfe) { + for (int t = 3; t < buflen; t++) { + userExit(bufin[p+t]); + } + } else if (bufin[p+2] == CMD_ACTOR_APPR && bufin[p+1] == 0xfe) { + for (int t = 3; t < buflen; t+=11) { + userEnter(bufin[p+t]); + } + } else if (bufin[p+2] == CMD_REGOBJID && bufin[p+1] == 0xff) { + char *longID = new char[16]; + int shortID; + int offs = p+3; + int long_len = bufin[offs++]; + memcpy(longID, &bufin[offs], long_len); + longID[long_len] = 0; + offs+=long_len; + shortID = bufin[offs++]; + if (longID != NULL || strlen(longID) > 0) { + Drone newDrone = *(new Drone(longID)); + objects[shortID] = newDrone; + } + } else if (bufin[p+2] == CMD_SESSEXIT && bufin[p+1] == 0x01) { + break; + } else if ((bufin[p+2] == CMD_ROOMID || bufin[p+2] == 0x1A) && bufin[p+1] == 0x01) { + char *longID = new char[255]; + int shortID; + int offs = p+3; + int long_len = bufin[offs++]; + memcpy(longID, &bufin[offs], long_len); + longID[long_len+1] = 0; + offs+=long_len; + shortID = ((uint16_t)bufin[offs++] << 8) | bufin[offs++]; + rooms[longID] = shortID; + roomID = shortID; + wprintw(wlog, "\n*Joining room %s", longID); + for (const auto& [key, value] : objects) { + objects.erase((char)key); + } + teleport(sock_fd, xPos, yPos, zPos, rot); + } else if (bufin[p+2] == CMD_BUDDYNTF && bufin[p+1] == 0x01) { + char* username = new char[24]; + int offs = p+3; + int username_len = bufin[offs++]; + memcpy(username, &bufin[offs], username_len); + username[username_len] = 0; + 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++]; + int exitType = bufin[offs++]; + int entryType = bufin[offs++]; + int roomid = ((uint16_t)bufin[offs++] << 8) | bufin[offs++]; + if (exitType != 0) { + // De-register ObjID and say user left. + userExit(objID); + } else { + if (entryType == 0) { + userExit(objID); + } else { + userEnter(objID); + } + } + } else { + //wprintw(wlog, "\n*LEN[%i] OID[%i] TYPE[%02X] OFF[%i]", bufin[p], bufin[p+1], bufin[p+2], p); + } + pos_form_cursor(form); + wrefresh(wform); + wrefresh(wlog); + refresh(); + if (buflen < sizeof(bufin) && bufin[bufin[p]] != 0x00) { + p += bufin[p]; + goto more_in_buffer; + } + memset(&(bufin[0]), 0, sizeof(bufin)); + } +} + +void sessInit(int sock_fd, char* username, char* password) { + unsigned char bufout[BUFFERSIZE] = {0}; + bufout[1] = 0x01; + bufout[2] = CMD_SESSINIT; + int l = 3; + + // Username + bufout[l++] = 2; + bufout[l++] = strlen(username); + for (int c = 0; c < strlen(username); c++) + bufout[l++] = username[c]; + + // Password + bufout[l++] = 6; + bufout[l++] = strlen(password); + for (int c = 0; c < strlen(password); c++) + bufout[l++] = password[c]; + + // Protocol + bufout[l++] = 3; + bufout[l++] = strlen(protocol); + for (int c = 0; c < strlen(protocol); c++) + bufout[l++] = protocol[c]; + + // Avatars + bufout[l++] = 7; + bufout[l++] = strlen(avatars); + for (int c = 0; c < strlen(avatars); c++) + bufout[l++] = avatars[c]; + + // Version + bufout[l++] = 9; + bufout[l++] = strlen(version); + for (int c = 0; c < strlen(version); c++) + bufout[l++] = version[c]; + + // Version + bufout[l++] = 12; + bufout[l++] = 1; + bufout[l++] = '1'; + + bufout[0] = l; + bufout[l+1] = 0; + wsend(sock_fd, bufout, 0); +} + +void sessExit(int sock_fd) { + unsigned char bufout[BUFFERSIZE] = {0}; + bufout[0] = 0x03; + bufout[1] = 0x01; + bufout[2] = CMD_SESSEXIT; + wsend(sock_fd, bufout, 0); +} + +void constructPropertyList(int type, std::map props, unsigned char* snd) { + snd[1] = 0x01; + snd[2] = type; + int l = 3; + for (const auto& [key, value] : props) { + snd[l++] = key; + snd[l++] = strlen(value); + for (int c = 0; c < strlen(value); c++) + snd[l++] = value[c]; + } + snd[0] = l; + snd[l+1] = 0; +} + +void readPropertyList(unsigned char* in) { + int l {3}; + while (l < in[0]) { + char property[128] = {0}; + int type = in[l++]; + l++; l++; + int len = in[l++]; + memcpy(property, &in[l], len); + property[len]='\0'; + properties[type] = (char*)property; + l+=len; + } +} + +/* +void readPropertyList(unsigned char* in) { + int l {3}; + for (int p = 0; p < in[3]; p++) { + char property[128] = {0}; + int type = in[l++]; + l++; l++; + int len = in[l++]; + memcpy(property, &in[l], len); + property[len]='\0'; + properties[type] = (char*)property; + l+=len; + } +} +*/ + +void setAvatar(int sock_fd, char* avatar) { + unsigned char bufav[BUFFERSIZE] = {0}; + int l = 1; + bufav[l++] = 0x01; + bufav[l++] = CMD_PROPSET; + bufav[l++] = 0x00; + bufav[l++] = 0x05; + bufav[l++] = 0x40; + bufav[l++] = 0x01; + + bufav[l++] = strlen(avatar); + for (int c = 0; c < strlen(avatar); c++) + bufav[l++] = avatar[c]; + + bufav[0] = l; + bufav[l+1] = 0; + wsend(sock_fd, bufav, 0); +} + +void roomIDReq(int sock_fd, char* room) { + char* fullRoom = dimAdd(room); + // Don't do this, rooms with new IDs won't update. + //if (rooms.find(fullRoom) != rooms.end()) { + // roomID = rooms[fullRoom]; + //} else { + unsigned char bufrm[BUFFERSIZE] = {0}; + bufrm[1] = 1; + bufrm[2] = CMD_ROOMIDREQ; + bufrm[3] = strlen(fullRoom); + int x = 4; + for (int z = 0; z < strlen(fullRoom); z++) + bufrm[x++] = fullRoom[z]; + bufrm[x++] = 0; + bufrm[0] = x; + wsend(sock_fd, bufrm, 0); + //} +} + +void teleport(int sock_fd, int x, int y, int z, int rot) { + unsigned char buftp[16] = {0}; + uint8_t _roomID[2]; + uint8_t _x[2]; + uint8_t _y[2]; + uint8_t _z[2]; + uint8_t _rot[2]; + memcpy(_roomID, &roomID, sizeof(_roomID)); + memcpy(_x, &x, sizeof(_x)); + memcpy(_y, &y, sizeof(_y)); + memcpy(_z, &z, sizeof(_z)); + memcpy(_rot, &rot, sizeof(_rot)); + + buftp[0] = 0x0f; + buftp[1] = 0x01; + buftp[2] = CMD_TELEPORT; + buftp[4] = _roomID[0]; buftp[3] = _roomID[1]; + buftp[5] = 0x00; buftp[6] = 0x01; + buftp[8] = _x[0]; buftp[7] = _x[1]; + buftp[10] = _y[0]; buftp[9] = _y[1]; + buftp[12] = _z[0]; buftp[11] = _z[1]; + buftp[14] = _rot[0]; buftp[13] = _rot[1]; + + wsend(sock_fd, buftp, 0); +} + +char* dimAdd(char* room) { + char* output = new char[BUFFERSIZE]; + int l = 0; + for (int s = 0; s < strlen(room); s++) + output[l++] = room[s]; + output[l++] = '<'; + for (int s = 0; s < strlen(dimension); s++) + output[l++] = dimension[s]; + output[l++] = '>'; + output[l++] = 0; + return output; +} + +void userEnter(char id) { + if (!((Drone)objects[id]).droneActive) { + wprintw(wlog, "\n+%s has entered the room.", objects[id].name); + objects[id].droneActive = true; + } +} + +void userExit(char id) { + if (((Drone)objects[id]).droneActive) { + wprintw(wlog, "\n-%s has left the room.", objects[id].name); + objects.erase((char)id); + } +} + +int wsend(int sock_fd, unsigned char str[], int flags) { + return send(sock_fd, str, str[0], flags); +} diff --git a/src/var_error.h b/src/var_error.h new file mode 100644 index 0000000..0a38a2f --- /dev/null +++ b/src/var_error.h @@ -0,0 +1,29 @@ +#ifndef H_VAR_ERROR +#define H_VAR_ERROR + +#define VAR_OK 0 | 200 +#define VAR_BAD_USER 1 +#define VAR_MAX_ORDINARY 2 +#define VAR_MAX_PRIORITY 3 +#define VAR_FATAL 5 +#define VAR_BAD_PROTOCOL 6 +#define VAR_BAD_CLIENTSW 7 +#define VAR_BAD_SERIAL 9 +#define VAR_TAKEN_SERIAL 10 +#define VAR_TAKEN_USER 11 +#define VAR_NO_SUCH_USER 12 +#define VAR_BAD_PASSWORD 13 +#define VAR_BAD_ACCOUNT 14 +#define VAR_NOT_LOGGEDON 15 +#define VAR_BAD_IPADDRESS 16 +#define VAR_LOGGEDON 16 +#define VAR_ROOM_FULL 21 +#define VAR_UNEXPECTED 100 | 101 | 102 | 103 +#define VAR_UNREACHABLE 104 | 105 | 106 | 107 +#define VAR_SHUTTING_DOWN 201 +#define VAR_RECONNECTING 202 +#define VAR_DISCONNECTED 203 +#define VAR_LOST_CONNECTION 204 +#define VAR_SINGLE_USER 205 + +#endif \ No newline at end of file