forgot to add some things

This commit is contained in:
David Skoland 2017-01-06 03:09:14 +01:00
parent 4fc1abe8cb
commit 29ec4e8af3
13 changed files with 326 additions and 36 deletions

View File

@ -25,7 +25,9 @@ SOURCES += main.cpp\
networkmanager.cpp \ networkmanager.cpp \
aoapplication.cpp \ aoapplication.cpp \
aopacket.cpp \ aopacket.cpp \
packet_distribution.cpp packet_distribution.cpp \
hex_functions.cpp \
encryption_functions.cpp
HEADERS += lobby.h \ HEADERS += lobby.h \
text_file_functions.h \ text_file_functions.h \
@ -38,4 +40,6 @@ HEADERS += lobby.h \
networkmanager.h \ networkmanager.h \
aoapplication.h \ aoapplication.h \
datatypes.h \ datatypes.h \
aopacket.h aopacket.h \
hex_functions.h \
encryption_functions.h

View File

@ -37,6 +37,20 @@ public:
QVector<server_type> favorite_list; QVector<server_type> favorite_list;
void ms_packet_received(AOPacket *p_packet); void ms_packet_received(AOPacket *p_packet);
void server_packet_received(AOPacket *p_packet);
void send_ms_packet(AOPacket *p_packet);
void send_server_packet(AOPacket *p_packet);
/////////////////server metadata//////////////////
unsigned int s_decryptor = 5;
bool encryption_needed = true;
bool ao2_features = false;
//player number, it's hardly used but might be needed for some old servers
bool s_pv = 0;
//////////////////////////////////////////////////
}; };
#endif // AOAPPLICATION_H #endif // AOAPPLICATION_H

View File

@ -1,5 +1,9 @@
#include "aopacket.h" #include "aopacket.h"
#include "encryption_functions.h"
#include <QDebug>
AOPacket::AOPacket(QString p_packet_string) AOPacket::AOPacket(QString p_packet_string)
{ {
QStringList packet_contents = p_packet_string.split("#"); QStringList packet_contents = p_packet_string.split("#");
@ -12,6 +16,12 @@ AOPacket::AOPacket(QString p_packet_string)
} }
} }
AOPacket::AOPacket(QString p_header, QStringList &p_contents)
{
m_header = p_header;
m_contents = p_contents;
}
AOPacket::~AOPacket() AOPacket::~AOPacket()
{ {
@ -28,5 +38,48 @@ QString AOPacket::to_string()
f_string += "#%"; f_string += "#%";
if (encrypted)
return "#" + f_string;
else
return f_string; return f_string;
} }
void AOPacket::encrypt_header(unsigned int p_key)
{
m_header = fanta_encrypt(m_header, p_key);
encrypted = true;
}
void AOPacket::decrypt_header(unsigned int p_key)
{
m_header = fanta_decrypt(m_header, p_key);
encrypted = false;
}
void AOPacket::net_encode()
{
for (int n_element = 0 ; n_element < m_contents.size() ; ++n_element)
{
QString f_element = m_contents.at(n_element);
f_element.replace("#", "<num>").replace("%", "<percent>").replace("$", "<dollar>").replace("&", "<and>");
m_contents.removeAt(n_element);
m_contents.insert(n_element, f_element);
}
}
void AOPacket::net_decode()
{
for (int n_element = 0 ; n_element < m_contents.size() ; ++n_element)
{
QString f_element = m_contents.at(n_element);
f_element.replace("<num>", "#").replace("<percent>", "%").replace("<dollar>", "$").replace("<and>", "&");
m_contents.removeAt(n_element);
m_contents.insert(n_element, f_element);
}
}

View File

@ -8,13 +8,22 @@ class AOPacket
{ {
public: public:
AOPacket(QString p_packet_string); AOPacket(QString p_packet_string);
AOPacket(QString header, QStringList &p_contents);
~AOPacket(); ~AOPacket();
QString get_header() {return m_header;} QString get_header() {return m_header;}
QStringList &get_contents() {return m_contents;} QStringList &get_contents() {return m_contents;}
QString to_string(); QString to_string();
void encrypt_header(unsigned int p_key);
void decrypt_header(unsigned int p_key);
void net_encode();
void net_decode();
private: private:
bool encrypted = false;
QString m_header; QString m_header;
QStringList m_contents; QStringList m_contents;
}; };

View File

