/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program 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. This program 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 this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ #include "pyNetClientComm.h" #include "../pfPython/pyAgeLinkStruct.h" #include "../pfPython/pyNetServerSessionInfo.h" #include "../pfPython/pyStatusLog.h" #include "../plNetCommon/plCreatePlayerFlags.h" #include "../pnNetCommon/plGenericVar.h" #include "hsStlUtils.h" #include "hsTimer.h" #include //////////////////////////////////////////////////////////////////// class pyNetClientCommCallback : public plNetClientComm::Callback { public: PyObject * fPyObject; pyNetClientCommCallback( PyObject * pyObject ) : fPyObject( pyObject ) { Py_XINCREF( fPyObject ); } ~pyNetClientCommCallback() { Py_XDECREF( fPyObject ); } void OperationStarted( UInt32 context ) { if ( fPyObject ) { // Call the callback. PyObject* func = PyObject_GetAttrString( fPyObject, "operationStarted" ); if ( func ) { if ( PyCallable_Check(func)>0 ) { PyObject* retVal = PyObject_CallMethod(fPyObject, "operationStarted", "l", context); Py_XDECREF(retVal); } } } } void OperationComplete( UInt32 context, int resultCode ) { if ( fPyObject ) { // Pass args. PyObject* pyArgs = PyObject_GetAttrString( fPyObject, "fCbArgs" ); if ( pyArgs ) { PyObject* pyDict = PyDict_New(); std::map args; fCbArgs.GetItems( args ); for ( std::map::iterator ii=args.begin(); ii!=args.end(); ++ii ) { UInt16 key = ii->first; PyObject* keyObj = PyInt_FromLong(key); char* strTemp = NULL; plCreatable* arg = ii->second; plCreatableGenericValue * genValue = plCreatableGenericValue::ConvertNoRef( arg ); if ( genValue ) { PyObject* valueObj; plGenericType & value = genValue->Value(); switch ( value.GetType() ) { case plGenericType::kInt: valueObj = PyLong_FromLong((Int32)value); PyDict_SetItem(pyDict, keyObj, valueObj); Py_DECREF(valueObj); break; case plGenericType::kUInt: valueObj = PyLong_FromUnsignedLong((UInt32)value); PyDict_SetItem(pyDict, keyObj, valueObj); Py_DECREF(valueObj); break; case plGenericType::kFloat: valueObj = PyFloat_FromDouble((float)value); PyDict_SetItem(pyDict, keyObj, valueObj); Py_DECREF(valueObj); break; case plGenericType::kDouble: valueObj = PyFloat_FromDouble((double)value); PyDict_SetItem(pyDict, keyObj, valueObj); Py_DECREF(valueObj); break; case plGenericType::kBool: if ((bool)value) valueObj = PyInt_FromLong(1); else valueObj = PyInt_FromLong(0); PyDict_SetItem(pyDict, keyObj, valueObj); Py_DECREF(valueObj); break; case plGenericType::kChar: strTemp = new char[2]; strTemp[0] = (char)value; strTemp[1] = 0; valueObj = PyString_FromString(strTemp); PyDict_SetItem(pyDict, keyObj, valueObj); Py_DECREF(valueObj); delete [] strTemp; break; case plGenericType::kString: valueObj = PyString_FromString((const char*)value); PyDict_SetItem(pyDict, keyObj, valueObj); Py_DECREF(valueObj); break; case plGenericType::kAny: break; case plGenericType::kNone: break; } } plNetServerSessionInfo * serverInfo = plNetServerSessionInfo::ConvertNoRef( arg ); if ( serverInfo ) { PyObject* valueObj = pyNetServerSessionInfo::New(*serverInfo); PyDict_SetItem(pyDict, keyObj, valueObj); Py_DECREF(valueObj); } Py_DECREF(keyObj); } PyObject_SetAttrString( fPyObject, "fCbArgs", pyDict ); Py_DECREF(pyDict); } // Call the callback. PyObject* func = PyObject_GetAttrString( fPyObject, "operationComplete" ); if ( func ) { if ( PyCallable_Check(func)>0 ) { PyObject* retVal = PyObject_CallMethod(fPyObject, "operationComplete", "li", context, resultCode); Py_XDECREF(retVal); } } } delete this; } }; //////////////////////////////////////////////////////////////////// // Error handler - throws exception in python script class pyNetClientCommErrorHandler : public plNetClientComm::ErrorHandler { public: void HandleError( Error err, int result ) { std::string msg; xtl::format( msg, "pyNetClientComm: Error: %s", plNetClientComm::ErrorHandler::ErrorStr( err ) ); PyErr_SetString(PyExc_KeyError, msg.c_str()); } } ThePyNetClientCommErrorHandler; //////////////////////////////////////////////////////////////////// // pyNetClientComm ---------------------------------------------- pyNetClientComm::pyNetClientComm() { fNetClient.SetErrorHandler( &ThePyNetClientCommErrorHandler ); } // ~pyNetClientComm ---------------------------------------------- pyNetClientComm::~pyNetClientComm() { } // NetAuthenticate ---------------------------------------------- int pyNetClientComm::NetAuthenticate( double maxAuthSecs, PyObject* cbClass/*=nil*/, UInt32 cbContext/*=0 */) { return fNetClient.NetAuthenticate( maxAuthSecs, new pyNetClientCommCallback( cbClass ), cbContext ); } // NetLeave ---------------------------------------------- int pyNetClientComm::NetLeave( UInt8 reason, PyObject* cbClass/*=nil*/, UInt32 cbContext/*=0 */) { return fNetClient.NetLeave( reason, new pyNetClientCommCallback( cbClass ), cbContext ); } // NetPing ---------------------------------------------- int pyNetClientComm::NetPing( int serverType, int timeoutSecs/*=0*/, PyObject* cbClass/*=nil*/, UInt32 cbContext/*=0 */) { return fNetClient.NetPing( serverType, timeoutSecs, new pyNetClientCommCallback( cbClass ), cbContext ); } // NetFindAge ---------------------------------------------- int pyNetClientComm::NetFindAge( const pyAgeLinkStruct* linkInfo, PyObject* cbClass/*=nil*/, UInt32 cbContext/*=0 */) { return fNetClient.NetFindAge( linkInfo->GetAgeLink(), new pyNetClientCommCallback( cbClass ), cbContext ); } // NetGetPlayerList ---------------------------------------------- int pyNetClientComm::NetGetPlayerList( PyObject* cbClass/*=nil*/, UInt32 cbContext/*=0 */) { return fNetClient.NetGetPlayerList( new pyNetClientCommCallback( cbClass ), cbContext ); } // NetSetActivePlayer ---------------------------------------------- int pyNetClientComm::NetSetActivePlayer( UInt32 playerID, const char* playerName, PyObject* cbClass/*=nil*/, UInt32 cbContext/*=0 */) { return fNetClient.NetSetActivePlayer( playerID, playerName, 0 /*ccrLevel*/, new pyNetClientCommCallback( cbClass ), cbContext ); } // NetCreatePlayer ---------------------------------------------- int pyNetClientComm::NetCreatePlayer( const char* playerName, const char* avatarShape, UInt32 createFlags, PyObject* cbClass/*=nil*/, UInt32 cbContext/*=0 */) { return fNetClient.NetCreatePlayer( playerName, avatarShape, createFlags, nil, nil, nil, new pyNetClientCommCallback( cbClass ), cbContext ); } // NetJoinAge ---------------------------------------------- int pyNetClientComm::NetJoinAge( PyObject* cbClass/*=nil*/, UInt32 cbContext/*=0 */) { return fNetClient.NetJoinAge( true /*tryP2P*/, true /*allowTimeout*/, new pyNetClientCommCallback( cbClass ), cbContext ); } // NetSetTimeout ---------------------------------------------- int pyNetClientComm::NetSetTimeout( float timeoutSecs, PyObject* cbClass/*=nil*/, UInt32 cbContext/*=0 */) { return fNetClient.NetSetTimeout( timeoutSecs, new pyNetClientCommCallback( cbClass ), cbContext ); } // SetLogLevel ---------------------------------------------- void pyNetClientComm::SetLogLevel( int logLevel ) { fNetClient.SetLogLevel( logLevel ); } // Startup ---------------------------------------------- int pyNetClientComm::Init( bool threaded/*=true */, int logLevel/*=0 */) { return fNetClient.Init( threaded, logLevel ); } // Shutdown ---------------------------------------------- int pyNetClientComm::Fini( float flushMsgsSecs/*=0.f */) { return fNetClient.Fini( flushMsgsSecs ); } // Update ---------------------------------------------- int pyNetClientComm::Update() { return fNetClient.Update( hsTimer::GetSeconds() ); } // SetActiveServer ---------------------------------------------- int pyNetClientComm::SetActiveServer( pyNetServerSessionInfo* nfo ) { return fNetClient.SetActiveServer( &nfo->ServerInfo() ); } // SetActiveServer2 ---------------------------------------------- int pyNetClientComm::SetActiveServer2( const char * addr, int port ) { plNetServerSessionInfo nfo; nfo.SetServerAddr( addr ); nfo.SetServerPort( port ); return fNetClient.SetActiveServer( &nfo ); } // SetAuthInfo ---------------------------------------------- int pyNetClientComm::SetAuthInfo( const char* acctName, const char* password ) { return fNetClient.SetAuthInfo( acctName, password ); } // SetLogByName ---------------------------------------------- void pyNetClientComm::SetLogByName( const char * name, UInt32 flags ) { plStatusLog * log = plStatusLogMgr::GetInstance().CreateStatusLog( 80, name, flags | plStatusLog::kTimestamp | plStatusLog::kDeleteForMe ); fNetClient.SetLog( log ); } // GetLog ---------------------------------------------- PyObject* pyNetClientComm::GetLog() const { return pyStatusLog::New( fNetClient.GetLog() ); } // SetServerSilenceTime ---------------------------------------------- void pyNetClientComm::SetServerSilenceTime( float secs ) { fNetClient.SetServerSilenceTime( secs ); } //////////////////////////////////////////////////////////////////// // End.