Modified:
/trunk/cockpit/src/Client.cpp
/trunk/cockpit/src/Client.h
/trunk/cockpit/src/MatchServer.cpp
/trunk/gogo/src/main.cpp
/trunk/include/cockpit/Transmitter.h
/trunk/include/cockpit/packet/Registry.h
/trunk/protocol/parse.py
=======================================
--- /trunk/cockpit/src/Client.cpp Tue Jun 8 19:24:50 2010
+++ /trunk/cockpit/src/Client.cpp Tue Jun 8 19:30:12 2010
@@ -42,6 +42,10 @@
Client::Client(Logger* _logger, ClientHandlerFactory* factory, io_service*
io)
: logger(_logger), handler(factory->create_client_handler()), socket(*io)
{
+ assert(_logger);
+ assert(factory);
+ assert(handler);
+ assert(io);
}
string Client::get_ip() const
@@ -62,6 +66,8 @@
recieve_packet_header();
} catch(const std::exception& ex) {
logger->info(format("[%1%] Connection terminated (%2%).") % get_ip() %
ex.what());
+ } catch(...) {
+ logger->error("Fatal error initializing the ClientHandler.");
}
}
@@ -90,13 +96,14 @@
}
void Client::on_packet_header(
- shared_ptr<PacketHeader> p, // NOTE: This only fills in the packet header.
+ shared_ptr<PacketHeader> p,
system::error_code err,
size_t bytesTransferred)
{
if(err)
{
- logger->info(format("[%1%] Failure in recv(Header). Terminating the
connection.") % get_ip());
+ logger->info(format("[%1%] Failure in recv(Header).") % get_ip());
+ disconnect();
return;
}
@@ -155,15 +162,27 @@
// TODO: Decrypt the packet's parameters.
}
-void Client::on_payload(shared_array<uint8_t> p, boost::uint16_t
payloadSize, bool encrypted, system::error_code err, size_t
bytesTransferred)
+void Client::on_payload(shared_array<uint8_t> p, uint16_t payloadSize,
bool encrypted, system::error_code err, size_t bytesTransferred)
{
if(err)
{
- logger->debug(format("[%1%] Failure in recv(Payload). Terminating the
connection.") % get_ip());
+ logger->debug(format("[%1%] Failure in recv(Payload).") % get_ip());
+ disconnect();
return;
}
+ // If this gets triggered, boost is fucking up and we need to read the
docs some more.
assert(bytesTransferred == payloadSize);
+
+ if(payloadSize < sizeof(Payload))
+ {
+ logger->info(
+ format("[%1%] Invalid payload size of %2% bytes detected.") %
get_ip() % payloadSize
+ );
+
+ disconnect();
+ return;
+ }
Payload payload = extract_payload(p, encrypted);
uint16_t paramLength = payloadSize - sizeof(Payload); // LOL.
@@ -174,21 +193,49 @@
registry.dispatch(payload.commandID, params, paramLength);
+ // This begins the recieving loop again!
recieve_packet_header();
}
+
+void Client::on_send(system::error_code err, size_t bytesTransferred,
shared_ptr<Buffer> buf)
+{
+ if(err)
+ {
+ logger->info(format("Sending to %1% failed (%2%).") % get_ip() %
err.message());
+ disconnect();
+ return;
+ }
+
+ assert(bytesTransferred == buf->length());
+}
void Client::send(const packet::Packet* packet)
{
send(packet->serialize());
}
-void Client::send(const Buffer& buf)
-{
- try {
- socket.send(buffer(buf.data(), buf.length()));
- } catch(system::error_code ec) {
- logger->info(format("Sending to %1% failed (%2%).") % get_ip() %
ec.message());
- }
+void Client::send(const Buffer& _buf)
+{
+ shared_ptr<Buffer> buf = make_shared<Buffer>(_buf);
+
+ socket.async_send(
+ buffer(buf->data(), buf->length()),
+ bind(
+ &Client::on_send,
+ shared_from_this(),
+ _1,
+ _2,
+ buf
+ )
+ );
+}
+
+void Client::disconnect()
+{
+ logger->debug(format("Disconnecting %1%.") % get_ip());
+
+ socket.shutdown(socket_base::shutdown_both);
+ socket.close();
}
Client::~Client()
=======================================
--- /trunk/cockpit/src/Client.h Tue Jun 8 19:24:50 2010
+++ /trunk/cockpit/src/Client.h Tue Jun 8 19:30:12 2010
@@ -51,6 +51,12 @@
size_t bytesTransferred
);
+ void on_send(
+ boost::system::error_code err,
+ size_t bytesTransferred,
+ boost::shared_ptr<Buffer> buf
+ );
+
public:
Client(Logger* logger, ClientHandlerFactory* factory,
boost::asio::io_service* io);
@@ -59,6 +65,8 @@
void send(const packet::Packet* packet);
void send(const Buffer& buf);
+ void disconnect();
+
std::string get_ip() const;
~Client();
=======================================
--- /trunk/cockpit/src/MatchServer.cpp Tue Jun 8 19:24:50 2010
+++ /trunk/cockpit/src/MatchServer.cpp Tue Jun 8 19:30:12 2010
@@ -6,6 +6,8 @@
#include <cockpit/ClientHandlerFactory.h>
#include <cockpit/ClientHandler.h>
+#include <cassert>
+
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
@@ -30,6 +32,9 @@
MatchServer::Data::Data(Logger* _logger, ClientHandlerFactory* _factory,
io_service* io, uint16_t port)
: logger(_logger), factory(_factory), acceptor(*io,
tcp::endpoint(tcp::v4(), port))
{
+ assert(_logger);
+ assert(_factory);
+ assert(io);
}
MatchServer::Data::~Data()
@@ -42,6 +47,8 @@
static void asynchronously_accept_new_client(MatchServer::Data* d)
{
+ assert(d);
+
shared_ptr<Client> client = make_shared<Client>(d->logger, d->factory,
&d->acceptor.io_service());
d->acceptor.async_accept(
@@ -57,6 +64,7 @@
shared_ptr<Client> client,
system::error_code err)
{
+ assert(d);
asynchronously_accept_new_client(d);
if(err)
@@ -74,6 +82,9 @@
uint16_t port)
: d(new Data(logger, factory, io, port))
{
+ assert(d);
+ assert(d->logger);
+ assert(d->factory);
}
void MatchServer::run()
=======================================
--- /trunk/gogo/src/main.cpp Tue Jun 8 19:27:58 2010
+++ /trunk/gogo/src/main.cpp Tue Jun 8 19:30:12 2010
@@ -1,64 +1,25 @@
#include "ConsoleLogger.h"
-#include <cstdlib>
#include <exception>
-#include <boost/asio.hpp>
-#include "Structures.h"
-#include "Server.h"
-
-#include <database/MySQLGunzDB.h>
-#include <database/oopsies.h>
-
-#include <boost/thread.hpp>
+#include <boost/asio/io_service.hpp>
using namespace boost;
-using namespace boost::asio;
-using namespace cockpit;
-
-static void run_server_on(uint16_t port, Logger* logger)
-{
- io_service service(thread::hardware_concurrency());
- ip::tcp::endpoint endpoint(ip::tcp::v4(), port);
-
- Server server(logger, service, endpoint);
-
- // This loop ensures that the server is restarted if we get any
shenanigans
- // happening. Hopefully, we won't make segfaulting a regular problem =/
- for(;;)
- {
- try
- {
- service.run();
- break; // If this is hit, the IO service exited without a hitch.
- }
- catch(const std::exception& ex)
- {
- logger->error(format("Fatal error, server restarting: %1%") %
ex.what());
- }
- }
-}
int main()
{
- ConsoleLogger logger;
+ ConsoleLogger loggerImpl;
+ cockpit::Logger* logger = &loggerImpl;
+ asio::io_service ioService;
try {
- MySQLGunzDB database(&logger, "gunzdb", "localhost", "root", "root");
-
- try {
- AccountInfo accountInfo = database.GetAccountInfo("test", "test");
- } catch(const InvalidAccountInfo&) {
- logger.warning("Invalid login info.");
- }
-
- run_server_on(6000, &logger);
-
- return 0;
+ // IMPLEMENTATION HERE.
} catch(const std::exception& ex) {
- logger.error(ex.what());
+ logger->error(format("Fatal error: %1%") % ex.what());
return 1;
} catch(...) {
- logger.error("Unknown exception encountered. This is a programming
error. Report this message to the bugtracker.");
+ logger->error("Unknown exception encountered. This is a programming
error. Report this message to the bugtracker.");
return 2;
}
-}
+
+ return 0;
+}
=======================================
--- /trunk/include/cockpit/Transmitter.h Tue Jun 8 19:24:50 2010
+++ /trunk/include/cockpit/Transmitter.h Tue Jun 8 19:30:12 2010
@@ -20,6 +20,13 @@
*/
virtual void send(const packet::Packet* packet) = 0;
+ /**
+ Disconnects the client. No more handlers will be called, the
+ connection will be terminated, and eventually, the ClientHandler's
+ destructor will be called.
+ */
+ virtual void disconnect() = 0;
+
virtual ~Transmitter()
{
}
=======================================
--- /trunk/include/cockpit/packet/Registry.h Tue Jun 8 19:24:50 2010
+++ /trunk/include/cockpit/packet/Registry.h Tue Jun 8 19:30:12 2010
@@ -27,7 +27,7 @@
~Registry();
- // This signal is called when the parsing of a packet has failed. Do
whatever you want in here.
+ /// This signal is called when the parsing of a packet has failed. Do
whatever you want in here.
boost::signals2::signal<void (boost::uint16_t /* packetID */,
const boost::uint8_t* /* rawParameters */,
boost::uint16_t /* length */)>
OnFailedParse;
=======================================
--- /trunk/protocol/parse.py Tue Jun 8 19:24:50 2010
+++ /trunk/protocol/parse.py Tue Jun 8 19:30:12 2010
@@ -120,7 +120,7 @@
~Registry();
- // This signal is called when the parsing of a packet has failed. Do
whatever you want in here.
+ /// This signal is called when the parsing of a packet has failed. Do
whatever you want in here.
boost::signals2::signal<void (boost::uint16_t /* packetID */,
const boost::uint8_t* /* rawParameters */,
boost::uint16_t /* length */)>
OnFailedParse;"""