Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/proxy/src/lib/network/proxy/proxy_control.cc @ 9625

Last change on this file since 9625 was 9625, checked in by patrick, 18 years ago

yet another weekend commit, quite much work done:

  • introduced a new PERMISSION layer: PERMISSION_SERVER: the nearest server hast authority
  • tightening up permissions: brand new implementation to prevent sending unused variables in the network (less smog in the net:D_
  • removed some compiler warnings from some central modules
  • networkmonitor interface changed to work with networknodes mainly
  • better debug output for the network monitor
  • networnode inteface standardisation
  • force reconnection commands integration
File size: 11.4 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Patrick Boenzli (patrick@orxonox.ethz.ch)
13*/
14
15#include "proxy_control.h"
16
17#include "class_list.h"
18#include "shell_command.h"
19
20#include "state.h"
21#include "shared_network_data.h"
22#include "network_manager.h"
23#include "network_game_manager.h"
24#include "ip.h"
25#include "peer_info.h"
26
27#include "converter.h"
28
29#include "preferences.h"
30
31#include "debug.h"
32
33#include "monitor/network_monitor.h"
34
35
36#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_NETWORK
37
38ProxyControl* ProxyControl::singletonRef = NULL;
39
40
41SHELL_COMMAND(forceReconnect, ProxyControl, forceReconnectionShell);
42
43/**
44 * constructor
45 */
46ProxyControl::ProxyControl()
47{
48  this->setClassID( CL_PROXY_CONTROL, "ProxyControl" );
49
50  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_NEWCLIENT, messageHandlerNewClient, NULL );
51  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_LEAVECLIENT, messageHandlerLeaveClient, NULL );
52  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_COMMAND, messageHandlerCommand, NULL );
53
54
55  PRINTF(0)("ProxyControl created\n");
56}
57
58
59/**
60 * standard deconstructor
61 */
62ProxyControl::~ProxyControl()
63{
64  ProxyControl::singletonRef = NULL;
65}
66
67
68 /**
69 * override this function to be notified on change
70 * of your registred variables.
71 * @param id id's which have changed
72  */
73void ProxyControl::varChangeHandler( std::list< int > & id )
74{
75//   if ( std::find( id.begin(), id.end(), playableUniqueId_handle ) != id.end() )
76//   {
77//     this->setPlayableUniqueId( this->playableUniqueId );
78//
79//     PRINTF(0)("uniqueID changed %d %d %d\n", userId, SharedNetworkData::getInstance()->getHostID(), getUniqueID());
80//   }
81}
82
83
84/**
85 *  signals new client connected to this local proxy
86 *
87 *  byte 0 - 3     :      userId
88 *  byte 4 - 7     :      ip address (IPaddress.host)
89 *
90 * @param userId userId of the new client
91 */
92void ProxyControl::signalNewClient(int userId)
93{
94  PRINTF(0)("Signaling new Client: %i\n", userId);
95  // make sure we are a proxy server
96  assert(SharedNetworkData::getInstance()->isProxyServerActive());
97
98  byte data[2 * INTSIZE];
99  // write the userId in the message
100  assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE );
101  // and the ip as an int
102  PeerInfo* pInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(userId);
103  assert(pInfo != NULL);
104  assert( Converter::intToByteArray( pInfo->ip.host(), data + INTSIZE, INTSIZE ) == INTSIZE );
105
106  MessageManager::getInstance()->sendMessage( MSGID_PROXY_NEWCLIENT, data, 2*INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
107}
108
109
110/**
111 * this is the handler for proxy signals: new clients
112 *
113 * @param messageType the type of the message
114 * @param data message data
115 * @param dataLength length of the message data
116 * @param someData some other atteched data
117 * @param senderId id of the sender client
118 * @param destinationId id of the destination client
119 * @return true if succeeded
120 */
121bool ProxyControl::messageHandlerNewClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
122{
123  // body data length correct?
124  if ( dataLength != 2 * INTSIZE )
125  {
126    PRINTF(2)("new client message has wrong size: %d\n", dataLength );
127    return true;
128  }
129  // read the userId fromt he message body
130  int newClientId = 0;
131  assert( Converter::byteArrayToInt( data, &newClientId) == INTSIZE );
132  // now read the ip address
133  int ipHost = 0;
134  assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE );
135
136  // register the new node at the network monitor
137  NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor();
138  NetworkNode* nNode = netMon->getNodeByUserId(senderId); // this gets the proxy server who sent the msg
139  PeerInfo* pInfo = new PeerInfo();
140  pInfo->bLocal = false;
141  pInfo->ip = IP(ipHost, 9999);
142  pInfo->nodeType = NET_CLIENT;
143  pInfo->userId = newClientId;
144  netMon->addNode(nNode, pInfo);
145
146  PRINTF(0)("Got Signal: from %i new player arrived with userId: %i and ip: %i\n", senderId, newClientId, pInfo->ip.ipString().c_str());
147  // part for the master server
148  if( SharedNetworkData::getInstance()->isMasterServer())
149  {
150    // we now create the new player ship and stuff...
151    NetworkGameManager::getInstance()->signalNewPlayer(newClientId);
152  }
153
154  return true;
155}
156
157
158
159/**
160 *  signals client disconnect
161 * @param userId userId of the old client
162 */
163void ProxyControl::signalLeaveClient(int userId)
164{
165  PRINTF(0)("Signaling new Client: %i\n", userId);
166  // make sure we are a proxy server
167  assert(SharedNetworkData::getInstance()->isProxyServerActive());
168
169  byte data[INTSIZE];
170
171  assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE );
172
173  MessageManager::getInstance()->sendMessage( MSGID_PROXY_LEAVECLIENT, data, INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
174}
175
176
177/**
178 * this is the handler for proxy signals: removing clients
179 *
180 * @param messageType the type of the message
181 * @param data message data
182 * @param dataLength length of the message data
183 * @param someData some other atteched data
184 * @param senderId id of the sender client
185 * @param destinationId id of the destination client
186 * @return true if succeeded
187 */
188bool ProxyControl::messageHandlerLeaveClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
189{
190  // body data length correct?
191  if ( dataLength != INTSIZE )
192  {
193    PRINTF(2)("leave client message has wrong size: %d\n", dataLength );
194    return true;
195  }
196  // read the userId fromt he message body
197  int leaveClientId = 0;
198  assert( Converter::byteArrayToInt( data, &leaveClientId) == INTSIZE );
199
200  // remove the node from the network monitor
201  NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor();
202  NetworkNode* nNode = netMon->getNodeByUserId(senderId); // this gets the proxy server who sent the msg
203  netMon->removeNode(nNode, netMon->getPeerByUserId(leaveClientId));
204
205  PRINTF(0)("Got Signal: from %i player left with userId: %i\n", senderId, leaveClientId);
206  // part for the master server
207  if( SharedNetworkData::getInstance()->isMasterServer())
208  {
209    // we now create the new player ship and stuff...
210    NetworkGameManager::getInstance()->signalLeftPlayer(leaveClientId);
211  }
212  else if(SharedNetworkData::getInstance()->isProxyServerActive())
213  {
214
215  }
216
217  return true;
218}
219
220
221
222/**
223 * forces a client to reconnect to another server
224 * @param userId the userId of the client/user :D
225 * @param newAddress the addresss the client should connect to (fully quali dns)
226 */
227void ProxyControl::forceReconnection(int userId, const std::string& newAddress)
228{
229  IP ipAddr = IP(newAddress, 9999);
230  this->forceReconnection(userId, newAddress);
231}
232
233
234
235/**
236 * thumb command: staticly reconnect node 10 to node 0
237 */
238void ProxyControl::forceReconnectionShellThumb()
239{
240  this->forceReconnectionShell(10, 0);
241}
242
243/**
244 * a shell command wrapper
245 * @param userId the userId of the client/user :D
246 * @param serverId the userId of the server to connect to
247 */
248void ProxyControl::forceReconnectionShell(int userId, int serverId)
249{
250  PRINTF(0)("shell reconnectoin command: %i to %i\n", userId, serverId);
251
252  this->forceReconnection(userId, serverId);
253}
254
255
256/**
257 * forces a client to reconnect to another server
258 * @param userId the userId of the client/user :D
259 * @param serverId the userId of the server to connect to
260 */
261void ProxyControl::forceReconnection(int userId, int serverId)
262{
263  PeerInfo* serverInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(serverId);
264  if( serverInfo == NULL)
265  {
266    PRINTF(0)("There is no server with userId %i registered in this network. Check the uid again\n", serverId);
267    return;
268  }
269  else if( serverInfo->isClient())
270  {
271    PRINTF(0)("You can't connec to to a client (userId %i)\n", serverId);
272    return;
273  }
274
275
276  this->forceReconnection(userId, serverInfo->ip);
277}
278
279
280/**
281 * forces a client to reconnect to another server
282 * @param userId the userId of the client/user :D
283 * @param newAddress the addresss the client should connect to
284 */
285void ProxyControl::forceReconnection(int userId, IP newAddress)
286{
287  PRINTF(0)("forcing reconnection: userId %i to %s\n", userId, newAddress.ipString().c_str());
288  // make sure we are a proxy server
289
290  if( SharedNetworkData::getInstance()->isClient())
291  {
292    PRINTF(0)("I am client, got no right to force reconnection\n");
293    return;
294  }
295
296
297  byte data[3 * INTSIZE];
298
299  // write type of message
300  int type = PXY_RECONNECT;
301  assert( Converter::intToByteArray( type, data, INTSIZE ) == INTSIZE );
302  // write the userId in the message
303  assert( Converter::intToByteArray( userId, data + INTSIZE, INTSIZE ) == INTSIZE );
304  // and the ip as an int
305  PeerInfo* pInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(userId);
306  if( pInfo == NULL)
307  {
308    PRINTF(0)("There is no client with userId %i registered in this network. Check the uid again\n", userId);
309    return;
310  }
311  else if( pInfo->isMasterServer() || pInfo->isProxyServerActive())
312  {
313    PRINTF(0)("You cannont reconnect a %s, abording\n", pInfo->getNodeTypeString().c_str());
314    return;
315  }
316  assert( Converter::intToByteArray( newAddress.host(), data + 2 * INTSIZE, INTSIZE ) == INTSIZE );
317
318  PRINTF(0)("Sending reconnection command to: %i\n", userId);
319  MessageManager::getInstance()->sendMessage( MSGID_PROXY_COMMAND, data, 3*INTSIZE, RT_ALL_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
320}
321
322
323/**
324 * this is the handler for proxy commands
325 *
326 * @param messageType the type of the message
327 * @param data message data
328 * @param dataLength length of the message data
329 * @param someData some other atteched data
330 * @param senderId id of the sender client
331 * @param destinationId id of the destination client
332 * @return true if succeeded
333 */
334bool ProxyControl::messageHandlerCommand( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
335{
336  // body data length correct?
337  if ( dataLength != 3 * INTSIZE )
338  {
339    PRINTF(1)("leave client message has wrong size: %d\n", dataLength );
340    return true;
341  }
342
343  // read the command type
344  int type = 0;
345  assert( Converter::byteArrayToInt( data, &type) == INTSIZE );
346  PRINTF(0)("got command from %i with code %i\n", senderId, type);
347
348  // now distingush all different sorts of commands
349  switch( type)
350  {
351    case PXY_RECONNECT:
352    {
353      // now read the user id
354      int userId;
355      assert( Converter::byteArrayToInt( data + INTSIZE, &userId) == INTSIZE );
356      // and read the dest address
357      int ipHost = 0;
358      assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE );
359
360      // handle it
361      if( SharedNetworkData::getInstance()->getHostID() == userId &&
362         (SharedNetworkData::getInstance()->isMasterServer() || SharedNetworkData::getInstance()->isProxyServerActive()))
363      {
364        NetworkManager::getInstance()->reconnectToServer(IP(ipHost, 9999));
365      }
366      break;
367    }
368    default:
369      PRINTF(0)("Command not known with id %i\n", type);
370  }
371
372
373  // part for the master server
374  if( SharedNetworkData::getInstance()->isMasterServer())
375  {
376    // we now create the new player ship and stuff...
377//     NetworkGameManager::getInstance()->signalLeftPlayer(leaveClientId);
378  }
379  else if(SharedNetworkData::getInstance()->isProxyServerActive())
380  {
381
382  }
383
384  return true;
385}
386
Note: See TracBrowser for help on using the repository browser.