Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

tried again: shell. doesn't work:( don't know whats I did wrong…

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
41// SHELL_COMMAND(forceReconnect, ProxyControl, forceReconnectionShell);
42SHELL_COMMAND(bla, ProxyControl, forceReconnectionShellThumb);
43
44
45/**
46 * constructor
47 */
48ProxyControl::ProxyControl()
49{
50  this->setClassID( CL_PROXY_CONTROL, "ProxyControl" );
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  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: %i\n", senderId, newClientId, pInfo->ip.ipString().c_str());
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  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 node with userId %i registered in this network. Check the uid again\n");
267    return;
268  }
269  else if( serverInfo->isMasterServer() || serverInfo->isProxyServerActive())
270  {
271    PRINTF(0)("You can't connecto 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 node with userId %i registered in this network. Check the uid again\n");
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  MessageManager::getInstance()->sendMessage( MSGID_PROXY_COMMAND, data, 3*INTSIZE, RT_ALL_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
319}
320
321
322/**
323 * this is the handler for proxy commands
324 *
325 * @param messageType the type of the message
326 * @param data message data
327 * @param dataLength length of the message data
328 * @param someData some other atteched data
329 * @param senderId id of the sender client
330 * @param destinationId id of the destination client
331 * @return true if succeeded
332 */
333bool ProxyControl::messageHandlerCommand( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
334{
335  // body data length correct?
336  if ( dataLength != 3 * INTSIZE )
337  {
338    PRINTF(1)("leave client message has wrong size: %d\n", dataLength );
339    return true;
340  }
341
342  // read the command type
343  int type = 0;
344  assert( Converter::byteArrayToInt( data, &type) == INTSIZE );
345  PRINTF(0)("got command from %i with code %i\n", senderId, type);
346
347  // now distingush all different sorts of commands
348  switch( type)
349  {
350    case PXY_RECONNECT:
351    {
352      // now read the user id
353      int userId;
354      assert( Converter::byteArrayToInt( data + INTSIZE, &userId) == INTSIZE );
355      // and read the dest address
356      int ipHost = 0;
357      assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE );
358
359      // handle it
360      if( SharedNetworkData::getInstance()->getHostID() == userId &&
361         (SharedNetworkData::getInstance()->isMasterServer() || SharedNetworkData::getInstance()->isProxyServerActive()))
362      {
363        NetworkManager::getInstance()->reconnectToServer(IP(ipHost, 9999));
364      }
365      break;
366    }
367    default:
368      PRINTF(0)("Command not known with id %i\n", type);
369  }
370
371
372  // part for the master server
373  if( SharedNetworkData::getInstance()->isMasterServer())
374  {
375    // we now create the new player ship and stuff...
376//     NetworkGameManager::getInstance()->signalLeftPlayer(leaveClientId);
377  }
378  else if(SharedNetworkData::getInstance()->isProxyServerActive())
379  {
380
381  }
382
383  return true;
384}
385
Note: See TracBrowser for help on using the repository browser.