#define VCMI_DLL #pragma warning(disable:4355) #include "Connection.h" #include #include #include #ifndef _MSC_VER #include "../lib/RegisterTypes.cpp" #include "../hch/CObjectHandler.h" #endif //for smart objs serialization over net #include "CGameState.h" #include "map.h" #include "../hch/CObjectHandler.h" #include "../hch/CCreatureHandler.h" #include "VCMI_Lib.h" /* * Connection.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ using namespace boost; using namespace boost::asio::ip; template DLL_EXPORT void registerTypes(Serializer &s); //defined elsewhere and explicitly instantiated for used serializers CTypeList typeList; #define LOG(a) \ if(logging)\ out << a #if defined(__hppa__) || \ defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ (defined(__MIPS__) && defined(__MISPEB__)) || \ defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ defined(__sparc__) #define BIG_ENDIAN #else #define LIL_ENDIAN #endif void CConnection::init() { CISer::smartPointerSerialization = false; COSer::smartPointerSerialization = false; registerTypes(static_cast&>(*this)); registerTypes(static_cast&>(*this)); #ifdef LIL_ENDIAN myEndianess = true; #else myEndianess = false; #endif connected = true; std::string pom; //we got connection (*this) << std::string("Aiya!\n") << name << myEndianess; //identify ourselves (*this) >> pom >> pom >> contactEndianess; tlog0 << "Established connection with "<connect(*endpoint_iterator, error); if(!error) { init(); return; } else { tlog1 << "Problem with connecting: " << std::endl << error << std::endl; } endpoint_iterator++; } //we shouldn't be here - error handling connerror1: tlog1 << "Something went wrong... checking for error info" << std::endl; if(error) tlog1 << error <io_service()), name(Name)//, send(this), rec(this) { init(); } CConnection::CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_service, std::string Name) : name(Name)//, send(this), rec(this) { boost::system::error_code error = asio::error::host_not_found; socket = new tcp::socket(*io_service); acceptor->accept(*socket,error); if (error) { tlog1 << "Error on accepting: " << std::endl << error << std::endl; delete socket; throw "Can't establish connection :("; } init(); } int CConnection::write(const void * data, unsigned size) { //LOG("Sending " << size << " byte(s) of data" < CConnection & CConnection::operator&(const T &t) { throw new std::exception(); //XXX this is temporaly ? solution to fix gcc (4.3.3, other?) compilation // problem for more details contact t0@czlug.icis.pcz.pl or impono@gmail.com // do not remove this exception it shoudnt be called return *this; } void CConnection::close() { if(socket) { socket->close(); delete socket; socket = NULL; } } CGObjectInstance *CConnection::loadObject() { assert(gs); si32 id; *this >> id; assert(id >= 0 && id < gs->map->objects.size()); return gs->map->objects[id]; } void CConnection::saveObject( const CGObjectInstance *data ) { assert(gs); assert(data); *this << data->id; } CCreature * CConnection::loadCreature() { si32 id; *this >> id; assert(id >= 0 && id < VLC->creh->creatures.size()); return VLC->creh->creatures[id]; } void CConnection::saveCreature(const CCreature *data) { assert(data); *this << data->idNumber; } void CConnection::setGS( CGameState *state ) { gs = state; } bool CConnection::isOpen() const { return socket && connected; } CSaveFile::CSaveFile( const std::string &fname ) :sfile(NULL) { registerTypes(*this); openNextFile(fname); } CSaveFile::~CSaveFile() { delete sfile; } int CSaveFile::write( const void * data, unsigned size ) { sfile->write((char *)data,size); return size; } void CSaveFile::close() { delete sfile; sfile = NULL; } void CSaveFile::openNextFile(const std::string &fname) { close(); sfile = new std::ofstream(fname.c_str(),std::ios::binary); if(!(*sfile)) { tlog1 << "Error: cannot open to write " << fname << std::endl; sfile = NULL; } else { sfile->write("VCMI",4); //write magic identifier *this << version; //write format version } } CLoadFile::CLoadFile( const std::string &fname, bool requireLatest ) :sfile(NULL) { registerTypes(*this); openNextFile(fname, requireLatest); } CLoadFile::~CLoadFile() { delete sfile; } int CLoadFile::read( const void * data, unsigned size ) { sfile->read((char *)data,size); return size; } void CLoadFile::close() { delete sfile; sfile = NULL; } void CLoadFile::openNextFile(const std::string &fname, bool requireLatest) { sfile = new std::ifstream(fname.c_str(),std::ios::binary); if(!(*sfile)) { tlog1 << "Error: cannot open to read " << fname << std::endl; sfile = NULL; } else { char buffer[4]; sfile->read(buffer, 4); if(std::memcmp(buffer,"VCMI",4)) { tlog1 << "Error: not a VCMI save! (file " << fname << " )\n"; delete sfile; sfile = NULL; return; } *this >> myVersion; if(myVersion != version && requireLatest) { tlog1 << "Error: Not supported save format! (file " << fname << " )\n"; delete sfile; sfile = NULL; } } } CTypeList::CTypeList() { registerTypes(*this); } ui16 CTypeList::registerType( const std::type_info *type ) { TTypeMap::const_iterator i = types.find(type); if(i != types.end()) return i->second; //type found, return ID //type not found - add it to the list and return given ID ui16 id = types.size() + 1; types.insert(std::make_pair(type,id)); return id; } ui16 CTypeList::getTypeID( const std::type_info *type ) { TTypeMap::const_iterator i = types.find(type); if(i != types.end()) return i->second; else return 0; }