Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

solved the spaceturret synch problem
@bensch: read my mail, everything is commented there. the turret should then work
@bensch2: can you then please take a look at the shell commands in ProxyControl (see mail) thx!
|

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