Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

proxy control commands implementation, specialy reconnection command

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