aboutsummaryrefslogtreecommitdiff
path: root/cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text
diff options
context:
space:
mode:
Diffstat (limited to 'cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text')
-rw-r--r--cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text/x-cvsweb-markup&sortby=date/index.html506
1 files changed, 506 insertions, 0 deletions
diff --git a/cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text/x-cvsweb-markup&sortby=date/index.html b/cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text/x-cvsweb-markup&sortby=date/index.html
new file mode 100644
index 00000000..f68bcdc7
--- /dev/null
+++ b/cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text/x-cvsweb-markup&sortby=date/index.html
@@ -0,0 +1,506 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML>
+<HEAD><style> A { color:black }</style>
+<!-- hennerik CVSweb $Revision: 1.93 $ -->
+<TITLE>code/nel/src/net/login_server.cpp - view - 1.16</TITLE></HEAD>
+<BODY BGCOLOR="#eeeeee">
+<table width="100%" border=0 cellspacing=0 cellpadding=1 bgcolor="#aaaaaa"><tr valign=bottom><td><a href="login_server.cpp?sortby=date"><IMG SRC="http://www.nevrax.org/inc/img/picto-up.gif" ALT="[BACK]" BORDER="0" WIDTH="14" HEIGHT="13"></a> <b>Return to <A HREF="login_server.cpp?sortby=date">login_server.cpp</A>
+ CVS log</b> <IMG SRC="http://www.nevrax.org/inc/img/picto-news.gif" ALT="[TXT]" BORDER="0" WIDTH="13" HEIGHT="15"></td><td align=right><IMG SRC="http://www.nevrax.org/inc/img/picto-dir.gif" ALT="[DIR]" BORDER="0" WIDTH="15" HEIGHT="13"> <b>Up to <a href="/cvs/cvsweb.cgi/?sortby=date">Nevrax</a> / <a href="/cvs/cvsweb.cgi/code/?sortby=date">code</a> / <a href="/cvs/cvsweb.cgi/code/nel/?sortby=date">nel</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/?sortby=date">src</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/net/?sortby=date">net</a></b></td></tr></table><HR noshade><table width="100%"><tr><td bgcolor="#ffffff">File: <a href="/cvs/cvsweb.cgi/?sortby=date">Nevrax</a> / <a href="/cvs/cvsweb.cgi/code/?sortby=date">code</a> / <a href="/cvs/cvsweb.cgi/code/nel/?sortby=date">nel</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/?sortby=date">src</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/net/?sortby=date">net</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?sortby=date">login_server.cpp</a>&nbsp;(<A HREF="/cvs/cvsweb.cgi/~checkout~/code/nel/src/net/login_server.cpp?rev=1.16&amp;sortby=date" target="cvs_checkout" onClick="window.open('/cvs/cvsweb.cgi/~checkout~/code/nel/src/net/login_server.cpp?rev=1.16','cvs_checkout','resizeable,scrollbars');"><b>download</b></A>)<BR>
+Revision <B>1.16</B>, <i>Tue Mar 26 09:44:47 2002 UTC</i> (4 months ago) by <i>lecroart</i>
+<BR>Branch: <b>MAIN</b>
+<BR>CVS Tags: <b>georges_v2, HEAD</b><BR>Changes since <b>1.15: +57 -20
+ lines</b><PRE>
+CHANGED: unified the command format
+</PRE>
+</td></tr></table><HR noshade><PRE>/** \file login_server.cpp
+ * CLoginServer is the interface used by the front end to accepts authenticate users.
+ *
+ * $Id: login_server.cpp,v 1.16 2002/03/26 09:44:47 lecroart Exp $
+ *
+ */
+
+/* Copyright, 2000 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 &quot;stdnet.h&quot;
+
+#include &quot;nel/net/callback_client.h&quot;
+#include &quot;nel/net/service.h&quot;
+
+#include &quot;nel/net/login_cookie.h&quot;
+#include &quot;nel/net/login_server.h&quot;
+
+#include &quot;nel/net/udp_sock.h&quot;
+
+using namespace std;
+using namespace NLMISC;
+
+namespace NLNET {
+
+struct CPendingUser
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;CPendingUser (const CLoginCookie &amp;cookie) : Cookie (cookie) { }
+ &nbsp; &nbsp; &nbsp; &nbsp;CLoginCookie Cookie;
+};
+
+static list&lt;CPendingUser&gt; PendingUsers;
+
+static CCallbackServer *Server;
+static string ListenAddr;
+
+static TDisconnectClientCallback DisconnectClientCallback = NULL;
+
+/// contains the correspondance between userid and the sockid
+map&lt;uint32, TSockId&gt; UserIdSockAssociations;
+
+TNewClientCallback NewClientCallback = NULL;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+///////////// CONNECTION TO THE WELCOME SERVICE //////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+void cbWSChooseShard (CMessage &amp;msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;// the WS call me that a new client want to come in my shard
+ &nbsp; &nbsp; &nbsp; &nbsp;string reason;
+ &nbsp; &nbsp; &nbsp; &nbsp;CLoginCookie cookie;
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;//
+ &nbsp; &nbsp; &nbsp; &nbsp;// S08: receive &quot;CS&quot; message from WS and send &quot;SCS&quot; message to WS
+ &nbsp; &nbsp; &nbsp; &nbsp;//
+
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (cookie);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;list&lt;CPendingUser&gt;::iterator it;
+ &nbsp; &nbsp; &nbsp; &nbsp;for (it = PendingUsers.begin(); it != PendingUsers.end (); it++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((*it).Cookie == cookie)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// the cookie already exists, erase it and return false
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlwarning (&quot;cookie %s is already in the pending user list&quot;, cookie.toString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PendingUsers.erase (it);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;reason = &quot;cookie already exists&quot;;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;if (it == PendingUsers.end ())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// add it to the awaiting client
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PendingUsers.push_back (CPendingUser (cookie));
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;reason = &quot;&quot;;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (CNetManager::getSIDA (&quot;WS&quot;), &quot;SCS&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (reason);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (cookie);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (ListenAddr);
+ &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send (&quot;WS&quot;, msgout);
+}
+
+void cbWSChooseShard5 (CMessage &amp;msgin, const std::string &amp;serviceName, uint16 sid)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;// the WS call me that a new client want to come in my shard
+ &nbsp; &nbsp; &nbsp; &nbsp;string reason;
+ &nbsp; &nbsp; &nbsp; &nbsp;CLoginCookie cookie;
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;//
+ &nbsp; &nbsp; &nbsp; &nbsp;// S08: receive &quot;CS&quot; message from WS and send &quot;SCS&quot; message to WS
+ &nbsp; &nbsp; &nbsp; &nbsp;//
+
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (cookie);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;list&lt;CPendingUser&gt;::iterator it;
+ &nbsp; &nbsp; &nbsp; &nbsp;for (it = PendingUsers.begin(); it != PendingUsers.end (); it++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((*it).Cookie == cookie)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// the cookie already exists, erase it and return false
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlwarning (&quot;cookie %s is already in the pending user list&quot;, cookie.toString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PendingUsers.erase (it);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;reason = &quot;cookie already exists&quot;;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;if (it == PendingUsers.end ())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// add it to the awaiting client
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;New cookie %s inserted in the pending user list (awaiting new client)&quot;, cookie.toString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PendingUsers.push_back (CPendingUser (cookie));
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;reason = &quot;&quot;;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (&quot;SCS&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (reason);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (cookie);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (ListenAddr);
+ &nbsp; &nbsp; &nbsp; &nbsp;CUnifiedNetwork::getInstance()-&gt;send (&quot;WS&quot;, msgout);
+}
+
+void cbWSDisconnectClient5 (CMessage &amp;msgin, const std::string &amp;serviceName, uint16 sid)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;// the WS tells me that i have to disconnect a client
+
+ &nbsp; &nbsp; &nbsp; &nbsp;uint32 userid;
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (userid);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;map&lt;uint32, TSockId&gt;::iterator it = UserIdSockAssociations.find (userid);
+ &nbsp; &nbsp; &nbsp; &nbsp;if (it == UserIdSockAssociations.end ())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlwarning (&quot;Can't disconnect the user %d, he is not found&quot;, userid);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlinfo (&quot;Disconnect the user %d&quot;, userid);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Server-&gt;disconnect ((*it).second);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;if (DisconnectClientCallback != NULL)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DisconnectClientCallback (userid);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+}
+
+void cbWSDisconnectClient (CMessage &amp;msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;cbWSDisconnectClient5 (msgin, &quot;&quot;, 0);
+}
+
+static TCallbackItem WSCallbackArray[] =
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;CS&quot;, cbWSChooseShard },
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;DC&quot;, cbWSDisconnectClient },
+};
+
+static TUnifiedCallbackItem WSCallbackArray5[] =
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;CS&quot;, cbWSChooseShard5 },
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;DC&quot;, cbWSDisconnectClient5 },
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+///////////// CONNECTION TO THE CLIENT ///////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+void cbShardValidation (CMessage &amp;msgin, TSockId from, CCallbackNetBase &amp;netbase)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;//
+ &nbsp; &nbsp; &nbsp; &nbsp;// S13: receive &quot;SV&quot; message from client
+ &nbsp; &nbsp; &nbsp; &nbsp;//
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// the client send me a cookie
+ &nbsp; &nbsp; &nbsp; &nbsp;CLoginCookie cookie;
+ &nbsp; &nbsp; &nbsp; &nbsp;string reason;
+ &nbsp; &nbsp; &nbsp; &nbsp;msgin.serial (cookie);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// verify that the user was pending
+ &nbsp; &nbsp; &nbsp; &nbsp;reason = CLoginServer::isValidCookie (cookie);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout2 (netbase.getSIDA (), &quot;SV&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout2.serial (reason);
+ &nbsp; &nbsp; &nbsp; &nbsp;netbase.send (msgout2, from);
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;if (!reason.empty())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlwarning (&quot;User (%s) is not in the pending user list (cookie:%s)&quot;, netbase.hostAddress(from).asString().c_str(), cookie.toString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// deconnect him
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;netbase.disconnect (from);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// add the user association
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uint32 userid = cookie.getUserId();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;UserIdSockAssociations.insert (make_pair(userid, from));
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// identification OK, let's call the user callback
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (NewClientCallback != NULL)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NewClientCallback (from, cookie);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// ok, now, he can call all callback
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Server-&gt;authorizeOnly (NULL, from);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+}
+
+void ClientConnection (TSockId from, void *arg)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;nldebug(&quot;new client connection: %s&quot;, from-&gt;asString ().c_str ());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// the client could only call &quot;SV&quot; message
+ &nbsp; &nbsp; &nbsp; &nbsp;Server-&gt;authorizeOnly (&quot;SV&quot;, from);
+}
+
+
+static const TCallbackItem ClientCallbackArray[] =
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;{ &quot;SV&quot;, cbShardValidation },
+};
+
+void cfcbListenAddress (CConfigFile::CVar &amp;var)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;// set the new ListenAddr
+ &nbsp; &nbsp; &nbsp; &nbsp;ListenAddr = var.asString();
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;// is the var is empty or not found, take it from the listenAddress()
+ &nbsp; &nbsp; &nbsp; &nbsp;if (ListenAddr.empty())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ListenAddr = Server-&gt;listenAddress ().asIPString();
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo(&quot;Listen Address trapped '%s'&quot;, ListenAddr.c_str());
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+///////////// CONNECTION TO THE WELCOME SERVICE //////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+void CLoginServer::init (CCallbackServer &amp;server, TNewClientCallback ncl)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;// connect to the welcome service
+ &nbsp; &nbsp; &nbsp; &nbsp;connectToWS ();
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// add callback to the server
+ &nbsp; &nbsp; &nbsp; &nbsp;server.addCallbackArray (ClientCallbackArray, sizeof (ClientCallbackArray) / sizeof (ClientCallbackArray[0]));
+ &nbsp; &nbsp; &nbsp; &nbsp;server.setConnectionCallback (ClientConnection, NULL);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;try
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cfcbListenAddress (IService::getInstance()-&gt;ConfigFile.getVar(&quot;ListenAddress&quot;));
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IService::getInstance()-&gt;ConfigFile.setCallback(&quot;ListenAddress&quot;, cfcbListenAddress);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;catch(Exception &amp;)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// if the listen addr is not in the config file, try to find it dynamically
+ &nbsp; &nbsp; &nbsp; &nbsp;if (ListenAddr.empty())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ListenAddr = server.listenAddress ().asIPString();
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo(&quot;Listen Address trapped '%s'&quot;, ListenAddr.c_str());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;NewClientCallback = ncl;
+ &nbsp; &nbsp; &nbsp; &nbsp;Server = &amp;server;
+}
+
+void CLoginServer::init (CUdpSock &amp;server, TDisconnectClientCallback dc)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;// connect to the welcome service
+ &nbsp; &nbsp; &nbsp; &nbsp;connectToWS ();
+
+ &nbsp; &nbsp; &nbsp; &nbsp;try
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cfcbListenAddress (IService::getInstance()-&gt;ConfigFile.getVar(&quot;ListenAddress&quot;));
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IService::getInstance()-&gt;ConfigFile.setCallback(&quot;ListenAddress&quot;, cfcbListenAddress);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;catch(Exception &amp;)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;
+ &nbsp; &nbsp; &nbsp; &nbsp;// if the listen addr is not in the config file, try to find it dynamically
+ &nbsp; &nbsp; &nbsp; &nbsp;if (ListenAddr.empty())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ListenAddr = server.localAddr ().asIPString();
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo(&quot;Listen Addresss trapped '%s'&quot;, ListenAddr.c_str());
+
+ &nbsp; &nbsp; &nbsp; &nbsp;DisconnectClientCallback = dc;
+}
+
+string CLoginServer::isValidCookie (const CLoginCookie &amp;lc)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;// verify that the user was pending
+ &nbsp; &nbsp; &nbsp; &nbsp;list&lt;CPendingUser&gt;::iterator it;
+ &nbsp; &nbsp; &nbsp; &nbsp;for (it = PendingUsers.begin(); it != PendingUsers.end (); it++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((*it).Cookie == lc)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// ok, it was validate, remove it
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PendingUsers.erase (it);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// warn the WS that the client effectively connected
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uint8 con = 1;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (&quot;CC&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uint32 userid = lc.getUserId();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (userid);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (con);
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (CUnifiedNetwork::isUsed ())
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CUnifiedNetwork::getInstance()-&gt;send(&quot;WS&quot;, msgout);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send(&quot;WS&quot;, msgout);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return &quot;&quot;;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;return &quot;I didn't receive the cookie from WS&quot;;
+}
+
+void CLoginServer::connectToWS ()
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;if (CUnifiedNetwork::isUsed ())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CUnifiedNetwork::getInstance()-&gt;addCallbackArray(WSCallbackArray5, sizeof(WSCallbackArray5)/sizeof(WSCallbackArray5[0]));
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::addClient (&quot;WS&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::addCallbackArray (&quot;WS&quot;, WSCallbackArray, sizeof (WSCallbackArray) / sizeof (WSCallbackArray[0]));
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CMessage &nbsp; &nbsp; &nbsp; &nbsp;msg(&quot;UN_SIDENT&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nlassert (IService::getInstance());
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uint16 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ssid = IService::getInstance()-&gt;getServiceId();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;string name = IService::getInstance()-&gt;getServiceShortName();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msg.serial(name);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msg.serial(ssid); &nbsp; &nbsp; &nbsp; &nbsp;// serializes a 16 bits service id
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send(&quot;WS&quot;, msg);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+}
+
+void CLoginServer::clientDisconnected (uint32 userId)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;uint8 con = 0;
+ &nbsp; &nbsp; &nbsp; &nbsp;CMessage msgout (&quot;CC&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (userId);
+ &nbsp; &nbsp; &nbsp; &nbsp;msgout.serial (con);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;if (CUnifiedNetwork::isUsed ())
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CUnifiedNetwork::getInstance()-&gt;send(&quot;WS&quot;, msgout);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::send(&quot;WS&quot;, msgout);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+
+ &nbsp; &nbsp; &nbsp; &nbsp;// remove the user association
+ &nbsp; &nbsp; &nbsp; &nbsp;UserIdSockAssociations.erase (userId);
+}
+
+//
+// Commands
+//
+
+NLMISC_COMMAND (lsUsers, &quot;displays the list of all connected users&quot;, &quot;&quot;)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;if(args.size() != 0) return false;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot;Display the %d connected users :&quot;, UserIdSockAssociations.size());
+ &nbsp; &nbsp; &nbsp; &nbsp;for (map&lt;uint32, TSockId&gt;::iterator it = UserIdSockAssociations.begin(); it != UserIdSockAssociations.end (); it++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot;&gt; %u %s&quot;, (*it).first, (*it).second-&gt;asString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot;End ot the list&quot;);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;return true;
+}
+
+NLMISC_COMMAND (lsPending, &quot;displays the list of all pending users&quot;, &quot;&quot;)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;if(args.size() != 0) return false;
+
+ &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot;Display the %d pending users :&quot;, PendingUsers.size());
+ &nbsp; &nbsp; &nbsp; &nbsp;for (list&lt;CPendingUser&gt;::iterator it = PendingUsers.begin(); it != PendingUsers.end (); it++)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot;&gt; %s&quot;, (*it).Cookie.toString().c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot;End ot the list&quot;);
+
+ &nbsp; &nbsp; &nbsp; &nbsp;return true;
+}
+
+
+NLMISC_DYNVARIABLE(string, LSListenAddress, &quot;the listen address sended to the client to connect on this front_end&quot;)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;if (get)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*pointer = ListenAddr;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((*pointer).find (&quot;:&quot;) == string::npos)
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot;You must set the address + port (ie: \&quot;itsalive.nevrax.org:38000\&quot;)&quot;);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else if ((*pointer).empty())
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ListenAddr = Server-&gt;listenAddress ().asIPString();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ListenAddr = *pointer;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;log.displayNL (&quot;Listen Address trapped '%s'&quot;, ListenAddr.c_str());
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+}
+
+
+} // NLNET
+
+
+/////////////////////////////////////////////
+/////////////////////////////////////////////
+/////////////////////////////////////////////
+/*
+#include &quot;v2/service.h&quot;
+
+using namespace std;
+using namespace NLNET;
+
+void ClientConnection (TSockId from, const CLoginCookie &amp;cookie)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo(&quot;player (%d) comes in&quot;, cookie.getUserId());
+ &nbsp; &nbsp; &nbsp; &nbsp;from-&gt;setAppId (cookie.getUserId());
+}
+
+void ClientDisconnection (TSockId from, void *arg)
+{
+ &nbsp; &nbsp; &nbsp; &nbsp;nlinfo(&quot;player (%d) leaves&quot;, from-&gt;appId());
+ &nbsp; &nbsp; &nbsp; &nbsp;CLoginServer::clientDisconnected (from-&gt;appId());
+
+}
+
+class CFrontEndService : public NLNET::IService
+{
+public:
+
+ &nbsp; &nbsp; &nbsp; &nbsp;/// Init the service, load the universal time.
+ &nbsp; &nbsp; &nbsp; &nbsp;void init ()
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CLoginServer::init (dynamic_cast&lt;CCallbackServer&amp;&gt;(*CNetManager::getNetBase (&quot;FES&quot;)), ClientConnection);
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CNetManager::getNetBase (&quot;FES&quot;)-&gt;setDisconnectionCallback (ClientDisconnection, NULL);
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+};
+
+
+/// Naming Service
+NLNET_SERVICE_MAIN (CFrontEndService, &quot;FES&quot;, &quot;front_end_service&quot;, 0);
+*/
+</PRE> \ No newline at end of file