WorldsTerminal/src/main.cpp

776 lines
22 KiB
C++
Raw Normal View History

2023-09-22 17:28:35 -04:00
#include <map>
#include <thread>
#include <chrono>
#include <cstdlib>
#include <iostream>
2023-09-22 23:56:07 -04:00
#include <fstream>
2023-09-22 17:28:35 -04:00
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <curses.h>
#include <form.h>
#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;
2023-09-22 23:56:07 -04:00
std::cout << "Username: "; std::cin >> login_username;
2023-09-22 17:28:35 -04:00
initscr();
cbreak();
noecho();
refresh();
printf("*Password: ");
2023-09-22 23:56:07 -04:00
std::cin >> login_password;
2023-09-22 17:28:35 -04:00
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.
2023-09-22 23:56:07 -04:00
std::ifstream srcFile;
int srcLine = -1;
2023-09-22 17:28:35 -04:00
int msgoff = 1;
2023-09-22 23:56:07 -04:00
ccmd_parse:
2023-09-22 17:28:35 -04:00
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: ");
2023-09-22 23:56:07 -04:00
wprintw(wlog, "\n* .h Show this");
2023-09-22 17:28:35 -04:00
wprintw(wlog, "\n* .help");
2023-09-22 23:56:07 -04:00
wprintw(wlog, "\n* .login <username> <password> Login as a user");
wprintw(wlog, "\n* .source <file> Run commands from a text file");
wprintw(wlog, "\n* .f <add|del|list> [user] Modify friends list");
wprintw(wlog, "\n* .friends <add|del|list> [user]");
wprintw(wlog, "\n* .mute <add|del|list> [user] Mute users");
wprintw(wlog, "\n* .w <user> <msg> Whisper a message to a user");
2023-09-22 17:28:35 -04:00
wprintw(wlog, "\n* .whisper <user> <msg>");
wprintw(wlog, "\n* .avatar <URI> Change avatar");
2023-09-22 23:56:07 -04:00
wprintw(wlog, "\n* .teleport <x> <y> <z> <rot> [<world>#<room>] Teleport to coordinates");
2023-09-22 17:28:35 -04:00
wprintw(wlog, "\n* .dimension <text> Change dimension");
wprintw(wlog, "\n* .list Show room users");
wprintw(wlog, "\n* .clear Clear chat log");
2023-09-22 23:56:07 -04:00
wprintw(wlog, "\n* .logout Logs out of current user");
2023-09-22 17:28:35 -04:00
wprintw(wlog, "\n* .q Quit");
2023-09-22 23:56:07 -04:00
} 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) {
2023-09-22 17:28:35 -04:00
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 <USER> <MSG>"); 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);
2023-09-22 23:56:07 -04:00
} else if (strcmp(cmd, "f") == 0 || strcmp(cmd, "friends") == 0) {
char subcmd[4] = {0}; j = 0;
2023-09-22 17:28:35 -04:00
while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) {
2023-09-22 23:56:07 -04:00
subcmd[j++] = s;
2023-09-22 17:28:35 -04:00
}
2023-09-22 23:56:07 -04:00
subcmd[j++] = 0;
2023-09-22 17:28:35 -04:00
2023-09-22 23:56:07 -04:00
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<char*>::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<char*>::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<char*>::iterator v = friends.begin(); v != friends.end(); ++v)
wprintw(wlog, "%s %s", v==friends.begin()?",":"", *v);
} else {
wprintw(wlog, "\n.friend <add|del|list> [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<char*>::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<char*>::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<char*>::iterator v = mutes.begin(); v != mutes.end(); ++v)
wprintw(wlog, "%s %s", v==mutes.begin()?",":"", *v);
} else {
wprintw(wlog, "\n.mute <add|del|list> [user]");
}
2023-09-22 17:28:35 -04:00
} 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 <URI>"); 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 <TEXT>"); 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) {
2023-09-22 23:56:07 -04:00
bool _f = false;
wprintw(wlog, "\n*Users in room:");
2023-09-22 17:28:35 -04:00
for (const auto& [key, value] : objects) {
2023-09-22 23:56:07 -04:00
wprintw(wlog, "%s %s", _f?",":"", value.name);
_f=true;
2023-09-22 17:28:35 -04:00
}
} else if (strcmp(cmd, "q") == 0) {
goto quit;
} else {
wprintw(wlog, "\n*Unknown command: \"%s\"", cmd);
}
2023-09-22 23:56:07 -04:00
if (srcLine >= 0 && srcFile.getline(inmsg, 255)) {
srcLine++;
wprintw(wlog, "\n#%s", inmsg);
msgoff = 0;
goto ccmd_parse;
} else {
srcLine = -1;
srcFile.close();
}
2023-09-22 17:28:35 -04:00
} 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);
2023-09-22 23:56:07 -04:00
sessInit(sock_fd, login_username, login_password);
2023-09-22 17:28:35 -04:00
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);
2023-09-22 23:56:07 -04:00
sessInit(sock_fd, login_username, login_password);
2023-09-22 17:28:35 -04:00
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) {
2023-09-22 23:56:07 -04:00
bool muted = false;
2023-09-22 17:28:35 -04:00
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;
2023-09-22 23:56:07 -04:00
for (std::vector<char*>::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);
}
2023-09-22 17:28:35 -04:00
} else if (bufin[p+2] == CMD_WHISPER && bufin[p+1] == 0x01) {
2023-09-22 23:56:07 -04:00
int muted = false;
2023-09-22 17:28:35 -04:00
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;
2023-09-22 23:56:07 -04:00
for (std::vector<char*>::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);
}
2023-09-22 17:28:35 -04:00
} 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");
} 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));
}
}
2023-09-22 23:56:07 -04:00
void sessInit(int sock_fd, char* name, char* pass) {
2023-09-22 17:28:35 -04:00
unsigned char bufout[BUFFERSIZE] = {0};
bufout[1] = 0x01;
bufout[2] = CMD_SESSINIT;
int l = 3;
// Username
bufout[l++] = 2;
2023-09-22 23:56:07 -04:00
bufout[l++] = strlen(name);
for (int c = 0; c < strlen(name); c++)
bufout[l++] = name[c];
2023-09-22 17:28:35 -04:00
// Password
bufout[l++] = 6;
2023-09-22 23:56:07 -04:00
bufout[l++] = strlen(pass);
for (int c = 0; c < strlen(pass); c++)
bufout[l++] = pass[c];
2023-09-22 17:28:35 -04:00
// 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<int, char*> 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);
}