Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

the node registration now works perfectly and hirarchicaly

File size: 11.5 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  if( nNode == NULL)
140    PRINTF(0)("Couldn't find node %i! Error\n", senderId);
141  PeerInfo* pInfo = new PeerInfo();
142  pInfo->bLocal = false;
143  pInfo->ip = IP(ipHost, 9999);
144  pInfo->nodeType = NET_CLIENT;
145  pInfo->userId = newClientId;
146  netMon->addNode(nNode, pInfo);
147
148  PRINTF(0)("Got Signal: from %i new player arrived with userId: %i and ip: %s on %i\n", senderId, newClientId, pInfo->ip.ipString().c_str(), senderId);
149  // part for the master server
150  if( SharedNetworkData::getInstance()->isMasterServer())
151  {
152    // we now create the new player ship and stuff...
153    NetworkGameManager::getInstance()->signalNewPlayer(newClientId);
154  }
155
156  return true;
157}
158
159
160
161/**
162 *  signals client disconnect
163 * @param userId userId of the old client
164 */
165void ProxyControl::signalLeaveClient(int userId)
166{
167  PRINTF(0)("Signaling new Client: %i\n", userId);
168  // make sure we are a proxy server
169  assert(SharedNetworkData::getInstance()->isProxyServerActive());
170
171  byte data[INTSIZE];
172
173  assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE );
174
175  MessageManager::getInstance()->sendMessage( MSGID_PROXY_LEAVECLIENT, data, INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
176}
177
178
179/**
180 * this is the handler for proxy signals: removing clients
181 *
182 * @param messageType the type of the message
183 * @param data message data
184 * @param dataLength length of the message data
185 * @param someData some other atteched data
186 * @param senderId id of the sender client
187 * @param destinationId id of the destination client
188 * @return true if succeeded
189 */
190bool ProxyControl::messageHandlerLeaveClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
191{
192  // body data length correct?
193  if ( dataLength != INTSIZE )
194  {
195    PRINTF(2)("leave client message has wrong size: %d\n", dataLength );
196    return true;
197  }
198  // read the userId fromt he message body
199  int leaveClientId = 0;
200  assert( Converter::byteArrayToInt( data, &leaveClientId) == INTSIZE );
201
202  // remove the node from the network monitor
203  NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor();
204  NetworkNode* nNode = netMon->getNodeByUserId(senderId); // this gets the proxy server who sent the msg
205  netMon->removeNode(nNode, netMon->getPeerByUserId(leaveClientId));
206
207  PRINTF(0)("Got Signal: from %i player left with userId: %i\n", senderId, leaveClientId);
208  // part for the master server
209  if( SharedNetworkData::getInstance()->isMasterServer())
210  {
211    // we now create the new player ship and stuff...
212    NetworkGameManager::getInstance()->signalLeftPlayer(leaveClientId);
213  }
214  else if(SharedNetworkData::getInstance()->isProxyServerActive())
215  {
216
217  }
218
219  return true;
220}
221
222
223
224/**
225 * forces a client to reconnect to another server
226 * @param userId the userId of the client/user :D
227 * @param newAddress the addresss the client should connect to (fully quali dns)
228 */
229void ProxyControl::forceReconnection(int userId, const std::string& newAddress)
230{
231  IP ipAddr = IP(newAddress, 9999);
232  this->forceReconnection(userId, newAddress);
233}
234
235
236
237/**
238 * thumb command: staticly reconnect node 10 to node 0
239 */
240void ProxyControl::forceReconnectionShellThumb()
241{
242  this->forceReconnectionShell(10, 0);
243}
244
245/**
246 * a shell command wrapper
247 * @param userId the userId of the client/user :D
248 * @param serverId the userId of the server to connect to
249 */
250void ProxyControl::forceReconnectionShell(int userId, int serverId)
251{
252  PRINTF(0)("shell reconnectoin command: %i to %i\n", userId, serverId);
253
254  this->forceReconnection(userId, serverId);
255}
256
257
258/**
259 * forces a client to reconnect to another server
260 * @param userId the userId of the client/user :D
261 * @param serverId the userId of the server to connect to
262 */
263void ProxyControl::forceReconnection(int userId, int serverId)
264{
265  PeerInfo* serverInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(serverId);
266  if( serverInfo == NULL)
267  {
268    PRINTF(0)("There is no server with userId %i registered in this network. Check the uid again\n", serverId);
269    return;
270  }
271  else if( serverInfo->isClient())
272  {
273    PRINTF(0)("You can't connec to to a client (userId %i)\n", serverId);
274    return;
275  }
276
277
278  this->forceReconnection(userId, serverInfo->ip);
279}
280
281
282/**
283 * forces a client to reconnect to another server
284 * @param userId the userId of the client/user :D
285 * @param newAddress the addresss the client should connect to
286 */
287void ProxyControl::forceReconnection(int userId, IP newAddress)
288{
289  PRINTF(0)("forcing reconnection: userId %i to %s\n", userId, newAddress.ipString().c_str());
290  // make sure we are a proxy server
291
292  if( SharedNetworkData::getInstance()->isClient())
293  {
294    PRINTF(0)("I am client, got no right to force reconnection\n");
295    return;
296  }
297
298
299  byte data[3 * INTSIZE];
300
301  // write type of message
302  int type = PXY_RECONNECT;
303  assert( Converter::intToByteArray( type, data, INTSIZE ) == INTSIZE );
304  // write the userId in the message
305  assert( Converter::intToByteArray( userId, data + INTSIZE, INTSIZE ) == INTSIZE );
306  // and the ip as an int
307  PeerInfo* pInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(userId);
308  if( pInfo == NULL)
309  {
310    PRINTF(0)("There is no client with userId %i registered in this network. Check the uid again\n", userId);
311    return;
312  }
313  else if( pInfo->isMasterServer() || pInfo->isProxyServerActive())
314  {
315    PRINTF(0)("You cannont reconnect a %s, abording\n", pInfo->getNodeTypeString().c_str());
316    return;
317  }
318  assert( Converter::intToByteArray( newAddress.host(), data + 2 * INTSIZE, INTSIZE ) == INTSIZE );
319
320  PRINTF(0)("Sending reconnection command to: %i\n", userId);
321  MessageManager::getInstance()->sendMessage( MSGID_PROXY_COMMAND, data, 3*INTSIZE, RT_ALL_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
322}
323
324
325/**
326 * this is the handler for proxy commands
327 *
328 * @param messageType the type of the message
329 * @param data message data
330 * @param dataLength length of the message data
331 * @param someData some other atteched data
332 * @param senderId id of the sender client
333 * @param destinationId id of the destination client
334 * @return true if succeeded
335 */
336bool ProxyControl::messageHandlerCommand( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
337{
338  // body data length correct?
339  if ( dataLength != 3 * INTSIZE )
340  {
341    PRINTF(1)("leave client message has wrong size: %d\n", dataLength );
342    return true;
343  }
344
345  // read the command type
346  int type = 0;
347  assert( Converter::byteArrayToInt( data, &type) == INTSIZE );
348  PRINTF(0)("got command from %i with code %i\n", senderId, type);
349
350  // now distingush all different sorts of commands
351  switch( type)
352  {
353    case PXY_RECONNECT:
354    {
355      // now read the user id
356      int userId;
357      assert( Converter::byteArrayToInt( data + INTSIZE, &userId) == INTSIZE );
358      // and read the dest address
359      int ipHost = 0;
360      assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE );
361
362      // handle it
363      if( SharedNetworkData::getInstance()->getHostID() == userId &&
364         (SharedNetworkData::getInstance()->isMasterServer() || SharedNetworkData::getInstance()->isProxyServerActive()))
365      {
366        NetworkManager::getInstance()->reconnectToServer(IP(ipHost, 9999));
367      }
368      break;
369    }
370    default:
371      PRINTF(0)("Command not known with id %i\n", type);
372  }
373
374
375  // part for the master server
376  if( SharedNetworkData::getInstance()->isMasterServer())
377  {
378    // we now create the new player ship and stuff...
379//     NetworkGameManager::getInstance()->signalLeftPlayer(leaveClientId);
380  }
381  else if(SharedNetworkData::getInstance()->isProxyServerActive())
382  {
383
384  }
385
386  return true;
387}
388
Note: See TracBrowser for help on using the repository browser.