Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9638 was 9638, checked in by patrick, 19 years ago

tests in redirection forcing

File size: 11.2 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  this->setSynchronized(false);
51
52  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_NEWCLIENT, messageHandlerNewClient, NULL );
53  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_LEAVECLIENT, messageHandlerLeaveClient, NULL );
54  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_COMMAND, messageHandlerCommand, NULL );
55
56
57  PRINTF(0)("ProxyControl created\n");
58}
59
60
61/**
62 * standard deconstructor
63 */
64ProxyControl::~ProxyControl()
65{
66  ProxyControl::singletonRef = NULL;
67}
68
69
70 /**
71 * override this function to be notified on change
72 * of your registred variables.
73 * @param id id's which have changed
74  */
75void ProxyControl::varChangeHandler( std::list< int > & id )
76{
77//   if ( std::find( id.begin(), id.end(), playableUniqueId_handle ) != id.end() )
78//   {
79//     this->setPlayableUniqueId( this->playableUniqueId );
80//
81//     PRINTF(0)("uniqueID changed %d %d %d\n", userId, SharedNetworkData::getInstance()->getHostID(), getUniqueID());
82//   }
83}
84
85
86/**
87 *  signals new client connected to this local proxy
88 *
89 *  byte 0 - 3     :      userId
90 *  byte 4 - 7     :      ip address (IPaddress.host)
91 *
92 * @param userId userId of the new client
93 */
94void ProxyControl::signalNewClient(int userId)
95{
96  PRINTF(0)("Signaling new Client: %i\n", userId);
97  // make sure we are a proxy server
98  assert(SharedNetworkData::getInstance()->isProxyServerActive());
99
100  byte data[2 * INTSIZE];
101  // write the userId in the message
102  assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE );
103  // and the ip as an int
104  PeerInfo* pInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(userId);
105  assert(pInfo != NULL);
106  assert( Converter::intToByteArray( pInfo->ip.host(), data + INTSIZE, INTSIZE ) == INTSIZE );
107
108  MessageManager::getInstance()->sendMessage( MSGID_PROXY_NEWCLIENT, data, 2*INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
109}
110
111
112/**
113 * this is the handler for proxy signals: new clients
114 *
115 * @param messageType the type of the message
116 * @param data message data
117 * @param dataLength length of the message data
118 * @param someData some other atteched data
119 * @param senderId id of the sender client
120 * @param destinationId id of the destination client
121 * @return true if succeeded
122 */
123bool ProxyControl::messageHandlerNewClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
124{
125  // body data length correct?
126  if ( dataLength != 2 * INTSIZE )
127  {
128    PRINTF(2)("new client message has wrong size: %d\n", dataLength );
129    return true;
130  }
131  // read the userId fromt he message body
132  int newClientId = 0;
133  assert( Converter::byteArrayToInt( data, &newClientId) == INTSIZE );
134  // now read the ip address
135  int ipHost = 0;
136  assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE );
137
138  // register the new node at the network monitor
139  NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor();
140  NetworkNode* nNode = netMon->getNodeByUserId(senderId); // this gets the proxy server who sent the msg
141  if( nNode == NULL)
142    PRINTF(0)("Couldn't find node %i! Error\n", senderId);
143  PeerInfo* pInfo = new PeerInfo();
144  pInfo->bLocal = false;
145  pInfo->ip = IP(ipHost, 9999);
146  pInfo->nodeType = NET_CLIENT;
147  pInfo->userId = newClientId;
148  netMon->addNode(nNode, pInfo);
149
150  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);
151  // part for the master server
152  if( SharedNetworkData::getInstance()->isMasterServer())
153  {
154    // we now create the new player ship and stuff...
155    NetworkGameManager::getInstance()->signalNewPlayer(newClientId);
156  }
157
158  return true;
159}
160
161
162
163/**
164 *  signals client disconnect
165 * @param userId userId of the old client
166 */
167void ProxyControl::signalLeaveClient(int userId)
168{
169  PRINTF(0)("Signaling new Client: %i\n", userId);
170  // make sure we are a proxy server
171  assert(SharedNetworkData::getInstance()->isProxyServerActive());
172
173  byte data[INTSIZE];
174
175  assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE );
176
177  MessageManager::getInstance()->sendMessage( MSGID_PROXY_LEAVECLIENT, data, INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
178}
179
180
181/**
182 * this is the handler for proxy signals: removing clients
183 *
184 * @param messageType the type of the message
185 * @param data message data
186 * @param dataLength length of the message data
187 * @param someData some other atteched data
188 * @param senderId id of the sender client
189 * @param destinationId id of the destination client
190 * @return true if succeeded
191 */
192bool ProxyControl::messageHandlerLeaveClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
193{
194  // body data length correct?
195  if ( dataLength != INTSIZE )
196  {
197    PRINTF(2)("leave client message has wrong size: %d\n", dataLength );
198    return true;
199  }
200  // read the userId fromt he message body
201  int leaveClientId = 0;
202  assert( Converter::byteArrayToInt( data, &leaveClientId) == INTSIZE );
203
204  // remove the node from the network monitor
205  NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor();
206  NetworkNode* nNode = netMon->getNodeByUserId(senderId); // this gets the proxy server who sent the msg
207  netMon->removeNode(nNode, netMon->getPeerByUserId(leaveClientId));
208
209  PRINTF(0)("Got Signal: from %i player left with userId: %i\n", senderId, leaveClientId);
210  // part for the master server
211  if( SharedNetworkData::getInstance()->isMasterServer())
212  {
213    // we now create the new player ship and stuff...
214    NetworkGameManager::getInstance()->signalLeftPlayer(leaveClientId);
215  }
216  else if(SharedNetworkData::getInstance()->isProxyServerActive())
217  {
218
219  }
220
221  return true;
222}
223
224
225
226/**
227 * forces a client to reconnect to another server
228 * @param userId the userId of the client/user :D
229 * @param newAddress the addresss the client should connect to (fully quali dns)
230 */
231void ProxyControl::forceReconnection(int userId, const std::string& newAddress)
232{
233  IP ipAddr = IP(newAddress, 9999);
234  this->forceReconnection(userId, newAddress);
235}
236
237
238
239/**
240 * thumb command: staticly reconnect node 10 to node 0
241 */
242void ProxyControl::forceReconnectionShellThumb()
243{
244  this->forceReconnectionShell(10, 0);
245}
246
247/**
248 * a shell command wrapper
249 * @param userId the userId of the client/user :D
250 * @param serverId the userId of the server to connect to
251 */
252void ProxyControl::forceReconnectionShell(int userId, int serverId)
253{
254  PRINTF(0)("shell reconnectoin command: %i to %i\n", userId, serverId);
255
256  this->forceReconnection(userId, serverId);
257}
258
259
260/**
261 * forces a client to reconnect to another server
262 * @param userId the userId of the client/user :D
263 * @param serverId the userId of the server to connect to
264 */
265void ProxyControl::forceReconnection(int userId, int serverId)
266{
267  PeerInfo* serverInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(serverId);
268  if( serverInfo == NULL)
269  {
270    PRINTF(0)("There is no server with userId %i registered in this network. Check the uid again\n", serverId);
271    return;
272  }
273  else if( serverInfo->isClient())
274  {
275    PRINTF(0)("You can't connec to to a client (userId %i)\n", serverId);
276    return;
277  }
278
279
280  this->forceReconnection(userId, serverInfo->ip);
281}
282
283
284/**
285 * forces a client to reconnect to another server
286 * @param userId the userId of the client/user :D
287 * @param newAddress the addresss the client should connect to
288 */
289void ProxyControl::forceReconnection(int userId, IP newAddress)
290{
291  PRINTF(0)("forcing reconnection: userId %i to %s\n", userId, newAddress.ipString().c_str());
292  // make sure we are a proxy server
293
294  if( SharedNetworkData::getInstance()->isClient())
295  {
296    PRINTF(0)("I am client, got no right to force reconnection\n");
297    return;
298  }
299
300
301  byte data[3 * INTSIZE];
302
303  // write type of message
304  int type = PXY_RECONNECT;
305  assert( Converter::intToByteArray( type, data, INTSIZE ) == INTSIZE );
306  // write the userId in the message
307  assert( Converter::intToByteArray( userId, data + INTSIZE, INTSIZE ) == INTSIZE );
308  // and the ip as an int
309  PeerInfo* pInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(userId);
310  if( pInfo == NULL)
311  {
312    PRINTF(0)("There is no client with userId %i registered in this network. Check the uid again\n", userId);
313    return;
314  }
315  else if( pInfo->isMasterServer() || pInfo->isProxyServerActive())
316  {
317    PRINTF(0)("You cannont reconnect a %s, abording\n", pInfo->getNodeTypeString().c_str());
318    return;
319  }
320  assert( Converter::intToByteArray( newAddress.host(), data + 2 * INTSIZE, INTSIZE ) == INTSIZE );
321
322  PRINTF(0)("Sending reconnection command to: %i\n", userId);
323  MessageManager::getInstance()->sendMessage( MSGID_PROXY_COMMAND, data, 3*INTSIZE, RT_USER, userId, MP_HIGHBANDWIDTH );
324}
325
326
327/**
328 * this is the handler for proxy commands
329 *
330 * @param messageType the type of the message
331 * @param data message data
332 * @param dataLength length of the message data
333 * @param someData some other atteched data
334 * @param senderId id of the sender client
335 * @param destinationId id of the destination client
336 * @return true if succeeded
337 */
338bool ProxyControl::messageHandlerCommand( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
339{
340  // body data length correct?
341  if ( dataLength != 3 * INTSIZE )
342  {
343    PRINTF(1)("leave client message has wrong size: %d\n", dataLength );
344    return true;
345  }
346
347  // read the command type
348  int type = 0;
349  assert( Converter::byteArrayToInt( data, &type) == INTSIZE );
350  PRINTF(0)("got command from %i with code %i\n", senderId, type);
351
352  // now distingush all different sorts of commands
353  switch( type)
354  {
355    case PXY_RECONNECT:
356    {
357      // now read the user id
358      int userId;
359      assert( Converter::byteArrayToInt( data + INTSIZE, &userId) == INTSIZE );
360      // and read the dest address
361      int ipHost = 0;
362      assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE );
363
364      PRINTF(0)("Got reconnection command from %i: reconnect!\n", senderId);
365      // handle it
366      if( SharedNetworkData::getInstance()->getHostID() == userId)
367      {
368        NetworkManager::getInstance()->reconnectToServer(IP(ipHost, 9999));
369      }
370      break;
371    }
372    default:
373      PRINTF(0)("Command not known with id %i\n", type);
374  }
375
376
377
378  return true;
379}
380
Note: See TracBrowser for help on using the repository browser.