Ok, I've had an idea for some time to make a proxy that beginners can code with, and isn't a hell of a mess like qoproxy and derivatives are. The idea I've come up with is a library where all networking code, packet serialization, login, authentication etc is hidden from the coder in a static lib or DLL. This also has other advantages, such as sharing code for bots, and not having to update your own bots if TQ decide to mess something up, you'd just need an updated version of the API.
The API will expose an event driven OOP interface that really anyone with some knowledge of C++ should be able to use. Each received packet will trigger it's own event, and the packet all have their own classes with meaningful names and properties.
I've designed it to be as simple as possible while hiding everything so people can't break their own bots. You need no knowledge of networking because it's all done for you. Project is currently named blacknull, but it's open for change.
Anyway, as an example of what a bot will look like, here's a 5 minute thing I made. It's basically an auto messager that'll reply to anyone with a custom message when they whisper you in game. You'd activate the bot by typing "/autoreply I'm currently afk", and deactivate it with "/noreply". The code below is very simple, if you don't understand it, start learning C++ [Only registered and activated users can see links. Click Here To Register...] perhaps before you ask any questions.
Once you have all your logic in place, starting up the bot is simple. You need to pass the packet event classes above to it so the API knows about your newly coded methods. This will be an auto generated start file for your bots, but you're free to edit it if you want.
Ok, so that code alone is for demonstration and useless without the blacknull API , but eventually it should work when the API is complete. There's already code in place, the packet encryption is no problem at all. Infact, most of the work is documenting it. I'd say it's about 50% complete anyway, but before I finish things off, I'm interested in some feedback. Particularly, will anyone use it? What would you change to make it easier to use? Are there any specific features you think it should contain? At the moment this is only working for a single client, but the plan is to handle many. In that case, I'm after opinions on how best to handle that, will you want to create your own packet_event classes for each seperate bot, or would you prefer to handle seperate clients by checking the hero_id on incoming packets, or do you have another idea?
Anyway, please take some time to look over the above code and gimme your comments if you're interested. I won't guarantee I'll finish this until I get some feedback. There's another coder who has worked on it so far, but not sure if he is interested in doing more.
On a side-note, I have a simple binary-packet-editor that uses blacknull, it's almost ready for release but a few bugs need fixing. The UI is somwhat based on behelit's CoProxy, and it has practically the same functionality. It's cross platform as it's using wxWidgets, and blacknull is designed to be portable too.
[Only registered and activated users can see links. Click Here To Register...]
The API will expose an event driven OOP interface that really anyone with some knowledge of C++ should be able to use. Each received packet will trigger it's own event, and the packet all have their own classes with meaningful names and properties.
I've designed it to be as simple as possible while hiding everything so people can't break their own bots. You need no knowledge of networking because it's all done for you. Project is currently named blacknull, but it's open for change.
Anyway, as an example of what a bot will look like, here's a 5 minute thing I made. It's basically an auto messager that'll reply to anyone with a custom message when they whisper you in game. You'd activate the bot by typing "/autoreply I'm currently afk", and deactivate it with "/noreply". The code below is very simple, if you don't understand it, start learning C++ [Only registered and activated users can see links. Click Here To Register...] perhaps before you ask any questions.
Code:
/* auto_reply_bot.cpp
This is the primary code file you'll be editing to fit in your packet events and sending packets.
*/
#include "auto_reply_bot.hpp"
#include <string>
namespace auto_reply_bot
{
std::string* auto_reply; //var to hold our auto reply message
bool auto_reply_on=false;
client_packet_event::client_packet_event()
{
// the register_event() function is required to overide the internal handle for these packets.
// you must register each packet you use for code to work, everything else will be forwarded by the api.
register_event(CHAT_PACKET);
}
void client_packet_event::on_chat_packet(chat_packet* chat)
{
if (chat->is_command()) // is_command() returns true if the chat message begins with "/"
{
if (strcmp((const char*)chat->strip_command(),"autoreply")) // strip_command() returns the string that follows a "/"
{
auto_reply = chat->strip_args(); // strip_args() returns the rest of message after the command.
auto_reply_on = true;
}
if (strcmp((const char*)chat->strip_command(),"noreply"))
{
auto_reply_on = false;
}
}
else send_to_server((packet*)chat);
}
server_packet_event::server_packet_event()
{
register_event(CHAT_PACKET);
}
void server_packet_event::on_chat_packet(chat_packet* chat)
{
if (auto_reply_on)
{
if (chat->chat_type()==WHISPER)
{
chat_packet reply;
reply.msg_from(my_hero->name);
reply.send_to(chat->msg_from());
reply.chat_type(WHISPER);
reply.message(auto_reply);
send_to_server((packet*)&reply);
}
}
send_to_client((packet*)chat);
}
}
Code:
/* auto_reply_bot.hpp
Header file for the bot, you can add to this, but needn't worry about
what is already written here, it will be auto-generated from a template.
*/
#include <blacknull.hpp>
namespace auto_reply_bot
{
using namespace blacknull;
class client_packet_event : public packet_event
{
public:
client_packet_event();
virtual ~client_packet_event();
private:
void on_chat_packet(chat_packet*);
void on_hero_info_packet(hero_info_packet*);
void on_create_character_packet(create_character_packet*);
//.. on_other_packets_etc(...)
//... Will contain a full list of client packets eventually
};
class server_packet_event : public packet_event
{
public:
server_packet_event();
virtual ~server_packet_event();
private:
void on_chat_packet(chat_packet*);
void on_spawn_packet(spawn_packet*);
//.. Will also contain a completed list
};
}
Code:
/* main.cpp
Auto generated file to start up the basic proxy.
*/
#include <blacknull.hpp>
#include "auto_reply_bot.hpp"
using namespace blacknull;
using namespace auto_reply_bot;
int main(int argc, char* argv[])
{
proxy_config* config = new proxy_config();
config->local_auth_ip("127.0.0.1"); //This is uneccessary since localhost is the default in the api
config->local_game_ip("127.0.0.1"); //Just to demonstrate other IPs can be used instead.
packet_event* client_events = new server_packet_event();
packet_event* server_events = new client_packet_event();
proxy* co_proxy = new proxy(config, client_events, server_events);
co_proxy->run();
}
Anyway, please take some time to look over the above code and gimme your comments if you're interested. I won't guarantee I'll finish this until I get some feedback. There's another coder who has worked on it so far, but not sure if he is interested in doing more.
On a side-note, I have a simple binary-packet-editor that uses blacknull, it's almost ready for release but a few bugs need fixing. The UI is somwhat based on behelit's CoProxy, and it has practically the same functionality. It's cross platform as it's using wxWidgets, and blacknull is designed to be portable too.
[Only registered and activated users can see links. Click Here To Register...]