1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 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) 2015-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/>.
27 #include "client_edition_module.h"
31 #include "../../interface_v3/interface_manager.h"
34 #include "nel/net/unified_network.h"
35 #include "nel/net/module_message.h"
36 #include "nel/net/module_socket.h"
37 #include "nel/net/module_builder_parts.h"
38 #include "nel/net/module_manager.h"
40 #include "nel/misc/command.h"
41 #include "nel/misc/path.h"
42 #include "nel/misc/types_nl.h"
43 #include "nel/misc/sstring.h"
45 #include "nel/ligo/primitive.h"
46 #include "nel/ligo/ligo_config.h"
47 #include "nel/ligo/primitive_utils.h"
49 #include "game_share/utils.h"
51 #include "game_share/object.h"
52 #include "game_share/scenario.h"
53 #include "game_share/r2_messages.h"
54 #include "game_share/ring_access.h"
56 #include "property_accessor.h"
59 #include "../object_factory_client.h"
61 #include "com_lua_module.h"
63 #include "../../session_browser_impl.h"
64 #include "../../client_cfg.h"
65 #include "../../user_entity.h"
66 #include "../../view.h"
67 #include "../../init_main_loop.h"
68 #include "../../continent_manager.h"
69 #include "../../world_database_manager.h"
70 #include "../../far_tp.h"
71 #include "../../net_manager.h"
81 using namespace NLMISC
;
82 using namespace NLLIGO
;
83 using namespace NLNET
;
85 CVariable
<std::string
> UserComponentsExamplesDirectory ("DSS", "UserComponentsExampleDirectory", "", "examples/user_componts", 0, true );
86 CVariable
<std::string
> UserComponentsComponentsDirectory ("DSS", "UserComponentsComponentsDirectory", "", "examples/user_componts", 0, true );
87 CVariable
<std::string
> UserComponentsComponentExtension ("DSS", "UserComponentsComponentExtension", "", "gz", 0, true );
88 CVariable
<std::string
> UserComponentsSourceExtension ("DSS", "UserComponentsSourceExtension", "", "lua", 0, true );
93 // if client request an operation, and the server accept then the client do not need to received the same msg he send
94 // other client must receive the answer
95 class IServerAnswerMsg
;
96 class CServerAnswerForseener
99 typedef uint32 TMessageId
;
102 CServerAnswerForseener():_MaxMessageId(0){}
103 ~CServerAnswerForseener();
104 // if ok == true, then simulate the replay that The Server would do for other client
105 // if ok == false, remove the Forseen Answer from the answer queue.
106 void ack(CClientEditionModule
* client
, NLNET::IModuleProxy
*server
, TMessageId msgId
, bool ok
);
108 // Add to the Forssen Answer queue (we do not take the ownership of value)
109 TMessageId
onScenarioUploaded( const CObject
* hlScenario
) ;
110 TMessageId
onNodeSet(const std::string
&instanceId
, const std::string
&attrName
, const R2::CObject
*value
);
111 TMessageId
onNodeInserted(const std::string
&instanceId
, const std::string
&attrName
, sint32 position
, const std::string
&key
, const R2::CObject
*value
);
112 TMessageId
onNodeErased(const std::string
&instanceId
, const std::string
&attrName
, sint32 position
);
113 TMessageId
onNodeMoved(const std::string
&instanceId1
, const std::string
&attrName1
, sint32 position1
, const std::string
&instanceId2
, const std::string
&attrName2
, sint32 position2
);
116 typedef std::map
<TMessageId
, IServerAnswerMsg
*> TAnswers
;
119 uint32 _MaxMessageId
;
124 class IServerAnswerMsg
127 virtual void ok(CClientEditionModule
* client
, NLNET::IModuleProxy
*server
) = 0;
128 virtual ~IServerAnswerMsg() {}
131 class CServerAnswerMsgScenarioUploaded
: public IServerAnswerMsg
134 CServerAnswerMsgScenarioUploaded( const R2::CObject
* value
)
135 :_Value( value
?value
->clone():0){}
137 void ok(CClientEditionModule
* client
, NLNET::IModuleProxy
*server
)
139 client
->onScenarioUploaded(server
, _Value
.get());
142 CUniquePtr
<R2::CObject
> _Value
;
145 class CServerAnswerMsgSet
: public IServerAnswerMsg
148 CServerAnswerMsgSet(const std::string
&instanceId
, const std::string
&attrName
, const R2::CObject
* value
)
149 :_InstanceId(instanceId
), _AttrName(attrName
), _Value( value
?value
->clone():0){}
151 void ok(CClientEditionModule
* client
, NLNET::IModuleProxy
*server
)
153 client
->onNodeSet(server
, _InstanceId
, _AttrName
, _Value
.get());
156 std::string _InstanceId
;
157 std::string _AttrName
;
158 CUniquePtr
<R2::CObject
> _Value
;
161 class CServerAnswerMsgInserted
: public IServerAnswerMsg
164 CServerAnswerMsgInserted(const std::string
&instanceId
, const std::string
&attrName
, sint32 position
, const std::string
&key
, const R2::CObject
* value
)
165 :_InstanceId(instanceId
), _AttrName(attrName
), _Position(position
), _Key(key
), _Value( value
?value
->clone():0){}
167 void ok(CClientEditionModule
* client
, NLNET::IModuleProxy
*server
)
169 client
->onNodeInserted(server
, _InstanceId
, _AttrName
, _Position
, _Key
, _Value
.get());
172 std::string _InstanceId
;
173 std::string _AttrName
;
176 CUniquePtr
<R2::CObject
> _Value
;
179 class CServerAnswerMsgErased
: public IServerAnswerMsg
182 CServerAnswerMsgErased(const std::string
&instanceId
, const std::string
&attrName
, sint32 position
)
183 :_InstanceId(instanceId
), _AttrName(attrName
), _Position(position
){}
185 void ok(CClientEditionModule
* client
, NLNET::IModuleProxy
*server
)
187 client
->onNodeErased(server
, _InstanceId
, _AttrName
, _Position
);
190 std::string _InstanceId
;
191 std::string _AttrName
;
195 class CServerAnswerMsgMoved
: public IServerAnswerMsg
198 CServerAnswerMsgMoved(const std::string
&instanceId1
, const std::string
&attrName1
, sint32 position1
,
199 const std::string
&instanceId2
, const std::string
&attrName2
, sint32 position2
)
200 :_InstanceId1(instanceId1
), _AttrName1(attrName1
), _Position1(position1
),
201 _InstanceId2(instanceId2
), _AttrName2(attrName2
), _Position2(position2
){}
203 void ok(CClientEditionModule
* client
, NLNET::IModuleProxy
*server
)
205 client
->onNodeMoved(server
, _InstanceId1
, _AttrName1
, _Position1
, _InstanceId2
, _AttrName2
, _Position2
);
208 std::string _InstanceId1
;
209 std::string _AttrName1
;
211 std::string _InstanceId2
;
212 std::string _AttrName2
;
222 NLNET_REGISTER_MODULE_FACTORY(CClientEditionModule
, "ClientEditionModule");
225 //----------------------------- <CServerAnswer> -------------------------------
226 CServerAnswerForseener::~CServerAnswerForseener()
228 TAnswers::iterator
first(_Answers
.begin()), last(_Answers
.end());
229 for (; first
!= last
; ++first
)
231 IServerAnswerMsg
* msg
= first
->second
;
239 void CServerAnswerForseener::ack(CClientEditionModule
* client
, NLNET::IModuleProxy
*server
, TMessageId msgId
, bool ok
)
241 TAnswers::iterator found
= _Answers
.find(msgId
);
242 BOMB_IF( found
== _Answers
.end(), "Message not found", return);
244 IServerAnswerMsg
* msg
= found
->second
;
247 msg
->ok(client
, server
);
250 _Answers
.erase(found
);
253 // Add to the Forseen Answer queue
254 CServerAnswerForseener::TMessageId
CServerAnswerForseener::onScenarioUploaded( const R2::CObject
* hlScenario
)
256 bool ok
= _Answers
.insert( std::make_pair(++_MaxMessageId
, new CServerAnswerMsgScenarioUploaded(hlScenario
))).second
;
258 return _MaxMessageId
;
261 CServerAnswerForseener::TMessageId
CServerAnswerForseener::onNodeSet(const std::string
&instanceId
, const std::string
&attrName
, const R2::CObject
* value
)
263 bool ok
= _Answers
.insert(std::make_pair(++_MaxMessageId
, new CServerAnswerMsgSet(instanceId
, attrName
, value
))).second
;
265 return _MaxMessageId
;
268 CServerAnswerForseener::TMessageId
CServerAnswerForseener::onNodeInserted(const std::string
&instanceId
, const std::string
&attrName
, sint32 position
, const std::string
&key
, const R2::CObject
* value
)
270 bool ok
= _Answers
.insert(std::make_pair(++_MaxMessageId
, new CServerAnswerMsgInserted(instanceId
, attrName
, position
, key
, value
))).second
;
272 return _MaxMessageId
;
275 CServerAnswerForseener::TMessageId
CServerAnswerForseener::onNodeErased(const std::string
&instanceId
, const std::string
&attrName
, sint32 position
)
277 bool ok
= _Answers
.insert(std::make_pair(++_MaxMessageId
, new CServerAnswerMsgErased(instanceId
, attrName
, position
))).second
;
279 return _MaxMessageId
;
282 CServerAnswerForseener::TMessageId
CServerAnswerForseener::onNodeMoved(const std::string
&instanceId1
, const std::string
&attrName1
, sint32 position1
, const std::string
&instanceId2
, const std::string
&attrName2
, sint32 position2
)
284 bool ok
= _Answers
.insert(std::make_pair(++_MaxMessageId
, new CServerAnswerMsgMoved(instanceId1
, attrName1
, position1
, instanceId2
, attrName2
, position2
))).second
;
286 return _MaxMessageId
;
289 //------------------------------- <CEditorConfig> -------------------------------------------
292 std::map
<std::string
, uint32
> CEditorConfig::_NameToId
;
294 CEditorConfig::CEditorConfig()
296 if (_NameToId
.empty())
298 _NameToId
["BossSpawner"] = 0;
299 _NameToId
["Timer"] = 1;
300 _NameToId
["ZoneTrigger"] = 2;
301 _NameToId
["UserTrigger"] = 3;
302 _NameToId
["TalkTo"] = 4;
303 _NameToId
["RequestItem"] = 5;
304 _NameToId
["GiveItem"] = 6;
305 _NameToId
["EasterEgg"] = 7;
306 _NameToId
["LootSpawner"] = 8;
307 _NameToId
["Fauna"] = 9;
308 _NameToId
["BanditCamp"] = 10;
309 _NameToId
["ChatSequence"] = 11;
310 _NameToId
["TimedSpawner"] = 12;
311 _NameToId
["Ambush"] = 13;
312 _NameToId
["ManHunt"] = 14;
313 _NameToId
["VisitZone"] = 15;
314 _NameToId
["KillNpc"] = 16;
315 _NameToId
["HuntTask"] = 17;
316 _NameToId
["DeliveryTask"] = 18;
317 _NameToId
["TargetMob"] = 19;
318 _NameToId
["HiddenChest"] = 20;
319 _NameToId
["RandomChest"] = 21;
320 _NameToId
["UserComponent"] = 22;
321 _NameToId
["Npc"] = 23;
322 _NameToId
["GetItemFromSceneryObjectTaskStep"] = 24;
323 _NameToId
["GetItemFromSceneryObject"] = 25;
324 _NameToId
["SceneryObjectInteractionTaskStep"] = 26;
325 _NameToId
["SceneryObjectInteraction"] = 27;
326 _NameToId
["SceneryObjectRemover"] = 28;
327 _NameToId
["RewardProvider"] = 29;
328 _NameToId
["NpcInteraction"] = 30;
329 _NameToId
["Quest"] = 31;
330 _NameToId
["ProximityDialog"] = 32;
335 void CEditorConfig::setDisplayInfo(const std::string
& formName
, bool displayInfo
)
337 //H_AUTO(R2_CEditorConfig_setDisplayInfo)
338 CInterfaceManager
*IM
= CInterfaceManager::getInstance ();
339 uint32 index
= _NameToId
[formName
];
340 uint32 newValue
= static_cast<uint32
>(NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:R2:DISPLAYINFO")->getValue32());
341 if (displayInfo
== false )
342 newValue
&= ~(1 << index
);
344 newValue
|= (1 << index
);
345 NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:R2:DISPLAYINFO")->setValue32(static_cast<sint32
>(newValue
));
349 void CEditorConfig::setDisplayInfo(uint32 displayInfo
)
351 //H_AUTO(R2_CEditorConfig_setDisplayInfo)
352 CInterfaceManager
*IM
= CInterfaceManager::getInstance ();
353 NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:R2:DISPLAYINFO")->setValue32(static_cast<sint32
>(displayInfo
));
358 bool CEditorConfig::mustDisplayInfo(const std::string
& formName
) const
360 //H_AUTO(R2_CEditorConfig_mustDisplayInfo)
361 CInterfaceManager
*IM
= CInterfaceManager::getInstance ();
362 std::map
<std::string
, uint32
>::const_iterator found
= _NameToId
.find(formName
);
363 if (found
== _NameToId
.end())
365 uint32 index
= (*found
).second
;
366 uint32 newValue
= static_cast<uint32
>(NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:R2:DISPLAYINFO")->getValue32());
367 uint32 ok
= (newValue
>> index
) & 0x00000001;
373 bool CEditorConfig::hasDisplayInfo(const std::string
& formName
) const
375 //H_AUTO(R2_CEditorConfig_hasDisplayInfo)
376 std::map
<std::string
, uint32
>::const_iterator found
= _NameToId
.find(formName
);
377 if (found
!= _NameToId
.end())
382 uint32
CEditorConfig::getDisplayInfo() const
384 //H_AUTO(R2_CEditorConfig_getDisplayInfo)
385 CInterfaceManager
*IM
= CInterfaceManager::getInstance ();
386 return static_cast<uint32
>(NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:R2:DISPLAYINFO")->getValue32());
391 //----------------------------<CClientEditionModule>-------------------------------------------------------------
392 CClientEditionModule::CClientEditionModule()
395 CShareClientEditionItfSkel::init(this);
396 _Initialized
= false;
397 _ChannelId
= TChanID::Unknown
;
400 _ServerAnswerForseener
= 0;
403 CClientEditionModule::~CClientEditionModule()
408 void CClientEditionModule::init(NLNET::IModuleSocket
* clientGw
, CDynamicMapClient
* client
)
410 //H_AUTO(R2_CClientEditionModule_init)
413 // _ClientGw = clientGw;
416 _TranslationModule
= 0;
417 _SessionId
= TSessionId(0);
421 this->plugModule(clientGw
);
424 void CClientEditionModule::init()
426 //H_AUTO(R2_CClientEditionModule_init)
429 _Emotes
.reset( new CEmoteBehavior() );
430 _Palette
= new CPalette();
431 _Scenario
= new CScenario(0);
432 _Factory
= new CObjectFactoryClient(_Eid
);
433 _PropertyAccessor
= new CPropertyAccessor(_Client
, _Factory
);
434 // CObjectSerializer::Factory = _Factory;
435 CObjectSerializerClient::setClientObjectFactory(_Factory
);
438 _MaxStaticObjects
= 100;
440 _ClientEditorConfig
= new CEditorConfig();
442 _MustStartScenario
= false;
443 _ScenarioUpToDate
= false;
444 _IsSessionOwner
= false;
445 _ServerAnswerForseener
= new CServerAnswerForseener();
449 // when server is launched locally, it shouldn't use the client factory,
450 // this class disable when local server is called
451 //class CSerialFactoryBackup
454 // CSerialFactoryBackup(CObjectFactory *newValue = NULL) : ClientFactory(CObjectSerializer::Factory)
456 // CObjectSerializer::Factory = newValue;
458 // ~CSerialFactoryBackup()
460 // CObjectSerializer::Factory = ClientFactory;
462 // CObjectFactory *ClientFactory;
466 void CClientEditionModule::release()
468 //H_AUTO(R2_CClientEditionModule_release)
469 delete _ServerAnswerForseener
; _ServerAnswerForseener
= 0;
470 delete _Palette
; _Palette
= 0;
471 delete _Scenario
; _Scenario
= 0;
472 delete _Factory
; _Factory
= 0;
473 delete _PropertyAccessor
; _PropertyAccessor
= 0;
474 _Initialized
= false;
480 void CClientEditionModule::onModuleUp(NLNET::IModuleProxy
*moduleProxy
)
482 //H_AUTO(R2_CClientEditionModule_onModuleUp)
483 std::string moduleClassName
= moduleProxy
->getModuleClassName();
485 if (moduleClassName
== "ServerEditionModule")
487 _ServerEditionProxy
= moduleProxy
;
491 if (moduleClassName
== "ServerAnimationModule")
493 _ServerAnimationProxy
= moduleProxy
;
500 void CClientEditionModule::onModuleDown(NLNET::IModuleProxy
*moduleProxy
)
502 //H_AUTO(R2_CClientEditionModule_onModuleDown)
503 std::string moduleClassName
= moduleProxy
->getModuleClassName();
505 if (moduleClassName
== "ServerEditionModule")
507 _ServerEditionProxy
= NULL
;
509 else if ( moduleClassName
== "ServerAnimationModule")
511 _ServerAnimationProxy
= NULL
;
517 bool CClientEditionModule::onProcessModuleMessage(IModuleProxy
*senderModuleProxy
, const CMessage
&message
)
519 //H_AUTO(R2_CClientEditionModule_onProcessModuleMessage)
521 // CSerialFactoryBackup fb(_Factory); // restore client factory the time to process server msg ...
523 // if (CShareClientEditionItfSkel::onDispatchMessage(senderModuleProxy, message))
530 std::string operationName
= message
.getName();
532 if (operationName
== "CUCD") //onUserComponentDownloaded
534 CUserComponent
* component
= new CUserComponent();
535 //message.serial(const_cast<CUserComponent&>(*component));
536 component
->serial( const_cast<CMessage
&>(message
));
537 onUserComponentDownloaded(senderModuleProxy
, component
);
541 if (operationName
== "HELLO")
543 // this is just the firewall opening message, nothing to do
547 if (operationName
== "ADV_CONN")
549 CEditor::connectionMsg("");
550 CClientMessageAdventureUserConnection bodyConnection
;
551 nlRead(message
,serial
,bodyConnection
);
552 onRingAccessUpdated(0, bodyConnection
.RingAccess
);
554 nlinfo("R2CED: user Connected as Client %d In Mode %d", bodyConnection
.EditSlotId
, bodyConnection
.Mode
);
555 _SessionId
= bodyConnection
.SessionId
;
556 _AiInstanceId
= bodyConnection
.AiInstance
;
557 _SessionType
= bodyConnection
.SessionType
;
558 _IsSessionOwner
= bodyConnection
.IsSessionOwner
;
559 _EditSessionLink
= bodyConnection
.EditSessionLink
;
561 switch(bodyConnection
.SessionType
)
563 case st_edit
: getEditor().setAccessMode(CEditor::AccessEditor
); break;
564 case st_anim
: getEditor().setAccessMode(CEditor::AccessDM
); break;
565 default: nlassert(0 && "SessionType not handled.");
568 if (bodyConnection
.SessionType
== st_edit
)
571 if (bodyConnection
.Mode
== 1)
573 _Client
->onResetEditionMode();
577 CObject
* data
= bodyConnection
.HighLevel
.getData();
578 if (!data
&& bodyConnection
.InCache
)
581 CScenarioValidator sv
;
582 CScenarioValidator::TValues values
;
583 std::string md5
, signature
;
585 if ( sv
.setScenarioToLoad("save/r2_buffer.dat", values
, md5
, signature
, true)
587 && CScenarioValidator::AutoSaveSignature
== signature
)
589 data
= _Client
->getComLuaModule().loadLocal("save/r2_buffer.dat", values
);
593 nlinfo("Data corrupted (the server has refused to accept the scenario).");
596 _Client
->onEditionModeConnected(bodyConnection
.EditSlotId
, bodyConnection
.SessionId
.asInt(), data
, bodyConnection
.VersionName
, bodyConnection
.MustTp
, bodyConnection
.InitialActIndex
);
597 if (bodyConnection
.Mode
== 2)
599 _Client
->onEditionModeDisconnected();
600 _Client
->onTestModeConnected();
602 // warn server that adventure has been connected, so we are ready to receive the TP message
603 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
604 proxy
.advConnACK(this);
606 else if (bodyConnection
.SessionType
== st_anim
)
608 // 0 -> wait loading animation
609 // 1 -> waiting the other to load animation
611 // 3 -> play (simple player)
612 _Client
->onAnimationModeConnected(bodyConnection
);
614 // warn server that advneutre has been connected, so we are ready to receive the TP message
621 if (operationName
== "EDITOR_STOP")
623 _Client
->onEditionModeDisconnected();
624 _Client
->onTestModeConnected();
629 if ( operationName
=="stringTable")
631 nlwarning("received string table!");
633 nlRead(message
, serial
, nb
);
635 nlwarning("%d entries! ",nb
);
640 nlRead(message
, serial
,localId
);
641 nlRead(message
,serial
,value
);
642 nlwarning("{ %s , %s}",localId
.c_str(),value
.c_str());
648 if(operationName
== "stringValue")
652 nlRead(message
,serial
,localId
);
653 nlRead(message
,serial
,value
);
654 nlwarning("received {%s , %s}",localId
.c_str(),value
.c_str());
658 if (operationName
== "idList")
661 nlRead(message
,serial
,nb
);
663 nlwarning("%d entries! ",nb
);
667 nlRead(message
,serial
,localId
);
668 nlwarning("{ %s }",localId
.c_str());
673 if (operationName
== "HELLO")
675 // this is just the firewall opening message, nothing to do
679 if (operationName
== "NPC_APROP")
682 nlRead(message
,serial
,modes
);
683 _Client
->onNpcAnimationTargeted(modes
);
692 void CClientEditionModule::onTestModeDisconnected(NLNET::IModuleProxy
* /* moduleProxy */, TSessionId sessionId
, uint32 lastAct
, TScenarioSessionType sessionType
)
694 //H_AUTO(R2_CClientEditionModule_onTestModeDisconnected)
695 // indicate the Editor that the animation has stopped.
696 _Client
->onTestModeDisconnected(sessionId
, lastAct
, sessionType
);
699 if ( sessionType
== st_edit
)
701 this->requestReconnection();
708 void CClientEditionModule::onModuleSecurityChange(IModuleProxy
* /* moduleProxy */)
710 //H_AUTO(R2_CClientEditionModule_onModuleSecurityChange)
713 void CClientEditionModule::requestCreateScenario(CObject
* scenario
)
715 //H_AUTO(R2_CClientEditionModule_requestCreateScenario)
716 this->requestUploadScenario(scenario
);
720 bool CClientEditionModule::requestTeleportOneCharacterToAnother(uint32 sessionId
, uint32 sourceCharId
, uint32 destCharId
)
722 //H_AUTO(R2_CClientEditionModule_requestTeleportOneCharacterToAnother)
723 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return false);
725 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
726 proxy
.teleportOneCharacterToAnother(this, (TSessionId
)sessionId
, sourceCharId
, destCharId
);
731 void CClientEditionModule::requestUpdateRtScenario( CObject
* scenario
)
733 //H_AUTO(R2_CClientEditionModule_requestUpdateRtScenario)
734 // CSerialFactoryBackup fb;
735 CMessage
message ("requestUpdateRtScenario");
736 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
737 CObjectSerializerServer
obj(scenario
);
741 _ServerEditionProxy
->sendModuleMessage(this, message
);
746 void CClientEditionModule::requestCreatePrimitives()
748 //H_AUTO(R2_CClientEditionModule_requestCreatePrimitives)
749 CMessage
message ("DBG_CREATE_PRIMITIVES");
750 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
751 _ServerEditionProxy
->sendModuleMessage(this, message
);
755 void CClientEditionModule::requestStopTest()
757 //H_AUTO(R2_CClientEditionModule_requestStopTest)
758 CMessage
message ("STOP_TEST");
759 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
760 _ServerEditionProxy
->sendModuleMessage(this, message
);
766 bool CClientEditionModule::requestUploadScenario(CObject
* scenario
)
768 //H_AUTO(R2_CClientEditionModule_requestUploadScenario)
769 // CSerialFactoryBackup fb;
770 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return false);
772 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
773 CObjectSerializerServer
body(scenario
);
776 proxy.onScenarioUploadAsked(this, body, true);
779 uint32 messageId
= _ServerAnswerForseener
->onScenarioUploaded( scenario
);
781 sendMsgToDss(CShareServerEditionItfProxy::buildMessageFor_onScenarioUploadAsked(msg
, messageId
, body
, true));
786 void CClientEditionModule::requestSetNode(const std::string
& instanceId
, const std::string
& attrName
, CObject
* value
)
788 //H_AUTO(R2_CClientEditionModule_requestSetNode)
791 CObject
*clObj
= getEditor().getDMC().find(instanceId
, attrName
);
792 if (clObj
&& clObj
->getGhost())
794 value
->setGhost(true);
796 if (value
->getGhost())
798 // this is a local value -> forward directly to client
799 CObject
*temp
= value
->clone();
800 getEditor().getDMC().nodeSet(instanceId
, attrName
, temp
);
805 if (!attrName
.empty())
807 CObject
* instance
= _Scenario
->find(instanceId
);
811 CObject
* property
= _PropertyAccessor
->getPropertyValue(instance
, attrName
);
812 if (property
&& property
->equal(value
))
814 //nlinfo("R2Cl: Optimisation(message not send)");
820 requestSetNodeNoTest(instanceId
, attrName
, value
);
824 void CClientEditionModule::requestSetNodeNoTest(const std::string
& instanceId
, const std::string
& attrName
, CObject
* value
)
826 //H_AUTO(R2_CClientEditionModule_requestSetNodeNoTest)
827 // CSerialFactoryBackup fb;
828 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
829 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
830 CObjectSerializerServer
value2(value
);
832 uint32 messageId
= _ServerAnswerForseener
->onNodeSet(instanceId
, attrName
, value
);
833 proxy
.onNodeSetAsked(this, messageId
, instanceId
, attrName
, value2
);
837 void CClientEditionModule::requestEraseNode( const std::string
& instanceId
, const std::string
& attrName
, sint32 position
)
839 //H_AUTO(R2_CClientEditionModule_requestEraseNode)
840 CObject
*clObj
= getEditor().getDMC().find(instanceId
, attrName
, position
);
841 if (clObj
&& clObj
->getGhost())
843 // this is a ghost value -> forward directly to client
844 getEditor().getDMC().nodeErased(instanceId
, attrName
, position
);
848 // CSerialFactoryBackup fb;
849 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
850 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
851 uint32 messageId
= _ServerAnswerForseener
->onNodeErased(instanceId
, attrName
, position
);
852 proxy
.onNodeEraseAsked(this, messageId
, instanceId
, attrName
, position
);
855 void CClientEditionModule::requestInsertNode(const std::string
& instanceId
, const std::string
& attrName
, sint32 position
, const std::string
& key
, CObject
* value
)
857 //H_AUTO(R2_CClientEditionModule_requestInsertNode)
860 // if value is inserted in a ghost node, then it inherits the 'ghost' flag
861 CObject
*clObj
= getEditor().getDMC().find(instanceId
, attrName
, -1);
862 if (clObj
&& clObj
->getGhost())
864 value
->setGhost(true);
866 if (value
->getGhost())
868 // this is a ghost value -> forward directly to client
869 getEditor().getDMC().nodeInserted(instanceId
, attrName
, position
, key
, value
->clone());
873 // CSerialFactoryBackup fb;
874 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
875 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
876 CObjectSerializerServer
value2(value
);
878 uint32 messageId
= _ServerAnswerForseener
->onNodeInserted(instanceId
, attrName
, position
, key
, value
);
879 proxy
.onNodeInsertAsked(this, messageId
, instanceId
, attrName
, position
, key
, value2
);
883 void CClientEditionModule::requestMoveNode(
884 const std::string
& instanceId
, const std::string
& attrName
, sint32 position
,
885 const std::string
& destInstanceId
, const std::string
& destAttrName
, sint32 destPosition
)
887 //H_AUTO(R2_CClientEditionModule_requestMoveNode)
888 CObject
*src
= getEditor().getDMC().find(instanceId
, attrName
, position
);
889 CObject
*dest
= getEditor().getDMC().find(destInstanceId
, destAttrName
);
892 nlassert(src
->getGhost() == dest
->getGhost());
895 // this is a ghost value -> forward directly to client
896 getEditor().getDMC().nodeMoved(instanceId
, attrName
, position
,
897 destInstanceId
, destAttrName
, destPosition
);
901 if (src
) nlassert(!src
->getGhost());
902 if (dest
) nlassert(!dest
->getGhost());
903 // CSerialFactoryBackup fb;
905 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
906 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
907 uint32 messageId
= _ServerAnswerForseener
->onNodeMoved(instanceId
, attrName
, position
, destInstanceId
, destAttrName
, destPosition
);
908 proxy
.onNodeMoveAsked(this, messageId
, instanceId
, attrName
, position
, destInstanceId
, destAttrName
, destPosition
);
912 void CClientEditionModule::requestMapConnection( uint32 scenarioId
, bool mustTp
, bool mustUpdateHighLevel
)
914 //H_AUTO(R2_CClientEditionModule_requestMapConnection)
915 // CSerialFactoryBackup fb;
916 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
917 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
918 proxy
.onMapConnectionAsked(this, (TSessionId
)scenarioId
, mustTp
, mustUpdateHighLevel
, R2::TUserRole::ur_editor
);
922 void CClientEditionModule::requestReconnection()
924 //H_AUTO(R2_CClientEditionModule_requestReconnection)
925 if (_SessionId
.asInt() != 0)
927 this->requestMapConnection(_SessionId
.asInt(), false, false);
932 CScenario
* CClientEditionModule::getCurrentScenario() const {return _Scenario
; }
935 void CClientEditionModule::addPaletteElement(const std::string
& attrName
, CObject
* paletteElement
)
937 //H_AUTO(R2_CClientEditionModule_addPaletteElement)
938 _Palette
->addPaletteElement(attrName
, paletteElement
);
941 bool CClientEditionModule::isInPalette(const std::string
& key
) const
943 //H_AUTO(R2_CClientEditionModule_isInPalette)
944 return _Palette
->isInPalette(key
);
947 CObject
* CClientEditionModule::getPropertyValue(CObject
* component
, const std::string
& attrName
) const
949 //H_AUTO(R2_CClientEditionModule_getPropertyValue)
950 return _PropertyAccessor
->getPropertyValue(component
, attrName
);
953 CObject
* CClientEditionModule::getPropertyValue(const std::string
& instanceId
, const std::string
& attrName
) const
955 //H_AUTO(R2_CClientEditionModule_getPropertyValue)
956 CObject
* component
= _Scenario
->find(instanceId
);
957 if (!component
) return 0;
958 return _PropertyAccessor
->getPropertyValue(component
, attrName
);
961 CObject
* CClientEditionModule::getPropertyList(CObject
* component
) const
963 //H_AUTO(R2_CClientEditionModule_getPropertyList)
964 typedef std::list
<std::string
> TContainer
;
966 TContainer properties
;
968 _PropertyAccessor
->getPropertyList(component
, properties
);
969 TContainer::const_iterator
first(properties
.begin()), last(properties
.end());
970 for ( ; first
!= last
; ++first
)
972 component
->add(new CObjectString(*first
));
977 CObject
* CClientEditionModule::getPaletteElement(const std::string
& key
)const
979 //H_AUTO(R2_CClientEditionModule_getPaletteElement)
980 return _Palette
->getPaletteElement(key
);
984 CObject
* CClientEditionModule::newComponent(const std::string
& type
) const
986 //H_AUTO(R2_CClientEditionModule_newComponent)
987 return _Factory
->newComponent(type
);
990 void CClientEditionModule::registerGenerator(CObject
* classObject
)
992 //H_AUTO(R2_CClientEditionModule_registerGenerator)
993 _Factory
->registerGenerator(classObject
);
996 CPropertyAccessor
& CClientEditionModule::getPropertyAccessor() const
998 //H_AUTO(R2_CClientEditionModule_getPropertyAccessor)
999 nlassert(_PropertyAccessor
);
1000 return *_PropertyAccessor
;
1003 void CClientEditionModule::updateScenario(CObject
* scenario
)
1005 //H_AUTO(R2_CClientEditionModule_updateScenario)
1006 nlassert(_Scenario
);
1007 _Scenario
->setHighLevel(scenario
);
1008 std::string eid
= getEid();
1009 _Factory
->setMaxId(eid
, _Scenario
->getMaxId(eid
));
1012 void CClientEditionModule::setEid(const std::string
& eid
)
1014 //H_AUTO(R2_CClientEditionModule_setEid)
1016 _Factory
->setPrefix(_Eid
);
1020 bool CClientEditionModule::askUpdateCharMode(R2::TCharMode mode
)
1022 //H_AUTO(R2_CClientEditionModule_askUpdateCharMode)
1023 // CSerialFactoryBackup fb;
1024 if (_ServerEditionProxy
== NULL
) { return false; };
1026 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
1027 proxy
.onCharModeUpdateAsked(this, mode
);
1032 void CClientEditionModule::onCharModeUpdated(NLNET::IModuleProxy
* /* senderModuleProxy */, R2::TCharMode mode
)
1034 //H_AUTO(R2_CClientEditionModule_onCharModeUpdated)
1037 UserEntity
->setR2CharMode(mode
);
1043 void CClientEditionModule::startScenario(class NLNET::IModuleProxy
* proxy
, bool ok
, uint32
/* startingAct */, const std::string
& errorReason
)
1045 //H_AUTO(R2_CClientEditionModule_startScenario)
1048 if (_SessionType
== st_edit
)
1050 _Client
->onTestModeConnected();
1051 R2::getEditor().setMode(CEditor::DMMode
);
1053 else if(_SessionType
== st_anim
)
1056 this->connectAnimationModePlay();
1058 CEditor::connectionMsg("");
1060 if (_CharMode
== TCharMode::Dm
)
1062 R2::getEditor().setMode(CEditor::AnimationModeDm
);
1063 askMissionItemsDescription();
1065 else if (_CharMode
== TCharMode::Tester
|| _CharMode
== TCharMode::Player
)
1067 R2::getEditor().setMode(CEditor::AnimationModePlay
);
1071 nlwarning("Error Mode not handled %d", _CharMode
.getValue());
1072 R2::getEditor().setMode(CEditor::AnimationModePlay
);
1079 CEditor::connectionMsg("uiR2EDR2StartTestError");
1080 requestReconnection();
1083 if (!ok
&& errorReason
.empty())
1085 systemMsg(proxy
, "ERR", "", errorReason
);
1091 void CClientEditionModule::startingScenario(class NLNET::IModuleProxy
* /* serverProxy */, uint32 charId
)
1093 //H_AUTO(R2_CClientEditionModule_startingScenario)
1094 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
1096 CObjectSerializerServer hlData
;
1097 CObjectSerializerServer rtData
;
1102 // Some times save is refused: be NevraxScenario must not be changed
1104 CScenarioValidator sv
;
1105 CScenarioValidator::TValues values
;
1106 std::string md5
, signature
;
1107 R2::getEditor().getLua().executeScriptNoThrow("r2.Translator.initStartingActIndex()");
1109 sv
.setScenarioToLoad("save/r2_buffer.dat", values
, md5
, signature
, true);
1110 _LastReadHeader
= values
;
1111 uint32 lastActIndex
= _StartingActIndex
;
1112 CObject
* hlScenario2
= _Client
->getComLuaModule().loadLocal("save/r2_buffer.dat", _LastReadHeader
);
1113 _StartingActIndex
= lastActIndex
;
1117 _Client
->scenarioUpdated(hlScenario2
, false, lastActIndex
);
1119 _StartingActIndex
= lastActIndex
;
1125 uint32 myUserId
= NetMngr
.getUserId();
1126 std::string connectionState
;
1128 if (myUserId
== (charId
>>4) || ClientCfg
.Local
)
1131 std::string errorMsg
;
1133 CObject
* hlScenario
= _Scenario
->getHighLevel();
1134 hlData
.setData(hlScenario
); // clone before modify by translateFeatures
1135 // translateFeatures change _StartingActIndex
1137 _Factory
->setMaxId("RtAct", 0);
1138 _Factory
->setMaxId("RtAiState", 0);
1139 _Factory
->setMaxId("RtNpcGrp", 0);
1140 _Factory
->setMaxId("RtNpcEventHandlerAction", 0);
1141 _Factory
->setMaxId("RtNpcEventHandler", 0);
1142 _Factory
->setMaxId("RtLocation", 0);
1143 _Factory
->setMaxId("RtTextManager", 0);
1144 _Factory
->setMaxId("RtScenario", 0);
1145 _Factory
->setMaxId("RtUserTrigger", 0);
1146 _Factory
->setMaxId("RtScenario", 0);
1147 _Factory
->setMaxId("RtEntryText", 0);
1148 _Factory
->setMaxId("RtPlotItem", 0);
1150 CUniquePtr
<CObject
> rtDataPtr( _Client
->getComLuaModule().translateFeatures(hlScenario
, errorMsg
) );
1151 rtData
.setData(rtDataPtr
.get());
1153 if (rtDataPtr
.get())
1156 connectionState
= "uiR2EDUploadScenario";
1159 string filename
= CFile::findNewFile("scenario.rt.txt");
1160 COFile
output(filename
);
1162 rtDataPtr
->serialize(ss
);
1163 output
.serialBuffer((uint8
*)ss
.c_str(),(uint
)ss
.size());
1169 nlwarning("%s",errorMsg
.c_str());
1170 connectionState
= "uiR2EDR2StartTestError";
1173 TScenarioSessionType sessionType
= _SessionType
;
1175 if (ok
&& sessionType
== st_anim
)
1179 NLNET::CMessage msg
;
1180 uint32 messageId
= _ServerAnswerForseener
->onScenarioUploaded( hlScenario
);
1181 sendMsgToDss(CShareServerEditionItfProxy::buildMessageFor_onScenarioUploadAsked(msg
, messageId
, hlData
, false));
1186 TScenarioHeaderSerializer
header(_LastReadHeader
);
1188 NLNET::CMessage msg
;
1189 sendMsgToDss(CShareServerEditionItfProxy::buildMessageFor_startScenario(msg
, ok
, header
, rtData
, _StartingActIndex
));
1194 connectionState
= "uiR2EDR2WaitUploadScenario";
1197 if (_SessionType
== st_edit
)
1199 _Client
->onEditionModeDisconnected();
1200 R2::getEditor().setMode(CEditor::GoingToDMMode
);
1202 else if (_SessionType
== st_anim
)
1204 _Client
->onEditionModeDisconnected();
1205 R2::getEditor().setMode(CEditor::AnimationModeGoingToDm
);
1209 CEditor::connectionMsg(connectionState
);
1213 bool CClientEditionModule::requestStartScenario()
1215 //H_AUTO(R2_CClientEditionModule_ )
1217 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return false);
1219 CEditor::connectionMsg("uimR2EDGoToDMMode");
1221 R2::getEditor().getLua().executeScriptNoThrow("r2.Version.save(\"save/r2_buffer.dat\")");
1222 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
1223 proxy
.startingScenario(this);
1228 void CClientEditionModule::updateUserComponentsInfo(const std::string
& filename
, const std::string
& name
, const std::string
& description
, uint32 timestamp
, const std::string
& md5hash
)
1230 //H_AUTO(R2_CClientEditionModule_updateUserComponentsInfo)
1231 TUserComponents::iterator found
= _UserComponents
.find(filename
);
1232 if (found
== _UserComponents
.end())
1234 nlwarning("Error: try to update information on a unknown component '%s'", filename
.c_str() );
1237 found
->second
->Name
= name
;
1238 found
->second
->Description
= description
;
1239 found
->second
->TimeStamp
= timestamp
;
1240 found
->second
->Md5Id
.fromString( md5hash
);
1244 void CClientEditionModule::registerUserComponent(const std::string
& filename
)
1246 //H_AUTO(R2_CClientEditionModule_registerUserComponent)
1247 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
1249 TUserComponents::iterator found
= _UserComponents
.find(filename
);
1250 if (found
== _UserComponents
.end())
1252 nlwarning("Error: try to upload unknown component '%s'", filename
.c_str() );
1256 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
1257 proxy
.onUserComponentRegistered(this, found
->second
->Md5
);
1261 CUserComponent
* CClientEditionModule::getUserComponentByHashMd5( const NLMISC::CHashKeyMD5
& md5
) const
1263 //H_AUTO(R2_CClientEditionModule_getUserComponentByHashMd5)
1265 TUserComponents::const_iterator
first(_UserComponents
.begin()), last(_UserComponents
.end());
1266 for (; first
!= last
&& (first
->second
->Md5
!= md5
) ; ++first
) {}
1269 nlwarning("Error: try to upload unknown component '%s'", md5
.toString().c_str() );
1273 return first
->second
;
1277 void CClientEditionModule::onUserComponentUploading(NLNET::IModuleProxy
* /* senderModuleProxy */, const CHashKeyMD5
& md5
)
1279 //H_AUTO(R2_CClientEditionModule_onUserComponentUploading)
1280 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
1282 CUserComponent
* userComponent
= getUserComponentByHashMd5(md5
);
1286 NLNET::CMessage message
;
1287 message
.setType("SUCU"); //onUserComponentUploaded
1288 userComponent
->serial(message
);
1289 _ServerEditionProxy
->sendModuleMessage(this, message
);
1296 void CClientEditionModule::onUserComponentRegistered(NLNET::IModuleProxy
* /* senderModuleProxy */, const CHashKeyMD5
& md5
)
1298 //H_AUTO(R2_CClientEditionModule_onUserComponentRegistered)
1299 BOMB_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
1300 CUserComponent
* userComponent
= getUserComponentByHashMd5(md5
);
1303 CShareServerEditionItfProxy
proxy(_ServerEditionProxy
);
1304 proxy
.onUserComponentDownloading(this, md5
);
1308 std::string filename
= userComponent
->getFilename();
1309 R2::getEditor().getLua().executeScriptNoThrow(NLMISC::toString("r2.UserComponentsManager:addUserComponent('%s')", filename
.c_str()));
1314 void CClientEditionModule::onUserComponentDownloaded(NLNET::IModuleProxy
*senderModuleProxy
, CUserComponent
* component
)
1316 //H_AUTO(R2_CClientEditionModule_onUserComponentDownloaded)
1318 // case 1 data are compressed
1319 component
->UncompressedData
= new uint8
[component
->UncompressedDataLength
+ 1];
1320 uLongf dataLength
= static_cast<uLongf
>(component
->UncompressedDataLength
);
1321 sint32 decompressionState
= uncompress (reinterpret_cast<Bytef
*>(component
->UncompressedData
), &dataLength
,
1322 reinterpret_cast<Bytef
*>(component
->CompressedData
), component
->CompressedDataLength
);
1324 component
->UncompressedDataLength
= static_cast<uint32
>(dataLength
);
1326 if (decompressionState
!= Z_OK
)
1328 nlwarning("Error: the downloaded user component is corrupted '%s'", component
->Filename
.c_str());
1332 component
->UncompressedData
[component
->UncompressedDataLength
] = '\0';
1334 // insert user component into user components map
1336 TUserComponents::iterator found
= _UserComponents
.find(component
->Filename
);
1337 if (found
!= _UserComponents
.end())
1339 delete found
->second
;
1340 found
->second
= component
;
1343 _UserComponents
[component
->Filename
] = component
;
1346 saveUserComponentFile(component
->Filename
, true);
1348 onUserComponentRegistered(senderModuleProxy
, component
->Md5
);
1355 bool CClientEditionModule::loadUserComponent(const std::string
& filename
, bool mustReload
)
1357 //H_AUTO(R2_CClientEditionModule_loadUserComponent)
1360 TUserComponents::const_iterator found
= _UserComponents
.find(filename
);
1361 if (found
!= _UserComponents
.end())
1367 std::string sourceExtension
= UserComponentsSourceExtension
.get();
1368 std::string componentExtension
= UserComponentsComponentExtension
.get();
1371 uint32 uncompressedFileLength
= 0;
1372 uint8
* uncompressedFile
=0;
1373 uint32 compressedFileLength
= 0;
1374 uint8
* compressedFile
=0;
1375 bool compressed
= false;
1378 if (CFile::getExtension(filename
) == sourceExtension
)
1383 else if (CFile::getExtension(filename
) == componentExtension
)
1390 nlwarning("Wrong file extension '%s'", filename
.c_str() );
1391 nlwarning("Allowed file extension '%s' '%s'", sourceExtension
.c_str(), componentExtension
.c_str());
1396 uint32 timeStamp
= 0;
1399 FILE* file
= nlfopen(filename
, "rb");
1402 nlwarning("Try to open an invalid file %s (access error)", filename
.c_str());
1406 // file length are the last uint32 of a file
1407 if (fseek(file
,0, SEEK_END
) != 0)
1409 nlwarning("Try to open an invalid file %s (size error)", filename
.c_str());
1413 uncompressedFileLength
= ftell(file
); // size of file
1416 if (fseek(file
, 0, SEEK_SET
) != 0)
1418 nlwarning("Try to open an invalid file %s (size error)", filename
.c_str());
1423 uncompressedFile
= new uint8
[uncompressedFileLength
];
1424 int length
= (int)fread(uncompressedFile
, sizeof(char), uncompressedFileLength
, file
);
1427 nlwarning("Error while reading %s", filename
.c_str());
1428 delete[] uncompressedFile
;
1434 if ( length
< static_cast<sint32
>(uncompressedFileLength
))
1436 nlwarning("Error while reading %s (corrupted data)", filename
.c_str());
1437 delete[] uncompressedFile
;
1445 // Test if data are not too big
1446 if (uncompressedFileLength
> 200*1024)
1448 nlwarning("Try to open an invalid file %s (size error)", filename
.c_str());
1449 delete [] uncompressedFile
;
1453 std::string compiledInfoHeader
= "--COMPONENT HEADER\n";
1454 std::string compiledInfoFooter
= "--COMPONENT BODY\n";
1457 std::string
data((const char*)&uncompressedFile
[0], (const char*)&uncompressedFile
[uncompressedFileLength
]);
1458 std::string::size_type start
= data
.find(compiledInfoHeader
);
1459 if ( start
!= std::string::npos
)
1461 std::string::size_type finish
= data
.find(compiledInfoFooter
, start
+ compiledInfoHeader
.length());
1462 if (finish
!= std::string::npos
)
1464 finish
+= compiledInfoFooter
.size();
1465 data
= data
.substr(0, start
) + data
.substr(finish
, data
.size() - finish
);
1469 // REGENERATE HEADER
1470 md5Id
= getMD5((uint8
*)data
.data(), (uint32
)data
.size());
1471 timeStamp
= NLMISC::CTime::getSecondsSince1970();
1473 //std::stringstream ss;
1474 //ss << compiledInfoHeader;
1475 //ss << "local fileinfo = {}\n";
1476 //ss << toString("fileinfo.Package='%s'\n", filename.c_str());
1477 //ss << toString("fileinfo.Version='%s'\n", "1");
1478 //ss << toString("fileinfo.MD5='%s'\n", md5Id.toString().c_str());
1479 //ss << toString("fileinfo.TimeStamp='%u'\n", timeStamp);
1480 //ss << toString("r2.UserComponentsManager:registerFileInfo(fileinfo)\n");
1481 //ss << compiledInfoFooter;
1487 str
+= compiledInfoHeader
;
1488 str
+= "local fileinfo = {}\n";
1489 str
+= toString("fileinfo.Package='%s'\n", filename
.c_str());
1490 str
+= toString("fileinfo.Version='%s'\n", "1");
1491 str
+= toString("fileinfo.MD5='%s'\n", md5Id
.toString().c_str());
1492 str
+= toString("fileinfo.TimeStamp='%u'\n", timeStamp
);
1493 str
+= toString("r2.UserComponentsManager:registerFileInfo(fileinfo)\n");
1494 str
+= compiledInfoFooter
;
1498 delete [] uncompressedFile
;
1499 uncompressedFile
= new uint8
[ data
.size() ];
1500 memcpy(uncompressedFile
, data
.c_str(), data
.size());
1501 uncompressedFileLength
= (uint32
)data
.size();
1505 // Get Uncompressed File length (4 last byte of a gz)
1506 FILE* file
= nlfopen(filename
, "rb");
1509 nlwarning("Try to open an invalid file %s (access error)", filename
.c_str());
1513 // file length are the last uint32 of a file
1514 if (fseek(file
, -4, SEEK_END
) != 0)
1516 nlwarning("Try to open an invalid file %s (size error)", filename
.c_str());
1521 if (fread((void*)&uncompressedFileLength
, sizeof(uncompressedFileLength
), 1, file
) != 1)
1523 nlwarning("Error while reading %s", filename
.c_str());
1526 #ifdef NL_BIG_ENDIAN
1527 NLMISC_BSWAP32(uncompressedFileLength
);
1532 // Test if data are not too big
1533 if (uncompressedFileLength
> 200*1024)
1535 nlwarning("Try to open an invalid file %s (size error)", filename
.c_str());
1536 delete [] compressedFile
;
1540 // Read the compressed File
1542 gzFile file
= gzopen ( filename
.c_str(), "rb");
1543 uncompressedFile
= new uint8
[uncompressedFileLength
+1];
1545 int length
= gzread(file
, uncompressedFile
, uncompressedFileLength
);
1548 nlwarning("Error while reading %s", filename
.c_str());
1549 delete [] uncompressedFile
;
1550 delete [] compressedFile
;
1556 if ( length
< static_cast<sint32
>(uncompressedFileLength
))
1558 nlwarning("Error while reading %s (corrupted data)", filename
.c_str());
1559 delete [] uncompressedFile
;
1560 delete [] compressedFile
;
1566 // Read the compressed File
1570 delete [] compressedFile
; compressedFile
= 0;
1572 //size of the destination buffer, which must be at least 0.1% larger than sourceLen plus 12 bytes
1575 uLongf destLen
= uncompressedFileLength
+ uncompressedFileLength
/ 1000 + 12;
1576 Bytef
*dest
= new Bytef
[destLen
];
1577 int ok
= compress(dest
, &destLen
, (Bytef
*)uncompressedFile
, uncompressedFileLength
);
1580 delete [] uncompressedFile
;
1581 delete [] compressedFile
;
1582 nlwarning("Error while reading %s (can't compress data)", filename
.c_str());
1585 compressedFile
= reinterpret_cast<uint8
*>(dest
);
1586 compressedFileLength
= static_cast<uint32
>(destLen
);
1588 uncompressedFile
[uncompressedFileLength
] = '\0';
1591 // TODO: compute md5Id and timeStamp
1593 _UserComponents
[filename
] = new CUserComponent(filename
, uncompressedFile
, uncompressedFileLength
, compressedFile
, compressedFileLength
);
1594 _UserComponents
[filename
]->Md5Id
= md5Id
;
1595 _UserComponents
[filename
]->TimeStamp
= timeStamp
;
1600 std::string
CClientEditionModule::readUserComponentFile(const std::string
& filename
)
1602 //H_AUTO(R2_CClientEditionModule_readUserComponentFile)
1604 if (!loadUserComponent(filename
, false))
1609 CUserComponent
* component
= getUserComponentByFilename(filename
);
1614 const char * str
= (const char*)component
->getUncompressedData();
1615 std::string
value(str
);
1621 CUserComponent
* CClientEditionModule::getUserComponentByFilename(const std::string
& filename
) const
1623 //H_AUTO(R2_CClientEditionModule_getUserComponentByFilename)
1624 TUserComponents::const_iterator found
= _UserComponents
.find(filename
);
1625 if (found
!= _UserComponents
.end())
1627 return found
->second
;
1632 void CClientEditionModule::saveUserComponentFile(const std::string
& filename
, bool mustCompress
)
1634 //H_AUTO(R2_CClientEditionModule_saveUserComponentFile)
1636 bool ok
= loadUserComponent(filename
);
1640 CUserComponent
* component
= getUserComponentByFilename(filename
);
1643 std::string compressedName
;
1644 std::string uncompressedName
;
1647 if (CFile::getExtension(filename
) == UserComponentsSourceExtension
.toString())
1649 uncompressedName
= filename
;
1650 compressedName
= toString("%s/%s.%s",
1651 UserComponentsComponentsDirectory
.c_str(),
1652 component
->Md5Id
.toString().c_str(),
1653 UserComponentsComponentExtension
.c_str());
1655 else if (CFile::getExtension(filename
) == UserComponentsComponentExtension
.toString())
1657 compressedName
= filename
;
1658 uncompressedName
= toString("%s/%s.%s",
1659 UserComponentsExamplesDirectory
.c_str(),
1660 CFile::getFilenameWithoutExtension(component
->Filename
).c_str(),
1661 UserComponentsSourceExtension
.c_str());
1668 FILE* output
= nlfopen(uncompressedName
, "wb");
1671 if (fwrite(component
->UncompressedData
, sizeof(char), component
->UncompressedDataLength
, output
) != component
->UncompressedDataLength
)
1673 nlwarning("Unable to write %s", component
->UncompressedData
);
1683 gzFile output
= gzopen(compressedName
.c_str(), "wb");
1686 gzwrite(output
, (const voidp
) component
->UncompressedData
, component
->UncompressedDataLength
);
1694 void CClientEditionModule::refreshComponents()
1696 //H_AUTO(R2_CClientEditionModule_refreshComponents)
1698 // verify directory exist
1699 bool createDirectorySuccess = false;
1700 if ( !CFile::isDirectory(_ScriptDirectory))
1702 createDirectorySuccess = CFile::createDirectory(_ScriptDirectory);
1705 // verify content of directory has not changed
1706 uint32 lastDirectoryModificationDate = CFile::getFileModificationDate(const std::string &filename);
1707 if (_LastDirectoryModificationDate == lastDirectoryModificationDate )
1711 _LastDirectoryModificationDate = lastDirectoryModificationDate
1713 // get Developper Component Script;
1714 std::vector<std::string> result;
1715 CPath::getPathContent (_ScriptDirectory, false, false, true, result, false, false);
1717 CInterfaceManager *pIM= CInterfaceManager::getInstance();
1718 std::vector<std::string> script(1);
1719 bool ok = pIM->pars veInterface(script, true, false);
1722 _LastRefreshComponents = NLMISC::CTime::getLocalTime();
1726 void CClientEditionModule::ackMsg( NLNET::IModuleProxy
*sender
, uint32 msgId
, bool ok
)
1728 _ServerAnswerForseener
->ack(this, sender
, msgId
, ok
);
1731 void CClientEditionModule::onScenarioUploaded(NLNET::IModuleProxy
* /* sender */, const R2::CObjectSerializerClient
&hlScenario
)
1733 //H_AUTO(R2_CClientEditionModule_onScenarioUploaded)
1735 _Client
->scenarioUpdated(hlScenario
.getData(), false, 1);//give ownership
1738 // The client request to set a node on a hl scenario.
1739 void CClientEditionModule::onNodeSet(NLNET::IModuleProxy
* /* sender */, const std::string
&instanceId
, const std::string
&attrName
, const R2::CObjectSerializerClient
&value
)
1741 //H_AUTO(R2_CClientEditionModule_onNodeSet)
1743 _Client
->nodeSet(instanceId
, attrName
, value
.getData()); //todo ownership
1746 // The ServerEditionMode inserts a node on a hl scenario.
1747 void CClientEditionModule::onNodeInserted(NLNET::IModuleProxy
* /* sender */, const std::string
&instanceId
, const std::string
&attrName
, sint32 position
, const std::string
&key
, const R2::CObjectSerializerClient
&value
)
1749 //H_AUTO(R2_CClientEditionModule_onNodeInserted)
1751 _Client
->nodeInserted( instanceId
, attrName
, position
, key
, value
.getData()); //todo ownership
1754 // The ServerEditionMode erases a node on a hl scenario.
1755 void CClientEditionModule::onNodeErased(NLNET::IModuleProxy
* /* sender */, const std::string
&instanceId
, const std::string
&attrName
, sint32 position
)
1757 //H_AUTO(R2_CClientEditionModule_onNodeErased)
1759 _Client
->nodeErased( instanceId
, attrName
, position
);
1762 // The ServerEditionMode a move node on a hl scenario.
1763 void CClientEditionModule::onNodeMoved(NLNET::IModuleProxy
* /* sender */, const std::string
&instanceId1
, const std::string
&attrName1
, sint32 position1
, const std::string
&instanceId2
, const std::string
&attrName2
, sint32 position2
)
1765 //H_AUTO(R2_CClientEditionModule_onNodeMoved)
1767 _Client
->nodeMoved(instanceId1
, attrName1
, position1
,
1768 instanceId2
, attrName2
, position2
);
1771 void CClientEditionModule::onQuotaUpdated(NLNET::IModuleProxy
* /* senderModuleProxy */, uint32 maxNpcs
, uint32 maxStaticObjects
)
1773 //H_AUTO(R2_CClientEditionModule_onQuotaUpdated)
1774 //R2::getEditor().getLua().executeScriptNoThrow(toString("r2.QuotaMgr.onQuotaUpdated(%u, %u)", maxNpcs, maxStaticObjects));
1776 _MaxStaticObjects
= maxStaticObjects
;
1780 uint32
CClientEditionModule::getCurrentMaxId()
1782 //H_AUTO(R2_CClientEditionModule_getCurrentMaxId)
1783 if (_Scenario
== NULL
)
1785 std::string eid
= getEid();
1786 sint32 currentId
= _Factory
->getMaxId(eid
);
1787 nlassert(currentId
>= -1);
1789 return static_cast<uint32
>(currentId
+ 1);
1793 void CClientEditionModule::reserveIdRange(uint32 range
)
1795 //H_AUTO(R2_CClientEditionModule_reserveIdRange)
1796 nlassert(_Scenario
);
1797 std::string eid
= getEid();
1798 sint32 currentId
= _Scenario
->getMaxId(eid
);
1799 nlassert(currentId
>= -1);
1801 sint32 maxId
= currentId
+ static_cast<sint32
>(range
+ 1);
1803 //_Scenario->setMaxId(eid, maxId);
1804 _Factory
->setMaxId(eid
, maxId
);
1807 std::string
CClientEditionModule::getEmoteBehaviorFromEmoteId(const std::string
& emoteId
) const
1809 //H_AUTO(R2_CClientEditionModule_getEmoteBehaviorFromEmoteId)
1810 return _Emotes
->get(emoteId
);
1816 void CClientEditionModule::resetDisplayInfo()
1818 //H_AUTO(R2_CClientEditionModule_resetDisplayInfo)
1819 this->_ClientEditorConfig
->setDisplayInfo(0xFFFFFFFF);
1822 void CClientEditionModule::setDisplayInfo(const std::string
& formName
, bool displayInfo
)
1824 //H_AUTO(R2_CClientEditionModule_setDisplayInfo)
1825 this->_ClientEditorConfig
->setDisplayInfo(formName
, displayInfo
);
1826 //CShareServerEditionItfProxy proxy(_ServerEditionProxy);
1827 //uint32 newDisplayInfo = this->_ClientEditorConfig->getDisplayInfo();
1828 //proxy.setDisplayInfo(this, newDisplayInfo);
1832 bool CClientEditionModule::mustDisplayInfo(const std::string
& formName
) const
1834 //H_AUTO(R2_CClientEditionModule_mustDisplayInfo)
1835 bool ok
= this->_ClientEditorConfig
->mustDisplayInfo(formName
);
1839 bool CClientEditionModule::hasDisplayInfo(const std::string
& formName
) const
1841 //H_AUTO(R2_CClientEditionModule_hasDisplayInfo)
1842 bool ok
= this->_ClientEditorConfig
->hasDisplayInfo(formName
);
1846 void CClientEditionModule::onDisplayInfoUpdated(NLNET::IModuleProxy
* /* senderModuleProxy */, uint32 displayInfo
)
1848 //H_AUTO(R2_CClientEditionModule_onDisplayInfoUpdated)
1849 this->_ClientEditorConfig
->setDisplayInfo(displayInfo
);
1853 void CClientEditionModule::setStartingActIndex(uint32 startingActIndex
)
1855 //H_AUTO(R2_CClientEditionModule_setStartingActIndex)
1856 _StartingActIndex
= startingActIndex
;
1859 void CClientEditionModule::onTpPositionSimulated(NLNET::IModuleProxy
* /* sender */, TSessionId
/* sessionId */, uint64
/* characterId64 */, sint32 x
, sint32 y
, sint32 z
, uint8
/* scenarioSeason */)
1861 //H_AUTO(R2_CClientEditionModule_onTpPositionSimulated)
1863 CVector
dest((float)x
, (float)y
, (float) z
);
1866 UserEntity
->pos(dest
); // change position in pacs
1867 // Select the closest continent from the new position.
1868 beginLoading (LoadingBackground
);
1869 #define BAR_STEP_TP 2 // fixme : this define is duplicated....
1870 ProgressBar
.reset (BAR_STEP_TP
);
1871 string
nmsg("Loading...");
1872 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1873 ProgressBar
.progress(0);
1874 ContinentMngr
.select(dest
, ProgressBar
);
1876 // Teleport the User.
1877 UserEntity
->tp(dest
);
1878 ProgressBar
.finish();
1882 void CClientEditionModule::onDisconnected(NLNET::IModuleProxy
* /* sender */)
1884 //H_AUTO(R2_CClientEditionModule_onDisconnected)
1885 R2::getEditor().getLua().executeScriptNoThrow(NLMISC::toString("r2.onDisconnected()"));
1888 void CClientEditionModule::onKicked(NLNET::IModuleProxy
* /* sender */, uint32 timeBeforeDisconnection
, bool mustKick
)
1890 //H_AUTO(R2_CClientEditionModule_onKicked)
1892 R2::getEditor().getLua().push(timeBeforeDisconnection
);
1893 R2::getEditor().getLua().push(mustKick
);
1894 R2::getEditor().callEnvFunc( "onKicked", 2, 0);
1899 // Target : Animation Module
1901 void CClientEditionModule::requestTalkAs(const std::string
& npcname
)
1903 //H_AUTO(R2_CClientEditionModule_requestTalkAs)
1904 CMessage
msg("talk_as");
1905 msg
.serial(const_cast<std::string
&>(npcname
));
1906 _ServerAnimationProxy
->sendModuleMessage(this, msg
);
1909 void CClientEditionModule::requestStringTable()
1911 //H_AUTO(R2_CClientEditionModule_requestStringTable)
1912 CMessage
msg("requestStringTable");
1913 _ServerAnimationProxy
->sendModuleMessage(this, msg
);
1916 void CClientEditionModule::requestSetStringValue(std::string
& id
,std::string
& value
)
1918 //H_AUTO(R2_CClientEditionModule_requestSetStringValue)
1919 CMessage
msg("requestSetValue");
1922 _ServerAnimationProxy
->sendModuleMessage(this,msg
);
1925 void CClientEditionModule::requestStartAct(uint32 actId
)
1927 //H_AUTO(R2_CClientEditionModule_requestStartAct)
1928 CMessage
message ("requestStartAct");
1929 message
.serial(actId
);
1930 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return);
1931 _ServerAnimationProxy
->sendModuleMessage(this, message
);
1934 void CClientEditionModule::requestSetWeather(uint16 weatherValue
)
1936 //H_AUTO(R2_CClientEditionModule_requestSetWeather)
1937 CMessage
message ("requestSetWeather");
1938 message
.serial(weatherValue
);
1939 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return);
1940 _ServerAnimationProxy
->sendModuleMessage(this, message
);
1943 void CClientEditionModule::requestSetSeason(uint8 seasonValue
)
1945 //H_AUTO(R2_CClientEditionModule_requestSetSeason)
1946 CMessage
message ("requestSetSeason");
1947 message
.serial(seasonValue
);
1948 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return);
1949 _ServerAnimationProxy
->sendModuleMessage(this, message
);
1952 void CClientEditionModule::requestStopAct()
1954 //H_AUTO(R2_CClientEditionModule_requestStopAct)
1955 CMessage
message ("requestStopAct");
1956 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return);
1957 _ServerAnimationProxy
->sendModuleMessage(this, message
);
1960 void CClientEditionModule::requestStopTalkAs()
1962 //H_AUTO(R2_CClientEditionModule_requestStopTalkAs)
1963 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return);
1965 CMessage
msg("stopTalk");
1966 _ServerAnimationProxy
->sendModuleMessage(this, msg
);
1969 void CClientEditionModule::requestStringValue(std::string
& localId
)
1971 //H_AUTO(R2_CClientEditionModule_requestStringValue)
1972 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return);
1973 CMessage
msg("requestStringValue");
1974 msg
.serial(localId
);
1975 _ServerAnimationProxy
->sendModuleMessage(this, msg
);
1977 void CClientEditionModule::requestTpPosition(float x
, float y
, float z
)
1979 //H_AUTO(R2_CClientEditionModule_requestTpPosition)
1980 DROP_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
1981 CShareServerEditionItfProxy
serverEditionModule(_ServerEditionProxy
);
1982 serverEditionModule
.onTpPositionAsked(this, x
, y
, z
);
1987 void CClientEditionModule::requestIdList()
1989 //H_AUTO(R2_CClientEditionModule_requestIdList)
1990 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return);
1991 CMessage
msg("requestIdList");
1992 _ServerAnimationProxy
->sendModuleMessage(this, msg
);
1997 bool CClientEditionModule::requestTpToEntryPoint(uint32 actIndex
)
1999 //H_AUTO(R2_CClientEditionModule_requestTpToEntryPoint)
2000 DROP_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return false);
2001 if (R2::getEditor().isClearingContent()) { return true;}
2003 CShareServerEditionItfProxy
serverEditionModule(_ServerEditionProxy
);
2004 serverEditionModule
.tpToEntryPoint(this, actIndex
);
2009 bool CClientEditionModule::requestSetStartingAct(uint32 actIndex
)
2011 //H_AUTO(R2_CClientEditionModule_requestSetStartingAct)
2012 DROP_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return false);
2014 CShareServerEditionItfProxy
serverEditionModule(_ServerEditionProxy
);
2015 serverEditionModule
.setStartingAct(this, actIndex
);
2021 bool CClientEditionModule::connectAnimationModePlay()
2023 //H_AUTO(R2_CClientEditionModule_connectAnimationModePlay)
2024 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return false);
2026 CShareServerAnimationItfProxy
serverAnimationModule(_ServerAnimationProxy
);
2027 serverAnimationModule
.connectAnimationModePlay(this);
2032 void CClientEditionModule::onAnimationModePlayConnected(NLNET::IModuleProxy
* /* senderModuleProxy */)
2034 //H_AUTO(R2_CClientEditionModule_onAnimationModePlayConnected)
2035 _Client
->onAnimationModePlayConnected();
2039 void CClientEditionModule::scheduleStartAct(NLNET::IModuleProxy
* /* sender */, uint32 errorId
, uint32 actId
, uint32 nbSeconds
)
2041 //H_AUTO(R2_CClientEditionModule_scheduleStartAct)
2042 R2::getEditor().getLua().push(errorId
);
2043 R2::getEditor().getLua().push(actId
);
2044 R2::getEditor().getLua().push(nbSeconds
);
2045 R2::getEditor().callEnvFunc( "onScheduleStartAct", 3, 0);
2050 void CClientEditionModule::updateScenarioHeader(NLNET::IModuleProxy
* /* sender */, const TScenarioHeaderSerializer
& header
)
2052 //H_AUTO(R2_CClientEditionModule_updateScenarioHeader)
2053 _ScenarioHeader
= header
.Value
;
2054 R2::getEditor().getLua().executeScriptNoThrow( "r2.onScenarioHeaderUpdated(r2.getScenarioHeader())" );
2057 void CClientEditionModule::updateMissionItemsDescription(NLNET::IModuleProxy
* /* sender */, TSessionId
/* sessionId */, const std::vector
<R2::TMissionItem
> &missionItem
)
2059 //H_AUTO(R2_CClientEditionModule_updateMissionItemsDescription)
2061 uint maxNumPlotItems
= CEditor::getMaxNumPlotItems();
2062 for(i
= 0; i
< std::min((uint
) missionItem
.size(), maxNumPlotItems
); ++i
)
2064 CCDBNodeLeaf
*leaf
= CEditor::getPlotItemSheetDBLeaf(i
);
2067 uint32 sheetId
= (uint32
) missionItem
[i
].SheetId
.asInt();
2068 leaf
->setValue32(sheetId
);
2069 getEditor().setPlotItemInfos(missionItem
[i
]);
2072 for(; i
< maxNumPlotItems
; ++i
)
2074 CCDBNodeLeaf
*leaf
= CEditor::getPlotItemSheetDBLeaf(i
);
2077 leaf
->setValue32(0);
2082 void CClientEditionModule::updateActPositionDescriptions(NLNET::IModuleProxy
* /* sender */, const TActPositionDescriptions
&actPositionDescriptions
)
2084 //H_AUTO(R2_CClientEditionModule_updateActPositionDescriptions)
2085 this->_ActPositionDescriptions
= actPositionDescriptions
;
2086 R2::getEditor().getLua().executeScriptNoThrow( "r2.onRuntimeActUpdated(r2.getRuntimeActs())" );
2090 void CClientEditionModule::updateUserTriggerDescriptions(NLNET::IModuleProxy
* /* sender */, const TUserTriggerDescriptions
&userTriggerDescriptions
)
2092 //H_AUTO(R2_CClientEditionModule_updateUserTriggerDescriptions)
2093 this->_UserTriggerDescriptions
= userTriggerDescriptions
;
2094 R2::getEditor().getLua().executeScriptNoThrow( "r2.onUserTriggerDescriptionUpdated(r2.getUserTriggers())" );
2098 bool CClientEditionModule::askMissionItemsDescription()
2100 //H_AUTO(R2_CClientEditionModule_askMissionItemsDescription)
2101 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return false);
2102 CShareServerAnimationItfProxy
serverAnimationModule(_ServerAnimationProxy
);
2103 serverAnimationModule
.askMissionItemsDescription(this);
2107 bool CClientEditionModule::requestTriggerUserTrigger(uint32 actId
, uint triggerId
)
2109 //H_AUTO(R2_CClientEditionModule_requestTriggerUserTrigger)
2110 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return false);
2111 CShareServerAnimationItfProxy
serverAnimationModule(_ServerAnimationProxy
);
2112 serverAnimationModule
.onUserTriggerTriggered(this, actId
, triggerId
);
2115 void CClientEditionModule::onCurrentActIndexUpdated(NLNET::IModuleProxy
* /* sender */, uint32 actId
)
2117 //H_AUTO(R2_CClientEditionModule_onCurrentActIndexUpdated)
2118 this->_CurrentActIndex
= actId
;
2119 R2::getEditor().getLua().executeScriptNoThrow( "r2.onCurrentActIndexUpdated(r2.getCurrentActIndex())" );
2123 void CClientEditionModule::dssTarget( std::vector
<std::string
>& args
)
2125 //H_AUTO(R2_CClientEditionModule_dssTarget)
2126 DROP_IF(_ServerAnimationProxy
== NULL
, "Server Animation Module not connected", return);
2128 CShareServerAnimationItfProxy
serverAnimationModule(_ServerAnimationProxy
);
2129 serverAnimationModule
.onDssTarget(this, args
);
2133 void CClientEditionModule::updateIncarningList(NLNET::IModuleProxy
* /* sender */, const std::vector
<uint32
> & botId
)
2135 //H_AUTO(R2_CClientEditionModule_updateIncarningList)
2136 this->_IncarnatingList
= botId
;
2137 R2::getEditor().getLua().executeScriptNoThrow( "r2.onIncarnatingListUpdated()" );
2140 void CClientEditionModule::updateTalkingAsList(NLNET::IModuleProxy
* /* sender */, const std::vector
<uint32
> & botId
)
2142 //H_AUTO(R2_CClientEditionModule_updateTalkingAsList)
2143 this->_TalkingAsList
= botId
;
2144 R2::getEditor().getLua().executeScriptNoThrow( "r2.onTalkingAsListUpdated()" );
2147 std::vector
<uint32
> CClientEditionModule::getIncarnatingList() const
2149 //H_AUTO(R2_CClientEditionModule_getIncarnatingList)
2150 return this->_IncarnatingList
;
2153 std::vector
<uint32
> CClientEditionModule::getTalkingAsList() const
2155 //H_AUTO(R2_CClientEditionModule_getTalkingAsList)
2156 return this->_TalkingAsList
;
2160 void CClientEditionModule::systemMsg(NLNET::IModuleProxy
* /* sender */, const std::string
& msgType
, const std::string
& who
, const std::string
& msg
)
2162 //H_AUTO(R2_CClientEditionModule_systemMsg)
2163 R2::getEditor().getLua().push(msgType
);
2164 R2::getEditor().getLua().push(who
);
2165 R2::getEditor().getLua().push(msg
);
2166 R2::getEditor().callEnvFunc("onSystemMessageReceived", 3 , 0);
2170 void CClientEditionModule::updateScenarioRingAccess(bool ok
, const std::string
& ringAccess
, const std::string
& errMsg
)
2172 //H_AUTO(R2_CClientEditionModule_updateScenarioRingAccess)
2174 DROP_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
2176 CShareServerEditionItfProxy
serverEditionModule(_ServerEditionProxy
);
2177 serverEditionModule
.onScenarioRingAccessUpdated(this, ok
, ringAccess
, errMsg
);
2180 std::string
CClientEditionModule::getCharacterRingAccess() const
2182 //H_AUTO(R2_CClientEditionModule_getCharacterRingAccess)
2186 void CClientEditionModule::onRingAccessUpdated(NLNET::IModuleProxy
* /* moduleSocket */, const std::string
& ringAccess
)
2188 //H_AUTO(R2_CClientEditionModule_onRingAccessUpdated)
2190 _RingAccess
= ringAccess
;
2191 //Remove first and last char
2192 if (!_RingAccess
.empty())
2194 if (_RingAccess
[0] == '\'' || _RingAccess
[0] == '"')
2196 _RingAccess
= _RingAccess
.substr(1);
2199 if (!_RingAccess
.empty())
2201 if (_RingAccess
[_RingAccess
.size()-1] == '\''
2202 || _RingAccess
[_RingAccess
.size()-1] == '"')
2204 _RingAccess
= _RingAccess
.substr(0, _RingAccess
.size()-1);
2207 R2::getEditor().getLua().push(_RingAccess
);
2208 R2::getEditor().callEnvFunc( "onRingAccessUpdated",1 ,0);
2214 void CClientEditionModule::addToSaveList(const std::string
& filename
, const std::vector
< std::pair
< std::string
, std::string
> >& values
)
2216 //H_AUTO(R2_CClientEditionModule_addToSaveList)
2219 std::string name
= filename
; // Must use prefix or suffix?
2223 CObject
* scenario
= getCurrentScenario()->getHighLevel();
2227 nlwarning("Can't save: no scenario yet");
2231 CScenarioValidator
* sv
= new CScenarioValidator();
2232 CScenarioValidator::TValues
v1(values
);
2235 ok
= sv
->setScenarioToSave(filename
, scenario
, v1
, md5
);
2243 if ( !_ScenarioToSave
.insert( std::make_pair(md5
, sv
)).second
)
2245 nlwarning("Ask 2 time the save of the same scenario?");
2249 DROP_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
2251 CShareServerEditionItfProxy
serverEditionModule(_ServerEditionProxy
);
2252 serverEditionModule
.saveScenarioFile(this, md5
,R2::TScenarioHeaderSerializer (v1
) );
2256 // :TODO: VIANNEY add all
2257 _LastReadHeader
.clear();
2258 _LastReadHeader
.push_back( std::pair
<std::string
, std::string
>("BodyMD5", sv
->getBodyMd5() ));
2259 _LastReadHeader
.insert(_LastReadHeader
.end(), values
.begin(), values
.end());
2263 // sv.openHeader(filename, v2, true);
2267 /**********************************************************/
2268 /****** ADD TO USER COMPONENT SAVE LIST *******************/
2269 /**********************************************************/
2270 void CClientEditionModule::addToUserComponentSaveList(const std::string
& filename
, const std::vector
< std::pair
< std::string
, std::string
> >& values
, std::string
&body
)
2272 //H_AUTO(R2_CClientEditionModule_addToSaveList)
2275 std::string name
= filename
; // Must use prefix or suffix?
2279 CUserComponentValidator
* ucv
= new CUserComponentValidator();
2280 CUserComponentValidator::TValues
v1(values
);
2283 ok
= ucv
->setUserComponentToSave(filename
, v1
, md5
, body
);
2290 if ( !_UserComponentToSave
.insert( std::make_pair(md5
, ucv
)).second
)
2292 nlwarning("Ask 2 time the save of the same user component?");
2296 DROP_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return);
2298 CShareServerEditionItfProxy
serverEditionModule(_ServerEditionProxy
);
2299 serverEditionModule
.saveUserComponentFile(this, md5
,R2::TScenarioHeaderSerializer (v1
) );
2306 void CClientEditionModule::saveUserComponentFileAccepted(NLNET::IModuleProxy
*senderModuleProxy
, const std::string
& md5
, const std::string
& signature
, bool ok
)
2308 //H_AUTO(R2_CClientEditionModule_saveScenarioFileAccepted)
2310 TUserComponentToSave::iterator
found(_UserComponentToSave
.find(md5
));
2311 if (found
== _UserComponentToSave
.end())
2313 nlwarning("The client has ask more than one time to save the same file");
2317 CUserComponentValidator
* userComponentToSave
= found
->second
;
2318 _UserComponentToSave
.erase(found
);
2322 userComponentToSave
->applySave(signature
);
2323 addToUserComponentLoadList(userComponentToSave
->getFilename(), new CLoadUserComponentSucceeded(this));
2327 systemMsg(senderModuleProxy
, "ERR", "", "uiR2EDServerRefuseToSave");
2333 bool CClientEditionModule::addToUserComponentLoadList( const std::string
& filename
, CUserComponentValidatorLoadSuccededCallback
* cb
)
2335 //H_AUTO(R2_CClientEditionModule_addToLoadList)
2336 CUserComponentValidator
* ucv
= new CUserComponentValidator(cb
);
2337 CUserComponentValidator::TValues values
;
2339 std::string signature
;
2341 nlinfo("Adding user component '%s' to load list", filename
.c_str());
2342 ok
= ucv
->setUserComponentToLoad(filename
, values
, md5
, signature
, ClientCfg
.CheckR2ScenarioMD5
);
2345 R2::getEditor().callEnvFunc( "displayModifiedUserComponentFileError", 0, 0);
2346 nlwarning("setUserComponentToLoad failed");
2350 if ( !_UserComponentToLoad
.insert( std::make_pair(md5
, ucv
)).second
)
2352 nlwarning("Ask 2 time the load of the same user component?"); //or the same empty uc file
2356 DROP_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return false);
2358 CShareServerEditionItfProxy
serverEditionModule(_ServerEditionProxy
);
2359 serverEditionModule
.loadUserComponentFile(this, md5
, signature
);
2364 void CClientEditionModule::loadUserComponentFileAccepted(NLNET::IModuleProxy
* /* senderModuleProxy */, const std::string
& md5
, bool ok
)
2366 //H_AUTO(R2_CClientEditionModule_loadScenarioFileAccepted)
2368 TUserComponentToLoad::iterator
found(_UserComponentToLoad
.find(md5
));
2369 if (found
== _UserComponentToLoad
.end())
2371 nlwarning("The client has ask more than one time to save the same file");
2375 CUniquePtr
<CUserComponentValidator
> userComponentToLoad(found
->second
);
2376 _UserComponentToLoad
.erase(found
);
2380 nlwarning("The server has refuse the client to load the a file"); //should (can) not happen
2381 this->systemMsg(0, "ERR", "", "The server has refuse the client to load the a file");
2385 std::string filename
;
2387 CUserComponentValidator::TValues values
;
2388 userComponentToLoad
->applyLoad(filename
, body
, values
);
2389 _LastReadHeader
= values
;
2394 /**************************************************************************************/
2396 void CClientEditionModule::saveScenarioFileAccepted(NLNET::IModuleProxy
*senderModuleProxy
, const std::string
& md5
, const std::string
& signature
, bool ok
)
2398 //H_AUTO(R2_CClientEditionModule_saveScenarioFileAccepted)
2400 TScenarioToSave::iterator
found(_ScenarioToSave
.find(md5
));
2401 if (found
== _ScenarioToSave
.end())
2403 nlwarning("The client has ask more than one time to save the same file");
2407 CUniquePtr
<CScenarioValidator
> scenarioToSave(found
->second
);
2408 _ScenarioToSave
.erase(found
);
2412 scenarioToSave
->applySave(signature
);
2416 systemMsg(senderModuleProxy
, "ERR", "", "uiR2EDServerRefuseToSave");
2421 bool CClientEditionModule::addToLoadList( const std::string
& filename
, CScenarioValidatorLoadSuccededCallback
* cb
)
2423 //H_AUTO(R2_CClientEditionModule_addToLoadList)
2424 CScenarioValidator
* sv
= new CScenarioValidator(cb
);
2425 CScenarioValidator::TValues values
;
2427 std::string signature
;
2429 ok
= sv
->setScenarioToLoad(filename
, values
, md5
, signature
, ClientCfg
.CheckR2ScenarioMD5
);
2430 if (!ok
){ return false; }
2432 if ( !_ScenarioToLoad
.insert( std::make_pair(md5
, sv
)).second
)
2434 nlwarning("Ask 2 time the load of the same scenario?"); //or the same empty scenario
2438 DROP_IF(_ServerEditionProxy
== NULL
, "Server Edition Module not connected", return false);
2440 CShareServerEditionItfProxy
serverEditionModule(_ServerEditionProxy
);
2441 serverEditionModule
.loadScenarioFile(this, md5
, signature
);
2446 void CClientEditionModule::loadScenarioSucceded(const std::string
& filename
, const std::string
& body
, const CScenarioValidator::TValues
& values
)
2448 //H_AUTO(R2_CClientEditionModule_loadScenarioSucceded)
2449 string initialIsland
, initialEntryPoint
, initialSeason
;
2450 string creatorMD5
, modifiedByMD5
;
2453 for(uint i
=0; i
<values
.size(); i
++)
2455 const std::pair
<std::string
, std::string
>& pair
= values
[i
];
2456 if(pair
.first
== "InitialIsland") initialIsland
= pair
.second
;
2457 else if(pair
.first
== "InitialEntryPoint") initialEntryPoint
= pair
.second
;
2458 else if(pair
.first
== "InitialSeason") initialSeason
= pair
.second
;
2459 else if(pair
.first
== "OwnerMd5") initialSeason
= pair
.second
;
2460 else if(pair
.first
== "CreatorMD5") creatorMD5
= pair
.second
;
2461 else if(pair
.first
== "OtherCharAccess") locked
= pair
.second
;
2462 else if(pair
.first
== "ModifierMD5") modifiedByMD5
= pair
.second
;
2463 else if(pair
.first
== "Name") name
= pair
.second
;
2468 if (!modifiedByMD5
.empty() && !locked
.empty() && locked
== "RunOnly")
2470 bool ok
= hasCharacterSameCharacterIdMd5(modifiedByMD5
);
2473 this->systemMsg(0, "ERR", "", "uiR2EDLoadingLockedScenario");
2478 R2::getEditor().getUI().displaySystemInfo(CI18N::get("uiR2EDLoadingScenario"), "BC");
2479 CObject
* object
= _Client
->getComLuaModule().loadFromBuffer(body
, filename
, values
);
2480 _LastReadHeader
= values
;
2483 if (!initialIsland
.empty() && !initialEntryPoint
.empty() && !initialSeason
.empty())
2485 // CShareServerEditionItfProxy serverEditionModule(_ServerEditionProxy);
2486 // serverEditionModule.teleportWhileUploadingScenario(this, initialIsland, initialEntryPoint, initialSeason);
2487 R2::getEditor().clearContent();
2489 _Client
->requestUploadScenario(object
);
2490 if (!name
.empty() && object
&& object
->isTable() && object
->isString("InstanceId"))
2492 CObjectString
objectName(name
);
2493 _Client
->requestSetNode(object
->toString("InstanceId"), "Ghost_Name", &objectName
);
2497 if (CFile::fileExists(filename
))
2499 CFile::copyFile("save/r2_buffer.dat", filename
);
2504 void CClientEditionModule::loadAnimationSucceded(const std::string
& filename
, const std::string
& body
, const CScenarioValidator::TValues
& values
)
2506 //H_AUTO(R2_CClientEditionModule_loadAnimationSucceded)
2508 _Client
->loadAnimationFromBuffer(body
, filename
, errMsg
, values
);
2511 void CClientEditionModule::loadScenarioFileAccepted(NLNET::IModuleProxy
* /* senderModuleProxy */, const std::string
& md5
, bool ok
)
2513 //H_AUTO(R2_CClientEditionModule_loadScenarioFileAccepted)
2515 TScenarioToLoad::iterator
found(_ScenarioToLoad
.find(md5
));
2516 if (found
== _ScenarioToLoad
.end())
2518 nlwarning("The client has ask more than one time to save the same file");
2522 CUniquePtr
<CScenarioValidator
> scenarioToLoad(found
->second
);
2523 _ScenarioToLoad
.erase(found
);
2527 nlwarning("The server has refuse the client to load the a file"); //should (can) not append
2528 this->systemMsg(0, "ERR", "", "The server has refuse the client to load the a file");
2532 std::string filename
;
2534 CScenarioValidator::TValues values
;
2535 scenarioToLoad
->applyLoad(filename
, body
, values
);
2536 _LastReadHeader
= values
;
2540 void CClientEditionModule::setMute(bool mute
)
2542 //H_AUTO(R2_CClientEditionModule_setMute)
2546 void CLoadUserComponentSucceeded::doOperation(const std::string
& filename
,const std::string
& body
,const CScenarioValidator::TValues
& header
)
2548 CLuaState
& state
= R2::getEditor().getLua();
2549 state
.push((std::string
)filename
);
2550 state
.push((std::string
)body
);
2553 CClientEditionModule::TScenarioHeader::const_iterator
first(header
.begin()), last(header
.end());
2555 for ( ; first
!= last
; ++first
)
2558 state
.push(first
->first
);
2559 state
.push(first
->second
);
2563 //R2::getEditor().getLua().push((bool)mustKick);
2564 R2::getEditor().callEnvFunc( "loadUserComponentCallback", 3, 0);
2569 void CLoadAnimationSucceded::doOperation(const std::string
& filename
,const std::string
& body
,const CScenarioValidator::TValues
& values
)
2571 //H_AUTO(R2_CLoadAnimationSucceded_doOperation)
2572 _Module
->loadAnimationSucceded(filename
, body
, values
);
2575 void CLoadScenarioSucceded::doOperation(const std::string
& filename
,const std::string
& body
,const CScenarioValidator::TValues
& values
)
2577 //H_AUTO(R2_CLoadScenarioSucceded_doOperation)
2578 _Module
->loadScenarioSucceded(filename
, body
, values
);
2582 void CClientEditionModule::resetNameGiver()
2584 //H_AUTO(R2_CClientEditionModule_resetNameGiver)
2588 bool CClientEditionModule::hasCharacterSameCharacterIdMd5(const std::string
& charIdMd5
) const
2590 if (ClientCfg
.Local
== 1 )
2596 uint32 first
=0,last
=(uint32
)charIdMd5
.size();
2597 for (;first
!= last
; ++first
)
2601 char c
= charIdMd5
[first
];
2602 if ('0' <= c
&& c
<= '9')
2606 else if ('A' <= c
&& c
<= 'F')
2611 uint32 charId
= CRingAccess::uncypherCharId(val
);
2613 uint32 myUserId
= NetMngr
.getUserId();
2614 if ((charId
>>4) != myUserId
)
2622 class CModuleMessageSender
: public R2::IMessageSender
2625 CModuleMessageSender(const NLNET::TModuleProxyPtr
& proxy
, NLNET::IModule
* senderModule
):_Proxy(proxy
), _Sender(senderModule
){}
2627 void operator()(const NLNET::CMessage
& msg
)
2631 nlwarning("Can not send Message %s to destination", msg
.getName().c_str());
2635 // Send msg to DSS (after cuting msg)
2636 if (ClientCfg
.R2EDDssNetwork
== 1)
2638 _Proxy
->sendModuleMessage(_Sender
, msg
);
2643 if (ClientCfg
.Local
)
2649 charId
= CSessionBrowserImpl::getCharId();
2653 // Send msg to DSS (Simulate forward system)
2654 if (ClientCfg
.R2EDDssNetwork
== 2)
2657 NLNET::CMessage handle
;
2658 R2::CShareServerEditionItfProxy::buildMessageFor_forwardToDss(handle
, charId
, msg
);
2659 _Proxy
->sendModuleMessage(_Sender
, handle
);
2664 // Send msg to DSS (Simulate forward system)
2665 if (ClientCfg
.R2EDDssNetwork
== 3)
2668 NLNET::CMessage handle
;
2669 R2::CShareServerEditionItfProxy::buildMessageFor_forwardToDss(handle
, charId
, msg
);
2670 CSessionBrowserImpl::getInstance().send(handle
);
2674 nlwarning("Error Msg lost");
2678 NLNET::TModuleProxyPtr _Proxy
;
2679 NLNET::IModule
* _Sender
;
2683 void CClientEditionModule::sendMsgToDss(const NLNET::CMessage
& msg
)
2687 if (ClientCfg
.Local
)
2693 charId
= CSessionBrowserImpl::getCharId();
2695 // Direct send msg to DSS (not cut)
2696 if (ClientCfg
.R2EDDssNetwork
== 0)
2698 _ServerEditionProxy
->sendModuleMessage(this, msg
);
2702 CModuleMessageSender
sender(_ServerEditionProxy
, this);
2703 CMessageSpliter::sendSplitedMsg(charId
, msg
, sender
);
2707 //----------------------------------------------------------------------------------------------------------------
2713 void CMessageSpliter::sendSplitedMsg(uint32 charId
, const NLNET::CMessage
& msg
, IMessageSender
& sender
)
2716 static const uint32 packetSize
= 512; // 16K by packet
2717 uint32 size
= msg
.length();
2718 uint32 nbPacket
= 1 + (size
-1) / packetSize
;
2720 // :TODO: use the brodcast form of the message instead of manual message
2723 nldebug("Sending DSS message");
2727 NLNET::CMessage subMsg
;
2728 R2::CShareServerEditionItfProxy::buildMessageFor_multiPartMsgHead(subMsg
, charId
, msg
.getName(), nbPacket
, size
);
2736 const uint8
* buffer
= msg
.buffer();
2740 for (; i
!= nbPacket
; ++i
)
2744 // send packetSize octet except for the last packet that just send the remainings data
2745 uint32 dataSend
= (i
+1)*packetSize
> size
? size
- packetSize
*i
:packetSize
;
2747 std::vector
<uint8
> data(const_cast<uint8
*>(&buffer
[i
*packetSize
]), const_cast<uint8
*>(&buffer
[i
*packetSize
+ dataSend
]) );
2748 NLNET::CMessage subMsg
;
2749 R2::CShareServerEditionItfProxy::buildMessageFor_multiPartMsgBody(subMsg
, charId
, i
, data
);
2754 // TODO -> add callback send( (size - packetSize*i) / size)
2759 NLNET::CMessage subMsg
;
2760 R2::CShareServerEditionItfProxy::buildMessageFor_multiPartMsgFoot(subMsg
, charId
);
2767 // Messages from dss that notify that he has received data
2768 // We received first a multiPartMsgHead, then X multiPartMsgBody, then one multiPartMsgFoot
2769 void CClientEditionModule::multiPartMsgHead(NLNET::IModuleProxy
* /* sender */, const std::string
& msgName
, uint32 nbPacket
, uint32 size
)
2771 R2::getEditor().getLua().executeScriptNoThrow( NLMISC::toString("r2:onMessageSendingStart('%s', %u, %u)",msgName
.c_str(), nbPacket
, size
) );
2774 void CClientEditionModule::multiPartMsgBody(NLNET::IModuleProxy
* /* sender */, uint32 packetId
, uint32 packetSize
)
2776 R2::getEditor().getLua().executeScriptNoThrow( NLMISC::toString("r2:onMessageSendingUpdate(%u, %u)", packetId
, packetSize
));
2779 void CClientEditionModule::multiPartMsgFoot(NLNET::IModuleProxy
* /* sender */)
2781 R2::getEditor().getLua().executeScriptNoThrow( NLMISC::toString("r2:onMessageSendingFinish()"));