@ -0,0 +1,69 @@
#include "encryption_functions.h"
#include "hex_functions.h"
#include <cstddef>
#include <stdlib.h>
#include <sstream>
#include <iomanip>
#include <QVector>
QString fanta_encrypt(QString temp_input, unsigned int p_key)
{
//using standard stdlib types is actually easier here because of implicit char<->int conversion
//which in turn makes encryption arithmetic easier
unsigned int key = p_key;
unsigned int C1 = 53761;
unsigned int C2 = 32618;
QVector<uint_fast8_t> temp_result;
std::string input = temp_input.toUtf8().constData();
for (unsigned int pos = 0 ; pos < input.size() ; ++pos)
{
uint_fast8_t output = input.at(pos) ^ (key >> 8) % 256;
temp_result.append(output);
key = (temp_result.at(pos) + key) * C1 + C2;
}
std::string result = "";
for (uint_fast8_t i_int : temp_result)
{
result += omni::int_to_hex(i_int);
}
QString final_result = QString::fromStdString(result);
return final_result;
}
QString fanta_decrypt(QString temp_input, unsigned int key)
{
std::string input = temp_input.toUtf8().constData();
QVector<unsigned int> unhexed_vector;
for(unsigned int i=0; i< input.length(); i+=2)
{
std::string byte = input.substr(i,2);
unsigned int hex_int = strtoul(byte.c_str(), nullptr, 16);
unhexed_vector.append(hex_int);
}
unsigned int C1 = 53761;
unsigned int C2 = 32618;
std::string result = "";
for (int pos = 0 ; pos < unhexed_vector.size() ; ++pos)
{
unsigned char output = unhexed_vector.at(pos) ^ (key >> 8) % 256;
result += output;
key = (unhexed_vector.at(pos) + key) * C1 + C2;
}
return QString::fromStdString(result);
}

View File

@ -1,4 +1,9 @@
#ifndef ENCRYPTION_FUNCTIONS_H #ifndef ENCRYPTION_FUNCTIONS_H
#define ENCRYPTION_FUNCTIONS_H #define ENCRYPTION_FUNCTIONS_H
#include <QString>
QString fanta_encrypt(QString p_input, unsigned int key);
QString fanta_decrypt(QString p_input, unsigned int key);
#endif // ENCRYPTION_FUNCTIONS_H #endif // ENCRYPTION_FUNCTIONS_H

View File

@ -1,6 +1,6 @@
//WELCOME TO THE EXTREME GHETTO HEX CONVERSION KLUDGE BECAUSE I COULDNT MAKE ANYTHING ELSE WORK //WELCOME TO THE EXTREMELY GHETTO HEX CONVERSION KLUDGE BECAUSE I COULDNT MAKE ANYTHING ELSE WORK
#include "hex_operations.h" #include "hex_functions.h"
namespace omni namespace omni
{ {

View File

@ -15,6 +15,7 @@ Lobby::Lobby(AOApplication *parent) : QMainWindow()
this->setWindowTitle("Attorney Online 2"); this->setWindowTitle("Attorney Online 2");
this->resize(m_lobby_width, m_lobby_height); this->resize(m_lobby_width, m_lobby_height);
this->setFixedSize(m_lobby_width, m_lobby_height);
ui_background = new AOImage(this); ui_background = new AOImage(this);
ui_public_servers = new AOButton(this); ui_public_servers = new AOButton(this);
@ -152,7 +153,7 @@ void Lobby::on_refresh_released()
AOPacket *f_packet = new AOPacket("ALL#%"); AOPacket *f_packet = new AOPacket("ALL#%");
ao_app->net_manager->send_ms_packet(f_packet); ao_app->send_ms_packet(f_packet);
delete f_packet; delete f_packet;
} }
@ -231,16 +232,19 @@ void Lobby::on_server_list_clicked(QModelIndex p_model)
ui_description->moveCursor(QTextCursor::Start); ui_description->moveCursor(QTextCursor::Start);
ui_description->ensureCursorVisible(); ui_description->ensureCursorVisible();
//T0D0: uncomment when implemented ui_player_count->setText("Offline");
//ao_app->net_manager->connect_to_server(f_server.ip, f_server.port);
ao_app->net_manager->connect_to_server(f_server);
} }
void Lobby::on_chatfield_return_pressed() void Lobby::on_chatfield_return_pressed()
{ {
QString raw_packet = "CT#" + ui_chatname->text() + "#" + ui_chatmessage->text() + "#%"; QString f_header = "CT";
AOPacket *f_packet = new AOPacket(raw_packet); QStringList f_contents{ui_chatname->text(), ui_chatmessage->text()};
ao_app->net_manager->send_ms_packet(f_packet); AOPacket *f_packet = new AOPacket(f_header, f_contents);
ao_app->send_ms_packet(f_packet);
ui_chatmessage->clear(); ui_chatmessage->clear();
@ -267,7 +271,13 @@ void Lobby::list_favorites()
} }
} }
void Lobby::append_chat_message(QString p_message_line) void Lobby::append_chatmessage(QString p_message_line)
{ {
ui_chatbox->appendPlainText(p_message_line); ui_chatbox->appendPlainText(p_message_line);
} }
void Lobby::set_player_count(int players_online, int max_players)
{
QString f_string = "Online: " + QString::number(players_online) + "/" + QString::number(max_players);
ui_player_count->setText(f_string);
}

