From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../x-cvsweb-markup&sortby=date/index.html | 556 +++++++++++++++++++++ 1 file changed, 556 insertions(+) create mode 100644 cvs/cvsweb.cgi/code/nel/src/net/callback_net_base.cpp?rev=1.33&content-type=text/x-cvsweb-markup&sortby=date/index.html (limited to 'cvs/cvsweb.cgi/code/nel/src/net/callback_net_base.cpp?rev=1.33&content-type=text/x-cvsweb-markup&sortby=date/index.html') diff --git a/cvs/cvsweb.cgi/code/nel/src/net/callback_net_base.cpp?rev=1.33&content-type=text/x-cvsweb-markup&sortby=date/index.html b/cvs/cvsweb.cgi/code/nel/src/net/callback_net_base.cpp?rev=1.33&content-type=text/x-cvsweb-markup&sortby=date/index.html new file mode 100644 index 00000000..b3f66b6e --- /dev/null +++ b/cvs/cvsweb.cgi/code/nel/src/net/callback_net_base.cpp?rev=1.33&content-type=text/x-cvsweb-markup&sortby=date/index.html @@ -0,0 +1,556 @@ + + + +code/nel/src/net/callback_net_base.cpp - view - 1.33 + +
[BACK] Return to callback_net_base.cpp + CVS log [TXT][DIR] Up to Nevrax / code / nel / src / net

File: Nevrax / code / nel / src / net / callback_net_base.cpp (download)
+Revision 1.33, Wed Jun 12 10:16:34 2002 UTC (6 weeks, 4 days ago) by lecroart +
Branch: MAIN +
CVS Tags: HEAD
Changes since 1.32: +4 -7 + lines
+ADDED: changed NULL into InvalidSockId
+
+

