Completely overhaul connection and session system.
This commit is contained in:
parent
4e7f8a85f8
commit
53e19a604f
40
src/client.h
40
src/client.h
|
@ -1,29 +1,39 @@
|
|||
#ifndef H_CLIENT
|
||||
#define H_CLIENT
|
||||
#include<vector>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#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
|
||||
#define BUFFERSIZE 65535
|
||||
bool netstatus = false;
|
||||
|
||||
|
||||
WINDOW* wlog;
|
||||
WINDOW* wform;
|
||||
FORM *form;
|
||||
FIELD *entries[1];
|
||||
|
||||
char* protocol = "24";
|
||||
int autosock;
|
||||
int roomsock;
|
||||
|
||||
std::thread aRecv_t;
|
||||
std::thread rRecv_t;
|
||||
std::thread rKA_t;
|
||||
|
||||
char* worldsserver = "209.240.84.122";
|
||||
uint16_t autoport = 6650;
|
||||
uint16_t roomport = 5672;
|
||||
|
||||
int protocol = 24;
|
||||
char* version = "0000000000";
|
||||
char* default_avatar = "avatar:pengo.mov";
|
||||
char* avatars = "1024";
|
||||
char* avatar = "avatar:pengo.mov";
|
||||
int avatars = 253;
|
||||
char* room = "GroundZero#Reception";
|
||||
char* dimension = "dimension-1";
|
||||
uint16_t roomID = 1;
|
||||
|
||||
char login_username[128];
|
||||
char login_password[128];
|
||||
char login_username[16];
|
||||
char login_password[16];
|
||||
|
||||
uint16_t xPos = 0;
|
||||
uint16_t yPos = 0;
|
||||
|
@ -40,12 +50,14 @@ std::vector<char*> mutes;
|
|||
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 autoInit();
|
||||
void roomInit();
|
||||
void roomKeepAlive();
|
||||
void reciever(int sock_fd, bool autoserver);
|
||||
void sessInit(int sock_fd, char* username, char* password);
|
||||
void sessExit(int sock_fd);
|
||||
void readPropertyList(unsigned char* in);
|
||||
std::map<char, char*> readOldPropertyList(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);
|
||||
|
|
243
src/main.cpp
243
src/main.cpp
|
@ -1,9 +1,9 @@
|
|||
#include <map>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -16,6 +16,7 @@
|
|||
#include "client.h"
|
||||
#include "var_error.h"
|
||||
#include "cmds.h"
|
||||
#include "props.h"
|
||||
|
||||
static char* trim(char *str) {
|
||||
char *end;
|
||||
|
@ -29,29 +30,27 @@ static char* trim(char *str) {
|
|||
*(end+1) = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
struct sockaddr_in auto_addr;
|
||||
struct sockaddr_in room_addr;
|
||||
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 >> login_username;
|
||||
auto_addr.sin_family = AF_INET;
|
||||
inet_pton(AF_INET, worldsserver, &auto_addr.sin_addr);
|
||||
auto_addr.sin_port = htons(autoport);
|
||||
|
||||
room_addr.sin_family = AF_INET;
|
||||
inet_pton(AF_INET, worldsserver, &room_addr.sin_addr);
|
||||
room_addr.sin_port = htons(roomport);
|
||||
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
refresh();
|
||||
|
||||
printf("*Password: ");
|
||||
std::cin >> login_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);
|
||||
|
||||
|
@ -63,33 +62,17 @@ int main(int argc, char const* argv[]) {
|
|||
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);
|
||||
pos_form_cursor(form);
|
||||
wmove(wform, 0, 0);
|
||||
wrefresh(wform);
|
||||
wmove(wlog, LINES-2, 0);
|
||||
wrefresh(wlog);
|
||||
refresh();
|
||||
wprintw(wlog, "\n*Welcome to WorldsTerm. Enter '.help' for a list of commands.");
|
||||
wprintw(wlog, "\n*To get started, '.connect' to the server and '.login'.");
|
||||
wrefresh(wlog);
|
||||
|
||||
int key = 0;
|
||||
while ((key = wgetch(wform))) {
|
||||
|
@ -97,6 +80,7 @@ int main(int argc, char const* argv[]) {
|
|||
if (key == 10) {
|
||||
form_driver(form, REQ_VALIDATION);
|
||||
char* inmsg = trim(field_buffer(entries[0], 0));
|
||||
set_field_buffer(entries[0], 0, "");
|
||||
int msglen = 0;
|
||||
if ((msglen = strlen(inmsg)) > 0) {
|
||||
if (inmsg[0] == '.' && msglen > 1) { // Starting a command.
|
||||
|
@ -139,6 +123,34 @@ int main(int argc, char const* argv[]) {
|
|||
inmsg = new char[256];
|
||||
srcLine = 0;
|
||||
}
|
||||
} else if (strcmp(cmd, "connect") == 0) {
|
||||
autoInit();
|
||||
} else if (strcmp(cmd, "disconnect") == 0) {
|
||||
if (aRecv_t.joinable()) aRecv_t.detach();
|
||||
wsend(autosock, new unsigned char[] {0x03, 0x01, CMD_SESSEXIT}, 0);
|
||||
} else if (strcmp(cmd, "login") == 0) {
|
||||
char username[16] = {0}; j = 0;
|
||||
while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x20) {
|
||||
username[j++] = s;
|
||||
}
|
||||
username[j++] = 0;
|
||||
char password[16] = {0}; j = 0;
|
||||
while (msgoff < msglen && (s = inmsg[msgoff++]) != 0x00) {
|
||||
password[j++] = s;
|
||||
}
|
||||
password[j++] = 0;
|
||||
|
||||
if (strlen(username) == 0 || strlen(password) == 0) { wprintw(wlog, "\n*.login <username> <password>"); continue; }
|
||||
int u = 0;
|
||||
for(u; u < strlen(username); u++)
|
||||
login_username[u] = username[u];
|
||||
login_username[u];
|
||||
int p = 0;
|
||||
for(p; p < strlen(password); p++)
|
||||
login_password[p] = password[p];
|
||||
login_password[p];
|
||||
wprintw(wlog, "\n*Logging in as %s.", username);
|
||||
sessInit(autosock, username, password);
|
||||
} else if ((strcmp(cmd, "w") == 0 || strcmp(cmd, "whisper") == 0) && srcLine < 0) {
|
||||
int k = 1;
|
||||
bufout[k++] = 0;
|
||||
|
@ -368,6 +380,9 @@ int main(int argc, char const* argv[]) {
|
|||
wprintw(wlog, "%s %s", _f?",":"", value.name);
|
||||
_f=true;
|
||||
}
|
||||
} else if (strcmp(cmd, "logout") == 0) {
|
||||
wsend(autosock, new unsigned char[] {0x03, 0x01, CMD_SESSEXIT}, 0);
|
||||
wsend(roomsock, new unsigned char[] {0x03, 0x01, CMD_SESSEXIT}, 0);
|
||||
} else if (strcmp(cmd, "q") == 0) {
|
||||
goto quit;
|
||||
} else {
|
||||
|
@ -396,7 +411,6 @@ int main(int argc, char const* argv[]) {
|
|||
wsend(roomsock, bufout, 0);
|
||||
}
|
||||
bufout[0] = 0;
|
||||
set_field_buffer(entries[0], 0, "");
|
||||
}
|
||||
} else if (key == KEY_LEFT) {
|
||||
form_driver(form, REQ_PREV_CHAR);
|
||||
|
@ -427,32 +441,44 @@ int main(int argc, char const* argv[]) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void autoInit(int sock_fd) {
|
||||
wsend(sock_fd, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 0);
|
||||
sleep(1);
|
||||
sessInit(sock_fd, login_username, login_password);
|
||||
sleep(1);
|
||||
setAvatar(sock_fd, default_avatar);
|
||||
roomIDReq(sock_fd, room);
|
||||
void autoInit() {
|
||||
if ((autosock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
perror("AutoSock creation error");
|
||||
|
||||
pos_form_cursor(form);
|
||||
wrefresh(wform);
|
||||
wrefresh(wlog);
|
||||
refresh();
|
||||
if (connect(autosock, (struct sockaddr*)&auto_addr, sizeof(auto_addr)) < 0)
|
||||
perror("AutoServ connection failed");
|
||||
|
||||
wprintw(wlog, "\n*Connected to AutoServer %s:%i", worldsserver, autoport);
|
||||
// Initialize connection.
|
||||
aRecv_t = std::thread(reciever, autosock, true);
|
||||
wsend(autosock, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 0);
|
||||
wrefresh(wlog);
|
||||
netstatus = true;
|
||||
}
|
||||
|
||||
void roomInit(int sock_fd) {
|
||||
wsend(sock_fd, new unsigned char[] {0x03, 0xff, CMD_PROPREQ}, 0);
|
||||
sleep(1);
|
||||
sessInit(sock_fd, login_username, login_password);
|
||||
setAvatar(sock_fd, default_avatar);
|
||||
while (true) {
|
||||
teleport(sock_fd, xPos, yPos, zPos, rot);
|
||||
sleep(15);
|
||||
void roomInit() {
|
||||
if ((roomsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
perror("AutoSock creation error");
|
||||
|
||||
if ((connect(roomsock, (struct sockaddr*)&room_addr, sizeof(room_addr))) < 0)
|
||||
perror("RoomServ connection failed");
|
||||
wprintw(wlog, "\n*Connected to RoomServer %s:%i", worldsserver, roomport);
|
||||
rRecv_t = std::thread(reciever, roomsock, false);
|
||||
rKA_t = std::thread(roomKeepAlive);
|
||||
sessInit(roomsock, login_username, login_password);
|
||||
login_password[0] = 0;
|
||||
wrefresh(wlog);
|
||||
}
|
||||
|
||||
void roomKeepAlive() {
|
||||
while (netstatus) {
|
||||
teleport(roomsock, xPos, yPos, zPos, rot);
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
void reciever(int sock_fd) {
|
||||
void reciever(int sock_fd, bool autoserver = false) {
|
||||
unsigned char bufin[BUFFERSIZE] = {};
|
||||
unsigned char bufout[BUFFERSIZE] = {};
|
||||
while (read(sock_fd, bufin, sizeof(bufin)) > 0) {
|
||||
|
@ -524,7 +550,73 @@ void reciever(int sock_fd) {
|
|||
objects[shortID] = newDrone;
|
||||
}
|
||||
} else if (bufin[p+2] == CMD_SESSEXIT && bufin[p+1] == 0x01) {
|
||||
break;
|
||||
close(sock_fd);
|
||||
if (autoserver) {
|
||||
wprintw(wlog, "\n*Logged out of %s.", login_username);
|
||||
login_username[0] = 0;
|
||||
|
||||
// Clear
|
||||
properties.erase(properties.begin(), properties.end());
|
||||
objects.erase(objects.begin(), objects.end());
|
||||
rooms.erase(rooms.begin(), rooms.end());
|
||||
friends.clear();
|
||||
mutes.clear();
|
||||
|
||||
aRecv_t.detach();
|
||||
netstatus = false;
|
||||
wprintw(wlog, "\n*Disconnected!", sock_fd);
|
||||
} else {
|
||||
wprintw(wlog, "\n*Leaving room %s<%s>", room, dimension);
|
||||
roomID = 1;
|
||||
room = "GroundZero#Reception";
|
||||
dimension = "dimension-1";
|
||||
xPos = 0;
|
||||
yPos = 0;
|
||||
zPos = 0;
|
||||
rot = 0;
|
||||
|
||||
rRecv_t.detach();
|
||||
rKA_t.detach();
|
||||
}
|
||||
} else if (bufin[p+2] == CMD_SESSINIT && bufin[p+1] == 0x01) {
|
||||
std::map<char, char*> props = readOldPropertyList(&bufin[p]);
|
||||
int err = VAR_FATAL;
|
||||
for (const auto& [key, value] : props) {
|
||||
switch (key) {
|
||||
case PROP_ERROR:
|
||||
err = atoi(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (err != VAR_OK) {
|
||||
char* errMsg = "UNKNOWN";
|
||||
switch(err) {
|
||||
case VAR_BAD_PASSWORD:
|
||||
errMsg = "Invalid Password."; break;
|
||||
case VAR_BAD_ACCOUNT:
|
||||
errMsg = "Account is no longer valid."; break;
|
||||
case VAR_BAD_IPADDRESS:
|
||||
errMsg = "Invalid client IP address!"; break;
|
||||
case VAR_NO_SUCH_USER:
|
||||
errMsg = "User does not exist."; break;
|
||||
}
|
||||
wprintw(wlog, "\n*Error %i: %s", err, errMsg);
|
||||
|
||||
if (autoserver) {
|
||||
aRecv_t.detach();
|
||||
netstatus = false;
|
||||
} else {
|
||||
rRecv_t.detach();
|
||||
rKA_t.detach();
|
||||
}
|
||||
} else {
|
||||
if (!autoserver) {
|
||||
memset(&(login_password[0]), 0, sizeof(login_password));
|
||||
setAvatar(sock_fd, avatar);
|
||||
} else {
|
||||
roomIDReq(sock_fd, room);
|
||||
}
|
||||
}
|
||||
} else if ((bufin[p+2] == CMD_ROOMID || bufin[p+2] == 0x1A) && bufin[p+1] == 0x01) {
|
||||
char *longID = new char[255];
|
||||
int shortID;
|
||||
|
@ -536,6 +628,7 @@ void reciever(int sock_fd) {
|
|||
shortID = ((uint16_t)bufin[offs++] << 8) | bufin[offs++];
|
||||
rooms[longID] = shortID;
|
||||
roomID = shortID;
|
||||
if (autoserver) roomInit();
|
||||
wprintw(wlog, "\n*Joining room %s", longID);
|
||||
for (const auto& [key, value] : objects) {
|
||||
objects.erase((char)key);
|
||||
|
@ -579,6 +672,7 @@ void reciever(int sock_fd) {
|
|||
}
|
||||
memset(&(bufin[0]), 0, sizeof(bufin));
|
||||
}
|
||||
wrefresh(wlog);
|
||||
}
|
||||
|
||||
void sessInit(int sock_fd, char* name, char* pass) {
|
||||
|
@ -600,16 +694,20 @@ void sessInit(int sock_fd, char* name, char* pass) {
|
|||
bufout[l++] = pass[c];
|
||||
|
||||
// Protocol
|
||||
char* pstr = new char[4];
|
||||
sprintf(pstr, "%d", protocol);
|
||||
bufout[l++] = 3;
|
||||
bufout[l++] = strlen(protocol);
|
||||
for (int c = 0; c < strlen(protocol); c++)
|
||||
bufout[l++] = protocol[c];
|
||||
bufout[l++] = strlen(pstr);
|
||||
for (int c = 0; c < strlen(pstr); c++)
|
||||
bufout[l++] = pstr[c];
|
||||
|
||||
// Avatars
|
||||
char* avstr = new char[4];
|
||||
sprintf(avstr, "%d", avatars);
|
||||
bufout[l++] = 7;
|
||||
bufout[l++] = strlen(avatars);
|
||||
for (int c = 0; c < strlen(avatars); c++)
|
||||
bufout[l++] = avatars[c];
|
||||
bufout[l++] = strlen(avstr);
|
||||
for (int c = 0; c < strlen(avstr); c++)
|
||||
bufout[l++] = avstr[c];
|
||||
|
||||
// Version
|
||||
bufout[l++] = 9;
|
||||
|
@ -663,6 +761,21 @@ void readPropertyList(unsigned char* in) {
|
|||
}
|
||||
}
|
||||
|
||||
std::map<char, char*> readOldPropertyList(unsigned char* in) {
|
||||
std::map<char, char*> oldprops = {};
|
||||
int l {3};
|
||||
while (l < in[0]) {
|
||||
char* value = new char[255];
|
||||
char type = in[l++];
|
||||
int len = in[l++];
|
||||
memcpy(value, &in[l], len);
|
||||
l+=len;
|
||||
value[len]=0;
|
||||
oldprops[type] = value;
|
||||
}
|
||||
return oldprops;
|
||||
}
|
||||
|
||||
/*
|
||||
void readPropertyList(unsigned char* in) {
|
||||
int l {3};
|
||||
|
@ -772,4 +885,4 @@ void userExit(char id) {
|
|||
|
||||
int wsend(int sock_fd, unsigned char str[], int flags) {
|
||||
return send(sock_fd, str, str[0], flags);
|
||||
}
|
||||
}
|
32
src/props.h
Normal file
32
src/props.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef PROPS_H
|
||||
#define PROPS_H
|
||||
|
||||
#define PROP_APPNAME 1
|
||||
#define PROP_USERNAME 2
|
||||
#define PROP_PROTOCOL 3
|
||||
#define PROP_ERROR 4
|
||||
#define PROP_CHANNEL 5
|
||||
#define PROP_PASSWORD 6
|
||||
#define PROP_AVATARS 7
|
||||
#define PROP_UPDATETIME 8
|
||||
#define PROP_CLIENT 9
|
||||
#define PROP_SERIAL 10
|
||||
#define PROP_EMAIL 11
|
||||
#define PROP_LOGONOFF 12
|
||||
#define PROP_DURATION 13
|
||||
#define PROP_GUEST 14
|
||||
#define PROP_SERVERTYPE 15
|
||||
#define PROP_BIZCARD 16
|
||||
#define PROP_NEW_PASSWORD 20
|
||||
#define PROP_PRIV 22
|
||||
#define PROP_ASLEEP 23
|
||||
#define PROP_EX_HTTP_SERVER 24
|
||||
#define PROP_SCRIPT_SERVER 25
|
||||
#define PROP_SMTP_SERVER 26
|
||||
#define PROP_MAIL_DOMAIN 27
|
||||
#define PROP_NEW_USERNAME 28
|
||||
#define PROP_IN_HTTP_SERVER 29
|
||||
#define PROP_INVENTORY 30
|
||||
|
||||
#endif
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef H_VAR_ERROR
|
||||
#define H_VAR_ERROR
|
||||
|
||||
#define VAR_OK 0 | 200
|
||||
#define VAR_OK 0
|
||||
#define VAR_BAD_USER 1
|
||||
#define VAR_MAX_ORDINARY 2
|
||||
#define VAR_MAX_PRIORITY 3
|
||||
|
|
Loading…
Reference in New Issue
Block a user