summaryrefslogtreecommitdiff
path: root/server/server.cpp
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2013-12-25 09:00:59 +0100
committerTreeki <treeki@gmail.com>2013-12-25 09:00:59 +0100
commitb7a8b597b00eedde277836eb8530ba742edcad5d (patch)
tree1b959fa0eec02ff4e22e168aa4379b2b64575ce3 /server/server.cpp
downloadbounce_qt-master.tar.gz
bounce_qt-master.zip
commit initial bitsHEADmaster
Diffstat (limited to '')
-rw-r--r--server/server.cpp131
1 files changed, 131 insertions, 0 deletions
diff --git a/server/server.cpp b/server/server.cpp
new file mode 100644
index 0000000..6c9412b
--- /dev/null
+++ b/server/server.cpp
@@ -0,0 +1,131 @@
+#include "server.h"
+#include "packetreader.h"
+#include "packetwriter.h"
+#include "ircnetworkconfig.h"
+#include "ircnetwork.h"
+#include "bouncer.h"
+
+Server::Server(QObject *parent) :
+ Socket(parent)
+{
+ Bouncer::instance()->generateSessionKey(m_sessionKey);
+}
+
+
+
+void Server::handlePacket(int type, PacketReader &reader) {
+ switch (type) {
+ case C2B_OOB_Login:
+ net_login(reader);
+ break;
+
+ case C2B_ConsoleInput:
+ net_consoleInput(reader.readString(MaxConsoleStringSize));
+ break;
+ }
+}
+
+
+
+void Server::net_login(PacketReader &reader) {
+ if (m_handshakeStatus > 0)
+ return;
+
+ quint32 errorCode = attemptLogin(reader);
+
+ if (errorCode > 0) {
+ // Yay, we failed somewhere above, so send out an error code
+ // and disconnect the client!
+ Packet packet(B2C_OOB_LoginFailed,
+ QByteArray((const char *)&errorCode, sizeof(errorCode)));
+
+ sendPacket(packet, /*isHandshakePacket=*/true);
+ unlinkSocket(/*disconnect=*/true);
+ }
+}
+
+int Server::attemptLogin(PacketReader &reader) {
+ quint32 protocolVer = reader.readU32();
+ if (protocolVer != ProtocolVersion)
+ return 1;
+
+ quint32 lastReceivedID = reader.readU32();
+
+ quint8 checkSessKey[SessionKeySize];
+ if (!reader.readBytes(checkSessKey, 64))
+ return 2;
+
+ QString username = reader.readString(100);
+ QString password = reader.readString(100);
+ if (username.isNull() || password.isNull())
+ return 2;
+
+ // Parsed the packet, try out the stuff
+ Server *auth = Bouncer::instance()->authenticate(this, username, password, checkSessKey);
+ if (!auth)
+ return 3;
+
+ // Who are we?
+ if (auth != this) {
+ // Taking over another session!!
+ auth->clearAcknowledgedPackets(lastReceivedID);
+ auth->takeOverSocket(this);
+ return 0;
+ }
+
+ // We've successfully authed here, so go ahead.
+ m_identified = true;
+ sendLoginSuccess();
+
+ // Probably don't need to call flushPacketCache here:
+ // theoretically it should be empty at this point.....
+
+ return 0;
+}
+
+void Server::takeOverSocket(Socket *donor) {
+ Socket::takeOverSocket(donor);
+ sendLoginSuccess();
+
+ flushPacketCache();
+}
+
+void Server::sendLoginSuccess() {
+ PacketWriter writer(4 + SessionKeySize);
+ writer.writeU32(lastReceivedPacketID());
+ writer.writeBytes(m_sessionKey, SessionKeySize);
+
+ Packet packet(B2C_OOB_LoginSuccess, writer.buffer());
+ sendPacket(packet, /*isHandshakePacket=*/true);
+
+ m_handshakeStatus = 1;
+ flushPacketCache();
+}
+
+
+
+void Server::net_consoleInput(const QString &string) {
+ if (string.startsWith("woof"))
+ sendConsoleOutput(QString("woof back: [%1]").arg(string));
+
+ if (string.startsWith("addznc ")) {
+ IRCNetworkConfig config;
+ config.hostname = "209.20.91.134";
+ config.port = 1191;
+ config.password = string.mid(7);
+ config.useSSL = true;
+ Bouncer::instance()->addNetwork(config);
+ }
+
+ if (string.startsWith("connect")) {
+ Bouncer::instance()->networks.values()[0]->startConnection();
+ }
+}
+
+void Server::sendConsoleOutput(const QString &string) {
+ PacketWriter writer(4 + (string.size() * 2));
+ writer.writeString(string);
+
+ Packet packet(B2C_ConsoleOutput, writer.buffer());
+ sendPacket(packet);
+}