1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2014-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
29 #include "game_share/generic_xml_msg_mngr.h"
30 #include "game_share/msg_client_server.h"
31 #include "game_share/bot_chat_types.h"
32 #include "game_share/mode_and_behaviour.h"
33 #include "game_share/chat_group.h"
34 #include "game_share/character_summary.h"
35 #include "game_share/sphrase_com.h"
36 #include "game_share/msg_client_server.h"
37 #include "game_share/ryzom_database_banks.h"
38 #include "game_share/msg_encyclopedia.h"
39 #include "game_share/prerequisit_infos.h"
40 #include "game_share/permanent_ban_magic_number.h"
41 #include "game_share/item_special_effect.h"
42 #include "game_share/combat_flying_text.h"
43 #include "game_share/shard_names.h"
45 #include "nel/gui/group_list.h"
46 #include "interface_v3/interface_manager.h"
47 #include "net_manager.h"
48 #include "client_cfg.h"
50 #include "client_chat_manager.h"
51 #include "world_database_manager.h"
52 #include "continent_manager.h"
53 #include "motion/user_controls.h"
54 #include "interface_v3/bot_chat_manager.h"
55 #include "interface_v3/bot_chat_page_all.h"
56 #include "interface_v3/bot_chat_page_trade.h"
57 #include "interface_v3/bot_chat_page_create_guild.h"
58 #include "interface_v3/obs_huge_list.h"
59 #include "string_manager_client.h"
60 #include "interface_v3/people_interraction.h"
61 #include "interface_v3/bot_chat_manager.h"
62 #include "interface_v3/bot_chat_page_all.h"
63 #include "nel/gui/view_text_id.h"
64 #include "nel/gui/ctrl_text_button.h"
65 #include "interface_v3/input_handler_manager.h"
66 #include "interface_v3/guild_manager.h"
67 #include "interface_v3/skill_manager.h"
69 #include "interface_v3/inventory_manager.h"
70 #include "interface_v3/sphrase_manager.h"
71 #include "outpost_manager.h"
72 #include "interface_v3/encyclopedia_manager.h"
73 #include "user_entity.h"
74 #include "init_main_loop.h"
75 #include "interface_v3/group_map.h"
76 #include "sound_manager.h"
77 #include "interface_v3/group_compas.h"
78 #include "interface_v3/group_html_webig.h"
79 #include "interface_v3/bar_manager.h"
80 #include "permanent_ban.h"
82 #include "connection.h"
83 #include "faction_war_manager.h"
86 #include "r2/editor.h"
87 #include "game_share/r2_share_itf.h"
88 #include "game_share/r2_types.h"
90 #include "interface_v3/action_handler_base.h"
99 #define OLD_STRING_SYSTEM
100 #define BAR_STEP_TP 2
105 using namespace NLMISC
;
106 using namespace NL3D
;
110 extern bool FirstFrame
;
111 extern void selectTipsOfTheDay (uint tips
);
117 CGenericXmlMsgHeaderManager GenericMsgHeaderMngr
; // Manage messages
119 CNetManagerMulti NetMngr
; // Manage the connection.
121 CNetManager NetMngr
; // Manage the connection.
124 bool UseFemaleTitles
= false;
126 bool serverReceivedReady
= false;
128 static const std::string PLAYER_EXCHANGE_INVITATION_DIALOG
= "ui:interface:accept_trade_invitation";
130 // Hierarchical timer
131 H_AUTO_DECL ( RZ_Client_Net_Mngr_Update
)
136 extern bool noUserChar
; // \todo GUIGUI : do this better.
137 extern bool userChar
; // \todo GUIGUI : do this better.
138 extern std::vector
<CCharacterSummary
> CharacterSummaries
;
139 extern uint8 ServerPeopleActive
;
140 extern uint8 ServerCareerActive
;
141 extern vector
<CMainlandSummary
> Mainlands
;
142 extern bool UserCharPosReceived
;
143 extern CGenericXmlMsgHeaderManager GenericMsgHeaderMngr
;
144 extern CClientChatManager ChatMngr
;
146 extern bool CharNameValidArrived
;
147 extern bool CharNameValid
;
148 bool IsInRingSession
= false;
149 TSessionId HighestMainlandSessionId
; // highest in the position stack
151 extern const char *CDBBankNames
[INVALID_CDB_BANK
+1];
153 void cbImpulsionGatewayOpen(NLMISC::CBitMemStream
&bms
);
154 void cbImpulsionGatewayMessage(NLMISC::CBitMemStream
&bms
);
155 void cbImpulsionGatewayClose(NLMISC::CBitMemStream
&bms
);
163 void impulseDatabaseInitPlayer(NLMISC::CBitMemStream
&impulse
)
167 sint32 p
= impulse
.getPos();
169 // get the egs tick of this change
170 TGameCycle serverTick
;
171 impulse
.serial(serverTick
);
174 IngameDbMngr
.readDelta( serverTick
, impulse
, CDBPlayer
);
175 IngameDbMngr
.setInitPacketReceived();
176 nlinfo( "DB_INIT:PLR done (%u bytes)", impulse
.getPos()-p
);
178 catch (const Exception
&e
)
180 BOMB( NLMISC::toString( "Problem while decoding a DB_INIT:PLR msg, skipped: %s", e
.what() ), return );
184 void impulseDatabaseUpdatePlayer(NLMISC::CBitMemStream
&impulse
)
188 // get the egs tick of this change
189 TGameCycle serverTick
;
190 impulse
.serial(serverTick
);
193 IngameDbMngr
.readDelta( serverTick
, impulse
, CDBPlayer
); // unlike on the server, here there is only one unified CCDBSynchronized object
195 catch (const Exception
&e
)
198 BOMB( NLMISC::toString( "Problem while decoding a DB_UPDATE_PLR msg, skipped: %s", e
.what() ), return );
202 template <class CInventoryCategoryTemplate
>
203 void updateInventoryFromStream(NLMISC::CBitMemStream
&impulse
, const CInventoryCategoryTemplate
*templ
, bool notifyItemSheetChanges
);
205 void impulseDatabaseUpdateBank(NLMISC::CBitMemStream
&impulse
)
207 uint32 bank
= INVALID_CDB_BANK
;
210 // get the egs tick of this change
211 TGameCycle serverTick
;
212 impulse
.serial(serverTick
);
216 FILL_nbits_WITH_NB_BITS_FOR_CDBBANK
217 impulse
.serial( bank
, nbits
);
220 IngameDbMngr
.readDelta( serverTick
, impulse
, (TCDBBank
)bank
);
222 // read guild inventory update
223 if ( bank
== CDBGuild
)
225 updateInventoryFromStream( impulse
, (INVENTORIES::CInventoryCategoryForGuild
*)NULL
, false );
228 catch (const Exception
&e
)
230 BOMB( NLMISC::toString( "Problem while decoding a DB_GROUP:UPDATE_BANK %s msg, skipped: %s", CDBBankNames
[bank
], e
.what() ), return );
234 void impulseDatabaseInitBank(NLMISC::CBitMemStream
&impulse
)
236 uint32 bank
= INVALID_CDB_BANK
;
239 // get the egs tick of this change
240 TGameCycle serverTick
;
241 impulse
.serial(serverTick
);
245 FILL_nbits_WITH_NB_BITS_FOR_CDBBANK
246 impulse
.serial( bank
, nbits
);
249 IngameDbMngr
.readDelta( serverTick
, impulse
, (TCDBBank
)bank
);
250 nldebug( "CDB: DB_GROUP:INIT_BANK %s", CDBBankNames
[bank
] );
252 // read guild inventory update
253 if ( bank
== CDBGuild
)
255 updateInventoryFromStream( impulse
, (INVENTORIES::CInventoryCategoryForGuild
*)NULL
, false );
258 catch (const Exception
&e
)
260 BOMB( NLMISC::toString( "Problem while decoding a DB_GROUP:INIT_BANK %s msg, skipped: %s", CDBBankNames
[bank
], e
.what() ), return );
264 void impulseDatabaseResetBank(NLMISC::CBitMemStream
&impulse
)
266 uint32 bank
= INVALID_CDB_BANK
;
269 // get the egs tick of this change
270 TGameCycle serverTick
;
271 impulse
.serial(serverTick
);
273 // read the bank to reset
275 FILL_nbits_WITH_NB_BITS_FOR_CDBBANK
276 impulse
.serial( bank
, nbits
);
279 IngameDbMngr
.resetBank( serverTick
, bank
);
280 nldebug( "CDB: DB_GROUP:RESET_BANK %s", CDBBankNames
[bank
] );
282 catch (const Exception
&e
)
284 BOMB( NLMISC::toString( "Problem while decoding a DB_GROUP:RESET_BANK %s msg, skipped: %s", CDBBankNames
[bank
], e
.what() ), return );
288 static void readPrivileges(NLMISC::CBitMemStream
&impulse
)
290 nlassert(impulse
.isReading());
291 // nico : temporarily uses a try block here to avoid prb with people having updated client and not the server
294 impulse
.serial(UserPrivileges
);
296 catch(const EStreamOverflow
&)
298 nlwarning("User privileges not serialised, assuming none");
299 UserPrivileges
.clear();
303 void impulseNoUserChar(NLMISC::CBitMemStream
&impulse
)
305 // received NO_USER_CHAR
306 //nlinfo("impulseCallBack : Received CONNECTION:NO_USER_CHAR");
308 impulse
.serial(ServerPeopleActive
);
309 impulse
.serial(ServerCareerActive
);
310 readPrivileges(impulse
);
311 impulse
.serialCont(Mainlands
);
312 CharacterSummaries
.clear();
315 LoginSM
.pushEvent(CLoginStateMachine::ev_no_user_char
);
317 updatePatcherPriorityBasedOnCharacters();
320 void impulseFarTP(NLMISC::CBitMemStream
&impulse
)
323 TSessionId sessionId
;
324 impulse
.serial(sessionId
);
325 //nlinfo("impulseCallback : Received CONNECTION:FAR_TP %u", sessionId.asInt());
326 bool bailOutIfSessionVanished
;
327 impulse
.serial(bailOutIfSessionVanished
);
328 FarTP
.requestFarTPToSession(sessionId
, PlayerSelectedSlot
, CFarTP::JoinSession
, bailOutIfSessionVanished
);
332 static std::string
lookupSrcKeyFile(const std::string
&src
)
334 if (CFile::isExists("save/" + src
)) return "save/" + src
;
335 return CPath::lookup(src
, false);
338 void copyKeySet(const std::string
&srcPath
, const std::string
&destPath
)
340 // can't use CFile copyFile here, because src may be in a bnp file
342 srcStr
.resize(CFile::getFileSize(srcPath
));
345 nlwarning("Can't copy keys from %s : file not found or empty");
350 CIFile
ifile(srcPath
);
351 ifile
.serialBuffer((uint8
*) &srcStr
[0], (uint
)srcStr
.size());
352 COFile
ofile(destPath
);
353 ofile
.serialBuffer((uint8
*) &srcStr
[0], (uint
)srcStr
.size());
355 catch(const EStream
&)
357 nlwarning("Couldn't copy %s to %s to create new character keyset", srcPath
.c_str(), destPath
.c_str());
361 void impulseUserChars(NLMISC::CBitMemStream
&impulse
)
363 // received USER_CHARS
364 //nlinfo("impulseCallBack : Received CONNECTION:USER_CHARS");
366 impulse
.serial(ServerPeopleActive
);
367 impulse
.serial(ServerCareerActive
);
368 // read characters summary
369 CharacterSummaries
.clear();
370 impulse
.serialCont (CharacterSummaries
);
371 // read shard name summaries
372 std::vector
<string
> shardNames
;
373 impulse
.serialCont (shardNames
);
374 CShardNames::getInstance().loadShardNames(shardNames
);
376 readPrivileges(impulse
);
377 impulse
.serial(FreeTrial
);
379 impulse
.serialCont(Mainlands
);
382 LoginSM
.pushEvent(CLoginStateMachine::ev_chars_received
);
384 // Create the message for the server to select the first character.
385 /* CBitMemStream out;
386 if(GenericMsgHeaderMngr.pushNameToStream("CONNECTION:SELECT_CHAR", out))
388 CSelectCharMsg SelectCharMsg;
389 SelectCharMsg.c = 0; //TODO set here the character choosen by player
390 out.serial( SelectCharMsg );
392 NetMngr.send(NetMngr.getCurrentServerTick());
393 // send CONNECTION:USER_CHARS
394 nldebug("impulseCallBack : CONNECTION:SELECT_CHAR sent");
397 nlwarning("impulseCallBack : unknown message name : 'CONNECTION:SELECT_CHAR'.");
402 if (!NewKeysCharNameValidated
.empty())
404 // if there's a new char for which a key set was wanted, create it now
405 for (uint k
= 0; k
< CharacterSummaries
.size(); ++k
)
407 if (toLower(CharacterSummaries
[k
].Name
.toUtf8()) == toLower(NewKeysCharNameValidated
))
409 // first, stripes server name
410 copyKeySet(lookupSrcKeyFile(GameKeySet
), "save/keys_" + buildPlayerNameForSaveFile(NewKeysCharNameValidated
) + ".xml");
411 copyKeySet(lookupSrcKeyFile(RingEditorKeySet
), "save/keys_r2ed_" + buildPlayerNameForSaveFile(NewKeysCharNameValidated
) + ".xml");
416 updatePatcherPriorityBasedOnCharacters();
419 void impulseUserChar(NLMISC::CBitMemStream
&impulse
)
421 // received USER_CHAR
422 //nlinfo("impulseCallBack : Received CONNECTION:USER_CHAR");
424 // Serialize the message
425 COfflineEntityState posState
;
426 extern uint8 ServerSeasonValue
;
427 extern bool ServerSeasonReceived
;
429 CUserCharMsg::read( impulse
, posState
, ServerSeasonValue
, userRole
, IsInRingSession
, HighestMainlandSessionId
, CharFirstConnectedTime
, CharPlayedTime
);
430 ServerSeasonReceived
= true; // set the season that will be used when selecting the continent from the position
434 UserEntity
->pos(CVectorD((float)posState
.X
/1000.0f
, (float)posState
.Y
/1000.0f
, (float)posState
.Z
/1000.0f
));
435 UserEntity
->front(CVector((float)cos(posState
.Heading
), (float)sin(posState
.Heading
), 0.f
));
436 UserEntity
->dir(UserEntity
->front());
437 UserEntity
->setHeadPitch(0);
438 UserControls
.resetCameraDeltaYaw();
439 //nldebug("<impulseUserChar> pos : %f %f %f heading : %f",UserEntity->pos().x,UserEntity->pos().y,UserEntity->pos().z,posState.Heading);
441 // Update the position for the vision.
442 NetMngr
.setReferencePosition(UserEntity
->pos());
446 UserEntityInitPos
= CVectorD((float)posState
.X
/1000.0f
, (float)posState
.Y
/1000.0f
, (float)posState
.Z
/1000.0f
);
447 UserEntityInitFront
= CVector((float)cos(posState
.Heading
), (float)sin(posState
.Heading
), 0.f
);
448 //nldebug("<impulseUserChar> pos : %f %f %f heading : %f",UserEntityInitPos.x,UserEntityInitPos.y,UserEntityInitPos.z,posState.Heading);
450 // Update the position for the vision.
451 NetMngr
.setReferencePosition(UserEntityInitPos
);
454 UserCharPosReceived
= true;
456 // Configure the ring editor
457 extern R2::TUserRole UserRoleInSession
;
458 UserRoleInSession
= R2::TUserRole::TValues(userRole
);
459 ClientCfg
.R2EDEnabled
= IsInRingSession
/*&& (UserRoleInSession.getValue() != R2::TUserRole::ur_player)*/;
460 // !!!Do NOT uncomment the following line do the ClientCfg.R2EDEnabled = IsInRingSession && (UserRoleInSession != R2::TUserRole::ur_player);
461 // even with UserRoleInSession R2::TUserRole::ur_player the ring features must be activated
462 // because if the ring is not activated the dss do not know the existence of the player
463 // So we can not kick him, tp to him, tp in to next act ....
464 nldebug( "EnableR2Ed = %u, IsInRingSession = %u, UserRoleInSession = %u", (uint
)ClientCfg
.R2EDEnabled
, (uint
)IsInRingSession
, userRole
);
466 updatePatcherPriorityBasedOnCharacters();
469 void impulseCharNameValid(NLMISC::CBitMemStream
&impulse
)
471 //nlinfo("impulseCallBack : Received CONNECTION:VALID_NAME");
473 impulse
.serial(nTmp
);
474 CharNameValid
= ((nTmp
!= 0) ? true : false);
475 CharNameValidArrived
= true;
476 if (CharNameValid
) NewKeysCharNameValidated
= NewKeysCharNameWanted
;
480 void checkHandshake( NLMISC::CBitMemStream
&impulse
)
482 // Decode handshake to check versions
483 uint16 handshakeVersion
;
484 uint16 itemSlotVersion
;
485 impulse
.serial( handshakeVersion
);
486 if ( handshakeVersion
> 0 )
487 nlerror( "Server handshake version is more recent than client one" );
488 impulse
.serial( itemSlotVersion
);
489 if ( itemSlotVersion
!= INVENTORIES::CItemSlot::getVersion() )
490 nlerror( "Handshake: itemSlotVersion mismatch (S:%hu C:%hu)", itemSlotVersion
, INVENTORIES::CItemSlot::getVersion() );
494 void impulseServerReady(NLMISC::CBitMemStream
&impulse
)
496 // received CONNECTION:READY
497 //nlinfo("impulseCallBack : Received CONNECTION:READY");
499 serverReceivedReady
= true;
501 checkHandshake( impulse
);
503 LoginSM
.pushEvent(CLoginStateMachine::ev_ready_received
);
506 void impulseShardId(NLMISC::CBitMemStream
&impulse
)
511 impulse
.serial(shardId
);
515 impulse
.serial(webHost
);
516 if (!webHost
.empty())
521 nlinfo("WEB: Received SHARD_ID %d, web hosted at '%s', using '%s'", shardId
, webHost
.c_str(), WebServer
.c_str());
524 void impulseServerQuitOk(NLMISC::CBitMemStream
&impulse
)
526 // receive CONNECTION:SERVER_QUIT_OK
527 if (FarTP
.isFarTPInProgress())
529 FarTP
.onServerQuitOk();
533 // ensure first a quit request is really asked
534 if(game_exit_request
)
543 void impulseServerQuitAbort(NLMISC::CBitMemStream
&impulse
)
545 // receive CONNECTION:SERVER_QUIT_ABORT
546 if (FarTP
.isFarTPInProgress())
548 FarTP
.onServerQuitAbort();
552 // abort any quit request
553 game_exit_request
= false;
554 ryzom_exit_request
= false;
558 void impulseMailNotification(NLMISC::CBitMemStream
&impulse
)
560 if (PermanentlyBanned
) return;
561 // receive CONNECTION:MAIL_AVAILABLE
562 CInterfaceManager::getInstance()->notifyMailAvailable();
565 void impulseForumNotification(NLMISC::CBitMemStream
&impulse
)
567 if (PermanentlyBanned
) return;
568 // receive CONNECTION:GUILD_MESSAGE_AVAILABLE
569 CInterfaceManager::getInstance()->notifyForumUpdated();
573 void impulsePermanentBan(NLMISC::CBitMemStream
&impulse
)
576 impulse
.serial(magicNumber
);
577 if (magicNumber
!= PermanentBanMSGMagicNumber
) return; // bad msg
578 setPermanentBanMarkers(true);
579 applyPermanentBanPunishment();
580 PermanentlyBanned
= true;
583 void impulsePermanentUnban(NLMISC::CBitMemStream
&impulse
)
586 impulse
.serial(magicNumber
);
587 if (magicNumber
!= PermanentUnbanMSGMagicNumber
) return; // bad msg
588 setPermanentBanMarkers(false);
589 PermanentlyBanned
= false;
592 // allows to walk / run again
593 UserEntity
->walkVelocity(ClientCfg
.Walk
);
594 UserEntity
->runVelocity(ClientCfg
.Run
);
599 // ***************************************************************************
600 class CInterfaceChatDisplayer
: public CClientChatManager::IChatDisplayer
603 virtual void displayChat(TDataSetIndex compressedSenderIndex
, const std::string
&ucstr
, const std::string
&rawMessage
, CChatGroup::TGroupType mode
, NLMISC::CEntityId dynChatId
, std::string
&senderName
, uint bubbleTimer
=0);
604 virtual void displayTell(/*TDataSetIndex senderIndex, */const std::string
&ucstr
, const std::string
&senderName
);
605 virtual void clearChannel(CChatGroup::TGroupType mode
, uint32 dynChatDbIndex
);
608 // Add colorization tag for sender name
609 void colorizeSender(string
&text
, const string
&senderName
, CRGBA baseColor
);
612 static CInterfaceChatDisplayer InterfaceChatDisplayer
;
614 void CInterfaceChatDisplayer::colorizeSender(string
&text
, const string
&senderName
, CRGBA baseColor
)
616 // find the sender/text separator to put color tags
617 string::size_type pos
= senderName
.length() - 1;
618 if (pos
!= string::npos
)
622 CInterfaceProperty prop
;
623 prop
.readRGBA("UI:SAVE:CHAT:COLORS:SPEAKER"," ");
625 CChatWindow::encodeColorTag(prop
.getRGBA(), str
, false);
627 str
+= text
.substr(0, pos
+1);
629 CChatWindow::encodeColorTag(baseColor
, str
, true);
631 str
+= text
.substr(pos
+1);
637 // display a chat from network to interface
638 void CInterfaceChatDisplayer::displayChat(TDataSetIndex compressedSenderIndex
, const std::string
&ucstr
, const std::string
&rawMessage
, CChatGroup::TGroupType mode
, NLMISC::CEntityId dynChatId
, std::string
&senderName
, uint bubbleTimer
)
640 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
642 string stringCategory
= getStringCategory(ucstr
, finalString
);
644 bool bubbleWanted
= true;
646 // Subtract rawMessage from ucstr so that the 'sender' part remains.
647 string senderPart
= ucstr
.substr(0, ucstr
.length() - rawMessage
.length());
649 // search a "{no_bubble}" tag
651 string::size_type index
= finalString
.find("{no_bubble}");
652 const size_t tokenSize
= 11; // length of "{no_bubble}"
653 if (index
!= string::npos
)
655 bubbleWanted
= false;
656 finalString
= finalString
.substr(0, index
) + finalString
.substr(index
+tokenSize
,finalString
.size());
663 if (mode
!= CChatGroup::system
)
665 // Remove all {break}
668 string::size_type index
= finalString
.find("{break}");
669 if (index
== string::npos
) break;
670 finalString
= finalString
.substr(0, index
) + finalString
.substr(index
+7,finalString
.size());
674 sint32 dbIndex
= ChatMngr
.getDynamicChannelDbIndexFromId(dynChatId
);
675 clamp(dbIndex
, (sint32
)0 , (sint32
)CChatGroup::MaxDynChanPerPlayer
);
676 string entry
="UI:SAVE:CHAT:COLORS:";
679 case CChatGroup::dyn_chat
: entry
+="DYN:" + NLMISC::toString(dbIndex
); break;
680 case CChatGroup::say
: entry
+="SAY"; break;
681 case CChatGroup::shout
: entry
+="SHOUT"; break;
682 case CChatGroup::team
: entry
+="GROUP"; break;
683 case CChatGroup::guild
: entry
+="CLADE"; break;
684 case CChatGroup::civilization
: entry
+="CIVILIZATION"; break;
685 case CChatGroup::territory
: entry
+="TERRITORY"; break;
686 case CChatGroup::universe
: entry
+="UNIVERSE_NEW"; break;
687 case CChatGroup::region
: entry
+="REGION"; break;
688 case CChatGroup::tell
: entry
+="TELL"; break;
689 default: nlwarning("unknown group type"); return;
693 CInterfaceProperty prop
;
694 prop
.readRGBA(entry
.c_str()," ");
695 col
= prop
.getRGBA();
697 // Override color if the string contains the color
698 if (!stringCategory
.empty() && stringCategory
!= "SYS")
700 map
<string
, CClientConfig::SSysInfoParam
>::const_iterator it
;
701 it
= ClientCfg
.SystemInfoParams
.find(toLowerAscii(stringCategory
));
702 if (it
!= ClientCfg
.SystemInfoParams
.end())
704 col
= it
->second
.Color
;
709 if (stringCategory
== "emt")
711 bubbleWanted
= false;
714 if (mode
!= CChatGroup::system
)
716 // find the sender/text separator to put color tags
717 if (senderPart
.empty() && stringCategory
== "emt")
719 size_t pos
= finalString
.find(": ", 0);
720 if (pos
!= string::npos
)
722 senderPart
= finalString
.substr(0, pos
+ 2);
725 colorizeSender(finalString
, senderPart
, col
);
728 // play associated fx if any
729 if( !stringCategory
.empty() )
731 map
<string
, CClientConfig::SSysInfoParam
>::const_iterator it
;
732 it
= ClientCfg
.SystemInfoParams
.find( toLowerAscii(stringCategory
) );
733 if( it
!= ClientCfg
.SystemInfoParams
.end() )
735 if( !(*it
).second
.SysInfoFxName
.empty() )
737 NL3D::UParticleSystemInstance sysInfoFx
= FXMngr
.instantFX((*it
).second
.SysInfoFxName
);
738 if( !sysInfoFx
.empty() )
740 sysInfoFx
.setClusterSystem( UserEntity
->getClusterSystem() );
741 sysInfoFx
.setPos( UserEntity
->pos() );
745 nlwarning("<CInterfaceChatDisplayer::displayChat> Can't set chat fx %s",(*it
).second
.SysInfoFxName
.c_str());
751 // **** redirect to the correct interface output
752 if( stringCategory
!= "bbl" )
755 if (mode
== CChatGroup::system
)
757 pIM
->displaySystemInfo(finalString
, stringCategory
);
759 else if (mode
== CChatGroup::guild
)
761 PeopleInterraction
.ChatInput
.Guild
.displayMessage(finalString
, col
, 2, &windowVisible
);
763 else if (mode
== CChatGroup::team
)
765 PeopleInterraction
.ChatInput
.Team
.displayMessage(finalString
, col
, 2, &windowVisible
);
767 else if (mode
== CChatGroup::region
)
769 PeopleInterraction
.ChatInput
.Region
.displayMessage(finalString
, col
, 2, &windowVisible
);
771 else if (mode
== CChatGroup::universe
)
773 PeopleInterraction
.ChatInput
.Universe
.displayMessage(finalString
, col
, 2, &windowVisible
);
775 else if (mode
== CChatGroup::dyn_chat
)
777 // retrieve the DBIndex from the dynamic chat id
778 sint32 dbIndex
= ChatMngr
.getDynamicChannelDbIndexFromId(dynChatId
);
779 // if found, display, else discarded
780 if(dbIndex
>= 0 && dbIndex
< CChatGroup::MaxDynChanPerPlayer
)
782 PeopleInterraction
.ChatInput
.DynamicChat
[dbIndex
].displayMessage(finalString
, col
, 2, &windowVisible
);
784 // Add dynchannel info before text so that the chat log will show the correct string.
785 CCDBNodeLeaf
* node
= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_DYN_CHANNEL_NAME_IN_CHAT_CB", false);
786 if (pIM
->getLogState())
788 // Add dyn chan number before string
789 string prefix
= "[" + NLMISC::toString(dbIndex
) + "]";
790 // Find position to put the new string
792 size_t pos
= finalString
.find("]");
793 size_t colonpos
= finalString
.find(": @{");
794 // If no ] found or if found but after the colon (so part of the user chat)
795 if (pos
== string::npos
|| (colonpos
< pos
))
797 // No timestamp, so put it right after the color and add a space
798 pos
= finalString
.find("}");;
801 finalString
= finalString
.substr(0, pos
+ 1) + prefix
+ finalString
.substr(pos
+ 1);
803 if (node
&& node
->getValueBool())
805 uint32 textId
= ChatMngr
.getDynamicChannelNameFromDbIndex(dbIndex
);
807 STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId
, title
);
808 prefix
= (title
.empty() ? "" : " ") + title
;
809 pos
= finalString
.find("] ");
810 finalString
= finalString
.substr(0, pos
) + prefix
+ finalString
.substr(pos
);
816 nlwarning("Dynamic chat %s not found for message: %s", dynChatId
.toString().c_str(), finalString
.c_str());
821 string::size_type index
= finalString
.find("<BPFX>");
822 if (index
!= string::npos
)
824 bubbleWanted
= false;
825 finalString
= finalString
.substr(index
+6,finalString
.size());
826 string::size_type index2
= finalString
.find(string(" "));
828 if (index2
< (finalString
.size()-3))
830 playerName
= finalString
.substr(0,index2
);
831 finalString
= finalString
.substr(index2
+1,finalString
.size());
833 if (!senderName
.empty())
835 CEntityCL
*senderEntity
= EntitiesMngr
.getEntityByName (CEntityCL::removeTitleAndShardFromName(senderName
), true, true);
838 if (senderEntity
->Type
!= CEntityCL::Player
)
840 if (playerName
.empty())
842 senderEntity
->removeStateFx();
843 senderEntity
->setStateFx(finalString
);
848 CEntityCL
*destEntity
= EntitiesMngr
.getEntityByName (CEntityCL::removeTitleAndShardFromName(playerName
), false, true);
851 destEntity
->removeStateFx();
852 destEntity
->setStateFx(finalString
);
863 PeopleInterraction
.ChatInput
.AroundMe
.displayMessage(finalString
, col
, 2, &windowVisible
);
866 // if tell, bkup sendername
867 if (mode
== CChatGroup::tell
&& windowVisible
&& !senderName
.empty())
869 PeopleInterraction
.LastSenderName
= CEntityCL::removeTitleAndShardFromName(senderName
);
874 //nldebug("<impulseChat> Received CHAT : %s with category %s",finalString.toString().c_str(),stringCategory.c_str());
877 // **** Process chat entry for the bubbles
878 // todo hulud : registering a chat callback would be better than calling this hardcoded action handler
879 string finalRawMessage
;
880 // remove color qualifier from raw string
881 getStringCategory(rawMessage
, finalRawMessage
);
884 InSceneBubbleManager
.chatOpen(compressedSenderIndex
, finalRawMessage
, bubbleTimer
);
890 if (mode
== CChatGroup::dyn_chat
)
892 sint32 dbIndex
= ChatMngr
.getDynamicChannelDbIndexFromId(dynChatId
);
893 clamp(dbIndex
, (sint32
)0 , (sint32
)CChatGroup::MaxDynChanPerPlayer
);
895 channel
= "dyn" + toString(dbIndex
);
899 channel
= CChatGroup::groupTypeToString(mode
);
902 channel
= "#" + toString((uint32
)mode
);
905 if (!stringCategory
.empty() && NLMISC::compareCaseInsensitive(stringCategory
.c_str(), "SYS")) // Not empty and not 'SYS'
907 channel
= channel
+ "/" + stringCategory
;
909 pIM
->log (finalString
, channel
);
914 // display a tell from network to interface
915 void CInterfaceChatDisplayer::displayTell(/*TDataSetIndex senderIndex, */const std::string
&ucstr
, const std::string
&senderName
)
918 string finalString
= ucstr
;
920 // for now, '&' are removed by server so use another format until a special msg is made
921 if (strFindReplace(finalString
, "<R2_INVITE>", string()))
923 CLuaManager::getInstance().executeLuaScript("RingAccessPoint:forceRefresh()");
927 CInterfaceProperty prop
;
928 prop
.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," ");
931 string goodSenderName
= CEntityCL::removeTitleAndShardFromName(senderName
);
933 // The sender part is up to and including the first ":" after the goodSenderName
934 string::size_type pos
= finalString
.find(goodSenderName
);
935 pos
= finalString
.find(':', pos
);
936 pos
= finalString
.find(' ', pos
);
937 string senderPart
= finalString
.substr(0, pos
+1);
938 colorizeSender(finalString
, senderPart
, prop
.getRGBA());
940 PeopleInterraction
.ChatInput
.Tell
.displayTellMessage(/*senderIndex, */finalString
, goodSenderName
, prop
.getRGBA(), 2, &windowVisible
);
941 CInterfaceManager::getInstance()->log(finalString
, CChatGroup::groupTypeToString(CChatGroup::tell
));
943 // Open the free teller window
944 CChatGroupWindow
*pCGW
= PeopleInterraction
.getChatGroupWindow();
946 pCGW
->setActiveFreeTeller(goodSenderName
);
948 if (windowVisible
&& !goodSenderName
.empty())
949 PeopleInterraction
.LastSenderName
= goodSenderName
;
953 void CInterfaceChatDisplayer::clearChannel(CChatGroup::TGroupType mode
, uint32 dynChatDbIndex
)
955 if (mode
== CChatGroup::guild
) PeopleInterraction
.ChatInput
.Guild
.clearMessages();
956 else if (mode
== CChatGroup::team
) PeopleInterraction
.ChatInput
.Team
.clearMessages();
957 else if (mode
== CChatGroup::region
) PeopleInterraction
.ChatInput
.Region
.clearMessages();
958 else if (mode
== CChatGroup::arround
) PeopleInterraction
.ChatInput
.AroundMe
.clearMessages();
959 else if (mode
== CChatGroup::universe
) PeopleInterraction
.ChatInput
.Universe
.clearMessages();
960 else if (mode
== CChatGroup::dyn_chat
)
962 // if correct dbIndex, clear
963 if(dynChatDbIndex
<CChatGroup::MaxDynChanPerPlayer
)
964 PeopleInterraction
.ChatInput
.DynamicChat
[dynChatDbIndex
].clearMessages();
966 nlwarning("Dynamic chat %d not found for clearing", dynChatDbIndex
);
969 // don't support other for now (NB: actually used only for dyn_chat)
973 // ***************************************************************************
974 void impulseChat(NLMISC::CBitMemStream
&impulse
)
976 ChatMngr
.processChatString(impulse
, InterfaceChatDisplayer
);
979 void impulseChat2(NLMISC::CBitMemStream
&impulse
)
981 ChatMngr
.processChatString2(impulse
, InterfaceChatDisplayer
);
984 void impulseTell(NLMISC::CBitMemStream
&impulse
)
986 ChatMngr
.processTellString(impulse
, InterfaceChatDisplayer
);
989 void impulseFarTell(NLMISC::CBitMemStream
&impulse
)
991 ChatMngr
.processFarTellString(impulse
, InterfaceChatDisplayer
);
994 void impulseTell2(NLMISC::CBitMemStream
&impulse
)
996 ChatMngr
.processTellString2(impulse
, InterfaceChatDisplayer
);
999 void impulseDynString(NLMISC::CBitMemStream
&impulse
)
1001 ChatMngr
.processChatStringWithNoSender(impulse
, CChatGroup::system
, InterfaceChatDisplayer
);
1004 void inpulseDynStringInChatGroup(NLMISC::CBitMemStream
&impulse
)
1006 CChatGroup::TGroupType type
= CChatGroup::say
;
1007 impulse
.serialEnum(type
);
1008 ChatMngr
.processChatStringWithNoSender(impulse
, type
, InterfaceChatDisplayer
);
1011 // ***************************************************************************
1012 //void impulseAddDynStr(NLMISC::CBitMemStream &impulse)
1014 // bool huff = false;
1015 // impulse.serialBit(huff);
1018 // ucstring ucstr; // OLD
1020 // impulse.serial( index );
1021 // impulse.serial( ucstr );
1023 // vector<bool> code;
1026 // impulse.serialCont( code );
1028 // if (PermanentlyBanned) return;
1029 // #ifdef OLD_STRING_SYSTEM
1030 // ChatMngr.getDynamicDB().add( index, ucstr, code );
1032 // nlwarning( "// TRAP // WE MUST NEVER CALL THIS IMPULE ANYMORE : ALL IS HANDLED BY STRING_MANAGER NOW !!!" );
1035 // // received ADD_DYN_STR
1036 // nlinfo("impulseCallBack : Received ADD_DYN_STR : adding %s at index %d",ucstr.toString().c_str(),index);
1039 string getInterfaceNameFromId (sint botType, sint interfaceId)
1041 string interfaceName = "ui:interface:bot_chat_";
1045 case 0: interfaceName += "figurant_"; break;
1046 case 1: interfaceName += "figurant_presse_"; break;
1047 case 2: interfaceName += "chef_village_"; break;
1048 default: interfaceName += "figurant_"; break;
1051 switch (interfaceId)
1053 case BOTCHATTYPE::Intro: interfaceName += "intro"; break;
1054 case BOTCHATTYPE::FriendlyMainPage: interfaceName += "friendly_main"; break;
1055 case BOTCHATTYPE::NeutralMainPage: interfaceName += "neutral_main"; break;
1056 case BOTCHATTYPE::NastyMainPage: interfaceName += "nasty_main"; break;
1057 case BOTCHATTYPE::MoreNewsPage: interfaceName += "more_news"; break;
1058 case BOTCHATTYPE::Done: nlinfo ("end of bot chat"); interfaceName.clear(); break;
1060 return interfaceName;
1063 static char *shortNews[] = {
1064 "The wind is sour and brings only bad tidings...", "Kitins have been sighted near the village!", "",
1065 "The tribe of the Black Circle has recently", "increased its activities in our region.", "",
1066 "The Black Circle has made an incursion", "into our territory!", "",
1067 "The Black Circle has been sighted near one", "of our forward posts, deep in dangerous territory.", "",
1068 "The tide has washed up evil news, friend.", "The Black Circle is active in our region.", "",
1069 "Our people suffer from a debilitating shortage.", "We are in sore need of KamiBast.", "",
1070 "The economy is slow and our reserve of", "Live Seed low.", "",
1071 "We are in sore need of Live Seed", "If there is a Goo epidemic, we shall all perish!", "",
1072 "Our master mages have gotten wind of", "the growing Kami discontentment", "",
1075 static char *longNews[] = {
1076 "These powerful predators haven't come this near", "to the village since their devastating attack", "over 15 seasons ago!",
1077 "They are after more KamiBast", "for their occult practices.", "",
1078 "They have captured", "2 of our fortifications in the bush!", "",
1079 "They have taken over one of our richest sources", "of KamiBast, and are exploiting it", "for their own occult purposes.",
1080 "They now hold an important source", "of Live Seed hostage,", "close to one of our forward posts.",
1081 "We use the magical properties of KamiBast and", "its unusually rich fibers for all our crafts.", "",
1082 "If we don't harvest new Seed soon,", "we will have no way of purchasing goods", "and resources, beyond what we produce ourselves",
1083 "We use the rich Sap of Live Seed to produce", "an antidote that counters the disastrous", "effects of the Goo on all Atysian life forms.",
1084 "The Kamis are shaken by the Black Circle's", "presence. If the Circle continues it's occult", "practices, we will all suffer the Kamic anger.",
1090 char *table[] = { "figurant", "chef_village", "garde", "commercant" };
1092 sint rnd = rand ()%(sizeof(shortNews)/sizeof(shortNews[0])/3);
1095 for (uint i = 0; i < sizeof(table)/sizeof(table[0]); i++)
1097 { // set test for the friendly main
1099 iname = "ui:interface:bot_chat_";
1101 iname += "_friendly_main";
1103 CInterfaceGroup *inter = CWidgetManager::getInstance()->getWindowFromId(iname);
1106 nlwarning ("cant find interface 's%'", iname.c_str());
1110 CViewText *inter2 = (CViewText *)inter->getView("title0");
1111 nlassert (inter2 != NULL);
1112 inter2->setText(ucstring(shortNews[rnd*3])); // OLD
1114 CViewText *inter3 = (CViewText *)inter->getView("title1");
1115 nlassert (inter3 != NULL);
1116 inter3->setText(ucstring(shortNews[rnd*3+1])); // OLD
1118 CViewText *inter4 = (CViewText *)inter->getView("title2");
1119 nlassert (inter4 != NULL);
1120 inter4->setText(ucstring(shortNews[rnd*3+2])); // OLD
1122 { // set test for the neutral main
1124 iname = "ui:interface:bot_chat_";
1126 iname += "_neutral_main";
1128 CInterfaceGroup *inter = CWidgetManager::getInstance()->getWindowFromId(iname);
1131 nlwarning ("cant find interface 's%'", iname.c_str());
1135 CViewText *inter2 = (CViewText *)inter->getView("title0");
1136 nlassert (inter2 != NULL);
1137 inter2->setText(ucstring(shortNews[rnd*3])); // OLD
1139 CViewText *inter3 = (CViewText *)inter->getView("title1");
1140 nlassert (inter3 != NULL);
1141 inter3->setText(ucstring(shortNews[rnd*3+1])); // OLD
1143 { // set test for the more news
1145 iname = "ui:interface:bot_chat_";
1147 iname += "_more_news";
1149 CInterfaceGroup *inter = CWidgetManager::getInstance()->getWindowFromId(iname);
1152 nlwarning ("cant find interface 's%'", iname.c_str());
1156 CViewText *inter2 = (CViewText *)inter->getView("title0");
1157 nlassert (inter2 != NULL);
1158 inter2->setText(ucstring(longNews[rnd*3])); // OLD
1160 CViewText *inter3 = (CViewText *)inter->getView("title1");
1161 nlassert (inter3 != NULL);
1162 inter3->setText(ucstring(longNews[rnd*3+1])); // OLD
1164 CViewText *inter4 = (CViewText *)inter->getView("title2");
1165 nlassert (inter4 != NULL);
1166 inter4->setText(ucstring(longNews[rnd*3+2])); // OLD
1176 //=========================================
1177 /** Temp setup for choice list
1180 static void setupBotChatChoiceList(CInterfaceGroup *botChatGroup)
1182 // Temp for test. Should then be read from server msg
1183 std::vector<string> choices;
1184 for(uint k = 0; k < 90; ++k)
1186 choices.push_back("Choice " + toString(k));
1188 CBotChat::setChoiceList(botChatGroup, choices, false);
1192 //=========================================
1193 /** Temp setup for description list
1196 static void setupBotChatDescription(CInterfaceGroup *botChatGroup)
1199 for(uint k = 0; k < 90; ++k)
1201 desc += "This is a multi line description. ";
1203 CBotChat::setDescription(botChatGroup, desc);
1207 //=========================================
1208 /** Temp setup for bot chat gift
1211 static void setupBotChatBotGift(CInterfaceGroup *botChatGroup)
1213 // create dummy item in the db
1214 CInterfaceManager *im = CInterfaceManager::getInstance();
1215 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:20:0:SHEET")->setValue32(CSheetId("ai_flesh_poisson.item").asInt());
1216 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:20:0:QUALITY")->setValue32(0);
1217 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:20:1:SHEET")->setValue32(CSheetId("fyros_sword_lvl_01_05.item").asInt());
1218 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:20:1:QUALITY")->setValue32(2);
1219 CBotChat::setBotGift(botChatGroup, "Thanks to have succeeded the mission", "Here's your reward", "The bot has taken the object quest from your inventory");
1223 //-----------------------------------------------
1224 // impulseBotChatSetInterface :
1225 //-----------------------------------------------
1227 void impulseBotChatSetInterface(NLMISC::CBitMemStream
&impulse
)
1229 // received ADD_DYN_STR
1233 BOTCHATTYPE::TBotChatInterfaceId interfaceId
;
1236 impulse
.serial (user
);
1237 impulse
.serial (happyness
);
1239 // impulse.serialEnum (interfaceId);
1241 impulse
.serial(interfId
);
1242 interfaceId
= (BOTCHATTYPE::TBotChatInterfaceId
)(interfId
&0xff);
1243 uint8 botType
= (interfId
>>8) & 0xff;
1245 impulse
.serial (hasNews
);
1247 nldebug("impulseCallBack : Received BOT_CHAT:SET_INTERFACE interface %d, have news %s, happy %d, bottype %hu", interfaceId
, hasNews
?"yes":"no", happyness
,(uint16
)botType
);
1250 vector
<uint64
> args
;
1254 /* impulse.serial (stringId);
1255 impulse.serialCont (args);
1256 nlinfo ("receive the news '%s' with %d args", stringId.c_str(), args.size());
1258 // TEMP FOR THE DEMO, DON'T USE THE NETWORK NEW BUT SELECT A NEWS HERE
1260 CInterfaceGroup *inter = CWidgetManager::getInstance()->getWindowFromId("ui:interface:bot_chat_intro");
1261 nlassert (inter != NULL);
1262 inter->setActive(true);
1264 CViewText *inter2 = (CViewText *)inter->getView("hi");
1265 nlassert (inter2 != NULL);
1266 inter2->NetworkTextId.setString("IOS_NEWS_FOOTBALL_SHORT_EEII", &ChatMngr);
1267 inter2->NetworkTextId.Args.push_back(10);
1268 inter2->NetworkTextId.Args.push_back(20);
1269 inter2->NetworkTextId.Args.push_back(1);
1270 inter2->NetworkTextId.Args.push_back(2);
1273 // FOR THE DEMO, find and set a fake news:
1276 string interfaceName
= getInterfaceNameFromId (botType
, interfaceId
);
1278 if(interfaceName
.empty())
1280 nlwarning ("Received an unknown bot chat interface %d", interfaceId
);
1284 CInterfaceGroup
*inter
= CWidgetManager::getInstance()->getWindowFromId(interfaceName
);
1287 nlwarning ("Can't find interface name '%s' %d", interfaceName
.c_str(), interfaceId
);
1291 CInterfaceManager::getInstance()->setBotChatWin(inter
);
1292 if (inter
->getActive())
1294 nlwarning ("Interface %s is already active, not normal!", interfaceName
.c_str());
1298 nlinfo ("server want to me display the bot chat interface %s %d", interfaceName
.c_str(), interfaceId
);
1299 inter
->setActive(true);
1308 //-----------------------------------------------
1309 // impulseBeginTrade :
1310 //-----------------------------------------------
1311 void impulseBeginTrade(NLMISC::CBitMemStream
&impulse
)
1313 if (PermanentlyBanned
) return;
1315 CInterfaceGroup
* win
= CWidgetManager::getInstance()->getWindowFromId("ui:interface:trade");
1318 nlwarning("invalid interface ui:interface:trade");
1321 win
->setActive(true);
1324 //-----------------------------------------------
1325 // impulseBuyPrice :
1326 //-----------------------------------------------
1327 void impulseBuyPrice(NLMISC::CBitMemStream
&impulse
)
1329 uint16 botChatSession
;
1333 impulse
.serial(botChatSession
);
1334 impulse
.serial(price
);
1335 impulse
.serial(sheetID
);
1336 impulse
.serial(quality
);
1340 //-----------------------------------------------
1341 // impulseDynChatOpen
1342 //-----------------------------------------------
1343 void impulseDynChatOpen(NLMISC::CBitMemStream
&impulse
)
1345 uint32 BotUID
; // Compressed Index
1346 uint32 BotName
; // Server string
1347 vector
<uint32
> DynStrs
; // 0 - Desc, 1 - Option0, 2 - Option1, etc....
1348 impulse
.serial(BotUID
);
1349 impulse
.serial(BotName
);
1350 impulse
.serialCont(DynStrs
);
1352 if (PermanentlyBanned
) return;
1354 /* string sTmp = "impulseCallback : Received BOTCHAT:DYNCHAT_OPEN BotUID:";
1355 sTmp += toString(BotUID) + " BotName:";
1356 sTmp += toString(BotName) + " DynStrs:";
1357 for (uint32 i = 0; i < DynStrs.size(); ++i)
1359 sTmp += toString(DynStrs[i]);
1360 if (i != DynStrs.size()-1) sTmp += ",";
1362 nlinfo(sTmp.c_str());*/
1364 InSceneBubbleManager
.dynChatOpen(BotUID
, BotName
, DynStrs
);
1367 //-----------------------------------------------
1368 // impulseDynChatClose
1369 //-----------------------------------------------
1370 void impulseDynChatClose(NLMISC::CBitMemStream
&impulse
)
1372 uint32 BotUID
; // Compressed Index
1373 impulse
.serial(BotUID
);
1374 if (PermanentlyBanned
) return;
1375 //nlinfo("impulseCallback : Received BOTCHAT:DYNCHAT_CLOSE BotUID:"+toString(BotUID));
1376 InSceneBubbleManager
.dynChatClose(BotUID
);
1379 //-----------------------------------------------
1380 // impulseBeginCast:
1381 //-----------------------------------------------
1382 void impulseBeginCast(NLMISC::CBitMemStream
&impulse
)
1386 impulse
.serial(begin
);
1387 impulse
.serial(end
);
1388 if (PermanentlyBanned
) return;
1389 CInterfaceManager
* iMngr
= CInterfaceManager::getInstance();
1390 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SPELL_CAST")->setValue32(1);
1391 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:CAST_BEGIN")->setValue32(begin
);
1392 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:CAST_END")->setValue32(end
);
1397 //-----------------------------------------------
1398 // impulseCorrectPos :
1399 // Message from the server to correct the user position because he is not at the same position on the server..
1400 //-----------------------------------------------
1401 void impulseCorrectPos(NLMISC::CBitMemStream
&impulse
)
1404 //nlinfo("impulseCallback : Received TP:CORRECT");
1409 nlinfo("impulseCorrectPos: new user position %d %d %d", x
, y
, z
);
1411 if(UserEntity
->mode() != MBEHAV::COMBAT_FLOAT
)
1413 if (x
== 0) // Get SpeedAdjustement
1415 UserEntity
->setSpeedServerAdjust(-0.2f
);
1419 // Compute the destination.
1420 CVectorD dest
= CVectorD((float)x
/1000.0f
, (float)y
/1000.0f
, (float)z
/1000.0f
);
1421 // Update the position for the vision.
1422 NetMngr
.setReferencePosition(dest
);
1423 // Change the user poisition.
1424 UserEntity
->correctPos(dest
);
1427 }// impulseCorrectPos //
1429 class CDummyProgress
: public IProgressCallback
1431 void progress (float /* value */) {}
1434 //-----------------------------------------------
1436 // Message from the server to teleport the user.
1437 // \warning This function remove the current target. Do no use to correct a position.
1438 //-----------------------------------------------
1439 void impulseTPCommon(NLMISC::CBitMemStream
&impulse
, bool hasSeason
);
1440 void impulseTPCommon2(NLMISC::CBitMemStream
&impulse
, bool hasSeason
);
1442 void impulseTP(NLMISC::CBitMemStream
&impulse
)
1444 impulseTPCommon(impulse
, false);
1447 void impulseTPWithSeason(NLMISC::CBitMemStream
&impulse
)
1449 impulseTPCommon(impulse
, true);
1454 NLMISC::CBitMemStream Impulse
;
1457 SQueuedTP(const NLMISC::CBitMemStream
&impulse
, bool hasSeason
)
1458 :Impulse(impulse
), HasSeason(hasSeason
)
1463 // note - this method added by Sadge and Hamster to deal with unexplained recursive calls to impulseTPCommon
1464 // these calls are provoked by the net manager update which is called during loading
1465 void impulseTPCommon(NLMISC::CBitMemStream
&impulse
, bool hasSeason
)
1467 CNiceInputAuto niceInputs
;
1468 static std::list
<SQueuedTP
> queuedTPs
;
1469 SQueuedTP
thisTP(impulse
,hasSeason
);
1470 queuedTPs
.push_back(thisTP
);
1472 BOMB_IF(queuedTPs
.size()!=1,NLMISC::toString("Queueing recursive TPs depth=%u",queuedTPs
.size()),return);
1474 while(!queuedTPs
.empty())
1476 impulseTPCommon2(queuedTPs
.front().Impulse
,queuedTPs
.front().HasSeason
);
1477 queuedTPs
.pop_front();
1483 void impulseTPCommon2(NLMISC::CBitMemStream
&impulse
, bool hasSeason
)
1485 // choose a default screen if not setuped
1486 if (LoadingBackground
!= ResurectKamiBackground
&& LoadingBackground
!= ResurectKaravanBackground
1487 && LoadingBackground
!= TeleportKamiBackground
&& LoadingBackground
!= TeleportKaravanBackground
)
1488 LoadingBackground
= ElevatorBackground
;
1489 // if resurect but user not dead, choose default. NB: this is a bug, the tp impulse should tell
1490 // which background to choose. \todo yoyo: this is a temp fix
1491 if (UserEntity
&& !UserEntity
->isDead() && (LoadingBackground
== ResurectKamiBackground
|| LoadingBackground
== ResurectKaravanBackground
))
1492 LoadingBackground
= ElevatorBackground
;
1494 // Play music according to the background
1497 LoadingMusic
.clear();
1498 switch (LoadingBackground
)
1500 case TeleportKamiBackground
:
1501 LoadingMusic
= ClientCfg
.KamiTeleportMusic
;
1503 case TeleportKaravanBackground
:
1504 LoadingMusic
= ClientCfg
.KaravanTeleportMusic
;
1506 case ResurectKamiBackground
:
1507 case ResurectKaravanBackground
:
1508 // TODO: Resurrect music
1511 LoadingMusic
= ClientCfg
.TeleportLoadingMusic
;
1516 SoundMngr
->playEventMusic(LoadingMusic
, CSoundManager::LoadingMusicXFade
, true);
1519 // Create the loading texture.
1520 beginLoading (LoadingBackground
);
1523 UseEscapeDuringLoading
= false;
1526 selectTipsOfTheDay (rand());
1528 // start progress bar and display background
1529 ProgressBar
.reset (BAR_STEP_TP
);
1530 string
nmsg("Loading...");
1531 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1534 // received ADD_DYN_STR
1535 nlinfo("impulseTP: received a request for a TP.");
1541 impulse
.serialBit( useHeading
);
1542 // Is there an orientation too ?
1546 impulse
.serial(angle
);
1547 nlinfo("impulseTP: to %d %d %d %f", x
, y
, z
, angle
);
1548 CVector ori
= CVector((float)cos(angle
), (float)sin(angle
), 0.0f
);
1550 UserEntity
->dir(ori
, false, false);
1551 UserEntity
->front(ori
, false, false);
1552 UserEntity
->setHeadPitch(0);
1553 UserControls
.resetCameraDeltaYaw();
1556 nlinfo("impulseTP: to %d %d %d", x
, y
, z
);
1560 extern uint8 ServerSeasonValue
;
1561 extern bool ServerSeasonReceived
;
1562 impulse
.serial(ServerSeasonValue
);
1563 ServerSeasonReceived
= true;
1566 if (ClientCfg
.R2EDEnabled
)
1568 R2::getEditor().tpReceived();
1571 // Compute the destination.
1572 CVectorD dest
= CVectorD((float)x
/1000.0f
, (float)y
/1000.0f
, (float)z
/1000.0f
);
1573 // Update the position for the vision.
1574 NetMngr
.setReferencePosition(dest
);
1575 // Change the position of the entity and in Pacs.
1576 UserEntity
->pos(dest
);
1578 // Fade out the Game Sound
1580 SoundMngr
->fadeOutGameSound(ClientCfg
.SoundTPFade
);
1583 R2::TTeleportContext tpContext
= R2::TPContext_Unknown
;
1586 string tpCancelText
;
1590 R2::TR2TpInfos tpInfos
;
1591 impulse
.serial(tpInfos
);
1594 if ( tpInfos
.UseTpMessage
)
1596 tpReason
= CI18N::get(tpInfos
.TpReasonId
);
1598 uint32 size
= (uint32
)tpInfos
.TpReasonParams
.size();
1600 CSString
str(tpReason
);
1601 for (;first
!= size
; ++first
)
1603 std::string value
= tpInfos
.TpReasonParams
[first
];
1604 std::string key
= NLMISC::toString("%%%u", first
+1);
1605 str
= str
.replace( key
.c_str(), value
.c_str());
1607 tpReason
= string(str
);
1608 tpCancelText
= CI18N::get(tpInfos
.TpCancelTextId
);
1609 tpContext
= tpInfos
.TpContext
;
1613 catch (const EStream
&)
1615 tpReason
= "TP Reason";
1616 tpCancelText
= "Cancel TP"; // for test
1617 // try to deduce tp context from current editor mode
1618 switch (R2::getEditor().getMode())
1620 case R2::CEditor::EditionMode
:
1621 case R2::CEditor::NotInitialized
:
1622 tpContext
= R2::TPContext_Unknown
;
1623 tpReason
= string();
1624 tpCancelText
= string();
1626 case R2::CEditor::GoingToDMMode
:
1627 case R2::CEditor::TestMode
:
1628 case R2::CEditor::DMMode
:
1629 tpContext
= R2::TPContext_Edit
;
1631 case R2::CEditor::AnimationModeLoading
:
1632 case R2::CEditor::AnimationModeWaitingForLoading
:
1633 case R2::CEditor::AnimationModeDm
:
1634 case R2::CEditor::AnimationModeGoingToDm
:
1635 tpContext
= R2::TPContext_IslandOwner
;
1637 case R2::CEditor::AnimationModePlay
:
1638 case R2::CEditor::AnimationModeGoingToPlay
:
1640 tpContext
= R2::TPContext_Mainland
;
1647 if (!tpReason
.empty())
1652 case R2::TPContext_Mainland
: tpIcon
= "cancel_tp_main_land.tga"; break;
1653 case R2::TPContext_Edit
: tpIcon
= "cancel_tp_edit.tga"; break;
1654 case R2::TPContext_IslandOwner
: tpIcon
= "cancel_tp_island_owner.tga"; break;
1657 ProgressBar
.setTPMessages(tpReason
, tpCancelText
, tpIcon
);
1660 ProgressBar
.progress(0);
1661 // enable hardware mouse to allow to click the buttons
1662 //bool oldHardwareCursor = IsMouseCursorHardware();
1663 //InitMouseWithCursor(true);
1664 // Select the closest continent from the new position.
1665 ContinentMngr
.select(dest
, ProgressBar
);
1667 //InitMouseWithCursor(oldHardwareCursor);
1669 // reset 'cancel' button
1670 ProgressBar
.setTPMessages(string(), string(), "");
1673 // ProgressBar.enableQuitButton(false); // TMP TMP
1674 ProgressBar
.progress(1.f
); // do a last display without the buttons because first frame may take a while to draw, and the buttons have no more effect at this point.
1675 ProgressBar
.finish();
1676 // ProgressBar.enableQuitButton(true); // TMP TMP
1678 // Teleport the User.
1679 UserEntity
->tp(dest
);
1681 // Msg Received, send an acknowledge after the landscape has been loaded.
1683 if(GenericMsgHeaderMngr
.pushNameToStream("TP:ACK", out
))
1686 nlinfo("impulseTP: teleport acknowledge 'TP:ACK' sent.");
1689 nlwarning("impulseTP: unknown message name : 'TP:ACK'.");
1696 // if tp canceling was asked, act accordingly
1697 if (ProgressBar
.getTPCancelFlag(true))
1701 case R2::TPContext_Mainland
:
1702 CAHManager::getInstance()->runActionHandler("return_to_mainland", NULL
);
1704 case R2::TPContext_Edit
:
1705 CAHManager::getInstance()->runActionHandler("r2ed_stop_test", NULL
);
1707 case R2::TPContext_IslandOwner
:
1708 CAHManager::getInstance()->runActionHandler("r2_stop_live", NULL
);
1715 initHardwareCursor(true);
1718 //-----------------------------------------------
1719 // impulseCombatEngageFailed :
1720 //-----------------------------------------------
1721 void impulseCombatEngageFailed(NLMISC::CBitMemStream
&impulse
)
1723 if (PermanentlyBanned
) return;
1724 nlinfo("impulseCombatEngageFailed: Combat Engage Failed.");
1726 // Unlock the motion.
1727 UserControls
.locked(false);
1728 }// impulseCombatEngageFailed //
1730 //-----------------------------------------------
1731 // impulseTeamInvitation :
1732 //-----------------------------------------------
1733 void impulseTeamInvitation(NLMISC::CBitMemStream
&impulse
)
1735 nlinfo("impulseTeamInvitation: received an invitation");
1738 impulse
.serial(textID
);
1739 if (PermanentlyBanned
) return;
1741 CLuaManager::getInstance().executeLuaScript("game:onTeamInvation("+toString(textID
)+")", 0);
1742 }// impulseTeamInvitation //
1744 //-----------------------------------------------
1745 // impulseTeamShareOpen
1746 // The server request that the client opens the team sharing system
1747 //-----------------------------------------------
1748 void impulseTeamShareOpen(NLMISC::CBitMemStream
&impulse
)
1750 if (PermanentlyBanned
) return;
1751 CInterfaceManager
*im
= CInterfaceManager::getInstance();
1752 CGroupContainer
*gc
= dynamic_cast<CGroupContainer
*>( CWidgetManager::getInstance()->getElementFromId("ui:interface:team_share"));
1754 gc
->setActive(true);
1755 CWidgetManager::getInstance()->setTopWindow(gc
);
1758 }// impulseTeamShareOpen //
1760 //-----------------------------------------------
1761 // impulseTeamShareInvalid
1762 // invalidate the player validation. If someone has choosen an item/phrase after the player has validated
1763 // the player receive this message to let him know that the chance percentage to obtain a specific item has
1764 // changed and so the player can update its own settings to fit better to what he wants.
1765 // On the client side we have just to show the valid button. All the resets are done on the server side.
1766 //-----------------------------------------------
1767 void impulseTeamShareInvalid(NLMISC::CBitMemStream
&impulse
)
1769 if (PermanentlyBanned
) return;
1770 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1771 CCtrlTextButton
*pTB
= dynamic_cast<CCtrlTextButton
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:team_share:content:ok"));
1773 pTB
->setActive(true);
1774 }// impulseTeamShareInvalid //
1776 //-----------------------------------------------
1777 // impulseTeamShareClose
1778 // The server wants to close the team sharing interface (if the sharing has been validated or other reasons)
1779 //-----------------------------------------------
1780 void impulseTeamShareClose(NLMISC::CBitMemStream
&impulse
)
1782 if (PermanentlyBanned
) return;
1783 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1785 *pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:team_share"));
1787 pGC
->setActive(false);
1788 CCtrlTextButton
*pTB
= dynamic_cast<CCtrlTextButton
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:team_share:content:ok"));
1790 pTB
->setActive(true);
1791 }// impulseTeamShareClose //
1793 //-----------------------------------------------
1794 // impulseTeamContactInit
1795 // initialize friend list and ignore list from the contact list
1796 //-----------------------------------------------
1797 void impulseTeamContactInit(NLMISC::CBitMemStream
&impulse
)
1799 vector
<uint32
> vFriendListName
;
1800 vector
<TCharConnectionState
> vFriendListOnline
;
1801 vector
<ucstring
> vIgnoreListName
; // TODO: UTF-8 (serial)
1803 impulse
.serialCont(vFriendListName
);
1805 impulse
.serial(nbState
);
1806 vFriendListOnline
.resize(nbState
);
1807 for (uint i
=0; i
<nbState
; ++i
)
1809 impulse
.serialShortEnum(vFriendListOnline
[i
]);
1811 // impulse.serialCont(vFriendListOnline);
1812 impulse
.serialCont(vIgnoreListName
);
1814 if (PermanentlyBanned
) return;
1816 //nlinfo("impulseCallback : Received TEAM:CONTACT_INIT nbfriend:%d nbignore:%d", vFriendListName.size(), vIgnoreListName.size());
1818 PeopleInterraction
.initContactLists(vFriendListName
, vFriendListOnline
, vIgnoreListName
);
1819 }// impulseTeamContactInit //
1821 //-----------------------------------------------
1822 // impulseTeamContactCreate
1823 // create one character from the friend or ignore list
1824 //-----------------------------------------------
1825 void impulseTeamContactCreate(NLMISC::CBitMemStream
&impulse
)
1829 TCharConnectionState online
= ccs_offline
;
1832 impulse
.serial(contactId
);
1833 impulse
.serial(nameId
);
1834 impulse
.serialShortEnum(online
);
1835 impulse
.serial(nList
);
1837 // client patch to resolve bad server response when requesting ignore list contact creation
1838 if (nList
== 1) // ignore list
1840 // prevent adding an empty player to ignore list
1841 if (nameId
== 0) return;
1844 if (PermanentlyBanned
) return;
1846 //nlinfo("impulseCallback : Received TEAM:CONTACT_CREATE %d %d %s %d", contactId, nameId, online?"true":"false", nList);
1848 PeopleInterraction
.addContactInList(contactId
, nameId
, online
, nList
);
1850 }// impulseTeamContactStatus //
1852 //-----------------------------------------------
1853 // impulseTeamContactStatus
1854 // update one of the character from the friend list
1855 //-----------------------------------------------
1856 void impulseTeamContactStatus(NLMISC::CBitMemStream
&impulse
)
1859 TCharConnectionState online
= ccs_offline
;
1861 impulse
.serial(contactId
);
1862 impulse
.serialShortEnum(online
);
1864 if (PermanentlyBanned
) return;
1866 //nlinfo("impulseCallback : Received TEAM:CONTACT_STATUS %d %s", contactId, online == ccs_online ?"online": online==ccs_offline?"offline" : "foreign_online");
1868 // 0<=FriendList (actually ignore list does not show online state)
1869 PeopleInterraction
.updateContactInList(contactId
, online
, 0);
1871 // Resort the contact list if needed
1872 CInterfaceManager
* pIM
= CInterfaceManager::getInstance();
1873 CPeopleList::TSortOrder order
= (CPeopleList::TSortOrder
)(NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTACT_LIST:SORT_ORDER")->getValue32());
1875 if (order
== CPeopleList::sort_online
)
1877 PeopleInterraction
.FriendList
.sortEx(order
);
1879 }// impulseTeamContactStatus //
1882 //-----------------------------------------------
1883 // impulseTeamContactRemove
1884 // Remove a contact by the server
1885 //-----------------------------------------------
1886 void impulseTeamContactRemove(NLMISC::CBitMemStream
&impulse
)
1891 impulse
.serial(contactId
);
1892 impulse
.serial(nList
);
1894 if (PermanentlyBanned
) return;
1896 //nlinfo("impulseCallback : Received TEAM:CONTACT_REMOVE %d %d", contactId, nList);
1898 PeopleInterraction
.removeContactFromList(contactId
, nList
);
1900 }// impulseTeamContactRemove //
1903 //-----------------------------------------------
1904 // servers sets information of a guild member:
1905 // u16 ( member index ) u32 (player name ), u8 ( player grade + last bit set if player online ).
1906 //-----------------------------------------------
1907 /*void impulseGuildSetMemberInfo(NLMISC::CBitMemStream &impulse)
1910 impulse.serial(index);
1911 uint32 guildMemberName;
1912 impulse.serial(guildMemberName);
1914 impulse.serial(grade);
1915 bool online = ((grade&0x80) != 0);
1916 grade = (grade & 0x7F);
1917 CGuildManager::getInstance()->set(index, guildMemberName, grade, online);
1920 //-----------------------------------------------
1921 // vector of pair( u32 (player name ), u8 ( player grade + last bit set if player online ) )
1922 //-----------------------------------------------
1923 /*void impulseGuildInitMemberInfo(NLMISC::CBitMemStream &impulse)
1925 vector < pair < uint32, uint8 > > AllMembers;
1927 impulse.serial(nbEntries);
1928 AllMembers.resize(nbEntries);
1929 for (uint32 i = 0; i < nbEntries; ++i)
1932 impulse.serial(name);
1934 impulse.serial(gradeNonline);
1935 AllMembers[i].first = name;
1936 AllMembers[i].second = gradeNonline;
1939 CGuildManager::getInstance()->init(AllMembers);
1943 //-----------------------------------------------
1944 // impulseGuildInvitation
1945 //-----------------------------------------------
1946 /*void impulseGuildInvitation(NLMISC::CBitMemStream &impulse)
1948 nlinfo("impulseGuildInvitation");
1952 //-----------------------------------------------
1953 // impulseGuildJoinProposal
1954 // server sent to client invitation (uint32 invitorNameId, uint32 guildNameId
1955 //-----------------------------------------------
1956 void impulseGuildJoinProposal(NLMISC::CBitMemStream
&impulse
)
1960 impulse
.serial(phraseID
);
1962 if (PermanentlyBanned
) return;
1964 //nlinfo("impulseCallback : Received GUILD:JOIN_PROPOSAL %d", phraseID);
1966 CGuildManager::getInstance()->launchJoinProposal(phraseID
);
1967 /*//activate the pop up window
1968 CInterfaceManager *im = CInterfaceManager::getInstance();
1969 CGroupContainer *gc = dynamic_cast<CGroupContainer *>( CWidgetManager::getInstance()->getElementFromId("ui:interface:join_guild_proposal"));
1971 CViewText *vt = dynamic_cast<CViewText*>(gc->getView("invitor_name"));
1972 if (vt == NULL) return;
1973 vt->setText(invitor);
1974 gc->setActive(true);
1975 CWidgetManager::getInstance()->setTopWindow(gc);
1978 gc->enableBlink(2);*/
1979 }// impulseGuildJoinProposal //
1982 //-----------------------------------------------
1983 // impulseCloseTempInv
1984 //-----------------------------------------------
1985 void impulseCloseTempInv(NLMISC::CBitMemStream
&impulse
)
1987 CTempInvManager::getInstance()->close();
1990 //-----------------------------------------------
1991 // impulseAscencorTeleport
1992 //-----------------------------------------------
1993 void impulseAscencorTeleport(NLMISC::CBitMemStream
&impulse
)
1996 } // impulseAscencorTeleport //
1998 //-----------------------------------------------
1999 // impulseEnterCrZoneProposal
2000 // server sent to client invitation (uint32 invitorNameId, uint32 guildNameId
2001 //-----------------------------------------------
2002 void impulseEnterCrZoneProposal(NLMISC::CBitMemStream
&impulse
)
2005 impulse
.serial(phraseID
);
2006 if (PermanentlyBanned
) return;
2008 //nlinfo("impulseCallback : Received MISSION:ASK_ENTER_CRITICAL %d", phraseID);
2010 //activate the pop up window
2011 CInterfaceManager
*im
= CInterfaceManager::getInstance();
2012 CGroupContainer
*gc
= dynamic_cast<CGroupContainer
*>( CWidgetManager::getInstance()->getElementFromId("ui:interface:enter_crzone_proposal"));
2014 CViewTextID
*vti
= dynamic_cast<CViewTextID
*>(gc
->getView("phrase"));
2016 vti
->setTextId(phraseID
);
2017 gc
->setActive(true);
2018 CWidgetManager::getInstance()->setTopWindow(gc
);
2022 }// impulseEnterCrZoneProposal //
2024 //-----------------------------------------------
2025 // impulseCloseEnterCrZoneProposal
2026 // server close proposal interface
2027 //-----------------------------------------------
2028 void impulseCloseEnterCrZoneProposal(NLMISC::CBitMemStream
&impulse
)
2031 CInterfaceManager
* pIM
= CInterfaceManager::getInstance();
2032 CInterfaceGroup
*pIG
= (CInterfaceGroup
*)CWidgetManager::getInstance()->getElementFromId ("ui:interface:enter_crzone_proposal");
2034 pIG
->setActive(false);
2035 }// impulseCloseEnterCrZoneProposal //
2038 //-----------------------------------------------
2039 // impulseExchangeInvitation :
2040 //-----------------------------------------------
2041 void impulseExchangeInvitation(NLMISC::CBitMemStream
&impulse
)
2044 impulse
.serial(textID
);
2045 if (PermanentlyBanned
) return;
2046 CInterfaceManager
* iMngr
= CInterfaceManager::getInstance();
2048 // show the modal window that allow the player to accept / decline the invitation
2049 CGroupContainer
*wnd
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId(PLAYER_EXCHANGE_INVITATION_DIALOG
));
2052 wnd
->setActive(true);
2053 wnd
->updateCoords();
2055 wnd
->enableBlink(2);
2056 CWidgetManager::getInstance()->setTopWindow(wnd
);
2059 CViewTextID
*vti
= dynamic_cast<CViewTextID
*>(wnd
->getView("invite_phrase"));
2062 vti
->setTextId(textID
);
2065 }// impulseExchangeInvitation //
2067 //-----------------------------------------------
2068 // impulseExchangeCloseInvitation :
2069 //-----------------------------------------------
2070 void impulseExchangeCloseInvitation(NLMISC::CBitMemStream
&impulse
)
2072 if (PermanentlyBanned
) return;
2073 CInterfaceManager
* iMngr
= CInterfaceManager::getInstance();
2074 // hide the modal window that allow the player to accept / decline the invitation
2075 CInterfaceGroup
*wnd
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(PLAYER_EXCHANGE_INVITATION_DIALOG
));
2076 if (wnd
) wnd
->setActive(false);
2079 //-----------------------------------------------
2080 // impulseMountAbort :
2081 //-----------------------------------------------
2082 void impulseMountAbort(NLMISC::CBitMemStream
&impulse
)
2084 nlwarning("impulseMountAbort: Received ANIMALS:MOUNT_ABORT => no more used");
2085 }// impulseMountAbort //
2087 //-----------------------------------------------
2088 // impulseRyzomTime :
2089 // Synchronize the ryzom time with the server.
2090 //-----------------------------------------------
2092 void impulseRyzomTime(NLMISC::CBitMemStream &impulse)
2094 nlinfo("impulseRyzomTime: Ryzom Time Received");
2098 impulse.serial(serverTick);
2099 impulse.serial(ryzomTime);
2100 impulse.serial(ryzomDay);
2101 nlinfo("impulseRyzomTime: Day '%d' Time '%f'.", ryzomDay, ryzomTime);
2104 RT.setOrigin( serverTick, ryzomDay, ryzomTime );
2105 }// impulseRyzomTime //
2107 //-----------------------------------------------
2109 // Display server position
2110 //-----------------------------------------------
2111 void impulseWhere(NLMISC::CBitMemStream
&impulse
)
2113 //nlinfo("impulseCallback : Received DEBUG:REPLY_WHERE");
2119 if (PermanentlyBanned
) return;
2122 double xf
= ((double)x
)/1000.0f
;
2123 double yf
= ((double)y
)/1000.0f
;
2124 double zf
= ((double)z
)/1000.0f
;
2126 sprintf(buf
,"Your server position is : X= %g Y= %g Z= %g",xf
,yf
,zf
);
2128 CInterfaceManager::getInstance()->displaySystemInfo(buf
);
2131 //-----------------------------------------------
2133 // Display server position
2134 //-----------------------------------------------
2136 void impulseWho(NLMISC::CBitMemStream &impulse)
2138 nlinfo("impulseWho Received");
2139 CInterfaceManager::getInstance()->displaySystemInfo("Players currently in the game :");
2141 ucstring name; // OLD
2146 while( impulse.getPos() < (sint32)impulse.length() )
2148 impulse.serial(name);
2149 impulse.serial(loginId);
2150 impulse.serial(dist);
2151 impulse.serial(dirshort);
2153 double angle = dirshort * 2.0 * NLMISC::Pi / 255.0;
2154 angle -= NLMISC::Pi;
2155 nlinfo ("name %s uid %u dist %hu dirshort %hu angle %f", name.toString().c_str(),loginId, dist, (uint16)dirshort, angle);
2156 sint direction =(sint) floor( 0.5 + ( 8.0 * (angle + NLMISC::Pi)/(NLMISC::Pi) ) );
2157 direction = ((direction%16)+16)%16;
2158 static const string txts[]=
2178 str = toString (" - uid %d - distance %hu meters - direction ", loginId, dist);
2179 CInterfaceManager::getInstance()->displaySystemInfo(name + str + CI18N::get(txts[direction]));
2185 void impulseWhoGM(NLMISC::CBitMemStream &impulse)
2187 nlinfo("impulseWhoGM Received");
2188 CInterfaceManager::getInstance()->displaySystemInfo("Players currently in the game :");
2190 ucstring name; // OLD
2195 while( impulse.getPos() < (sint32)impulse.length() )
2197 impulse.serial(name);
2198 impulse.serial(loginId);
2199 impulse.serial(dist);
2200 impulse.serial(dirshort);
2202 double angle = dirshort * 2.0 * NLMISC::Pi / 255.0;
2203 angle -= NLMISC::Pi;
2204 nlinfo ("name %s uid %u dist %hu dirshort %hu angle %f", name.toString().c_str(),loginId, dist, (uint16)dirshort, angle);
2205 sint direction =(sint) floor( 0.5 + ( 8.0 * (angle + NLMISC::Pi)/(NLMISC::Pi) ) );
2206 direction = ((direction%16)+16)%16;
2207 static const string txts[]=
2227 str = toString (" - uid %d - distance %hu meters - direction ", loginId, dist);
2228 CInterfaceManager::getInstance()->displaySystemInfo(name + str + CI18N::get(txts[direction]));
2232 //-----------------------------------------------
2234 // check UDP validity
2235 //-----------------------------------------------
2236 void impulseCounter(NLMISC::CBitMemStream
&impulse
)
2238 //nlinfo("impulseCallBack : Received DEBUG:COUNTER");
2242 impulse
.serial(counter
);
2244 static uint queueTop
= 0;
2245 static deque
<bool> queue
;
2247 if (counter
> queueTop
)
2249 queue
.resize(queue
.size()+counter
-queueTop
, false);
2253 if (queueTop
-counter
+1 > queue
.size())
2255 nlinfo("COUNTER: counter %d arrived too late...", counter
);
2259 if (queue
[queue
.size()-1-(queueTop
-counter
)])
2261 nlwarning("COUNTER: Received counter %d more than once !", counter
);
2265 nldebug("COUNTER: set counter %d", counter
);
2266 queue
[queue
.size()-1-(queueTop
-counter
)] = true;
2269 while (queue
.size() > 128)
2273 nlwarning("COUNTER: counter %d not received !", queueTop
-queue
.size()-1);
2280 catch (const Exception
&e
)
2282 nlwarning ("Problem while decoding a COUTNER msg, skipped: %s", e
.what());
2286 //-----------------------------------------------
2287 // impulsePhraseSend :
2288 // A dyn string (or phrase) is send (so, we receive it)
2289 //-----------------------------------------------
2290 void impulsePhraseSend(NLMISC::CBitMemStream
&impulse
)
2292 STRING_MANAGER::CStringManagerClient::instance()->receiveDynString(impulse
);
2295 //-----------------------------------------------
2296 // impulseStringResp :
2297 // Update the local string set
2298 //-----------------------------------------------
2299 void impulseStringResp(NLMISC::CBitMemStream
&impulse
)
2303 impulse
.serial(stringId
);
2304 impulse
.serial(str
);
2306 if (PermanentlyBanned
) return;
2308 STRING_MANAGER::CStringManagerClient::instance()->receiveString(stringId
, str
);
2311 //-----------------------------------------------
2312 // impulseReloadCache :
2313 // reload the string cache
2314 //-----------------------------------------------
2315 void impulseReloadCache(NLMISC::CBitMemStream
&impulse
)
2318 impulse
.serial(timestamp
);
2319 if (PermanentlyBanned
) return;
2320 STRING_MANAGER::CStringManagerClient::instance()->loadCache(timestamp
);
2323 //-----------------------------------------------
2324 // impulseBotChatEnd
2325 // ForceThe end of the bot chat
2326 //-----------------------------------------------
2327 void impulseBotChatForceEnd(NLMISC::CBitMemStream
&impulse
)
2329 if (PermanentlyBanned
) return;
2330 CBotChatManager::getInstance()->setCurrPage(NULL
);
2334 //-----------------------------------------------
2335 // MISSION COMPLETED JOURNAL
2336 //-----------------------------------------------
2338 #define MC_M_CONTAINER "ui:interface:info_player_journal"
2339 #define MC_S_CONTAINER "ui:interface:ipj_com_missions"
2340 #define MC_TEMPLATE "tipj_mission_complete"
2341 //-----------------------------------------------
2342 CGroupContainer *getMissionCompletedContainer()
2344 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2345 CInterfaceElement *pIE = CWidgetManager::getInstance()->getElementFromId(MC_M_CONTAINER);
2346 CGroupContainer *pGCM = dynamic_cast<CGroupContainer*>(pIE);
2347 if (pGCM == NULL) return NULL;
2349 CGroupList *pList = pGCM->getList();
2350 CGroupContainer *pGCS = dynamic_cast<CGroupContainer*>(pList->getGroup(MC_S_CONTAINER));
2354 //-----------------------------------------------
2355 void clearMissions()
2357 CGroupContainer *pGCMC = getMissionCompletedContainer();
2358 CInterfaceGroup *pContent = pGCMC->getGroup("content");
2359 pContent->clearGroups();
2361 //-----------------------------------------------
2362 void addMission(uint32 titleID)
2364 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2365 CGroupContainer *pGCMC = getMissionCompletedContainer();
2368 nlwarning("cannot get container for missions completed");
2371 CInterfaceGroup *pContent = pGCMC->getGroup("content");
2373 uint32 nNbMission = pContent->getGroups().size();
2374 vector<pair<string, string> > vArgs;
2376 vArgs.push_back(pair<string,string>("id", "mc"+NLMISC::toString(nNbMission)));
2377 vArgs.push_back(pair<string,string>("mcid", NLMISC::toString(titleID)));
2379 if (nNbMission == 0)
2381 vArgs.push_back(pair<string,string>("posref", "TL TL"));
2382 vArgs.push_back(pair<string,string>("posparent", "parent"));
2383 vArgs.push_back(pair<string,string>("y", "0"));
2387 vArgs.push_back(pair<string,string>("posref", "BL TL"));
2390 CInterfaceGroup *pIG = pIM->createGroupInstance(MC_TEMPLATE, pContent->getId(), vArgs);
2393 nlwarning("cannot create a mission completed");
2396 pIG->setParent(pContent);
2397 if (nNbMission == 0)
2398 pIG->setParentPos(pContent);
2400 pIG->setParentPos(pContent->getGroups()[nNbMission-1]);
2401 pContent->addGroup(pIG);
2404 //-----------------------------------------------
2405 // impulseJournalInitCompletedMissions :
2406 // initialize the player journal missions for completed missions
2407 //-----------------------------------------------
2408 void impulseJournalInitCompletedMissions (NLMISC::CBitMemStream
&impulse
)
2411 vector<uint32> vMissionCompleted;
2412 impulse.serialCont(vMissionCompleted);
2416 for (uint32 i = 0; i < vMissionCompleted.size(); ++i)
2417 addMission (vMissionCompleted[i]);
2421 //-----------------------------------------------
2422 // impulseJournalInitCompletedMissions :
2423 // initialize the player journal missions for completed missions
2424 //-----------------------------------------------
2425 void impulseJournalUpdateCompletedMissions (NLMISC::CBitMemStream
&impulse
)
2428 uint32 nNewCompletedMission;
2429 impulse.serial(nNewCompletedMission);
2431 addMission (nNewCompletedMission);
2436 //-----------------------------------------------
2437 // impulseJournalCantAbandon :
2438 // server refuses mission abandon
2439 //-----------------------------------------------
2440 void impulseJournalCantAbandon (NLMISC::CBitMemStream
&impulse
)
2442 if (PermanentlyBanned
) return;
2443 /// reactivate abandon button
2444 CCDBNodeLeaf
*pNL
= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:MISSION_ABANDON_BUTTON",false);
2451 //-----------------------------------------------
2452 // server add a compass target
2453 //-----------------------------------------------
2454 void impulseJournalAddCompass(NLMISC::CBitMemStream
&impulse
)
2461 impulse
.serial(text
);
2462 if (PermanentlyBanned
) return;
2463 //nlinfo("impulseCallback : Received JOURNAL:ADD_COMPASS %d %d %d", x, y, text);
2464 CCompassDialogsManager::getInstance().addEntry( x
,y
,text
);
2467 //-----------------------------------------------
2468 // server removes a compass target
2469 //-----------------------------------------------
2470 void impulseJournalRemoveCompass(NLMISC::CBitMemStream
&impulse
)
2473 impulse
.serial(text
);
2474 if (PermanentlyBanned
) return;
2475 //nlinfo("impulseCallback : Received JOURNAL:REMOVE_COMPASS %d", text);
2476 CCompassDialogsManager::getInstance().removeEntry( text
);
2482 // the server ask me to execute a command
2484 void impulseRemoteAdmin (NLMISC::CBitMemStream
&impulse
)
2486 CLog logDisplayVars
;
2487 CLightMemDisplayer mdDisplayVars
;
2488 logDisplayVars
.addDisplayer (&mdDisplayVars
);
2489 mdDisplayVars
.setParam (10);
2492 impulse
.serial (rid
);
2494 impulse
.serial (cmd
);
2496 // remove the 2 first rc character if exists, only there to say to the EGS that is a remote command
2497 if (cmd
.size()>2 && tolower(cmd
[0])=='r' && tolower(cmd
[1])=='c') // FIXME: toLowerAscii
2498 cmd
= cmd
.substr(2);
2500 mdDisplayVars
.clear ();
2501 ICommand::execute(cmd
, logDisplayVars
, !ICommand::isCommand(cmd
));
2502 const std::deque
<std::string
> &strs
= mdDisplayVars
.lockStrings();
2505 if (ICommand::isCommand(cmd
))
2507 for (uint k
= 0; k
< strs
.size(); k
++)
2516 str
= strs
[0].substr(0,strs
[0].size()-1);
2517 // replace all spaces into underscore because space is a reserved char
2518 for (uint i
= 0; i
< str
.size(); i
++) if (str
[i
] == ' ') str
[i
] = '_';
2525 mdDisplayVars
.unlockStrings();
2527 //nlinfo("impulseCallback : Received COMMAND:REMOTE_ADMIN : Server asked me to execute '%s', result is '%s'", cmd.c_str(), str.c_str());
2530 if(GenericMsgHeaderMngr
.pushNameToStream("COMMAND:REMOTE_ADMIN_ANSWER", out
))
2536 //nlinfo("impulseCallback : COMMAND:REMOTE_ADMIN_ANSWER %d %s %s sent", rid, cmd.c_str(), str.c_str());
2541 //-----------------------------------------------
2542 // impulseGuildAscensor :
2543 // server request that the client launch the ascensor interface
2544 //-----------------------------------------------
2546 void impulseGuildAscensor (NLMISC::CBitMemStream
&impulse
)
2548 if (PermanentlyBanned
) return;
2549 //nlinfo("impulseCallback : Received GUILD:ASCENSOR");
2550 CGuildManager::getInstance()->launchAscensor();
2553 //-----------------------------------------------
2554 //impulseGuildLeaveAscensor
2555 //-----------------------------------------------
2556 void impulseGuildLeaveAscensor (NLMISC::CBitMemStream
&impulse
)
2558 if (PermanentlyBanned
) return;
2559 //nlinfo("impulseCallback : Received GUILD:LEAVE_ASCENSOR");
2560 CGuildManager::getInstance()->quitAscensor();
2563 //-----------------------------------------------
2564 //impulseGuildAbortCreation
2565 //-----------------------------------------------
2566 void impulseGuildAbortCreation (NLMISC::CBitMemStream
&impulse
)
2568 CBotChatPage
*pPage
= CBotChatManager::getInstance()->getCurrPage();
2569 CBotChatPageCreateGuild
*pPageCG
= dynamic_cast<CBotChatPageCreateGuild
*>(pPage
);
2570 if (pPageCG
== BotChatPageAll
->CreateGuild
)
2571 CBotChatManager::getInstance()->setCurrPage(NULL
);
2574 void impulseGuildOpenGuildWindow(NLMISC::CBitMemStream
&impulse
)
2576 CGuildManager::getInstance()->openGuildWindow();
2580 //-----------------------------------------------
2581 // impulseGuildOpenInventory
2582 //-----------------------------------------------
2583 void impulseGuildOpenInventory (NLMISC::CBitMemStream
&impulse
)
2585 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2586 NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:INVENTORY_GUILD_OPENED")->setValue32(1);
2589 //-----------------------------------------------
2590 // impulseGuildCloseInventory
2591 //-----------------------------------------------
2592 void impulseGuildCloseInventory (NLMISC::CBitMemStream
&impulse
)
2594 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2595 NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:INVENTORY_GUILD_OPENED")->setValue32(0);
2598 //-----------------------------------------------
2599 // impulseGuildUpdatePlayerTitle
2600 // server block/unblock some reserved titles
2601 //-----------------------------------------------
2602 void impulseGuildUpdatePlayerTitle(NLMISC::CBitMemStream
&impulse
)
2604 CSkillManager
*pSM
= CSkillManager::getInstance();
2606 impulse
.serial(bUnblock
);
2607 vector
<uint16
> vTitles
;
2608 impulse
.serialCont(vTitles
);
2609 if (PermanentlyBanned
) return;
2612 for (uint32 i
= 0; i
< vTitles
.size(); ++i
)
2613 pSM
->unblockTitleFromServer((CHARACTER_TITLE::ECharacterTitle
)vTitles
[i
]);
2617 for (uint32 i
= 0; i
< vTitles
.size(); ++i
)
2618 pSM
->blockTitleFromServer((CHARACTER_TITLE::ECharacterTitle
)vTitles
[i
]);
2622 //-----------------------------------------------
2623 // impulseGuildUseFemaleTitles
2624 // server activates/deactivates use of female titles
2625 //-----------------------------------------------
2626 void impulseGuildUseFemaleTitles(NLMISC::CBitMemStream
&impulse
)
2628 impulse
.serial( UseFemaleTitles
);
2631 //-----------------------------------------------
2632 // impulsePhraseDownLoad
2633 // server upload the phrases.
2634 //-----------------------------------------------
2635 void impulsePhraseDownLoad (NLMISC::CBitMemStream
&impulse
)
2637 std::vector
<CSPhraseSlot
> phrases
;
2639 // Read Known Phrases
2640 impulse
.serialCont(phrases
);
2641 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
2642 for(uint i
=0;i
<phrases
.size();i
++)
2644 if(phrases
[i
].PhraseSheetId
!= CSheetId::Unknown
)
2646 CSPhraseCom phraseCom
;
2647 pPM
->buildPhraseFromSheet(phraseCom
, phrases
[i
].PhraseSheetId
.asInt());
2648 pPM
->setPhraseNoUpdateDB(phrases
[i
].KnownSlot
, phraseCom
);
2652 pPM
->setPhraseNoUpdateDB(phrases
[i
].KnownSlot
, phrases
[i
].Phrase
);
2655 // must update the DB (NB: if initInGameDone) after all phrase set.
2656 pPM
->updateBookDB();
2658 // Then Read Memorized Phrases
2659 std::vector
<CSPhraseMemorySlot
> memorizedPhrases
;
2660 impulse
.serialCont(memorizedPhrases
);
2661 if (PermanentlyBanned
) return;
2662 for(uint i
=0;i
<memorizedPhrases
.size();i
++)
2664 pPM
->memorizePhrase(
2665 memorizedPhrases
[i
].MemoryLineId
,
2666 memorizedPhrases
[i
].MemorySlotId
,
2667 memorizedPhrases
[i
].PhraseId
);
2671 extern bool SabrinaPhraseBookLoaded
;
2672 SabrinaPhraseBookLoaded
= true;
2674 // update gray state, if game inited.
2675 pPM
->updateMemoryBar();
2678 //-----------------------------------------------
2679 // impulsePhraseConfirmBuy
2680 // server confirm/infirm the buy of botchat phrase.
2681 //-----------------------------------------------
2682 void impulsePhraseConfirmBuy (NLMISC::CBitMemStream
&impulse
)
2687 impulse
.serial(phraseId
);
2688 impulse
.serial(confirm
);
2690 if (PermanentlyBanned
) return;
2692 CSPhraseManager
*pSM
= CSPhraseManager::getInstance();
2693 pSM
->receiveBotChatConfirmBuy(phraseId
, confirm
);
2697 //-----------------------------------------------
2698 // impulsePhraseAckExecuteCyclic
2699 // server confirm/infirm the cyclic execution of a phrase
2700 //-----------------------------------------------
2701 void impulsePhraseAckExecuteCyclic (NLMISC::CBitMemStream
&impulse
)
2707 impulse
.serial(counter
);
2709 if (PermanentlyBanned
) return;
2712 CSPhraseManager
*pSM
= CSPhraseManager::getInstance();
2713 pSM
->receiveAckExecuteFromServer(true, counter
, ok
);
2717 //-----------------------------------------------
2718 // impulsePhraseAckExecuteCyclic
2719 // server confirm/infirm the execution of a phrase
2720 //-----------------------------------------------
2721 void impulsePhraseAckExecuteNext (NLMISC::CBitMemStream
&impulse
)
2727 impulse
.serial(counter
);
2729 if (PermanentlyBanned
) return;
2731 CSPhraseManager
*pSM
= CSPhraseManager::getInstance();
2732 pSM
->receiveAckExecuteFromServer(false, counter
, ok
);
2735 // Same params as in BOMB_IF
2736 #ifdef FINAL_VERSION
2737 #define SKIP_IF(condition,msg,skipAction) if (!(condition)); else skipAction;
2739 #define SKIP_IF(condition,msg,skipAction) if (!(condition)) WARN(msg); else skipAction;
2742 template <class CInventoryCategoryTemplate
>
2743 void updateInventoryFromStream (NLMISC::CBitMemStream
&impulse
, const CInventoryCategoryTemplate
*templ
, bool notifyItemSheetChanges
)
2747 // get the egs tick of this change
2748 TGameCycle serverTick
;
2749 impulse
.serial(serverTick
);
2751 // For All inventories
2752 for ( uint invId
=0; invId
!=CInventoryCategoryTemplate::NbInventoryIds
; ++invId
)
2756 impulse
.serialBit( hasContent
);
2762 impulse
.serial( nbChanges
, INVENTORIES::LowNumberBits
);
2763 if ( nbChanges
== INVENTORIES::LowNumberBound
)
2764 impulse
.serial( nbChanges
, 32 );
2766 const string invBranchStr
= CInventoryCategoryTemplate::getDbStr( (typename
CInventoryCategoryTemplate::TInventoryId
)invId
);
2767 ICDBNode::CTextId
textId( invBranchStr
);
2768 ICDBNode
*inventoryNode
= IngameDbMngr
.getNodePtr()->getNode( textId
, false );
2769 BOMB_IF(!inventoryNode
, "Inventory missing in database", return);
2772 for ( uint c
=0; c
!=nbChanges
; ++c
)
2774 // Unpack (the bitmemstream is written from high-order to low-order)
2775 uint32 iuInfoVersion
;
2776 impulse
.serial( iuInfoVersion
, 1 );
2777 if ( iuInfoVersion
== 1 )
2780 impulse
.serial( slotIndex
, CInventoryCategoryTemplate::SlotBitSize
);
2782 // Access the database leaf
2783 CCDBNodeBranch
*slotNode
= safe_cast
<CCDBNodeBranch
*>(inventoryNode
->getNode( (uint16
)slotIndex
));
2784 CCDBNodeLeaf
*leafNode
= type_cast
<CCDBNodeLeaf
*>(slotNode
->find( INVENTORIES::InfoVersionStr
));
2785 BOMB_IF( !leafNode
, "Inventory slot property missing in database", continue );
2787 // Apply or increment Info Version in database
2788 if ( CInventoryCategoryTemplate::needPlainInfoVersionTransfer() )
2791 impulse
.serial( infoVersion
, INVENTORIES::InfoVersionBitSize
);
2792 leafNode
->setPropCheckGC( serverTick
, infoVersion
);
2796 // NB: don't need to check GC on a info version upgrade, since this is always a delta of +1
2797 // the order of received of this impulse is not important
2798 leafNode
->setValue64( leafNode
->getValue64() + 1 );
2805 impulse
.serial( iuAll
, 1 );
2808 INVENTORIES::CItemSlot itemSlot
;
2809 itemSlot
.serialAll( impulse
, templ
);
2810 //nldebug( "Inv %s Update %u", CInventoryCategoryTemplate::InventoryStr[invId], itemSlot.getSlotIndex() );
2812 // Apply all properties to database
2813 CCDBNodeBranch
*slotNode
= safe_cast
<CCDBNodeBranch
*>(inventoryNode
->getNode( (uint16
)itemSlot
.getSlotIndex() ));
2814 for ( uint i
=0; i
!=INVENTORIES::NbItemPropId
; ++i
)
2816 CCDBNodeLeaf
*leafNode
= type_cast
<CCDBNodeLeaf
*>(slotNode
->find( string(INVENTORIES::CItemSlot::ItemPropStr
[i
]) ));
2817 SKIP_IF( !leafNode
, "Inventory slot property missing in database", continue );
2818 leafNode
->setPropCheckGC( serverTick
, (sint64
)itemSlot
.getItemProp( ( INVENTORIES::TItemPropId
)i
) );
2824 impulse
.serial( iuOneProp
, 1 );
2825 if ( iuOneProp
== 1 )
2827 INVENTORIES::CItemSlot itemSlot
;
2828 itemSlot
.serialOneProp( impulse
, templ
);
2829 //nldebug( "Inv %s Prop %u %s", CInventoryCategoryTemplate::InventoryStr[invId], itemSlot.getSlotIndex(), INVENTORIES::CItemSlot::ItemPropStr[itemSlot.getOneProp().ItemPropId] );
2831 // Apply property to database
2832 CCDBNodeBranch
*slotNode
= safe_cast
<CCDBNodeBranch
*>(inventoryNode
->getNode( (uint16
)itemSlot
.getSlotIndex() ));
2833 CCDBNodeLeaf
*leafNode
= type_cast
<CCDBNodeLeaf
*>(slotNode
->find( string(INVENTORIES::CItemSlot::ItemPropStr
[itemSlot
.getOneProp().ItemPropId
]) ));
2834 SKIP_IF( !leafNode
, "Inventory slot property missing in database", continue );
2835 leafNode
->setPropCheckGC( serverTick
, (sint64
)itemSlot
.getOneProp().ItemPropValue
);
2841 impulse
.serial( slotIndex
, CInventoryCategoryTemplate::SlotBitSize
);
2842 //nldebug( "Inv %s Reset %u", CInventoryCategoryTemplate::InventoryStr[invId], slotIndex );
2844 // Reset all properties in database
2845 CCDBNodeBranch
*slotNode
= safe_cast
<CCDBNodeBranch
*>(inventoryNode
->getNode( (uint16
)slotIndex
));
2846 for ( uint i
=0; i
!=INVENTORIES::NbItemPropId
; ++i
)
2848 // Instead of clearing all leaves (by index), we must find and clear only the
2849 // properties in TItemPropId, because the actual database leaves may have
2850 // less properties, and because we must not clear the leaf INFO_VERSION.
2851 // NOTE: For example, only player BAG inventory has WORNED leaf.
2852 CCDBNodeLeaf
*leafNode
= type_cast
<CCDBNodeLeaf
*>(slotNode
->find( string(INVENTORIES::CItemSlot::ItemPropStr
[i
]) ));
2853 SKIP_IF( !leafNode
, "Inventory slot property missing in database", continue );
2854 leafNode
->setPropCheckGC( serverTick
, 0 );
2862 CInventoryManager::getInstance()->sortBag();
2864 catch (const Exception
&e
)
2866 nlwarning ("Problem while decoding a DB_UPD_INV msg, skipped: %s", e
.what());
2870 //-----------------------------------------------
2871 // impulseUpdateInventory:
2872 //-----------------------------------------------
2873 void impulseUpdateInventory (NLMISC::CBitMemStream
&impulse
)
2875 updateInventoryFromStream( impulse
, (INVENTORIES::CInventoryCategoryForCharacter
*)NULL
, true );
2878 //-----------------------------------------------
2879 // impulseInitInventory:
2880 //-----------------------------------------------
2881 void impulseInitInventory (NLMISC::CBitMemStream
&impulse
)
2883 sint32 p
= impulse
.getPos();
2884 impulseUpdateInventory( impulse
);
2885 IngameDbMngr
.setInitPacketReceived();
2886 nlinfo( "DB_INIT:INV done (%u bytes)", impulse
.getPos()-p
);
2889 //-----------------------------------------------
2890 // impulseItemInfoSet:
2891 //-----------------------------------------------
2892 void impulseItemInfoSet (NLMISC::CBitMemStream
&impulse
)
2894 CItemInfos itemInfos
;
2895 impulse
.serial(itemInfos
);
2897 getInventory().onReceiveItemInfo(itemInfos
);
2900 //-----------------------------------------------
2901 // impulseItemInfoRefreshVersion:
2902 //-----------------------------------------------
2903 void impulseItemInfoRefreshVersion (NLMISC::CBitMemStream
&impulse
)
2907 impulse
.serial(slotId
);
2908 impulse
.serial(infoVersion
);
2910 getInventory().onRefreshItemInfoVersion(slotId
, infoVersion
);
2913 //-----------------------------------------------
2914 // impulsePrereqInfoSet:
2915 //-----------------------------------------------
2916 void impulsePrereqInfoSet (NLMISC::CBitMemStream
&impulse
)
2918 CPrerequisitInfos prereqInfos
;
2920 impulse
.serial(prereqInfos
);
2921 impulse
.serial(index
);
2923 //write infos in interface
2924 CBotChatManager::getInstance()->onReceiveMissionInfo(index
, prereqInfos
);
2927 //-----------------------------------------------
2928 //-----------------------------------------------
2929 void impulseDeathRespawnPoint (NLMISC::CBitMemStream
&impulse
)
2931 CRespawnPointsMsg msg
;
2932 impulse
.serial(msg
);
2933 if (PermanentlyBanned
) return;
2934 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2935 CGroupMap
*pMap
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:respawn_map:content:map_content:actual_map"));
2938 nlwarning("problem cannot find ui:interface:respawn_map:content:map_content:actual_map");
2941 pMap
->addRespawnPoints(msg
);
2944 pMap
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:actual_map"));
2947 nlwarning("problem cannot find ui:interface:map:content:map_content:actual_map");
2950 pMap
->addRespawnPoints(msg
);
2953 //-----------------------------------------------
2954 //-----------------------------------------------
2955 void impulseDeathRespawn (NLMISC::CBitMemStream
&impulse
)
2957 // TODO : Bring me to life !!!
2960 //-----------------------------------------------
2961 // impulseDuelInvitation :
2962 //-----------------------------------------------
2963 void impulseDuelInvitation(NLMISC::CBitMemStream
&impulse
)
2966 impulse
.serial(textID
);
2968 //nlinfo("impulseCallback : Received DUEL:INVITATION %d", textID);
2970 if (PermanentlyBanned
) return;
2972 //activate the pop up window
2973 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2974 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_duel_proposal"));
2975 if (pGC
== NULL
) return;
2976 CViewTextID
*pVTID
= dynamic_cast<CViewTextID
*>(pGC
->getView("invitor_name"));
2977 if (pVTID
== NULL
) return;
2978 pVTID
->setTextId(textID
);
2979 pGC
->setActive(true);
2980 CWidgetManager::getInstance()->setTopWindow(pGC
);
2981 pGC
->updateCoords();
2983 pGC
->enableBlink(2);
2985 }// impulseDuelInvitation //
2987 //-----------------------------------------------
2988 // impulseDuelCancelInvitation:
2989 //-----------------------------------------------
2990 void impulseDuelCancelInvitation(NLMISC::CBitMemStream
&impulse
)
2992 if (PermanentlyBanned
) return;
2993 //nlinfo("impulseCallback : Received DUEL:CANCEL_INVITATION");
2995 //activate the pop up window
2996 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2997 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_duel_proposal"));
2998 if (pGC
== NULL
) return;
2999 pGC
->setActive(false);
3001 }// impulseDuelCancelInvitation //
3003 //-----------------------------------------------
3004 // impulsePVPChallengeInvitation :
3005 //-----------------------------------------------
3006 void impulsePVPChallengeInvitation(NLMISC::CBitMemStream
&impulse
)
3009 impulse
.serial(textID
);
3011 if (PermanentlyBanned
) return;
3013 //nlinfo("impulseCallback : Received PVP_CHALLENGE:INVITATION %d", textID);
3015 //activate the pop up window
3016 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3017 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_challenge_proposal"));
3018 if (pGC
== NULL
) return;
3019 CViewTextID
*pVTID
= dynamic_cast<CViewTextID
*>(pGC
->getView("invitor_name"));
3020 if (pVTID
== NULL
) return;
3021 pVTID
->setTextId(textID
);
3022 pGC
->setActive(true);
3023 CWidgetManager::getInstance()->setTopWindow(pGC
);
3024 pGC
->updateCoords();
3026 pGC
->enableBlink(2);
3028 }// impulsePVPChallengeInvitation //
3030 //-----------------------------------------------
3031 // impulsePVPChallengeCancelInvitation:
3032 //-----------------------------------------------
3033 void impulsePVPChallengeCancelInvitation(NLMISC::CBitMemStream
&impulse
)
3035 //nlinfo("impulseCallback : Received PVP_CHALLENGE:CANCEL_INVITATION");
3037 //activate the pop up window
3038 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3039 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_challenge_proposal"));
3040 if (pGC
== NULL
) return;
3041 pGC
->setActive(false);
3043 }// impulsePVPChallengeCancelInvitation //
3047 //-----------------------------------------------
3048 // impulsePVPFactionPushFactionWar:
3049 //-----------------------------------------------
3050 void impulsePVPFactionPushFactionWar(NLMISC::CBitMemStream
&impulse
)
3052 //nlinfo("impulseCallback : Received PVP_FACTION:PUSH_FACTION_WAR");
3054 PVP_CLAN::CFactionWar factionWar
;
3055 impulse
.serialEnum(factionWar
.Clan1
);
3056 impulse
.serialEnum(factionWar
.Clan2
);
3058 CFactionWarManager::getInstance()->addFactionWar(factionWar
);
3062 //-----------------------------------------------
3063 // impulsePVPFactionPopFactionWar:
3064 //-----------------------------------------------
3065 void impulsePVPFactionPopFactionWar(NLMISC::CBitMemStream
&impulse
)
3067 //nlinfo("impulseCallback : Received PVP_FACTION:POP_FACTION_WAR");
3069 PVP_CLAN::CFactionWar factionWar
;
3070 impulse
.serialEnum(factionWar
.Clan1
);
3071 impulse
.serialEnum(factionWar
.Clan2
);
3073 CFactionWarManager::getInstance()->stopFactionWar(factionWar
);
3077 //-----------------------------------------------
3078 // impulsePVPFactionFactionWars:
3079 //-----------------------------------------------
3080 void impulsePVPFactionFactionWars(NLMISC::CBitMemStream
&impulse
)
3082 //nlinfo("impulseCallback : Received PVP_FACTION:FACTION_WARS");
3084 CFactionWarsMsg factionWars
;
3085 impulse
.serial(factionWars
);
3087 for( uint i
=0; i
<factionWars
.FactionWarOccurs
.size(); ++i
)
3089 CFactionWarManager::getInstance()->addFactionWar(factionWars
.FactionWarOccurs
[i
]);
3095 //-----------------------------------------------
3096 // impulsePVPChooseClan
3097 //-----------------------------------------------
3099 void impulsePVPChooseClan(NLMISC::CBitMemStream &impulse)
3101 nlinfo("impulsePVPChooseClan : Received PVP_CLAN:CHOOSE_CLAN");
3103 EGSPD::CPeople::TPeople clan1= EGSPD::CPeople::Unknown, clan2= EGSPD::CPeople::Unknown;
3104 impulse.serialEnum( clan1 );
3105 impulse.serialEnum( clan2 );
3107 if (PermanentlyBanned) return;
3109 //activate the pop up window
3110 CInterfaceManager *pIM = CInterfaceManager::getInstance();
3111 CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_clan_proposal"));
3112 if (pGC == NULL) return;
3113 pGC->setActive(true);
3115 CCtrlTextButton * butClan1 = dynamic_cast<CCtrlTextButton*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_clan_proposal:content:clan1"));
3116 if( butClan1 == NULL )
3118 butClan1->setText( EGSPD::CPeople::toString( clan1 ) );
3120 CCtrlTextButton * butClan2 = dynamic_cast<CCtrlTextButton*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_clan_proposal:content:clan2"));
3121 if( butClan2 == NULL )
3123 butClan2->setText( EGSPD::CPeople::toString( clan2 ) );
3127 //-----------------------------------------------
3128 // impulseEncyclopediaUpdate
3129 //-----------------------------------------------
3130 void impulseEncyclopediaUpdate(NLMISC::CBitMemStream
&impulse
)
3132 //nlinfo("impulseCallback : Received ENCYCLOPEDIA:UPDATE");
3134 CEncyclopediaUpdateMsg msg
;
3135 impulse
.serial(msg
);
3136 if (PermanentlyBanned
) return;
3137 CEncyclopediaManager::getInstance()->update(msg
);
3138 }// impulseEncyclopediaUpdate //
3140 //-----------------------------------------------
3141 // impulseEncyclopediaInit
3142 //-----------------------------------------------
3143 void impulseEncyclopediaInit(NLMISC::CBitMemStream
&impulse
)
3145 //nlinfo("impulseCallback : Received ENCYCLOPEDIA:INIT");
3147 CEncyclopediaUpdateMsg msg
;
3148 impulse
.serial(msg
);
3149 if (PermanentlyBanned
) return;
3150 CEncyclopediaManager::getInstance()->update(msg
);
3151 }// impulseEncyclopediaInit //
3153 //-----------------------------------------------
3154 //-----------------------------------------------
3155 void impulseItemOpenRoomInventory(NLMISC::CBitMemStream
&impulse
)
3157 if (PermanentlyBanned
) return;
3158 // This is a message because we may do other things there
3159 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3160 NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:INVENTORY_ROOM_OPENED")->setValue32(1);
3163 //-----------------------------------------------
3164 //-----------------------------------------------
3165 void impulseItemCloseRoomInventory(NLMISC::CBitMemStream
&impulse
)
3167 if (PermanentlyBanned
) return;
3168 // This is a message because we may do other things there
3169 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3170 NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:INVENTORY_ROOM_OPENED")->setValue32(0);
3172 // deactivate the pop up window
3173 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:inv_room"));
3174 if (pGC
== NULL
) return;
3175 pGC
->setActive(false);
3178 //-----------------------------------------------
3179 //-----------------------------------------------
3180 void impulseUserBars(NLMISC::CBitMemStream
&impulse
)
3183 sint32 hp
, sap
, sta
, focus
;
3184 impulse
.serial(msgNumber
);
3186 impulse
.serial(sap
);
3187 impulse
.serial(sta
);
3188 impulse
.serial(focus
);
3190 if (PermanentlyBanned
) return;
3192 // Setup the user Bars
3193 CBarManager::CBarInfo bi
;
3194 CBarManager::getInstance()->setupUserBarInfo(msgNumber
, hp
, sap
, sta
, focus
);
3197 //-----------------------------------------------
3198 //-----------------------------------------------
3199 void impulseOutpostChooseSide(NLMISC::CBitMemStream
&impulse
)
3203 bool playerGuildInConflict
;
3204 bool playerGuildIsAttacker
;
3205 impulse
.serial(outpostInFire
);
3206 impulse
.serial(playerGuildInConflict
);
3207 impulse
.serial(playerGuildIsAttacker
);
3208 uint32 ownerGuildNameId
;
3209 impulse
.serial( ownerGuildNameId
);
3210 uint32 attackerGuildNameId
;
3211 impulse
.serial( attackerGuildNameId
);
3213 impulse
.serial( declTimer
);
3216 OutpostManager
.startPvpJoinProposal(outpostInFire
, playerGuildInConflict
, playerGuildIsAttacker
,
3217 ownerGuildNameId
, attackerGuildNameId
, declTimer
);
3220 //-----------------------------------------------
3221 //-----------------------------------------------
3222 void impulseOutpostDeclareWarAck(NLMISC::CBitMemStream
&impulse
)
3226 uint32 timeStartAttack
;
3228 impulse
.serial(canValidate
);
3229 impulse
.serial(docTextId
);
3230 impulse
.serial(timeStartAttack
);
3232 // write result in Local DB.
3233 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3236 CCDBNodeLeaf
*node
= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:DECLARE_WAR_ACK_RECEIVED");
3238 node
->setValueBool(true);
3239 // set result of ACK
3240 node
= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:DECLARE_WAR_ACK_OK");
3242 node
->setValueBool(canValidate
);
3243 node
= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:DECLARE_WAR_ACK_TEXTID");
3245 node
->setValue32(docTextId
);
3246 node
= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:DECLARE_WAR_ACK_TIME_RANGE_ATT");
3248 node
->setValue32(timeStartAttack
);
3251 extern void addWebIGParams(string
&url
, bool trustedDomain
);
3253 //-----------------------------------------------
3254 //-----------------------------------------------
3255 class CServerMessageBoxOnReceiveTextId
: public STRING_MANAGER::IStringWaitCallback
3258 enum TTextType
{TitleType
= 0, ContentType
, NumTextType
};
3259 uint32 _TextId
[NumTextType
];
3260 bool _TextReceived
[NumTextType
];
3261 bool _AlreadyDisplayed
;
3264 void activateMsgBoxWindow()
3266 STRING_MANAGER::CStringManagerClient
*pSMC
= STRING_MANAGER::CStringManagerClient::instance();
3268 // get the content string (should have been received!)
3271 if(!pSMC
->getDynString(_TextId
[ContentType
], contentStr
))
3274 if(!pSMC
->getDynString(_TextId
[TitleType
], titleStr
))
3277 // if the string start with a @{Wxxxx} code, remove it and get the wanted window size
3278 sint w
= 256; // default size to 256 !!
3279 bool is_webig
= false;
3281 if(contentStr
.size()>=6 && contentStr
[0]=='W' && contentStr
[1]=='E' && contentStr
[2]=='B'
3282 && contentStr
[3]==' ' && contentStr
[4]==':' && contentStr
[5]==' ' )
3285 const uint digitStart
= 6;
3286 const uint digitMaxEnd
= (uint
)contentStr
.size();
3290 for(i
= digitStart
; i
< digitMaxEnd
; i
++)
3292 if(contentStr
[i
] == ' ')
3295 if(i
!= digitMaxEnd
)
3297 string web_app
= contentStr
.substr(digitStart
, i
-digitStart
);
3298 contentStr
= string(ClientCfg
.WebIgMainDomain
+ "/") + web_app
+ string("/index.php?") + contentStr
.substr((size_t)i
+ 1);
3306 else if(contentStr
.size()>=5 && contentStr
[0]=='@' && contentStr
[1]=='{' && contentStr
[2]=='W')
3309 const uint digitStart
= 3;
3310 const uint digitMaxEnd
= 8;
3311 for(i
=digitStart
;i
<contentStr
.size() && i
<digitMaxEnd
;i
++)
3313 if(contentStr
[i
]=='}')
3319 string digitStr
= contentStr
.substr(digitStart
, i
-digitStart
);
3320 fromString(digitStr
, w
);
3321 // remove the first tag
3322 contentStr
= contentStr
.substr(i
+1);
3326 // open the message box window or web ig
3327 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3331 CGroupHTML
*groupHtml
;
3332 string group
= titleStr
;
3334 group
= group
.substr(9, group
.size()-10);
3335 groupHtml
= dynamic_cast<CGroupHTML
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:"+group
+":content:html"));
3338 groupHtml
= dynamic_cast<CGroupHTML
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:webig:content:html"));
3344 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:"+group
));
3347 if (contentStr
.empty())
3349 pGC
->setActive(false);
3353 if (group
== "webig")
3354 pGC
->setActive(true);
3355 string url
= contentStr
;
3356 addWebIGParams(url
, true);
3357 groupHtml
->browse(url
.c_str());
3358 CWidgetManager::getInstance()->setTopWindow(pGC
);
3365 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:server_message_box"));
3368 // show the window with correct width
3370 pGC
->setActive(true);
3372 // must set the text by hand
3373 CViewText
*vt
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("server_message_box_content_view_text")));
3375 vt
->setTextFormatTaged(contentStr
);
3378 CWidgetManager::getInstance()->setTopWindow(pGC
);
3379 pGC
->invalidateCoords();
3380 // Yoyo: because of buggued group container, I found that 6 times is a good number....
3381 for(uint i
=0;i
<6;i
++)
3382 pGC
->updateCoords();
3384 pGC
->enableBlink(2);
3390 // called when the string is available
3391 virtual void onDynStringAvailable(uint stringId
, const std::string
&value
)
3393 // don't care if already displayed
3394 if(_AlreadyDisplayed
)
3397 // check if one of waited text
3398 for(uint i
=0;i
<NumTextType
;i
++)
3400 if(stringId
==_TextId
[i
])
3402 _TextReceived
[i
]= true;
3407 for(uint i
=0;i
<NumTextType
;i
++)
3409 if(!_TextReceived
[i
])
3412 // Yes => display window
3413 _AlreadyDisplayed
= true;
3414 activateMsgBoxWindow();
3418 void startWaitTexts(uint32 titleTextId
, uint32 docTextId
)
3421 _TextId
[TitleType
]= titleTextId
;
3422 _TextId
[ContentType
]= docTextId
;
3423 _TextReceived
[TitleType
]= false;
3424 _TextReceived
[ContentType
]= false;
3425 _AlreadyDisplayed
= false;
3427 // start to wait receive of those string (NB: they may be already here, but waitDynStrings calls directly the callback in this case)
3428 STRING_MANAGER::CStringManagerClient
*pSMC
= STRING_MANAGER::CStringManagerClient::instance();
3429 pSMC
->waitDynString(titleTextId
, this);
3430 pSMC
->waitDynString(docTextId
, this);
3433 CServerMessageBoxOnReceiveTextId ServerMessageBoxOnReceiveTextId
;
3436 void impulseUserPopup(NLMISC::CBitMemStream
&impulse
)
3440 impulse
.serial(titleTextId
);
3441 impulse
.serial(docTextId
);
3443 // setup TEMP DB for title
3444 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3445 CCDBNodeLeaf
*node
= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:SERVER_POPUP:TITLE");
3446 if(node
) node
->setValue32(titleTextId
);
3448 // Open the Popup only when the 2 dyn strings are available
3449 ServerMessageBoxOnReceiveTextId
.startWaitTexts(titleTextId
, docTextId
);
3452 //-----------------------------------------------
3453 //-----------------------------------------------
3454 //extern void impulseCombatFlyingHpDelta(NLMISC::CBitMemStream &impulse);
3455 void impulseCombatFlyingHpDelta(NLMISC::CBitMemStream
&impulse
)
3460 impulse
.serial(entityID
);
3461 impulse
.serial(rgba
);
3462 impulse
.serial(hpDelta
);
3463 CRGBA
color((uint8
)(rgba
>>24&255), (uint8
)(rgba
>>16&255), (uint8
)(rgba
>>8&255), (uint8
)(rgba
&255));
3464 CEntityCL
*entity
= EntitiesMngr
.getEntityByCompressedIndex(entityID
);
3466 entity
->addHPOutput(toString("%d", hpDelta
), color
);
3469 void impulseCombatFlyingTextItemSpecialEffectProc(NLMISC::CBitMemStream
&impulse
)
3475 impulse
.serial(entityID
);
3476 impulse
.serial(rgba
);
3477 impulse
.serial(effect
);
3478 impulse
.serial(param
);
3479 CRGBA
color((uint8
)(rgba
>>24&255), (uint8
)(rgba
>>16&255), (uint8
)(rgba
>>8&255), (uint8
)(rgba
&255));
3480 string text
= CI18N::get(toString("uiItemSpecialEffectFlyingText%s", ITEM_SPECIAL_EFFECT::toString((ITEM_SPECIAL_EFFECT::TItemSpecialEffect
)effect
).c_str()));
3481 strFindReplace(text
, "%param", toString("%d", param
));
3482 CEntityCL
*entity
= EntitiesMngr
.getEntityByCompressedIndex(entityID
);
3484 entity
->addHPOutput(text
, color
);
3487 void impulseCombatFlyingText(NLMISC::CBitMemStream
&impulse
)
3491 impulse
.serial(entityID
);
3492 impulse
.serial(tmp
);
3493 COMBAT_FLYING_TEXT::TCombatFlyingText type
= (COMBAT_FLYING_TEXT::TCombatFlyingText
)tmp
;
3495 CRGBA
color(255, 255, 255);
3501 case COMBAT_FLYING_TEXT::TargetDodge
: // The target dodged
3502 color
= CRGBA(255, 128, 64);
3503 text
= CI18N::get("uiDodge");
3506 case COMBAT_FLYING_TEXT::TargetParry
: // The target parried
3507 color
= CRGBA(255, 128, 64);
3508 text
= CI18N::get("uiParry");
3511 case COMBAT_FLYING_TEXT::TargetEvade
: // Actually the user miss his hit
3512 color
= CRGBA(255, 128, 64);
3513 text
= CI18N::get("uiEvade");
3516 case COMBAT_FLYING_TEXT::SelfEvade
: // Actually the target miss his hit
3517 color
= CRGBA(255, 255, 0);
3518 text
= CI18N::get("uiEvade");
3521 case COMBAT_FLYING_TEXT::TargetResist
: // The target resisted magic
3522 color
= CRGBA(255, 128, 64);
3523 text
= CI18N::get("uiResist");
3526 case COMBAT_FLYING_TEXT::SelfResist
: // The user resisted magic
3527 color
= CRGBA(255, 255, 0);
3528 text
= CI18N::get("uiResist");
3531 case COMBAT_FLYING_TEXT::SelfInterrupt
: // the user cast was interupted
3532 color
= CRGBA(200, 0, 0);
3533 text
= CI18N::get("uiInterrupt");
3537 case COMBAT_FLYING_TEXT::SelfFailure
: // The user failed to cast
3538 color
= CRGBA(200, 0, 0);
3539 text
= CI18N::get("uiFailure");
3542 default: // bad type
3543 nlwarning("Bad type for COMBAT_FLYING_TEXT:TCombatFlyingText enum");
3547 CEntityCL
*entity
= EntitiesMngr
.getEntityByCompressedIndex(entityID
);
3549 entity
->addHPOutput(text
, color
, dt
);
3552 void impulseSetSeason(NLMISC::CBitMemStream
&impulse
)
3554 extern uint8 ServerSeasonValue
;
3555 extern bool ServerSeasonReceived
;
3556 impulse
.serial(ServerSeasonValue
);
3557 ServerSeasonReceived
= true;
3560 void impulseDssDown(NLMISC::CBitMemStream
&impulse
)
3565 void impulseSetNpcIconDesc(NLMISC::CBitMemStream
&impulse
)
3568 impulse
.serial(nb8
);
3569 bool hasChanged
= false;
3570 for (uint i
=0; i
!=(uint
)nb8
; ++i
)
3572 TNPCIconCacheKey npcIconCacheKey
;
3573 impulse
.serial(npcIconCacheKey
);
3575 impulse
.serial(state
);
3576 hasChanged
= CNPCIconCache::getInstance().onReceiveMissionAvailabilityForThisChar(npcIconCacheKey
, (NPC_ICON::TNPCMissionGiverState
)state
) || hasChanged
; // mind the order to avoid partial evaluation
3579 CNPCIconCache::getInstance().refreshIconsOfScene();
3582 void impulseServerEventForMissionAvailability(NLMISC::CBitMemStream
&impulse
)
3584 CNPCIconCache::getInstance().onEventForMissionAvailabilityForThisChar();
3587 void impulseSetNpcIconTimer(NLMISC::CBitMemStream
&impulse
)
3589 NLMISC::TGameCycle delay
;
3590 impulse
.serial(delay
);
3591 CNPCIconCache::getInstance().setMissionGiverTimer(delay
);
3594 //-----------------------------------------------
3595 // initializeNetwork :
3596 //-----------------------------------------------
3597 void initializeNetwork()
3599 GenericMsgHeaderMngr
.setCallback("DB_UPD_PLR", impulseDatabaseUpdatePlayer
);
3600 GenericMsgHeaderMngr
.setCallback("DB_INIT:PLR", impulseDatabaseInitPlayer
);
3601 GenericMsgHeaderMngr
.setCallback("DB_UPD_INV", impulseUpdateInventory
);
3602 GenericMsgHeaderMngr
.setCallback("DB_INIT:INV", impulseInitInventory
);
3603 GenericMsgHeaderMngr
.setCallback("DB_GROUP:UPDATE_BANK", impulseDatabaseUpdateBank
);
3604 GenericMsgHeaderMngr
.setCallback("DB_GROUP:INIT_BANK", impulseDatabaseInitBank
);
3605 GenericMsgHeaderMngr
.setCallback("DB_GROUP:RESET_BANK", impulseDatabaseResetBank
);
3606 GenericMsgHeaderMngr
.setCallback("CONNECTION:NO_USER_CHAR", impulseNoUserChar
);
3607 GenericMsgHeaderMngr
.setCallback("CONNECTION:USER_CHARS", impulseUserChars
);
3608 GenericMsgHeaderMngr
.setCallback("CONNECTION:USER_CHAR", impulseUserChar
);
3609 GenericMsgHeaderMngr
.setCallback("CONNECTION:FAR_TP", impulseFarTP
);
3610 GenericMsgHeaderMngr
.setCallback("CONNECTION:READY", impulseServerReady
);
3611 GenericMsgHeaderMngr
.setCallback("CONNECTION:VALID_NAME", impulseCharNameValid
);
3612 GenericMsgHeaderMngr
.setCallback("CONNECTION:SHARD_ID", impulseShardId
);
3613 GenericMsgHeaderMngr
.setCallback("CONNECTION:SERVER_QUIT_OK", impulseServerQuitOk
);
3614 GenericMsgHeaderMngr
.setCallback("CONNECTION:SERVER_QUIT_ABORT", impulseServerQuitAbort
);
3615 GenericMsgHeaderMngr
.setCallback("CONNECTION:MAIL_AVAILABLE", impulseMailNotification
);
3616 GenericMsgHeaderMngr
.setCallback("CONNECTION:GUILD_MESSAGE_AVAILABLE", impulseForumNotification
);
3617 GenericMsgHeaderMngr
.setCallback("CONNECTION:PERMANENT_BAN", impulsePermanentBan
);
3618 GenericMsgHeaderMngr
.setCallback("CONNECTION:UNBAN", impulsePermanentUnban
);
3620 GenericMsgHeaderMngr
.setCallback("STRING:CHAT", impulseChat
);
3621 GenericMsgHeaderMngr
.setCallback("STRING:TELL", impulseTell
);
3622 GenericMsgHeaderMngr
.setCallback("STRING:FAR_TELL", impulseFarTell
);
3623 GenericMsgHeaderMngr
.setCallback("STRING:CHAT2", impulseChat2
);
3624 GenericMsgHeaderMngr
.setCallback("STRING:DYN_STRING", impulseDynString
);
3625 GenericMsgHeaderMngr
.setCallback("STRING:DYN_STRING_GROUP", inpulseDynStringInChatGroup
);
3626 GenericMsgHeaderMngr
.setCallback("STRING:TELL2", impulseTell2
);
3627 // GenericMsgHeaderMngr.setCallback("STRING:ADD_DYN_STR", impulseAddDynStr);
3628 GenericMsgHeaderMngr
.setCallback("TP:DEST", impulseTP
);
3629 GenericMsgHeaderMngr
.setCallback("TP:DEST_WITH_SEASON", impulseTPWithSeason
);
3630 GenericMsgHeaderMngr
.setCallback("TP:CORRECT", impulseCorrectPos
);
3631 GenericMsgHeaderMngr
.setCallback("COMBAT:ENGAGE_FAILED", impulseCombatEngageFailed
);
3632 GenericMsgHeaderMngr
.setCallback("BOTCHAT:DYNCHAT_OPEN", impulseDynChatOpen
);
3633 GenericMsgHeaderMngr
.setCallback("BOTCHAT:DYNCHAT_CLOSE", impulseDynChatClose
);
3635 GenericMsgHeaderMngr
.setCallback("CASTING:BEGIN", impulseBeginCast
);
3636 GenericMsgHeaderMngr
.setCallback("TEAM:INVITATION", impulseTeamInvitation
);
3637 GenericMsgHeaderMngr
.setCallback("TEAM:SHARE_OPEN", impulseTeamShareOpen
);
3638 GenericMsgHeaderMngr
.setCallback("TEAM:SHARE_INVALID", impulseTeamShareInvalid
);
3639 GenericMsgHeaderMngr
.setCallback("TEAM:SHARE_CLOSE", impulseTeamShareClose
);
3640 GenericMsgHeaderMngr
.setCallback("TEAM:CONTACT_INIT", impulseTeamContactInit
);
3641 GenericMsgHeaderMngr
.setCallback("TEAM:CONTACT_CREATE", impulseTeamContactCreate
);
3642 GenericMsgHeaderMngr
.setCallback("TEAM:CONTACT_STATUS", impulseTeamContactStatus
);
3643 GenericMsgHeaderMngr
.setCallback("TEAM:CONTACT_REMOVE", impulseTeamContactRemove
);
3645 GenericMsgHeaderMngr
.setCallback("EXCHANGE:INVITATION", impulseExchangeInvitation
);
3646 GenericMsgHeaderMngr
.setCallback("EXCHANGE:CLOSE_INVITATION", impulseExchangeCloseInvitation
);
3647 GenericMsgHeaderMngr
.setCallback("ANIMALS:MOUNT_ABORT", impulseMountAbort
);
3649 GenericMsgHeaderMngr
.setCallback("DEBUG:REPLY_WHERE", impulseWhere
);
3650 GenericMsgHeaderMngr
.setCallback("DEBUG:COUNTER", impulseCounter
);
3653 GenericMsgHeaderMngr
.setCallback("STRING_MANAGER:PHRASE_SEND", impulsePhraseSend
);
3654 GenericMsgHeaderMngr
.setCallback("STRING_MANAGER:STRING_RESP", impulseStringResp
);
3655 GenericMsgHeaderMngr
.setCallback("STRING_MANAGER:RELOAD_CACHE", impulseReloadCache
);
3657 GenericMsgHeaderMngr
.setCallback("BOTCHAT:FORCE_END", impulseBotChatForceEnd
);
3659 GenericMsgHeaderMngr
.setCallback("JOURNAL:INIT_COMPLETED_MISSIONS", impulseJournalInitCompletedMissions
);
3660 GenericMsgHeaderMngr
.setCallback("JOURNAL:UPDATE_COMPLETED_MISSIONS", impulseJournalUpdateCompletedMissions
);
3661 // GenericMsgHeaderMngr.setCallback("JOURNAL:CANT_ABANDON", impulseJournalCantAbandon);
3663 GenericMsgHeaderMngr
.setCallback("JOURNAL:ADD_COMPASS", impulseJournalAddCompass
);
3664 GenericMsgHeaderMngr
.setCallback("JOURNAL:REMOVE_COMPASS", impulseJournalRemoveCompass
);
3667 //GenericMsgHeaderMngr.setCallback("GUILD:SET_MEMBER_INFO", impulseGuildSetMemberInfo);
3668 //GenericMsgHeaderMngr.setCallback("GUILD:INIT_MEMBER_INFO", impulseGuildInitMemberInfo);
3670 GenericMsgHeaderMngr
.setCallback("GUILD:JOIN_PROPOSAL", impulseGuildJoinProposal
);
3672 GenericMsgHeaderMngr
.setCallback("GUILD:ASCENSOR", impulseGuildAscensor
);
3673 GenericMsgHeaderMngr
.setCallback("GUILD:LEAVE_ASCENSOR", impulseGuildLeaveAscensor
);
3674 GenericMsgHeaderMngr
.setCallback("GUILD:ABORT_CREATION", impulseGuildAbortCreation
);
3675 GenericMsgHeaderMngr
.setCallback("GUILD:OPEN_GUILD_WINDOW", impulseGuildOpenGuildWindow
);
3677 GenericMsgHeaderMngr
.setCallback("GUILD:OPEN_INVENTORY", impulseGuildOpenInventory
);
3678 GenericMsgHeaderMngr
.setCallback("GUILD:CLOSE_INVENTORY", impulseGuildCloseInventory
);
3680 GenericMsgHeaderMngr
.setCallback("GUILD:UPDATE_PLAYER_TITLE", impulseGuildUpdatePlayerTitle
);
3681 GenericMsgHeaderMngr
.setCallback("GUILD:USE_FEMALE_TITLES", impulseGuildUseFemaleTitles
);
3682 //GenericMsgHeaderMngr.setCallback("GUILD:INVITATION", impulseGuildInvitation);
3684 GenericMsgHeaderMngr
.setCallback("HARVEST:CLOSE_TEMP_INVENTORY", impulseCloseTempInv
);
3686 GenericMsgHeaderMngr
.setCallback("COMMAND:REMOTE_ADMIN", impulseRemoteAdmin
);
3688 GenericMsgHeaderMngr
.setCallback("PHRASE:DOWNLOAD", impulsePhraseDownLoad
);
3689 GenericMsgHeaderMngr
.setCallback("PHRASE:CONFIRM_BUY", impulsePhraseConfirmBuy
);
3690 GenericMsgHeaderMngr
.setCallback("PHRASE:EXEC_CYCLIC_ACK", impulsePhraseAckExecuteCyclic
);
3691 GenericMsgHeaderMngr
.setCallback("PHRASE:EXEC_NEXT_ACK", impulsePhraseAckExecuteNext
);
3693 GenericMsgHeaderMngr
.setCallback("ITEM_INFO:SET", impulseItemInfoSet
);
3694 GenericMsgHeaderMngr
.setCallback("ITEM_INFO:REFRESH_VERSION", impulseItemInfoRefreshVersion
);
3695 GenericMsgHeaderMngr
.setCallback("MISSION_PREREQ:SET", impulsePrereqInfoSet
);
3696 GenericMsgHeaderMngr
.setCallback("ITEM:OPEN_ROOM_INVENTORY", impulseItemOpenRoomInventory
);
3697 GenericMsgHeaderMngr
.setCallback("ITEM:CLOSE_ROOM_INVENTORY", impulseItemCloseRoomInventory
);
3699 GenericMsgHeaderMngr
.setCallback("DEATH:RESPAWN_POINT", impulseDeathRespawnPoint
);
3700 GenericMsgHeaderMngr
.setCallback("DEATH:RESPAWN", impulseDeathRespawn
);
3702 GenericMsgHeaderMngr
.setCallback("DUEL:INVITATION", impulseDuelInvitation
);
3703 GenericMsgHeaderMngr
.setCallback("DUEL:CANCEL_INVITATION", impulseDuelCancelInvitation
);
3705 GenericMsgHeaderMngr
.setCallback("PVP_CHALLENGE:INVITATION", impulsePVPChallengeInvitation
);
3706 GenericMsgHeaderMngr
.setCallback("PVP_CHALLENGE:CANCEL_INVITATION", impulsePVPChallengeCancelInvitation
);
3708 GenericMsgHeaderMngr
.setCallback("PVP_FACTION:PUSH_FACTION_WAR", impulsePVPFactionPushFactionWar
);
3709 GenericMsgHeaderMngr
.setCallback("PVP_FACTION:POP_FACTION_WAR", impulsePVPFactionPopFactionWar
);
3710 GenericMsgHeaderMngr
.setCallback("PVP_FACTION:FACTION_WARS", impulsePVPFactionFactionWars
);
3713 // GenericMsgHeaderMngr.setCallback("PVP_VERSUS:CHOOSE_CLAN", impulsePVPChooseClan);
3715 GenericMsgHeaderMngr
.setCallback("ENCYCLOPEDIA:UPDATE", impulseEncyclopediaUpdate
);
3716 GenericMsgHeaderMngr
.setCallback("ENCYCLOPEDIA:INIT", impulseEncyclopediaInit
);
3718 GenericMsgHeaderMngr
.setCallback("USER:BARS", impulseUserBars
);
3719 GenericMsgHeaderMngr
.setCallback("USER:POPUP", impulseUserPopup
);
3722 GenericMsgHeaderMngr
.setCallback("MISSION:ASK_ENTER_CRITICAL", impulseEnterCrZoneProposal
);
3723 GenericMsgHeaderMngr
.setCallback("MISSION:CLOSE_ENTER_CRITICAL", impulseCloseEnterCrZoneProposal
);
3725 // Module gateway message
3726 GenericMsgHeaderMngr
.setCallback( "MODULE_GATEWAY:FEOPEN", cbImpulsionGatewayOpen
);
3727 GenericMsgHeaderMngr
.setCallback( "MODULE_GATEWAY:GATEWAY_MSG", cbImpulsionGatewayMessage
);
3728 GenericMsgHeaderMngr
.setCallback( "MODULE_GATEWAY:FECLOSE", cbImpulsionGatewayClose
);
3730 GenericMsgHeaderMngr
.setCallback( "OUTPOST:CHOOSE_SIDE", impulseOutpostChooseSide
);
3731 GenericMsgHeaderMngr
.setCallback( "OUTPOST:DECLARE_WAR_ACK", impulseOutpostDeclareWarAck
);
3733 GenericMsgHeaderMngr
.setCallback( "COMBAT:FLYING_HP_DELTA", impulseCombatFlyingHpDelta
);
3734 GenericMsgHeaderMngr
.setCallback( "COMBAT:FLYING_TEXT_ISE", impulseCombatFlyingTextItemSpecialEffectProc
);
3735 GenericMsgHeaderMngr
.setCallback( "COMBAT:FLYING_TEXT", impulseCombatFlyingText
);
3737 GenericMsgHeaderMngr
.setCallback( "SEASON:SET", impulseSetSeason
);
3738 GenericMsgHeaderMngr
.setCallback( "RING_MISSION:DSS_DOWN", impulseDssDown
);
3740 GenericMsgHeaderMngr
.setCallback( "NPC_ICON:SET_DESC", impulseSetNpcIconDesc
);
3741 GenericMsgHeaderMngr
.setCallback( "NPC_ICON:SVR_EVENT_MIS_AVL", impulseServerEventForMissionAvailability
);
3742 GenericMsgHeaderMngr
.setCallback( "NPC_ICON:SET_TIMER", impulseSetNpcIconTimer
);
3746 //-----------------------------------------------
3747 // impulseCallBack :
3748 // The impulse callback to receive all msg from the frontend.
3749 //-----------------------------------------------
3750 void impulseCallBack(NLMISC::CBitMemStream
&impulse
, sint32 packet
, void *arg
)
3752 GenericMsgHeaderMngr
.execute(impulse
);
3759 //-----------------------------------------------
3762 //-----------------------------------------------
3763 CNetManager::CNetManager() : CNetworkConnection()
3765 #ifdef ENABLE_INCOMING_MSG_RECORDER
3766 _IsReplayStarting
= false;
3770 //-----------------------------------------------
3772 // Updates the whole connection with the frontend.
3773 // Call this method evently.
3774 // \return bool : 'true' if data were sent/received.
3775 //-----------------------------------------------
3776 bool CNetManager::update()
3778 H_AUTO_USE ( RZ_Client_Net_Mngr_Update
)
3780 #ifdef ENABLE_INCOMING_MSG_RECORDER
3781 if(_IsReplayStarting
)
3785 // If the client is in Local Mode -> no network.
3789 if(_CurrentServerTick
== 0)
3793 _MachineTimeAtTick
= T1
;
3794 _CurrentClientTime
= _MachineTimeAtTick
- _LCT
;
3795 _CurrentClientTick
= 0;
3796 _CurrentServerTick
= 10;
3802 if((T1
- _MachineTimeAtTick
) >= _MsPerTick
)
3804 NLMISC::TGameCycle nbTick
= (NLMISC::TGameCycle
)((T1
- _MachineTimeAtTick
)/_MsPerTick
);
3805 _CurrentClientTick
+= nbTick
;
3806 _CurrentServerTick
+= nbTick
;
3807 _MachineTimeAtTick
+= nbTick
*_MsPerTick
;
3810 // update the smooth server tick for debug
3811 CNetworkConnection::updateSmoothServerTick();
3814 #ifdef ENABLE_INCOMING_MSG_RECORDER
3819 // Update the base class.
3820 bool result
= CNetworkConnection::update();
3821 // Get changes with the update.
3822 const vector
<CChange
> &changes
= NetMngr
.getChanges();
3825 vector
<CChange
>::const_iterator it
;
3826 for(it
= changes
.begin(); it
< changes
.end(); ++it
)
3828 const CChange
&change
= *it
;
3829 // Update a property.
3830 if(change
.Property
< AddNewEntity
)
3832 if (!IgnoreEntityDbUpdates
|| change
.ShortId
== 0)
3834 // Update the visual property for the slot.
3835 EntitiesMngr
.updateVisualProperty(change
.GameCycle
, change
.ShortId
, change
.Property
, change
.PositionInfo
.PredictedInterval
);
3839 nlwarning("CNetManager::update : Skipping EntitiesMngr.updateVisualProperty() because IgnoreEntityDbUpdates=%s and change.ShortId=%d", (IgnoreEntityDbUpdates
?"true":"false"), change
.ShortId
);
3842 // Add New Entity (and remove the old one in the slot).
3843 else if(change
.Property
== AddNewEntity
)
3845 if (!IgnoreEntityDbUpdates
|| change
.ShortId
== 0)
3847 // Remove the old entity.
3848 EntitiesMngr
.remove(change
.ShortId
, false);
3849 // Create the new entity.
3850 if(EntitiesMngr
.create(change
.ShortId
, get(change
.ShortId
), change
.NewEntityInfo
) == 0)
3851 nlwarning("CNetManager::update : entity in the slot '%u' has not been created.", change
.ShortId
);
3855 nlwarning("CNetManager::update : Skipping EntitiesMngr.create() because IgnoreEntityDbUpdates=%s and change.ShortId=%d", (IgnoreEntityDbUpdates
?"true":"false"), change
.ShortId
);
3859 else if(change
.Property
== RemoveOldEntity
)
3861 if (!IgnoreEntityDbUpdates
|| change
.ShortId
== 0)
3863 // Remove the old entity.
3864 EntitiesMngr
.remove(change
.ShortId
, true);
3868 nlwarning("CNetManager::update : Skipping EntitiesMngr.remove() because IgnoreEntityDbUpdates=%s and change.ShortId=%d", (IgnoreEntityDbUpdates
?"true":"false"), change
.ShortId
);
3872 else if(change
.Property
== LagDetected
)
3874 nldebug("CNetManager::update : Lag detected.");
3877 else if(change
.Property
== ProbeReceived
)
3879 nldebug("CNetManager::update : Probe Received.");
3881 // Connection ready.
3882 else if(change
.Property
== ConnectionReady
)
3884 nldebug("CNetManager::update : Connection Ready.");
3886 // Property unknown.
3888 nlwarning("CNetManager::update : The property '%d' is unknown.", change
.Property
);
3890 ChatMngr
.flushBuffer(InterfaceChatDisplayer
);
3891 // Clear all changes.
3894 // Update data base server state
3895 if (IngameDbMngr
.getNodePtr())
3897 CInterfaceManager
*im
= CInterfaceManager::getInstance();
3900 CCDBNodeLeaf
*node
= NULL
;
3903 m_PingLeaf
= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:PING", false);
3907 node
= &*m_PingLeaf
;
3909 node
->setValue32(getPing());
3913 m_UploadLeaf
= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:UPLOAD", false);
3917 node
= &*m_UploadLeaf
;
3919 node
->setValue32((sint32
)(getMeanUpload()*1024.f
/8.f
));
3922 if (!m_DownloadLeaf
)
3923 m_DownloadLeaf
= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DOWNLOAD", false);
3927 node
= &*m_DownloadLeaf
;
3929 node
->setValue32((sint32
)(getMeanDownload()*1024.f
/8.f
));
3932 if (!m_PacketLostLeaf
)
3933 m_PacketLostLeaf
= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:PACKETLOST", false);
3935 if (m_PacketLostLeaf
)
3937 node
= &*m_PacketLostLeaf
;
3939 node
->setValue32((sint32
)getMeanPacketLoss());
3942 if (!m_ServerStateLeaf
)
3943 m_ServerStateLeaf
= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SERVERSTATE", false);
3945 if (m_ServerStateLeaf
)
3947 node
= &*m_ServerStateLeaf
;
3949 node
->setValue32((sint32
)getConnectionState());
3952 if (!m_ConnectionQualityLeaf
)
3953 m_ConnectionQualityLeaf
= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:CONNECTION_QUALITY", false);
3955 if (m_ConnectionQualityLeaf
)
3957 node
= &*m_ConnectionQualityLeaf
;
3959 node
->setValue32((sint32
)getConnectionQuality());
3964 // Return 'true' if data were sent/received.
3970 //-----------------------------------------------
3971 // getConnectionQuality :
3972 //-----------------------------------------------
3973 bool CNetManager::getConnectionQuality()
3975 // If the client is in Local Mode -> no network.
3979 return CNetworkConnection::getConnectionQuality();
3980 }// getConnectionQuality //
3984 * Buffers a bitmemstream, that will be converted into a generic action, to be sent later to the server (at next update).
3986 void CNetManager::push(NLMISC::CBitMemStream
&msg
)
3988 // If the client is in Local Mode -> no network.
3992 if (PermanentlyBanned
) return;
3994 CNetworkConnection::push(msg
);
3998 * Buffers a target action
4000 void CNetManager::pushTarget(CLFECOMMON::TCLEntityId slot
)
4002 // If the client is in Local Mode -> no network.
4005 if(UserEntity
->mode() != MBEHAV::COMBAT
4006 && UserEntity
->mode() != MBEHAV::COMBAT_FLOAT
)
4008 UserEntity
->targetSlot(slot
);
4013 CNetworkConnection::pushTarget(slot
, LHSTATE::NONE
);
4018 * Buffers a pick-up action
4020 void CNetManager::pushPickup(CLFECOMMON::TCLEntityId slot
, LHSTATE::TLHState lootOrHarvest
)
4022 // If the client is in Local Mode -> no network.
4028 CNetworkConnection::pushTarget(slot
, lootOrHarvest
);
4035 void CNetManager::send(NLMISC::TGameCycle gameCycle
)
4037 // If the client is in Local Mode -> no network.
4041 // wait till next server is received
4042 if (_LastSentCycle
>= gameCycle
)
4044 //nlinfo ("Try to CNetManager::send(%d) _LastSentCycle=%d more than one time with the same game cycle, so we wait new game cycle to send", gameCycle, _LastSentCycle);
4045 while (_LastSentCycle
>= gameCycle
)
4051 // Do not take all the CPU.
4054 gameCycle
= getCurrentServerTick();
4058 CNetworkConnection::send(gameCycle
);
4064 void CNetManager::send()
4066 // If the client is in Local Mode -> no network.
4070 CNetworkConnection::send();
4074 * Disconnects the current connection
4076 void CNetManager::disconnect()
4078 // If the client is in Local Mode -> no need to disconnect.
4082 CNetworkConnection::disconnect();
4087 * Reset data and init the socket
4089 void CNetManager::reinit()
4094 IngameDbMngr
.resetInitState();
4095 CNetworkConnection::reinit();
4098 void CNetManager::waitForServer()
4100 sint LastGameCycle
= getCurrentServerTick();
4104 // Event server get events
4105 CInputHandlerManager::getInstance()->pumpEventsNoIM();
4109 if (LastGameCycle
!= (sint
) getCurrentServerTick())
4116 }// waitForServer //
4119 #ifdef ENABLE_INCOMING_MSG_RECORDER
4120 //-----------------------------------------------
4121 // setReplayingMode :
4122 //-----------------------------------------------
4123 void CNetManager::setReplayingMode( bool onOff
, const std::string
& filename
)
4125 CNetworkConnection::setReplayingMode(onOff
, filename
);
4126 _IsReplayStarting
= onOff
;
4127 }// setReplayingMode //
4129 //-----------------------------------------------
4131 //-----------------------------------------------
4132 void CNetManager::startReplay()
4135 _MachineTimeAtTick
= T1
;
4136 if(_MachineTimeAtTick
>= _LCT
)
4137 _CurrentClientTime
= _MachineTimeAtTick
- _LCT
;
4139 _CurrentClientTime
= 0;
4140 // Replay now in progress.
4141 _IsReplayStarting
= false;
4147 * Create the net managers in CLIENT_MULTI mode
4149 void CNetManagerMulti::init( const std::string
& cookie
, const std::string
& addr
)
4151 uint nb
, baseCookie
;
4152 NLMISC::CConfigFile::CVar
*var
= ClientCfg
.ConfigFile
.getVarPtr( "NbConnections" );
4157 var
= ClientCfg
.ConfigFile
.getVarPtr( "UserId" );
4159 baseCookie
= var
->asInt();
4162 std::vector
<std::string
> fsAddrs
;
4163 fsAddrs
.push_back( addr
);
4164 string portString
= addr
.substr( addr
.find( ':' ) );
4165 var
= ClientCfg
.ConfigFile
.getVarPtr( "AdditionalFSList" );
4168 for ( uint i
=0; i
!=var
->size(); ++i
)
4169 fsAddrs
.push_back( var
->asString( i
) + portString
);
4171 nlinfo( "CNetManagerMulti: Creating %u connections to %u front-ends, baseCookie=%u...", nb
, fsAddrs
.size(), baseCookie
);
4173 for ( uint i
=0; i
!=nb
; ++i
)
4175 CNetManager
*nm
= new CNetManager();
4176 string multicook
= NLMISC::toString( "%8x|%8x|%8x", 0, 0, baseCookie
+ i
);
4177 nm
->init( multicook
, fsAddrs
[i
% fsAddrs
.size()] );
4178 _NetManagers
.push_back( nm
);
4184 std::string WebServer
;
4189 /////////////////////////////////////////////////////////////////////////////
4190 /////////////////////////////////////////////////////////////////////////////
4191 /////////////////////////////////////////////////////////////////////////////
4192 /////////////////////////////////////////////////////////////////////////////
4193 /////////// COMMANDS after should NOT appear IN the FINAL VERSION ///////////
4194 /////////////////////////////////////////////////////////////////////////////
4195 /////////////////////////////////////////////////////////////////////////////
4196 /////////////////////////////////////////////////////////////////////////////
4197 /////////////////////////////////////////////////////////////////////////////
4198 /////////////////////////////////////////////////////////////////////////////
4203 // temp : simulate a team msg in local mode
4204 NLMISC_COMMAND(localTellTeam
, "Temp : simulate a tell in local mode", "<people_name> <msg>")
4206 if (args
.empty()) return false;
4207 string player
= args
[0];
4209 if (args
.size() >= 2)
4212 for(uint k
= 2; k
< args
.size(); ++k
)
4214 msg
+= " " + args
[k
];
4217 TDataSetIndex dsi
= INVALID_DATASET_INDEX
;
4218 InterfaceChatDisplayer
.displayChat(dsi
, msg
, msg
, CChatGroup::team
, NLMISC::CEntityId::Unknown
, player
);
4222 // temp : simulate a tell in local mode
4223 NLMISC_COMMAND(localTell
, "Temp : simulate a tell in local mode", "<people_name> <msg>")
4225 if (args
.empty()) return false;
4226 string player
= args
[0];
4228 if (args
.size() >= 2)
4231 for(uint k
= 2; k
< args
.size(); ++k
)
4233 msg
+= " " + args
[k
];
4236 // TDataSetIndex dsi = INVALID_DATASET_ROW;
4237 InterfaceChatDisplayer
.displayTell(/*dsi, */msg
, player
);
4241 NLMISC_COMMAND(testDynChatOpen
, "", "")
4243 NLMISC::CBitMemStream bm
;
4244 if (bm
.isReading()) bm
.invert();
4245 uint32 BotUID
= 22; // Compressed Index
4246 uint32 BotName
= 654; // Server string
4247 vector
<uint32
> DynStrs
; // 0 - Desc, 1 - Option0, 2 - Option1, etc....
4248 DynStrs
.push_back(16540);
4249 DynStrs
.push_back(11465);
4250 DynStrs
.push_back(12654);
4253 bm
.serialCont(DynStrs
);
4255 bm
.seek(0, NLMISC::IStream::begin
);
4256 impulseDynChatOpen(bm
);
4260 NLMISC_COMMAND(testDynChatClose
, "", "")
4262 NLMISC::CBitMemStream bm
;
4263 if (bm
.isReading()) bm
.invert();
4264 uint32 BotUID
= 22; // Compressed Index
4267 bm
.seek(0, NLMISC::IStream::begin
);
4268 impulseDynChatClose(bm
);
4273 NLMISC_COMMAND(testCloseTempInv
, "","")
4275 NLMISC::CBitMemStream bm
;
4276 impulseCloseTempInv(bm
);
4280 NLMISC_COMMAND(testTeamInvite
, "","")
4282 NLMISC::CBitMemStream bm
;
4283 if (bm
.isReading()) bm
.invert();
4287 bm
.seek(0, NLMISC::IStream::begin
);
4288 impulseTeamInvitation(bm
);
4291 NLMISC_COMMAND(testGuildInvite
, "","")
4293 NLMISC::CBitMemStream bm
;
4294 if (bm
.isReading()) bm
.invert();
4299 bm
.seek(0, NLMISC::IStream::begin
);
4300 impulseGuildJoinProposal(bm
);
4304 NLMISC_COMMAND( testExchangeInvitation
, "Test the modal window for invitation exchange", "" )
4306 CBitMemStream impulse
;
4307 uint32 nameIndex
= 0;
4308 impulse
.serial(nameIndex
);
4310 impulseExchangeInvitation(impulse
);
4315 NLMISC_COMMAND(testAscensor
, "Temp : Simulate a GUILD:ASCENSOR message coming from server","")
4317 NLMISC::CBitMemStream bm
;
4318 if (bm
.isReading()) bm
.invert();
4322 bm
.seek(0, NLMISC::IStream::begin
);
4323 impulseGuildAscensor(bm
);
4327 NLMISC_COMMAND(testDuelInvite
, "","")
4329 NLMISC::CBitMemStream bm
;
4330 if (bm
.isReading()) bm
.invert();
4334 bm
.seek(0, NLMISC::IStream::begin
);
4335 impulseDuelInvitation(bm
);
4339 //NLMISC_COMMAND(receiveId, "","<num> <name>")
4342 // fromString(args[0], index);
4343 // ucstring ucstr = args[1]; // OLD
4345 // vector<bool> code;
4347 //#ifdef OLD_STRING_SYSTEM
4348 // ChatMngr.getDynamicDB().add( index, ucstr, code );
4350 // // TRAP // WE MUST NEVER CALL THIS COMMAND ANYMORE : ALL IS HANDLED BY STRING_MANAGER NOW !!!
4357 NLMISC_COMMAND(testOutpostChooseSide
, "","b b u32 u32")
4361 NLMISC::CBitMemStream bm
;
4362 if (bm
.isReading()) bm
.invert();
4363 bool playerGuildInConflict
;
4364 fromString(args
[0], playerGuildInConflict
);
4365 bool playerGuildIsAttacker
;
4366 fromString(args
[1], playerGuildIsAttacker
);
4367 bm
.serial(playerGuildInConflict
);
4368 bm
.serial(playerGuildIsAttacker
);
4369 uint32 ownerGuildNameId
;
4370 fromString(args
[2], ownerGuildNameId
);
4371 bm
.serial( ownerGuildNameId
);
4372 uint32 attackerGuildNameId
;
4373 fromString(args
[3], attackerGuildNameId
);
4374 bm
.serial( attackerGuildNameId
);
4375 uint32 declTimer
= 100;
4376 bm
.serial( declTimer
);
4379 bm
.seek(0, NLMISC::IStream::begin
);
4380 impulseOutpostChooseSide(bm
);
4384 NLMISC_COMMAND(testUserPopup
, "","u32 u32")
4388 NLMISC::CBitMemStream bm
;
4389 if (bm
.isReading()) bm
.invert();
4391 fromString(args
[0], titleId
);
4392 bm
.serial( titleId
);
4394 fromString(args
[1], textId
);
4395 bm
.serial( textId
);
4398 bm
.seek(0, NLMISC::IStream::begin
);
4399 impulseUserPopup(bm
);