/** \file callback_net_base.cpp
+ * Network engine, layer 3, base
+ *
+ * $Id: callback_net_base.cpp,v 1.33 2002/06/12 10:16:34 lecroart Exp $
+ */
+
+/* Copyright, 2001 Nevrax Ltd.
+ *
+ * This file is part of NEVRAX NEL.
+ * NEVRAX NEL 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 2, or (at your option)
+ * any later version.
+
+ * NEVRAX NEL 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 NEVRAX NEL; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#include "stdnet.h"
+
+#include "nel/misc/string_id_array.h"
+#include "nel/misc/hierarchical_timer.h"
+
+#include "nel/net/buf_sock.h"
+#include "nel/net/callback_net_base.h"
+
+#ifdef USE_MESSAGE_RECORDER
+#pragma message ( "NeL Net layer 3: message recorder enabled" )
+#include "nel/net/message_recorder.h"
+#else
+#pragma message ( "NeL Net layer 3: message recorder disabled" )
+#endif
+
+
+using namespace std;
+using namespace NLMISC;
+
+namespace NLNET {
+
+
+/*
+ *
+ */
+void cbnbMessageRecvAssociations (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
+{
+        // receive a new message association
+
+        CStringIdArray::TStringId size;
+        msgin.serial (size);
+
+        nldebug ("LNETL3NB_ASSOC: The other side gave me %d association strings", size);
+
+        for (CStringIdArray::TStringId i = 0; i < size; i++)
+        {
+                std::string name;
+                CStringIdArray::TStringId id;
+
+                msgin.serial (name);
+                msgin.serial (id);
+
+                // if id == -1, it means that there are no callback associated to this message
+                // it should not happen, it mean that one side send a message that the other side
+                // can't manage in his callbackarray.
+                // to resolve the problem, add the callback in the callbackarray in the other side
+                // and put NULL if you don't want to manage this message
+                nlassert (id != -1);
+
+                nldebug ("LNETL3NB_ASSOC:  association '%s' -> %d", name.c_str (), id);
+                netbase.getSIDA().addString (name, id);
+        }
+}
+
+
+/*
+ * the other side want to know some of my association, send them!
+ */
+void cbnbMessageAskAssociations (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
+{
+        CMessage msgout (netbase.getSIDA(), "RA");
+        CStringIdArray::TStringId size;
+        msgin.serial (size);
+
+        nldebug ("LNETL3NB_ASSOC: The other side want %d string associations", size);
+
+        msgout.serial (size);
+
+        for (sint i = 0; i < size; i++)
+        {
+                string name;
+                msgin.serial (name);
+                nldebug ("LNETL3NB_ASSOC:  sending association '%s' -> %d", name.c_str (), netbase._OutputSIDA.getId(name));
+
+                // if this assert occurs, it means that the other side ask an unknown message
+                // or that there are different types of client (with differents callbackarray) and one of the client doesn't have this callback
+                nlassert(netbase._OutputSIDA.getId(name) != -1);
+
+                msgout.serial (name);
+
+                CStringIdArray::TStringId id = netbase._OutputSIDA.getId (name);
+                msgout.serial (id);
+        }
+        // send the message to the other side
+        netbase.send (msgout, from);
+}
+
+static TCallbackItem cbnbMessageAssociationArray[] =
+{
+        { "AA", cbnbMessageAskAssociations },
+        { "RA", cbnbMessageRecvAssociations },
+};
+
+
+/*
+ * Disconnection callback
+ */
+void cbnbNewDisconnection (TSockId from, void *data)
+{
+        nlassert (data != NULL);
+        CCallbackNetBase *base = (CCallbackNetBase *)data;
+
+        nldebug("LNETL3NB: cbnbNewDisconnection()");
+
+#ifdef USE_MESSAGE_RECORDER
+        // Record or replay disconnection
+        base->noticeDisconnection( from );
+#endif
+        
+        // Call the client callback if necessary
+        if (base->_DisconnectionCallback != NULL)
+                base->_DisconnectionCallback (from, base->_DisconnectionCbArg);
+}
+
+
+/*
+ * Constructor
+ */
+CCallbackNetBase::CCallbackNetBase(  TRecordingState rec, const string& recfilename, bool recordall ) :
+        _FirstUpdate (true), _DisconnectionCallback(NULL), _DisconnectionCbArg(NULL)
+#ifdef USE_MESSAGE_RECORDER
+        , _MR_RecordingState(rec), _MR_UpdateCounter(0)
+#endif
+{
+        _ThreadId = getThreadId ();
+        _NewDisconnectionCallback = cbnbNewDisconnection;
+
+        _BytesSent = 0;
+        _BytesReceived = 0;
+
+        createDebug(); // for addNegativeFilter to work even in release and releasedebug modes
+
+        // add the callback needed to associate messages with id
+        addCallbackArray (cbnbMessageAssociationArray, sizeof (cbnbMessageAssociationArray) / sizeof (cbnbMessageAssociationArray[0]));
+
+#ifdef USE_MESSAGE_RECORDER
+        switch ( _MR_RecordingState )
+        {
+        case Record :
+                _MR_Recorder.startRecord( recfilename, recordall );
+                break;
+        case Replay :
+                _MR_Recorder.startReplay( recfilename );
+                break;
+        default:;
+                // No recording
+        }
+#endif
+}
+
+
+/*
+ *      Append callback array with the specified array
+ */
+void CCallbackNetBase::addCallbackArray (const TCallbackItem *callbackarray, CStringIdArray::TStringId arraysize)
+{
+        checkThreadId ();
+
+        // be sure that the 2 array have the same size
+        nlassert (_CallbackArray.size () == (uint)_OutputSIDA.size ());
+
+        if (arraysize == 1 && callbackarray[0].Callback == NULL && string("") == callbackarray[0].Key)
+        {
+                // it's an empty array, ignore it
+                return;
+        }
+
+        // resize the array
+        sint oldsize = _CallbackArray.size();
+
+        _CallbackArray.resize (oldsize + arraysize);
+        _OutputSIDA.resize (oldsize + arraysize);
+
+//TOO MUCH MESSAGE      nldebug ("L3NB_CB: Adding %d callback to the array", arraysize);
+
+        for (sint i = 0; i < arraysize; i++)
+        {
+                CStringIdArray::TStringId ni = oldsize + i;
+//TOO MUCH MESSAGE              nldebug ("L3NB_CB: Adding callback to message '%s', id '%d'", callbackarray[i].Key, ni);
+                // copy callback value
+                
+                _CallbackArray[ni] = callbackarray[i];
+                // add the string to the string id array
+                _OutputSIDA.addString (callbackarray[i].Key, ni);
+
+        }
+//      nldebug ("LNETL3NB_CB: Added %d callback Now, there's %d callback associated with message type", arraysize, _CallbackArray.size ());
+}
+
+
+/*
+ * processOneMessage()
+ */
+void CCallbackNetBase::processOneMessage ()
+{
+        checkThreadId ();
+
+        H_AUTO (CCallbackNetBase_processOneMessage);
+
+        CMessage msgin (_OutputSIDA, "", true);
+        TSockId tsid;
+        receive (msgin, &tsid);
+
+        _BytesReceived += msgin.length ();
+
+        nldebug ("LNETL3NB: Received a message %s from %s", msgin.toString().c_str(), tsid->asString().c_str());
+        
+        // now, we have to call the good callback
+        NLMISC::CStringIdArray::TStringId pos = -1;
+        if (msgin.TypeHasAnId)
+        {
+                pos = msgin.getId ();
+        }
+        else
+        {
+                std::string name = msgin.getName ();
+                sint16 i;
+                for (i = 0; i < (sint16) _CallbackArray.size (); i++)
+                {
+                        if (name == _CallbackArray[i].Key)
+                        {
+                                pos = i;
+                                break;
+                        }
+                }
+        }
+
+        TMsgCallback        cb = NULL;
+        if (pos < 0 || pos >= (sint16) _CallbackArray.size ())
+        {
+                if (_DefaultCallback == NULL)
+                {
+                        nlwarning ("LNETL3NB_CB: Callback %s not found in _CallbackArray", msgin.toString().c_str());
+                }
+                else
+                {
+                        cb = _DefaultCallback;
+                }
+        }
+        else
+        {
+                cb = _CallbackArray[pos].Callback;
+        }
+
+        TSockId realid = getSockId (tsid);
+
+        if (!realid->AuthorizedCallback.empty() && msgin.getName() != realid->AuthorizedCallback)
+        {
+                nlwarning ("LNETL3NB_CB: %s try to call the callback %s but only %s is authorized. Disconnect him!", tsid->asString().c_str(), msgin.toString().c_str(), tsid->AuthorizedCallback.c_str());
+                disconnect (tsid);
+        }
+        else if (cb == NULL)
+        {
+                nlwarning ("LNETL3NB_CB: Callback %s is NULL, can't call it", msgin.toString().c_str());
+        }
+        else
+        {
+                nldebug ("LNETL3NB_CB: Calling callback (%s)%s", msgin.getName().c_str(), (cb==_DefaultCallback)?" DEFAULT_CB":"");
+                cb(msgin, realid, *this);
+        }
+        
+/*
+        if (pos < 0 || pos >= (sint16) _CallbackArray.size ())
+        {
+                if (_DefaultCallback == NULL)
+                        nlwarning ("LNETL3NB_CB: Callback %s not found in _CallbackArray", msgin.toString().c_str());
+                else
+                {
+                        // ...
+                }
+        }
+        else
+        {
+                TSockId realid = getSockId (tsid);
+
+                if (!realid->AuthorizedCallback.empty() && msgin.getName() != realid->AuthorizedCallback)
+                {
+                        nlwarning ("LNETL3NB_CB: %s try to call the callback %s but only %s is authorized. Disconnect him!", tsid->asString().c_str(), msgin.toString().c_str(), tsid->AuthorizedCallback.c_str());
+                        disconnect (tsid);
+                }
+                else if (_CallbackArray[pos].Callback == NULL)
+                {
+                        nlwarning ("LNETL3NB_CB: Callback %s is NULL, can't call it", msgin.toString().c_str());
+                }
+                else
+                {
+                        nldebug ("LNETL3NB_CB: Calling callback (%s)", _CallbackArray[pos].Key);
+                        _CallbackArray[pos].Callback (msgin, realid, *this);
+                }
+        }
+*/
+}
+
+
+
+/*
+ * baseUpdate
+ * Recorded : YES
+ * Replayed : YES
+ */
+void CCallbackNetBase::baseUpdate (sint32 timeout)
+{
+        checkThreadId ();
+
+        H_AUTO (CCallbackNetBase_baseUpdate);
+
+        nlassert( timeout >= -1 );
+        TTime t0 = CTime::getLocalTime();
+
+        //
+        // The first time, we init time counters
+        //
+        if (_FirstUpdate)
+        {
+//              nldebug("LNETL3NB: First update()");
+                _FirstUpdate = false;
+                _LastUpdateTime = t0;
+                _LastMovedStringArray = t0;
+        }
+
+        //
+        // Every 1 seconds if we have new unknown association, we ask them to the other side
+        //
+        if (t0 - _LastUpdateTime >  1000)
+        {
+//              nldebug("LNETL3NB: baseUpdate()");
+                _LastUpdateTime = t0;
+
+                const set<string> &sa = _InputSIDA.getNeedToAskedStringArray ();
+                if (!sa.empty ())
+                {
+                        CMessage msgout (_InputSIDA, "AA");
+                        //nlassert (sa.size () < 65536); // no size limit anymore
+                        CStringIdArray::TStringId size = sa.size ();
+                        nldebug ("LNETL3NB_ASSOC: I need %d string association, ask them to the other side", size);
+                        msgout.serial (size);
+                        for (set<string>::iterator it = sa.begin(); it != sa.end(); it++)
+                        {
+                                nldebug ("LNETL3NB_ASSOC:  what is the id of '%s'?", (*it).c_str ());
+                                string str(*it);
+                                msgout.serial (str);
+                        }
+                        // send the message to the other side
+                        send (msgout, 0);
+                        _InputSIDA.moveNeedToAskToAskedStringArray();
+                        _LastMovedStringArray = t0;
+                }
+        }
+
+        //
+        // Every 60 seconds if we have not answered association, we ask again to get them!
+        //
+        if (!_InputSIDA.getAskedStringArray().empty() && t0 - _LastMovedStringArray > 60000)
+        {
+                // we didn't have an answer for the association, resend them
+                const set<string> sa = _InputSIDA.getAskedStringArray ();
+                CMessage msgout (_InputSIDA, "AA");
+                //nlassert (sa.size () < 65536); // no size limit anymore
+                CStringIdArray::TStringId size = sa.size ();
+                nldebug ("LNETL3NB_ASSOC: client didn't answer my asked association, retry! I need %d string association, ask them to the other side", size);
+                msgout.serial (size);
+                for (set<string>::iterator it = sa.begin(); it != sa.end(); it++)
+                {
+                        nldebug ("LNETL3NB_ASSOC:  what is the id of '%s'?", (*it).c_str ());
+                        string str(*it);
+                        msgout.serial (str);
+                }
+                // sends the message to the other side
+                send (msgout, 0);
+                _LastMovedStringArray = t0;
+        }
+
+        /*
+         * timeout -1    =>  read one message in the queue
+         * timeout 0     =>  read all messages in the queue
+         * timeout other =>  read all messages in the queue until timeout expired (at least all one time)
+         */
+
+        bool exit = false;
+
+        while (!exit)
+        {
+                // process all messages in the queue
+                while (dataAvailable ())
+                {
+                        processOneMessage ();
+                        if (timeout == -1)
+                        {
+                                exit = true;
+                                break;
+                        }
+                }
+
+                // need to exit?
+                if (timeout == 0 || (sint32)(CTime::getLocalTime() - t0) > timeout)
+                {
+                        exit = true;
+                }
+                else
+                {
+                        // enable multithreading on windows :-/
+                        H_AUTO (CCallbackNetBase_baseUpdate_nlSleep);
+                        nlSleep (10);
+                }
+        }
+
+#ifdef USE_MESSAGE_RECORDER
+        _MR_UpdateCounter++;
+#endif
+
+}
+
+
+const   CInetAddress& CCallbackNetBase::hostAddress (TSockId hostid)
+{
+        // should never be called
+        nlstop;
+        static CInetAddress tmp;
+        return tmp;
+}
+
+void    CCallbackNetBase::setOtherSideAssociations (const char **associationarray, NLMISC::CStringIdArray::TStringId arraysize)
+{
+        checkThreadId ();
+
+        nldebug ("LNETL3NB_ASSOC: setOtherSideAssociations() sets %d association strings", arraysize);
+
+        for (sint i = 0; i < arraysize; i++)
+        {
+                nldebug ("LNETL3NB_ASSOC:  association '%s' -> %d", associationarray[i], i);
+                getSIDA().addString (associationarray[i], i);
+        }
+}
+
+void    CCallbackNetBase::displayAllMyAssociations ()
+{
+        checkThreadId ();
+
+        _OutputSIDA.display ();
+}
+
+void    CCallbackNetBase::authorizeOnly (const char *callbackName, TSockId hostid)
+{
+        checkThreadId ();
+
+        nldebug ("LNETL3NB: authorizeOnly (%s, %s)", callbackName, hostid->asString().c_str());
+
+        hostid = getSockId (hostid);
+        
+        nlassert (hostid != InvalidSockId);
+
+        hostid->AuthorizedCallback = (callbackName == NULL)?"":callbackName;
+}
+
+
+#ifdef USE_MESSAGE_RECORDER
+
+/*
+ * Replay dataAvailable() in replay mode
+ */
+bool CCallbackNetBase::replayDataAvailable()
+{
+        nlassert( _MR_RecordingState == Replay );
+
+        if ( _MR_Recorder.ReceivedMessages.empty() )
+        {
+                // Fill the queue of received messages related to the present update
+                _MR_Recorder.replayNextDataAvailable( _MR_UpdateCounter );
+        }
+
+        return replaySystemCallbacks();
+}
+
+
+/*
+ * Record or replay disconnection
+ */
+void CCallbackNetBase::noticeDisconnection( TSockId hostid )
+{
+        nlassert (hostid != InvalidSockId);        // invalid hostid
+        if ( _MR_RecordingState != Replay )
+        {
+                if ( _MR_RecordingState == Record )
+                {
+                        // Record disconnection
+                        CMessage emptymsg;
+                        _MR_Recorder.recordNext( _MR_UpdateCounter, Disconnecting, hostid, emptymsg );
+                }
+        }
+        else
+        {
+                // Replay disconnection
+                hostid->disconnect( false );
+        }
+}
+
+#endif // USE_MESSAGE_RECORDER
+
+
+
+/*
+ * checkThreadId
+ */
+void CCallbackNetBase::checkThreadId () const
+{
+/*      some people use this class in different thread but with a mutex to be sure to have
+        no concurent access
+        if (getThreadId () != _ThreadId)
+        {
+                nlerror ("You try to access to the same CCallbackClient or CCallbackServer with 2 differents thread (%d and %d)", _ThreadId, getThreadId());
+        }
+*/
+}
+
+
+} // NLNET
+
+
\ No newline at end of file -- cgit v1.2.1