View File

@ -24,7 +24,8 @@ public:
void set_widgets(); void set_widgets();
void list_servers(); void list_servers();
void list_favorites(); void list_favorites();
void append_chat_message(QString p_message_line); void append_chatmessage(QString p_message_line);
void set_player_count(int players_online, int max_players);
private: private:
AOApplication *ao_app; AOApplication *ao_app;

View File

@ -12,7 +12,7 @@ int main(int argc, char *argv[])
main_app.construct_lobby(); main_app.construct_lobby();
main_app.net_manager->connect_to_master(); main_app.net_manager->connect_to_master();
AOPacket *f_packet = new AOPacket("ALL#%"); AOPacket *f_packet = new AOPacket("ALL#%");
main_app.net_manager->send_ms_packet(f_packet); main_app.send_ms_packet(f_packet);
main_app.w_lobby->show(); main_app.w_lobby->show();
return main_app.exec(); return main_app.exec();

View File

@ -30,20 +30,22 @@ void NetworkManager::connect_to_master()
ms_socket->connectToHost(ms_hostname, ms_port); ms_socket->connectToHost(ms_hostname, ms_port);
} }
void NetworkManager::send_ms_packet(AOPacket *p_packet) void NetworkManager::connect_to_server(server_type p_server)
{ {
QString f_packet = p_packet->to_string(); server_socket->close();
server_socket->abort();
ms_socket->write(f_packet.toLocal8Bit()); server_socket->connectToHost(p_server.ip, p_server.port);
qDebug() << "S(ms):" << f_packet;
} }
void NetworkManager::send_server_packet(AOPacket *p_packet) void NetworkManager::ship_ms_packet(QString p_packet)
{ {
QString f_packet = p_packet->to_string(); ms_socket->write(p_packet.toLocal8Bit());
}
ms_socket->write(f_packet.toLocal8Bit()); void NetworkManager::ship_server_packet(QString p_packet)
qDebug() << "S(ms):" << f_packet; {
server_socket->write(p_packet.toLocal8Bit());
} }
void NetworkManager::handle_ms_packet() void NetworkManager::handle_ms_packet()
@ -53,6 +55,42 @@ void NetworkManager::handle_ms_packet()
QString in_data = buffer; QString in_data = buffer;
if (!in_data.endsWith("%"))
{
ms_partial_packet = true;
ms_temp_packet += in_data;
return;
}
else
{
if (ms_partial_packet)
{
in_data = ms_temp_packet + in_data;
ms_temp_packet = "";
ms_partial_packet = false;
}
}
QStringList packet_list = in_data.split("%", QString::SplitBehavior(QString::SkipEmptyParts));
for (QString packet : packet_list)
{
AOPacket *f_packet = new AOPacket(packet);
ao_app->ms_packet_received(f_packet);
delete f_packet;
}
}
void NetworkManager::handle_server_packet()
{
char buffer[16384] = {0};
server_socket->read(buffer, server_socket->bytesAvailable());
QString in_data = buffer;
if (!in_data.endsWith("%")) if (!in_data.endsWith("%"))
{ {
partial_packet = true; partial_packet = true;
@ -76,14 +114,9 @@ void NetworkManager::handle_ms_packet()
{ {
AOPacket *f_packet = new AOPacket(packet); AOPacket *f_packet = new AOPacket(packet);
ao_app->ms_packet_received(f_packet); ao_app->server_packet_received(f_packet);
delete f_packet; delete f_packet;
} }
} }
void NetworkManager::handle_server_packet()
{
}

View File

@ -21,15 +21,18 @@ public:
QString ms_hostname = "master.aceattorneyonline.com"; QString ms_hostname = "master.aceattorneyonline.com";
int ms_port = 27016; int ms_port = 27016;
bool ms_partial_packet = false;
QString ms_temp_packet = "";
bool partial_packet = false; bool partial_packet = false;
QString temp_packet = ""; QString temp_packet = "";
void connect_to_master(); void connect_to_master();
void connect_to_server(server_type p_server);
public slots: public slots:
void send_ms_packet(AOPacket *p_packet); void ship_ms_packet(QString p_packet);
void ship_server_packet(QString p_packet);
void send_server_packet(AOPacket *p_packet);
private slots: private slots:
void handle_ms_packet(); void handle_ms_packet();

View File

@ -1,12 +1,17 @@
#include "aoapplication.h" #include "aoapplication.h"
#include "lobby.h" #include "lobby.h"
#include "networkmanager.h"
#include "encryption_functions.h"
#include <QDebug> #include <QDebug>
void AOApplication::ms_packet_received(AOPacket *p_packet) void AOApplication::ms_packet_received(AOPacket *p_packet)
{ {
p_packet->net_decode();
QString header = p_packet->get_header(); QString header = p_packet->get_header();
QStringList f_contents = p_packet->get_contents();
if (header != "CHECK") if (header != "CHECK")
qDebug() << "R(ms):" << p_packet->to_string(); qDebug() << "R(ms):" << p_packet->to_string();
@ -22,7 +27,7 @@ void AOApplication::ms_packet_received(AOPacket *p_packet)
if (sub_contents.size() < 4) if (sub_contents.size() < 4)
{ {
qDebug() << "W: malformed packet!"; qDebug() << "W: malformed packet";
continue; continue;
} }
@ -41,8 +46,6 @@ void AOApplication::ms_packet_received(AOPacket *p_packet)
} }
else if (header == "CT") else if (header == "CT")
{ {
QStringList f_contents = p_packet->get_contents();
QString message_line; QString message_line;
if (f_contents.size() == 1) if (f_contents.size() == 1)
@ -54,12 +57,98 @@ void AOApplication::ms_packet_received(AOPacket *p_packet)
if (lobby_constructed) if (lobby_constructed)
{ {
w_lobby->append_chat_message(message_line); w_lobby->append_chatmessage(message_line);
} }
if (courtroom_constructed) if (courtroom_constructed)
{ {
//T0D0: uncomment this when it's implemented //T0D0: uncomment this when it's implemented
//w_courtroom->append_chat_message(message_line); //w_courtroom->append_ms_chat_message(message_line);
} }
} }
} }
void AOApplication::server_packet_received(AOPacket *p_packet)
{
p_packet->net_decode();
QString header = p_packet->get_header();
QStringList f_contents = p_packet->get_contents();
QString f_packet = p_packet->to_string();
qDebug() << "R: " << f_packet;
if (header == "decryptor")
{
if (f_contents.size() == 0)
return;
//you may ask where 322 comes from. that would be a good question.
s_decryptor = fanta_decrypt(f_contents.at(0), 322).toUInt();
//T0D0 add an actual HDID here
AOPacket *hi_packet = new AOPacket("HI#ao2testinginprogressdontmindme#%");
send_server_packet(hi_packet);
delete hi_packet;
}
else if (header == "ID")
{
if (f_contents.size() < 1)
return;
}
else if (header == "CT")
{
if (f_contents.size() < 2)
{
qDebug() << "W: malformed packet!";
return;
}
//QString message_line = f_contents.at(0) + ": " + f_contents.at(1);
//T0D0, uncomment when implemented
//w_courtroom->append_ooc_chatmessage(message_line)
}
else if (header == "PN")
{
if (f_contents.size() < 2)
return;
w_lobby->set_player_count(f_contents.at(0).toInt(), f_contents.at(1).toInt());
}
}
void AOApplication::send_ms_packet(AOPacket *p_packet)
{
p_packet->net_encode();
QString f_packet = p_packet->to_string();
net_manager->ship_ms_packet(f_packet);
qDebug() << "S(ms):" << f_packet;
}
void AOApplication::send_server_packet(AOPacket *p_packet)
{
p_packet->net_encode();
QString f_packet = p_packet->to_string();
if (encryption_needed)
{
qDebug() << "S:(e)" << f_packet;
p_packet->encrypt_header(s_decryptor);
f_packet = p_packet->to_string();
}
else
{
qDebug() << "S:" << f_packet;
}
net_manager->ship_server_packet(f_packet);
}