Initial release
This commit is contained in:
commit
9e0e9ad789
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
nbproject/
|
||||||
|
build/
|
10
CMakeLists.txt
Normal file
10
CMakeLists.txt
Normal file
|
@ -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)
|
2
README.md
Normal file
2
README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Worlds Terminal
|
||||||
|
A simple terminal-based chat for Worlds.com, without the 3D.
|
4
src/CMakeLists.txt
Normal file
4
src/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
add_executable(worldsterm
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(worldsterm ${CURSES_LIBRARIES})
|
52
src/client.h
Normal file
52
src/client.h
Normal file
|
@ -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<char, char*> properties = {};
|
||||||
|
std::map<char, Drone> objects = {};
|
||||||
|
std::map<char*, uint16_t> 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
|
34
src/cmds.h
Normal file
34
src/cmds.h
Normal file
|
@ -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
|
15
src/drone.h
Normal file
15
src/drone.h
Normal file
|
@ -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
|
635
src/main.cpp
Normal file
635
src/main.cpp
Normal file
|
@ -0,0 +1,635 @@
|
||||||
|
#include <map>
|
||||||
|
#include <future>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#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;
|
||||||
|
|
||||||
|
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 <user> <msg> Whisper a message to a user.");
|
||||||
|
wprintw(wlog, "\n* .whisper <user> <msg>");
|
||||||
|
wprintw(wlog, "\n* .status <user> Watch for user to come online");
|
||||||
|
wprintw(wlog, "\n* .avatar <URI> Change avatar");
|
||||||
|
wprintw(wlog, "\n* .teleport <x> <y> <z> <rot> [<world>#<room>] Teleport to coordinates.");
|
||||||
|
wprintw(wlog, "\n* .dimension <text> 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 <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);
|
||||||
|
} 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 <USER>"); 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 <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) {
|
||||||
|
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<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);
|
||||||
|
}
|
29
src/var_error.h
Normal file
29
src/var_error.h
Normal file
|
@ -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
|
Loading…
Reference in New Issue
Block a user