Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/proxy/src/lib/network/player_stats.cc @ 9522

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

new the message handler is checking, if this message is also for the local host. if not the system tries to relay the message

File size: 6.9 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: Christoph Renner
13   co-programmer: ...
14*/
15
16#include "player_stats.h"
17
18#include "class_list.h"
19#include "src/lib/util/loading/factory.h"
20
21#include "player.h"
22#include "state.h"
23#include "shared_network_data.h"
24
25#include "converter.h"
26
27#include "preferences.h"
28
29#include "debug.h"
30#include "shell_command.h"
31
32
33CREATE_FACTORY(PlayerStats, CL_PLAYER_STATS);
34
35
36/**
37 * constructor
38 */
39PlayerStats::PlayerStats( int userId )
40{
41  init();
42
43  this->userId = userId;
44}
45
46/**
47 * constructor
48 */
49PlayerStats::PlayerStats( const TiXmlElement* root )
50{
51  init();
52}
53
54void PlayerStats::init( )
55{
56  this->setClassID( CL_PLAYER_STATS, "PlayerStats" );
57
58  this->userId = 0;
59  this->teamId = TEAM_NOTEAM;
60  this->preferedTeamId = TEAM_NOTEAM;
61  this->score = 0;
62  this->playableClassId = 0;
63  this->modelFileName = "";
64  this->nickName = "Player";
65  this->oldNickName = "Player";
66
67  userId_handle = registerVarId( new SynchronizeableInt( &userId, &userId, "userId" ) );
68  teamId_handle = registerVarId( new SynchronizeableInt( &teamId, &teamId, "teamId" ) );
69  preferedTeamId_handle = registerVarId( new SynchronizeableInt( &preferedTeamId, &preferedTeamId, "preferedUserId" ) );
70  score_handle = registerVarId( new SynchronizeableInt( &score, &score, "score" ) );
71  playableClassId_handle = registerVarId( new SynchronizeableInt( &playableClassId, &playableClassId, "playableClassId") );
72  playableUniqueId_handle = registerVarId( new SynchronizeableInt( &playableUniqueId, &playableUniqueId, "playableUniqueId" ) );
73  modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName" ) );
74  nickName_handler = registerVarId( new SynchronizeableString( &nickName, &nickName, "nickName" ) );
75
76  MessageManager::getInstance()->registerMessageHandler( MSGID_CHANGENICKNAME, changeNickHandler, NULL );
77
78  PRINTF(0)("PlayerStats created\n");
79}
80
81
82/**
83 * standard deconstructor
84 */
85PlayerStats::~PlayerStats()
86{
87}
88
89
90 /**
91 * override this function to be notified on change
92 * of your registred variables.
93 * @param id id's which have changed
94  */
95void PlayerStats::varChangeHandler( std::list< int > & id )
96{
97  if ( std::find( id.begin(), id.end(), playableUniqueId_handle ) != id.end() )
98  {
99    this->setPlayableUniqueId( this->playableUniqueId );
100
101    PRINTF(0)("uniqueID changed %d %d %d\n", userId, SharedNetworkData::getInstance()->getHostID(), getUniqueID());
102  }
103
104  if ( std::find( id.begin(), id.end(), nickName_handler ) != id.end() )
105  {
106    PRINTF(0)("user %s is now known as %s\n", oldNickName.c_str(), nickName.c_str());
107    this->oldNickName = nickName;
108  }
109}
110
111
112
113/**
114 * get stats for user userId
115 * @param userId user's id
116 * @return stats assigned to user
117 */
118PlayerStats * PlayerStats::getStats( int userId )
119{
120  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
121
122  if ( !list )
123  {
124    return NULL;
125  }
126
127  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
128  {
129    if ( dynamic_cast<PlayerStats*>(*it)->getUserId() == userId )
130    {
131      return dynamic_cast<PlayerStats*>(*it);
132    }
133  }
134
135  return NULL;
136}
137
138/**
139 * set playable class id and set playable
140 */
141void PlayerStats::setPlayableUniqueId( int uniqueId )
142{
143  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYABLE );
144
145  if ( !list )
146  {
147    this->playableUniqueId = uniqueId;
148    return;
149  }
150
151  this->playable = NULL;
152  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
153  {
154    if ( dynamic_cast<Playable*>(*it)->getUniqueID() == uniqueId )
155    {
156      this->playable = dynamic_cast<Playable*>(*it);
157      //TODO when OM_PLAYERS is ticked add line:
158      //this->playable->toList( OM_PLAYERS );
159      break;
160    }
161  }
162
163  if ( this->playable && userId == SharedNetworkData::getInstance()->getHostID() )
164  {
165    State::getPlayer()->setPlayable( this->playable );
166    // also set the team id
167  }
168
169  this->playableUniqueId = uniqueId;
170}
171
172/**
173 * get playable associated to player
174 * @return playable associated to player
175 */
176Playable * PlayerStats::getPlayable()
177{
178  if ( playable )
179    return playable;
180
181  assert( playableUniqueId > 0 );
182
183  setPlayableUniqueId( playableUniqueId );
184
185  assert( playable );
186
187  return playable;
188}
189
190/**
191 * client sends server a message to change nick and server changes nick directly
192 * @param nick new nickname
193 */
194void PlayerStats::setNickName( std::string nick )
195{
196  if ( SharedNetworkData::getInstance()->isMasterServer())
197  {
198    this->nickName = nick;
199    PRINTF(0)("user %s is now known as %s\n", oldNickName.c_str(), nickName.c_str());
200    oldNickName = nickName;
201    return;
202  }
203  else
204  {
205    byte * data = new byte[nick.length()+INTSIZE];
206
207    assert( Converter::stringToByteArray( nick, data, nick.length()+INTSIZE) == nick.length()+INTSIZE );
208
209    MessageManager::getInstance()->sendMessage( MSGID_CHANGENICKNAME, data, nick.length()+INTSIZE, RT_SERVER, NET_MASTER_SERVER, MP_HIGHBANDWIDTH );
210    return;
211  }
212}
213
214bool PlayerStats::changeNickHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
215{
216  std::string newNick;
217  int res = Converter::byteArrayToString( data, newNick, dataLength );
218
219  if ( res != dataLength )
220  {
221    PRINTF(2)("invalid message size from user %d\n", senderId);
222    newNick = "invalid";
223  }
224
225  if ( PlayerStats::getStats( senderId) )
226    PlayerStats::getStats( senderId )->setNickName( newNick );
227
228  return true;
229}
230
231void PlayerStats::shellNick( const std::string& newNick )
232{
233  if ( getStats( SharedNetworkData::getInstance()->getHostID() ) )
234    getStats( SharedNetworkData::getInstance()->getHostID() )->setNickName( newNick );
235
236  Preferences::getInstance()->setString( "multiplayer", "nickname", newNick );
237}
238
239
240
241void PlayerStats::deleteAllPlayerStats( )
242{
243  const std::list<BaseObject*> * list;
244
245  while ( (list  = ClassList::getList( CL_PLAYER_STATS )) != NULL && list->begin() != list->end() )
246    delete *list->begin();
247}
248
249
250
251ScoreList PlayerStats::getScoreList( )
252{
253  ScoreList result;
254
255  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
256
257  if ( !list )
258  {
259    return result;
260  }
261
262  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
263  {
264    PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
265
266    TeamScoreList::iterator it = result[stats.getTeamId()].begin();
267
268    while (  it != result[stats.getTeamId()].end() && stats.score > it->score )
269    {
270      it++;
271    }
272
273    PlayerScore score;
274    score.name = stats.getNickName();
275    score.score = stats.getScore();
276
277    result[stats.getTeamId()].insert(it, score);
278  }
279
280  return result;
281}
Note: See TracBrowser for help on using the repository browser.