aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Skoland <davidskoland@gmail.com>2017-01-06 03:09:14 +0100
committerDavid Skoland <davidskoland@gmail.com>2017-01-06 03:09:14 +0100
commit29ec4e8af37baf8a3abcd23377784f2754942a0d (patch)
tree4404d915d6fb311eabc59ff6c58277eaba6f0e57
parent4fc1abe8cbe2634b3e2186882b68c2e362c071c5 (diff)
forgot to add some things
-rw-r--r--Attorney_Online_remake.pro8
-rw-r--r--aoapplication.h14
-rw-r--r--aopacket.cpp55
-rw-r--r--aopacket.h9
-rw-r--r--encryption_functions.cpp69
-rw-r--r--encryption_functions.h5
-rw-r--r--hex_functions.cpp4
-rw-r--r--lobby.cpp24
-rw-r--r--lobby.h3
-rw-r--r--main.cpp2
-rw-r--r--networkmanager.cpp61
-rw-r--r--networkmanager.h9
-rw-r--r--packet_distribution.cpp99
13 files changed, 326 insertions, 36 deletions
diff --git a/Attorney_Online_remake.pro b/Attorney_Online_remake.pro
index b24292f2..f8a203fa 100644
--- a/Attorney_Online_remake.pro
+++ b/Attorney_Online_remake.pro
@@ -25,7 +25,9 @@ SOURCES += main.cpp\
networkmanager.cpp \
aoapplication.cpp \
aopacket.cpp \
- packet_distribution.cpp
+ packet_distribution.cpp \
+ hex_functions.cpp \
+ encryption_functions.cpp
HEADERS += lobby.h \
text_file_functions.h \
@@ -38,4 +40,6 @@ HEADERS += lobby.h \
networkmanager.h \
aoapplication.h \
datatypes.h \
- aopacket.h
+ aopacket.h \
+ hex_functions.h \
+ encryption_functions.h
diff --git a/aoapplication.h b/aoapplication.h
index f1bc56b7..0b8d453b 100644
--- a/aoapplication.h
+++ b/aoapplication.h
@@ -37,6 +37,20 @@ public:
QVector<server_type> favorite_list;
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
diff --git a/aopacket.cpp b/aopacket.cpp
index 553816bf..fa8f5be1 100644
--- a/aopacket.cpp
+++ b/aopacket.cpp
@@ -1,5 +1,9 @@
#include "aopacket.h"
+#include "encryption_functions.h"
+
+#include <QDebug>
+
AOPacket::AOPacket(QString p_packet_string)
{
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()
{
@@ -28,5 +38,48 @@ QString AOPacket::to_string()
f_string += "#%";
- return f_string;
+
+ if (encrypted)
+ return "#" + f_string;
+ else
+ 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);
+ }
+}
+
diff --git a/aopacket.h b/aopacket.h
index 13f47057..40dd3ec3 100644
--- a/aopacket.h
+++ b/aopacket.h
@@ -8,13 +8,22 @@ class AOPacket
{
public:
AOPacket(QString p_packet_string);
+ AOPacket(QString header, QStringList &p_contents);
~AOPacket();
QString get_header() {return m_header;}
QStringList &get_contents() {return m_contents;}
QString to_string();
+ void encrypt_header(unsigned int p_key);
+ void decrypt_header(unsigned int p_key);
+
+ void net_encode();
+ void net_decode();
+
private:
+ bool encrypted = false;
+
QString m_header;
QStringList m_contents;
};
diff --git a/encryption_functions.cpp b/encryption_functions.cpp
index e69de29b..56b6e34c 100644
--- a/encryption_functions.cpp
+++ b/encryption_functions.cpp
@@ -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);
+
+}
diff --git a/encryption_functions.h b/encryption_functions.h
index 0a9cf2e8..b6ea1d70 100644
--- a/encryption_functions.h
+++ b/encryption_functions.h
@@ -1,4 +1,9 @@
#ifndef 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
diff --git a/hex_functions.cpp b/hex_functions.cpp
index 9b1222ed..9db2b0a7 100644
--- a/hex_functions.cpp
+++ b/hex_functions.cpp
@@ -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
{
diff --git a/lobby.cpp b/lobby.cpp
index c7f27af2..7bcdaff7 100644
--- a/lobby.cpp
+++ b/lobby.cpp
@@ -15,6 +15,7 @@ Lobby::Lobby(AOApplication *parent) : QMainWindow()
this->setWindowTitle("Attorney Online 2");
this->resize(m_lobby_width, m_lobby_height);
+ this->setFixedSize(m_lobby_width, m_lobby_height);
ui_background = new AOImage(this);
ui_public_servers = new AOButton(this);
@@ -152,7 +153,7 @@ void Lobby::on_refresh_released()
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;
}
@@ -231,16 +232,19 @@ void Lobby::on_server_list_clicked(QModelIndex p_model)
ui_description->moveCursor(QTextCursor::Start);
ui_description->ensureCursorVisible();
- //T0D0: uncomment when implemented
- //ao_app->net_manager->connect_to_server(f_server.ip, f_server.port);
+ ui_player_count->setText("Offline");
+
+ ao_app->net_manager->connect_to_server(f_server);
}
void Lobby::on_chatfield_return_pressed()
{
- QString raw_packet = "CT#" + ui_chatname->text() + "#" + ui_chatmessage->text() + "#%";
- AOPacket *f_packet = new AOPacket(raw_packet);
+ QString f_header = "CT";
+ QStringList f_contents{ui_chatname->text(), ui_chatmessage->text()};
+
+ AOPacket *f_packet = new AOPacket(f_header, f_contents);
- ao_app->net_manager->send_ms_packet(f_packet);
+ ao_app->send_ms_packet(f_packet);
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);
}
+
+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);
+}
diff --git a/lobby.h b/lobby.h
index 16573c19..becf0e8a 100644
--- a/lobby.h
+++ b/lobby.h
@@ -24,7 +24,8 @@ public:
void set_widgets();
void list_servers();
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:
AOApplication *ao_app;
diff --git a/main.cpp b/main.cpp
index 9425c1fa..59578b4b 100644
--- a/main.cpp
+++ b/main.cpp
@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
main_app.construct_lobby();
main_app.net_manager->connect_to_master();
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();
return main_app.exec();
diff --git a/networkmanager.cpp b/networkmanager.cpp
index daca0f36..1aa5a00e 100644
--- a/networkmanager.cpp
+++ b/networkmanager.cpp
@@ -30,20 +30,22 @@ void NetworkManager::connect_to_master()
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());
- qDebug() << "S(ms):" << f_packet;
+ server_socket->connectToHost(p_server.ip, p_server.port);
}
-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());
- qDebug() << "S(ms):" << f_packet;
+void NetworkManager::ship_server_packet(QString p_packet)
+{
+ server_socket->write(p_packet.toLocal8Bit());
}
void NetworkManager::handle_ms_packet()
@@ -55,6 +57,42 @@ void NetworkManager::handle_ms_packet()
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("%"))
+ {
partial_packet = true;
temp_packet += in_data;
return;
@@ -76,14 +114,9 @@ void NetworkManager::handle_ms_packet()
{
AOPacket *f_packet = new AOPacket(packet);
- ao_app->ms_packet_received(f_packet);
+ ao_app->server_packet_received(f_packet);
delete f_packet;
}
}
-void NetworkManager::handle_server_packet()
-{
-
-}
-
diff --git a/networkmanager.h b/networkmanager.h
index 499ed9ec..e10dcca7 100644
--- a/networkmanager.h
+++ b/networkmanager.h
@@ -21,15 +21,18 @@ public:
QString ms_hostname = "master.aceattorneyonline.com";
int ms_port = 27016;
+ bool ms_partial_packet = false;
+ QString ms_temp_packet = "";
+
bool partial_packet = false;
QString temp_packet = "";
void connect_to_master();
+ void connect_to_server(server_type p_server);
public slots:
- void send_ms_packet(AOPacket *p_packet);
-
- void send_server_packet(AOPacket *p_packet);
+ void ship_ms_packet(QString p_packet);
+ void ship_server_packet(QString p_packet);
private slots:
void handle_ms_packet();
diff --git a/packet_distribution.cpp b/packet_distribution.cpp
index 5990d257..4e02fb46 100644
--- a/packet_distribution.cpp
+++ b/packet_distribution.cpp
@@ -1,12 +1,17 @@
#include "aoapplication.h"
#include "lobby.h"
+#include "networkmanager.h"
+#include "encryption_functions.h"
#include <QDebug>
void AOApplication::ms_packet_received(AOPacket *p_packet)
{
+ p_packet->net_decode();
+
QString header = p_packet->get_header();
+ QStringList f_contents = p_packet->get_contents();
if (header != "CHECK")
qDebug() << "R(ms):" << p_packet->to_string();
@@ -22,7 +27,7 @@ void AOApplication::ms_packet_received(AOPacket *p_packet)
if (sub_contents.size() < 4)
{
- qDebug() << "W: malformed packet!";
+ qDebug() << "W: malformed packet";
continue;
}
@@ -41,8 +46,6 @@ void AOApplication::ms_packet_received(AOPacket *p_packet)
}
else if (header == "CT")
{
- QStringList f_contents = p_packet->get_contents();
-
QString message_line;
if (f_contents.size() == 1)
@@ -54,12 +57,98 @@ void AOApplication::ms_packet_received(AOPacket *p_packet)
if (lobby_constructed)
{
- w_lobby->append_chat_message(message_line);
+ w_lobby->append_chatmessage(message_line);
}
if (courtroom_constructed)
{
//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);
+
+}