Created
April 11, 2011 10:03
-
-
Save apathyboy/913311 to your computer and use it in GitHub Desktop.
Testing tbb pipeline
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| This file is part of ANHServer. For more information, visit http://swganh.com | |
| Copyright (c) 2010 - 2011 ANH Studios | |
| ANHServer is free software: you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation, either version 3 of the License, or | |
| (at your option) any later version. | |
| ANHServer is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with ANHServer. If not, see <http://www.gnu.org/licenses/>. | |
| */ | |
| #include <cstddef> | |
| #include <functional> | |
| #include <iostream> | |
| #include <memory> | |
| #include <boost/asio.hpp> | |
| #include "zlib.h" | |
| #include "anh/byte_buffer.h" | |
| #include "anh/crc.h" | |
| #include "anh/utilities.h" | |
| using anh::ByteBuffer; | |
| namespace asio = boost::asio; | |
| using asio::ip::udp; | |
| using boost::system::error_code; | |
| using std::bind; | |
| using std::function; | |
| using std::make_pair; | |
| using std::make_shared; | |
| using std::shared_ptr; | |
| const uint32_t CRC_TABLE[256] = { | |
| 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, | |
| 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, | |
| 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, | |
| 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, | |
| 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, | |
| 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, | |
| 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, | |
| 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, | |
| 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, | |
| 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, | |
| 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, | |
| 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, | |
| 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, | |
| 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, | |
| 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, | |
| 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, | |
| 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, | |
| 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, | |
| 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, | |
| 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, | |
| 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, | |
| 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, | |
| 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, | |
| 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, | |
| 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, | |
| 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, | |
| 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, | |
| 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, | |
| 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, | |
| 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, | |
| 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, | |
| 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, | |
| 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, | |
| 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, | |
| 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, | |
| 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, | |
| 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, | |
| 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, | |
| 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, | |
| 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, | |
| 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, | |
| 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, | |
| 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d | |
| }; | |
| typedef function<void ( | |
| const udp::endpoint& /*remote_endpoint*/, | |
| ByteBuffer /*message*/)> NetworkCallback; | |
| uint32_t swgcrc(const char* source_string, uint32_t length, uint32_t seed) { | |
| uint32_t crc = CRC_TABLE[(~seed) & 0xFF]; | |
| crc ^= 0x00FFFFFF; | |
| uint32_t index = (seed >> 8) ^ crc; | |
| crc = (crc >> 8) & 0x00FFFFFF; | |
| crc ^= CRC_TABLE[index & 0xFF]; | |
| index = (seed >> 16) ^ crc; | |
| crc = (crc >> 8) & 0x00FFFFFF; | |
| crc ^= CRC_TABLE[index & 0xFF]; | |
| index = (seed >> 24) ^ crc; | |
| crc = (crc >> 8) &0x00FFFFFF; | |
| crc ^= CRC_TABLE[index & 0xFF]; | |
| for (uint16_t i = 0; i < length; i++) { | |
| index = (source_string[i]) ^ crc; | |
| crc = (crc >> 8) & 0x00FFFFFF; | |
| crc ^= CRC_TABLE[index & 0xFF]; | |
| } | |
| return ~crc; | |
| } | |
| class UdpCallbackSocket { | |
| public: | |
| UdpCallbackSocket( | |
| asio::io_service& io_service, | |
| uint16_t listen_port, | |
| NetworkCallback callback) | |
| : callback_(callback) | |
| , socket_(io_service, udp::endpoint(udp::v4(), listen_port)) | |
| , receive_buffer_(50000) | |
| , bytes_received_(0) | |
| , bytes_sent_(0) | |
| { | |
| startReceive(); | |
| } | |
| void send( | |
| shared_ptr<ByteBuffer> buffer, | |
| const udp::endpoint& remote_endpoint) | |
| { | |
| socket_.async_send_to( | |
| asio::buffer(buffer->data(), buffer->size()), | |
| remote_endpoint, | |
| [this, buffer] (const error_code& error, size_t bytes_transferred) | |
| { | |
| bytes_sent_ += bytes_transferred; | |
| }); | |
| } | |
| private: | |
| void startReceive() { | |
| socket_.async_receive_from( | |
| asio::buffer(receive_buffer_), | |
| remote_endpoint_, | |
| [this] (const error_code& error, size_t bytes_transferred) | |
| { | |
| bytes_received_ += bytes_transferred; | |
| ByteBuffer buffer(&receive_buffer_[0], bytes_transferred); | |
| callback_(remote_endpoint_, std::move(buffer)); | |
| startReceive(); | |
| }); | |
| } | |
| NetworkCallback callback_; | |
| udp::socket socket_; | |
| udp::endpoint remote_endpoint_; | |
| std::vector<uint8_t> receive_buffer_; | |
| uint64_t bytes_received_; | |
| uint64_t bytes_sent_; | |
| }; | |
| class LoginClient { | |
| public: | |
| LoginClient(udp::endpoint remote_endpoint) | |
| : remote_endpoint_(remote_endpoint) | |
| , connection_id_(0) | |
| , crc_length_(0) | |
| , max_udp_size_(0) | |
| {} | |
| const udp::endpoint& remote_endpoint() const { return remote_endpoint_; } | |
| void remote_endpoint(const udp::endpoint& remote_endpoint) { | |
| remote_endpoint_ = remote_endpoint; | |
| } | |
| uint32_t crc_length() const { return crc_length_; } | |
| void crc_length(uint32_t crc_length) { crc_length_ = crc_length; } | |
| uint32_t connection_id() const { return connection_id_; } | |
| void connection_id(uint32_t connection_id) { connection_id_ = connection_id; } | |
| uint32_t max_udp_size() const { return max_udp_size_; } | |
| void max_udp_size(uint32_t max_udp_size) { max_udp_size_ = max_udp_size; } | |
| private: | |
| udp::endpoint remote_endpoint_; | |
| uint32_t connection_id_; | |
| uint32_t crc_length_; | |
| uint32_t max_udp_size_; | |
| }; | |
| class LoginServer { | |
| public: | |
| LoginServer() | |
| : io_service_() | |
| , socket_(nullptr) | |
| , decompression_buffer_(496) | |
| , server_seed_(0xDEADBABE) | |
| , max_udp_size_(496) | |
| , encryption_method_(1) | |
| , seed_length_(4) | |
| {} | |
| void startup() { | |
| socket_ = make_shared<UdpCallbackSocket>( | |
| io_service_, | |
| 44990, | |
| bind( | |
| &LoginServer::handleMessage, | |
| this, | |
| std::placeholders::_1, | |
| std::placeholders::_2)); | |
| } | |
| void run() { | |
| io_service_.run(); | |
| } | |
| shared_ptr<LoginClient> findClient(const udp::endpoint& endpoint) const { | |
| auto find_it = client_map_.find(endpoint); | |
| if (find_it == client_map_.end()) { | |
| return nullptr; | |
| } | |
| return find_it->second; | |
| } | |
| private: | |
| void handleMessage(const udp::endpoint& address, ByteBuffer message) { | |
| auto client = findClient(address); | |
| if (client) { | |
| handleClientMessage(client, message); | |
| } else { | |
| handleUnknownSource(address, message); | |
| } | |
| } | |
| void handleClientMessage( | |
| shared_ptr<LoginClient> client, | |
| ByteBuffer message) | |
| { | |
| if (! validateCrc(client, message)) { | |
| return; | |
| } | |
| uint16_t opcode_header = 0; | |
| if (message.peek<uint8_t>() == 0) { | |
| opcode_header = anh::bigToHost(message.read<uint16_t>()); | |
| } | |
| decrypt(client, message); | |
| uint8_t compression_bit = message.peekAt<uint8_t>(message.size() + 1); | |
| message.resize(message.size() - 1); | |
| if (compression_bit != 0) { | |
| decompress(&zstream_, message); | |
| } | |
| } | |
| void handleUnknownSource( | |
| const udp::endpoint& address, | |
| ByteBuffer message) | |
| { | |
| std::cout << "Received message from unknown source: \n\n" << message << "\n"; | |
| if (anh::bigToHost(message.read<uint16_t>()) == 0x0001) { | |
| auto new_client = make_shared<LoginClient>(address); | |
| client_map_.insert(make_pair(address, new_client)); | |
| new_client->crc_length(anh::bigToHost(message.read<uint32_t>())); | |
| new_client->connection_id(anh::bigToHost(message.read<uint32_t>())); | |
| new_client->max_udp_size(anh::bigToHost(message.read<uint32_t>())); | |
| auto session_response = make_shared<ByteBuffer>(); | |
| session_response->write<uint16_t>(anh::hostToBig<uint16_t>(2)); | |
| session_response->write<uint32_t>(anh::hostToBig(new_client->connection_id())); | |
| session_response->write<uint32_t>(anh::hostToBig(server_seed_)); | |
| session_response->write<uint8_t>(new_client->crc_length()); | |
| session_response->write<uint8_t>(encryption_method_); | |
| session_response->write<uint8_t>(seed_length_); | |
| session_response->write<uint32_t>(anh::hostToBig(max_udp_size_)); | |
| std::cout << "Sending response: \n\n" << *session_response << "\n"; | |
| socket_->send(session_response, address); | |
| } | |
| } | |
| bool validateCrc(shared_ptr<LoginClient> client, ByteBuffer& message) { | |
| uint32_t crc_length = client->crc_length(); | |
| if (crc_length > 0) { | |
| uint32_t packetCrc = swgcrc(reinterpret_cast<const char*>(message.data()), message.size() - crc_length, server_seed_); | |
| std::cout << std::hex << packetCrc << "\n"; | |
| uint32_t testCrc = 0; | |
| uint32_t mask = 0; | |
| uint32_t pullbyte = 0; | |
| const unsigned char* data = message.data(); | |
| data += (message.size() - crc_length); | |
| for (uint32_t i = 0; i < crc_length; ++i) { | |
| pullbyte = data[i]; | |
| testCrc |= (pullbyte << (((crc_length - 1) - i) * 8)); | |
| mask <<= 8; | |
| mask |= 0xFF; | |
| } | |
| packetCrc &= mask; | |
| if (packetCrc != testCrc) { | |
| return false; | |
| } | |
| message.resize(message.size() - crc_length); | |
| return true; | |
| } | |
| return false; | |
| } | |
| void decrypt(shared_ptr<LoginClient> client, ByteBuffer& message) { | |
| uint32_t tmp_seed = 0; | |
| uint32_t seed = server_seed_; | |
| uint32_t block_count = (message.size() / 4); | |
| uint32_t byte_count = (message.size() % 4); | |
| unsigned char* data = message.raw(); | |
| for (uint32_t i = 0; i < block_count; ++i) { | |
| tmp_seed = (reinterpret_cast<uint32_t*>(data))[i]; | |
| (reinterpret_cast<uint32_t*>(data))[i] ^= seed; | |
| seed = tmp_seed; | |
| } | |
| for (uint32_t i = block_count * 4; i < message.size(); ++i) { | |
| data[i] ^= seed; | |
| } | |
| } | |
| void decompress(z_stream* stream, ByteBuffer& message) { | |
| stream->zalloc = Z_NULL; | |
| stream->zfree = Z_NULL; | |
| stream->opaque = Z_NULL; | |
| stream->avail_in = Z_NULL; | |
| stream->next_in = Z_NULL; | |
| inflateInit(stream); | |
| stream->next_in = reinterpret_cast<Bytef*>(message.raw()); | |
| stream->avail_in = message.size(); | |
| stream->next_out = reinterpret_cast<Bytef*>(&decompression_buffer_[0]); | |
| stream->avail_out = decompression_buffer_.capacity(); | |
| inflate(stream, Z_FINISH); | |
| message.swap(ByteBuffer(decompression_buffer_.data(), stream->total_out)); | |
| inflateEnd(stream); | |
| } | |
| typedef std::map<udp::endpoint, shared_ptr<LoginClient>> LoginClientMap; | |
| LoginClientMap client_map_; | |
| asio::io_service io_service_; | |
| z_stream zstream_; | |
| shared_ptr<UdpCallbackSocket> socket_; | |
| std::vector<uint8_t> decompression_buffer_; | |
| uint32_t server_seed_; | |
| uint32_t max_udp_size_; | |
| uint8_t encryption_method_; | |
| uint8_t seed_length_; | |
| }; | |
| int main() { | |
| try { | |
| LoginServer server; | |
| server.startup(); | |
| server.run(); | |
| } catch (std::exception& e) { | |
| std::cerr << e.what() << std::endl; | |
| } | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| This file is part of ANHServer. For more information, visit http://swganh.com | |
| Copyright (c) 2010 - 2011 ANH Studios | |
| ANHServer is free software: you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation, either version 3 of the License, or | |
| (at your option) any later version. | |
| ANHServer is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with ANHServer. If not, see <http://www.gnu.org/licenses/>. | |
| */ | |
| #ifndef LOGIN_DUMMY_PACKET_H_ | |
| #define LOGIN_DUMMY_PACKET_H_ | |
| #include <boost/asio.hpp> | |
| #include "anh/byte_buffer.h" | |
| class Packet { | |
| public: | |
| private: | |
| boost::asio::ip::udp::endpoint endpoint; | |
| }; | |
| #endif // LOGIN_DUMMY_PACKET_H_ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| This file is part of ANHServer. For more information, visit http://swganh.com | |
| Copyright (c) 2010 - 2011 ANH Studios | |
| ANHServer is free software: you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation, either version 3 of the License, or | |
| (at your option) any later version. | |
| ANHServer is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with ANHServer. If not, see <http://www.gnu.org/licenses/>. | |
| */ | |
| #include "soe_pipeline.h" | |
| #include <iostream> | |
| using std::cout; | |
| const uint32_t CRC_TABLE[256] = { | |
| 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, | |
| 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, | |
| 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, | |
| 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, | |
| 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, | |
| 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, | |
| 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, | |
| 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, | |
| 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, | |
| 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, | |
| 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, | |
| 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, | |
| 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, | |
| 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, | |
| 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, | |
| 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, | |
| 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, | |
| 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, | |
| 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, | |
| 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, | |
| 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, | |
| 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, | |
| 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, | |
| 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, | |
| 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, | |
| 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, | |
| 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, | |
| 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, | |
| 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, | |
| 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, | |
| 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, | |
| 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, | |
| 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, | |
| 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, | |
| 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, | |
| 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, | |
| 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, | |
| 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, | |
| 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, | |
| 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, | |
| 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, | |
| 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, | |
| 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d | |
| }; | |
| void* IncomingMessageFilter::operator()(void* item) { | |
| } | |
| void* CrcFilter::operator()(void* item) { | |
| anh::ByteBuffer& message = *static_cast<anh::ByteBuffer*>(item); | |
| uint32_t packetCrc = crc_(reinterpret_cast<const char*>(message.data()), message.size() - crc_length_, crc_seed_); | |
| uint32_t testCrc = 0; | |
| uint32_t mask = 0; | |
| uint32_t pullbyte = 0; | |
| const unsigned char* data = message.data(); | |
| data += (message.size() - crc_length_); | |
| for (uint32_t i = 0; i < crc_length_; ++i) { | |
| pullbyte = data[i]; | |
| testCrc |= (pullbyte << (((crc_length_ - 1) - i) * 8)); | |
| mask <<= 8; | |
| mask |= 0xFF; | |
| } | |
| packetCrc &= mask; | |
| if (packetCrc != testCrc) { | |
| return NULL; | |
| } | |
| message.resize(message.size() - crc_length_); | |
| return &message; | |
| } | |
| uint32_t CrcFilter::crc_( | |
| const char* source_string, | |
| uint32_t length, | |
| uint32_t seed) const | |
| { | |
| uint32_t crc = CRC_TABLE[(~seed) & 0xFF]; | |
| crc ^= 0x00FFFFFF; | |
| uint32_t index = (seed >> 8) ^ crc; | |
| crc = (crc >> 8) & 0x00FFFFFF; | |
| crc ^= CRC_TABLE[index & 0xFF]; | |
| index = (seed >> 16) ^ crc; | |
| crc = (crc >> 8) & 0x00FFFFFF; | |
| crc ^= CRC_TABLE[index & 0xFF]; | |
| index = (seed >> 24) ^ crc; | |
| crc = (crc >> 8) &0x00FFFFFF; | |
| crc ^= CRC_TABLE[index & 0xFF]; | |
| for (uint16_t i = 0; i < length; i++) { | |
| index = (source_string[i]) ^ crc; | |
| crc = (crc >> 8) & 0x00FFFFFF; | |
| crc ^= CRC_TABLE[index & 0xFF]; | |
| } | |
| return ~crc; | |
| } | |
| void* DecryptionFilter::operator()(void* item) { | |
| anh::ByteBuffer& message = *static_cast<anh::ByteBuffer*>(item); | |
| uint32_t tmp_seed = 0; | |
| uint32_t seed = crc_seed_; | |
| uint32_t block_count = (message.size() / 4); | |
| uint32_t byte_count = (message.size() % 4); | |
| unsigned char* data = message.raw(); | |
| for (uint32_t i = 0; i < block_count; ++i) { | |
| tmp_seed = (reinterpret_cast<uint32_t*>(data))[i]; | |
| (reinterpret_cast<uint32_t*>(data))[i] ^= seed; | |
| seed = tmp_seed; | |
| } | |
| for (uint32_t i = block_count * 4; i < message.size(); ++i) { | |
| data[i] ^= seed; | |
| } | |
| return &message; | |
| } | |
| void* DecompressionFilter::operator()(void* item) { | |
| anh::ByteBuffer& message = *static_cast<anh::ByteBuffer*>(item); | |
| zstream_.zalloc = Z_NULL; | |
| zstream_.zfree = Z_NULL; | |
| zstream_.opaque = Z_NULL; | |
| zstream_.avail_in = Z_NULL; | |
| zstream_.next_in = Z_NULL; | |
| inflateInit(&zstream_); | |
| zstream_.next_in = reinterpret_cast<Bytef*>(message.raw()); | |
| zstream_.avail_in = message.size(); | |
| zstream_.next_out = reinterpret_cast<Bytef*>(&decompression_buffer_[0]); | |
| zstream_.avail_out = decompression_buffer_.capacity(); | |
| inflate(&zstream_, Z_FINISH); | |
| message.swap(anh::ByteBuffer(decompression_buffer_.data(), zstream_.total_out)); | |
| inflateEnd(&zstream_); | |
| cout << "Processed message \n\n" << message << "\n"; | |
| return &message; | |
| } | |
| void* OutputFilter::operator()(void* item) { | |
| anh::ByteBuffer& message = *static_cast<anh::ByteBuffer*>(item); | |
| cout << "Processed message \n\n" << message << "\n"; | |
| return nullptr; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| This file is part of ANHServer. For more information, visit http://swganh.com | |
| Copyright (c) 2010 - 2011 ANH Studios | |
| ANHServer is free software: you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation, either version 3 of the License, or | |
| (at your option) any later version. | |
| ANHServer is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with ANHServer. If not, see <http://www.gnu.org/licenses/>. | |
| */ | |
| #ifndef LOGIN_DUMMY_SOE_PIPELINE_H_ | |
| #define LOGIN_DUMMY_SOE_PIPELINE_H_ | |
| #include <cstdint> | |
| #include <memory> | |
| #include <tbb/pipeline.h> | |
| #include <zlib.h> | |
| #include "anh/byte_buffer.h" | |
| class IncomingMessageFilter : public tbb::filter { | |
| public: | |
| IncomingMessageFilter() | |
| : tbb::filter(true) | |
| {} | |
| ~IncomingMessageFilter() {} | |
| void* operator()(void* item); | |
| }; | |
| class CrcFilter : public tbb::filter { | |
| public: | |
| CrcFilter(uint32_t crc_seed, uint32_t crc_length) | |
| : tbb::filter(false) | |
| , crc_seed_(crc_seed) | |
| , crc_length_(crc_length_) | |
| {} | |
| ~CrcFilter() {} | |
| void* operator()(void* item); | |
| private: | |
| uint32_t crc_( | |
| const char* source_string, | |
| uint32_t length, | |
| uint32_t seed) const; | |
| uint32_t crc_seed_; | |
| uint32_t crc_length_; | |
| }; | |
| class DecryptionFilter : public tbb::filter { | |
| public: | |
| DecryptionFilter(uint32_t crc_seed) | |
| : tbb::filter(false) | |
| , crc_seed_(crc_seed) | |
| {} | |
| ~DecryptionFilter() {} | |
| void* operator()(void* item); | |
| private: | |
| uint32_t crc_seed_; | |
| }; | |
| class DecompressionFilter : public tbb::filter { | |
| public: | |
| DecompressionFilter(uint32_t max_packet_size) | |
| : tbb::filter(true) | |
| , max_packet_size_(max_packet_size) | |
| { | |
| decompression_buffer_.reserve(max_packet_size); | |
| } | |
| ~DecompressionFilter() {} | |
| void* operator()(void* item); | |
| private: | |
| z_stream zstream_; | |
| std::vector<uint8_t> decompression_buffer_; | |
| uint32_t max_packet_size_; | |
| }; | |
| class OutputFilter : public tbb::filter { | |
| public: | |
| OutputFilter(uint32_t max_packet_size) | |
| : tbb::filter(true) | |
| {} | |
| ~OutputFilter() {} | |
| void* operator()(void* item); | |
| }; | |
| #endif // LOGIN_DUMMY_SOE_PIPELINE_H_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment