/* Pack an action to a bit stream. Set transmitTimestamp=true for server-->client, * false for client-->server. If true, set the current gamecycle. */ void CActionFactory::pack (CAction *action, NLMISC::CBitMemStream &message, NLMISC::TGameCycle /* currentCycle */ ) { //H_BEFORE(FactoryPack); //sint32 val = message.getPosInBit (); // if (action->Code < 4) { // short code (0 1 2 3) bool shortcode = true; uint32 code = action->Code; message.serialAndLog1 (shortcode); message.serialAndLog2 (code, 2); } else { bool shortcode = false; message.serialAndLog1 (shortcode); message.serialAndLog1 (action->Code); } action->pack (message); //H_AFTER(FactoryPack); //OLIV: nlassertex (message.getPosInBit () - val == (sint32)CActionFactory::getInstance()->size (action), ("CActionFactory::pack () : action %d packed %u bits, should be %u, size() is wrong", action->Code, message.getPosInBit () - val, CActionFactory::getInstance()->size (action))); // nlinfo ("ac:%p pack one action in message %d %hu %u %d", action, action->Code, (uint16)(action->CLEntityId), val, message.getPosInBit()-val); }
// *************************************************************************** void CClientChatManager::processTellString(NLMISC::CBitMemStream& bms, IChatDisplayer &chatDisplayer) { CChatMsg chatMsg; // Serial. For tell message, there is no chat mode, coz we know we are in tell mode ! bms.serial (chatMsg.CompressedIndex); bms.serial (chatMsg.SenderNameId); bms.serial (chatMsg.Content); if (PermanentlyBanned) return; chatMsg.ChatMode = (uint8) CChatGroup::tell; // If !complete, wait ucstring senderStr; bool complete = true; complete &= STRING_MANAGER::CStringManagerClient::instance()->getString(chatMsg.SenderNameId, senderStr); if (!complete) { _ChatBuffer.push_back(CChatMsgNode(chatMsg, true)); nldebug("<impulseTell> Received TELL, put in buffer : waiting association"); return; } // display ucstring ucstr; buildTellSentence(senderStr, chatMsg.Content, ucstr); chatDisplayer.displayTell(/*chatMsg.CompressedIndex, */ucstr, senderStr); }
/* * Push one change to the stream (permanent mode) */ void CCDBSynchronised::pushDeltaPermanent( NLMISC::CBitMemStream& s, CCDBStructNodeLeaf *node, uint32& bitsize ) { TCDBDataIndex index = node->getDataIndex(); // Test if the property type is valid. if ( node->type() > ICDBStructNode::UNKNOWN && node->type() < ICDBStructNode::Nb_Prop_Type ) { // Serialize the Property Value according to the Property Type. uint64 value; value = (uint64)_DataContainer.getValue64( index ); // "delta from 0" if ( node->type() == ICDBStructNode::TEXT ) { s.serialAndLog2( value, 32 ); bitsize += 32; if ( VerboseDatabase ) nldebug( "CDB: Pushing permanent value %"NL_I64"d (TEXT-32) for index %d prop %s", (sint64)value, index, node->buildTextId().toString().c_str() ); } else { s.serialAndLog2( value, (uint)node->type() ); bitsize += (uint32)node->type(); if ( VerboseDatabase ) nldebug( "CDB: Pushing permanent value %"NL_I64"d (%u bits) for index %d prop %s", (sint64)value, (uint32)node->type(), index, node->buildTextId().toString().c_str() ); } } else nlwarning("CCDBStructNodeLeaf::writeDeltaPermanent : Property Type Unknown ('%d') -> not serialized.", (uint)node->type()); }
// *************************************************************************** void CClientChatManager::processTellString2(NLMISC::CBitMemStream& bms, IChatDisplayer &chatDisplayer) { // serial CChatMsg2 chatMsg; chatMsg.ChatMode = CChatGroup::tell; bms.serial(chatMsg.CompressedIndex); bms.serial(chatMsg.SenderNameId); bms.serial(chatMsg.PhraseId); // if !complete, wait ucstring senderStr; ucstring rawMessage; bool complete = true; complete &= STRING_MANAGER::CStringManagerClient::instance()->getString(chatMsg.SenderNameId, senderStr); complete &= STRING_MANAGER::CStringManagerClient::instance()->getDynString(chatMsg.PhraseId, rawMessage); if (!complete) { _ChatBuffer.push_back(CChatMsgNode(chatMsg, true)); nldebug("<impulseTell> Received TELL, put in buffer : waiting association"); return; } // display ucstring ucstr; buildTellSentence(senderStr, rawMessage, ucstr); chatDisplayer.displayTell(/*chatMsg.CompressedIndex, */ucstr, senderStr); }
// *************************************************************************************** void CBotChatPageDynamicMission::sendChoices() { uint k; #ifdef NL_DEBUG for(k = 0; k < DYNAMIC_MISSION_NUM_CHOICES; ++k) { nlassert(_Choice[k] != -1); } #endif NLMISC::CBitMemStream out; static const char *msgName = "BOTCHAT:DM_CHOICE"; if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) { for(k = 0; k < DYNAMIC_MISSION_NUM_CHOICES; ++k) { uint8 u8Choice = (uint8) _Choice[k]; out.serial(u8Choice); } NetMngr.push(out); } else { nlwarning(" unknown message name %s", msgName); } }
// *************************************************************************************** void CBotChatPageMission::acceptMission() { if (!_CurrSel) return; sint index = _CurrSel->getIndexInParent(); if (index < 0) return; // send msg to server NLMISC::CBitMemStream out; static const char *msgName; if(_MType==MISSION_DESC::ZCCharge) msgName= "BOTCHAT:DUTY_APPLY"; else msgName= "BOTCHAT:PICK_MISSION"; if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) { uint8 missionIndex = (uint8) index; out.serial(missionIndex); NetMngr.push(out); } else { nlwarning(" unknown message name %s", msgName); } // close the selection box activateWindow(WIN_BOT_CHAT_ACCEPT_MISSION, false); // close the botchat CBotChatManager::getInstance()->setCurrPage(NULL); _CurrSel = NULL; }
virtual void execute (CCtrlBase * /* pCaller */, const string &Params) { CInterfaceManager *pIM = CInterfaceManager::getInstance(); string guildNameWin = getParam(Params, "guild"); string IconWin = getParam(Params, "icon"); string guildDescWin = getParam(Params, "desc"); CGroupEditBox *pGEB = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(guildNameWin)); if (pGEB == NULL) return; CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getElementFromId(IconWin)); if (pCS == NULL) return; CGroupEditBox *pDesc = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(guildDescWin)); ucstring guildName = pGEB->getInputString(); ucstring guildDesc; if (pDesc != NULL) guildDesc = pDesc->getInputString(); uint64 icon = CGuildManager::iconMake((uint8)pCS->getGuildBack(), (uint8)pCS->getGuildSymbol(), pCS->getInvertGuildSymbol(), pCS->getGuildColor1(), pCS->getGuildColor2()); const string msgName = "GUILD:CREATE"; NLMISC::CBitMemStream out; if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) { out.serial( guildName ); out.serial( icon ); out.serial( guildDesc ); NetMngr.push(out); } //CBotChatManager::getInstance()->setCurrPage(NULL); }
// *************************************************************************** void CClientChatManager::processChatString2(NLMISC::CBitMemStream& bms, IChatDisplayer &chatDisplayer) { CChatMsg2 chatMsg; bms.serial( chatMsg ); if (PermanentlyBanned) return; CChatGroup::TGroupType type = static_cast<CChatGroup::TGroupType>(chatMsg.ChatMode); ucstring senderStr; ucstring rawMessage; // here, the type cannot be dyn_chat (no DynChatId in the message) => discard if(type==CChatGroup::dyn_chat) { nlwarning("Client don't support dyn_chat with CChatMsg2 messages => '%x' aborted", chatMsg.PhraseId); return; } // if !complete, wait bool complete = true; complete &= STRING_MANAGER::CStringManagerClient::instance()->getString(chatMsg.SenderNameId, senderStr); complete &= STRING_MANAGER::CStringManagerClient::instance()->getDynString(chatMsg.PhraseId, rawMessage); if (!complete) { _ChatBuffer.push_back(CChatMsgNode(chatMsg, false)); //nldebug("<impulseChat> Received CHAT, put in buffer : waiting association"); return; } rawMessage += ucstring(" "); rawMessage += chatMsg.CustomTxt; // display ucstring ucstr; buildChatSentence(chatMsg.CompressedIndex, senderStr, rawMessage, type, ucstr); chatDisplayer.displayChat(chatMsg.CompressedIndex, ucstr, rawMessage, type, CEntityId::Unknown, senderStr); }
// *************************************************************************** void CClientChatManager::processChatStringWithNoSender( NLMISC::CBitMemStream& bms, CChatGroup::TGroupType type, IChatDisplayer &chatDisplayer) { nlassert(type!=CChatGroup::dyn_chat); // serial CChatMsg2 chatMsg; uint32 phraseID; bms.serial(phraseID); if (PermanentlyBanned) return; chatMsg.CompressedIndex = INVALID_DATASET_INDEX; chatMsg.SenderNameId = 0; chatMsg.ChatMode = type; chatMsg.PhraseId = phraseID; ucstring ucstr; // if !complete, wait bool complete = STRING_MANAGER::CStringManagerClient::instance()->getDynString(chatMsg.PhraseId, ucstr); if (!complete) { _ChatBuffer.push_back(CChatMsgNode(chatMsg, false)); //nldebug("<impulseDynString> Received CHAT, put in buffer : waiting association"); return; } // diplay ucstring senderName(""); chatDisplayer.displayChat(INVALID_DATASET_INDEX, ucstr, ucstr, type, CEntityId::Unknown, senderName); }
void fillBitMemStream( const CCharacterInfos *charInfo, CStringManager::TLanguages language, const CStringManager::TReplacement &rep, NLMISC::CBitMemStream &bms) { uint32 eventFactionId = SM->translateEventFaction(Identifier); // serial the string ID bms.serial(eventFactionId); }
void CStringManager::CParameterTraits::fillBitMemStream( const CCharacterInfos *charInfo,TLanguages language, const TReplacement &rep, NLMISC::CBitMemStream &bms) { const CStringManager::CEntityWords &ew = SM->getEntityWords(language, ParamId.Type); std::string rowName = NLMISC::strlwr(getParameterId()); uint32 stringId; stringId = ew.getStringId(rowName, rep.Format); bms.serial(stringId); }
/* * Write the id to a bit stream for server-client comms, and return the size of data written */ inline sint ICDBStructNode::CBinId::writeToBitMemStream( NLMISC::CBitMemStream& f ) const { sint bitsize = 0; for ( uint i=0; i<Ids.size(); i++ ) { uint32& nodeIndex = const_cast<uint32&>(Ids[i].first); f.serialAndLog2( nodeIndex, Ids[i].second ); bitsize += Ids[i].second; } return bitsize; }
/* Unpack some actions from a bit stream. Set transmitTimestamp=true for server-->client, * false for client-->server. If true, set the current gamecycle. */ void CActionFactory::unpack (NLMISC::CBitMemStream &message, std::vector <CAction *>& actions, NLMISC::TGameCycle /* currentCycle */ ) { actions.clear (); static int n = 0; n++; while ((sint32)message.length() * 8 - message.getPosInBit () >= 8) { TActionCode code; bool shortcode; message.serial (shortcode); if (shortcode) { code = 0; uint32 val; message.serial (val, 2); code = (TActionCode) val; } else { message.serial (code); } CAction *action = create (INVALID_SLOT, code); //nlinfo ("m%d size: p:%d s:%d c:%d (actionsize: %d) slot:%hu", n, message.getPosInBit (), message.length() * 8, code, action->size(), (uint16)action->CLEntityId); if (action == NULL) { nlwarning ("Unpacking an action with unknown code, skip it (%u)", code); } else { action->unpack (message); actions.push_back (action); } } }
void fillBitMemStream( const CCharacterInfos *charInfo, CStringManager::TLanguages language, const CStringManager::TReplacement &rep, NLMISC::CBitMemStream &bms) { uint32 nameId1 = SM->storeString(Identifier); uint32 nameId2 = SM->translateShortName(nameId1); const ucstring &name = SM->getString(nameId2); if (!name.empty() && name[0] == '$') { // this name is a generic name, translate the title ucstring title = name.substr(1, name.size()-2); nameId2 = SM->translateTitle(title.toString(), language); } // serial the string ID bms.serial(nameId2); }
void fillBitMemStream( const CCharacterInfos *charInfo,CStringManager::TLanguages language, const CStringManager::TReplacement &rep, NLMISC::CBitMemStream &bms) { // need to evaluate the name of the bot : should be in the charinfo ucstring temp; CCharacterInfos *botInfo = IOS->getCharInfos(EId); if (botInfo != 0) { if (!botInfo->ShortName.empty()) { uint32 index = botInfo->ShortNameIndex; bms.serial(index); return; } if (!botInfo->Title.empty()) { uint32 index = SM->translateTitle(botInfo->Title, language); bms.serial(index); return; } } // hum, no name available CParameterTraitsEntity::fillBitMemStream(charInfo, language, rep, bms); }
void fillBitMemStream( const CCharacterInfos *charInfo,CStringManager::TLanguages language, const CStringManager::TReplacement &rep, NLMISC::CBitMemStream &bms) { ucstring temp; CCharacterInfos *playerInfo = IOS->getCharInfos(EId); if (playerInfo != 0) { if (!playerInfo->ShortName.empty()) { uint32 index = playerInfo->ShortNameIndex; bms.serial(index); return; } } // hum, no name available CParameterTraitsEntity::fillBitMemStream(charInfo,language, rep, bms); }
/// fill overloaded to deals with ring user defined item with custom names void fillBitMemStream( const CCharacterInfos *charInfo, CStringManager::TLanguages language, const CStringManager::TReplacement &rep, NLMISC::CBitMemStream &bms) { // check if SheetId if in the table or user item const CStringManager::TRingUserItemInfos &itemInfos = SM->getUserItems(); CStringManager::TRingUserItemInfos::const_iterator it(itemInfos.find(SheetId)); if (it != itemInfos.end() && !it->second.empty()) { // this item has some user name, check the aiInstance const vector<CStringManager::TRingUserItemInfo> &userItemInfos = it->second; for (uint i=0; i<userItemInfos.size(); ++i) { if (userItemInfos[i].AIInstance == charInfo->AIInstance) { // ok, this item is renamed ! // use the user name for a list a predefined column : // name, named, nameda, p, pd if ( rep.Format == "name" || rep.Format == "named" || rep.Format == "nameda" || rep.Format == "p" || rep.Format == "pd") { nlWrite(bms, serial, userItemInfos[i].ItemNameId); } else { // not a valid replacement, return a 'backspace' character static uint32 noString = SM->storeString(ucstring()+ucchar(8)); bms.serial(noString); } /// return here --------------------- return; } } } // normal item name, use the base function instead CParameterTraitsSheet::fillBitMemStream( charInfo, language, rep, bms); }
// *************************************************************************** void CClientChatManager::processChatString( NLMISC::CBitMemStream& bms, IChatDisplayer &chatDisplayer) { // before displaying anything, must ensure dynamic channels are up to date // NB: only processChatString() have to do this. Other methods cannot be in dyn_chat mode updateDynamicChatChannels(chatDisplayer); // serial CChatMsg chatMsg; bms.serial( chatMsg ); CChatGroup::TGroupType type = static_cast<CChatGroup::TGroupType>(chatMsg.ChatMode); ucstring senderStr; bool complete = true; complete &= STRING_MANAGER::CStringManagerClient::instance()->getString(chatMsg.SenderNameId, senderStr); if (type == CChatGroup::dyn_chat) { // retrieve the DBIndex from the dynamic chat id sint32 dbIndex = ChatMngr.getDynamicChannelDbIndexFromId(chatMsg.DynChatChanID); // if the client database is not yet up to date, put the chat message in buffer if (dbIndex < 0) complete = false; } // if !complete, wait if (!complete) { _ChatBuffer.push_back(CChatMsgNode(chatMsg, false)); //nldebug("<impulseChat> Received CHAT, put in buffer : waiting association"); return; } // display ucstring ucstr; buildChatSentence(chatMsg.CompressedIndex, senderStr, chatMsg.Content, type, ucstr); chatDisplayer.displayChat(chatMsg.CompressedIndex, ucstr, chatMsg.Content, type, chatMsg.DynChatChanID, senderStr); }
void fillBitMemStream( const CCharacterInfos *charInfo,CStringManager::TLanguages language, const CStringManager::TReplacement &rep, NLMISC::CBitMemStream &bms) { if ( EId == CEntityId::Unknown && _AIAlias != 0) { CAIAliasManager& aiAliasMgr = IOS->getAIAliasManager(); if (aiAliasMgr.is(_AIAlias)) { static const string NAME("name"); CSString format = rep.Format; if (format.left(4) != NAME) { // can't replace this parameter, write a del char const static string s("\010"); uint32 index = SM->storeString(s); bms.serial(index); return; } else { uint32 index ; index = aiAliasMgr.getShortNameIndex(_AIAlias); if (index) { bms.serial(index); return; } index = aiAliasMgr.getTitleIndex(_AIAlias, language); if (index) { bms.serial(index); return; } } // No translated title or translated phrase found send '' // ucstring temp(EId.toString()); const ucstring NoName("''"); uint32 index = SM->storeString(NoName); bms.serial(index); return; } } if (EId.getType() == RYZOMID::player || EId.getType() == RYZOMID::npc) { CCharacterInfos *playerInfo = IOS->getCharInfos(EId); if (playerInfo != 0) { static const string NAME("name"); CSString format = rep.Format; if (format.left(4) != NAME) { // can't replace this parameter, write a del char const static string s("\010"); uint32 index = SM->storeString(s); bms.serial(index); return; } else { if (!playerInfo->ShortName.empty()) { uint32 index = playerInfo->ShortNameIndex; bms.serial(index); return; } if (!playerInfo->Title.empty()) { uint32 index = SM->translateTitle(playerInfo->Title, language); // we must match this index against the function table bms.serial(index); return; } } } } // special case fauna entity or unnamed npc (i.e. npc not registered with a character name, like fauna in npc state machine) if (EId.getType() == RYZOMID::creature || EId.getType() == RYZOMID::npc) { // a big FAKE STRING_MANAGER::TParamType realType = ParamId.Type; ParamId.Type = STRING_MANAGER::creature; CParameterTraits::fillBitMemStream(charInfo, language, rep, bms); // restore normal type ParamId.Type = realType; return; } // no info on the name, just send the EID as string. // ucstring temp(EId.toString()); const ucstring NoName("''"); uint32 index = SM->storeString(NoName); bms.serial(index); }
/// Fill a bitmem strean with the parameter value. virtual void fillBitMemStream( const CCharacterInfos *charInfo, CStringManager::TLanguages language, const CStringManager::TReplacement &rep, NLMISC::CBitMemStream &bms) { uint32 id = SM->storeString(Literal); bms.serial(id); }
void fillBitMemStream( const CCharacterInfos *charInfo,CStringManager::TLanguages language, const CStringManager::TReplacement &rep, NLMISC::CBitMemStream &bms) { bms.serial(StringId); }
void fillBitMemStream( const CCharacterInfos *charInfo,CStringManager::TLanguages language, const CStringManager::TReplacement &rep, NLMISC::CBitMemStream &bms) { // TODO : serial only 48 bits bms.serial(Money); }
//----------------------------------------------- // writePermanentDelta // // TODO: Maybe an optimization will be required to prevent sending null properties // when a character is added to a CCDBGroup. //----------------------------------------------- bool CCDBSynchronised::writePermanentDelta( NLMISC::CBitMemStream& s ) { static uint nbPermaDeltaSent = 0; // Test the changed property count and make room to store the number of property pushed (poked later) uint origChangedPropertyCount = _DataContainer.getPermanentChangedPropertyCount(); if ( origChangedPropertyCount == 0 ) return false; uint bitposOfNbChanges = s.getPosInBit(); uint32 dummy = 0; s.serial( dummy, CDBChangedPropertyCountBitSize ); // optimising s.reserveBits( CDBChangedPropertyCountBitSize ) // Browse changes and write them uint32 nbChanges = 0; uint32 bitsize = CDBChangedPropertyCountBitSize; // initialize with the size of the reserved bits for the number of changes TCDBDataIndex dataIndex = _DataContainer.getPermanentFirstChanged(); while ( dataIndex != CDB_LAST_CHANGED /*&& (bitsize < maxBitSize)*/ ) { ++nbPermaDeltaSent; // Retrieve the structure node corresponding to the index ICDBStructNode *node = CCDBStructBanks::instance()->getNodeFromDataIndex( _Bank, dataIndex ); nlassert( node ); if ( node->isAtomic() ) // counts for 1 change { #ifdef NL_DEBUG nlassert( dynamic_cast<CCDBStructNodeBranch*>(node) ); // should not be leaf because the main tracker pushes the atom group index for atomic leaves #endif // Build and push the binary atom id ICDBStructNode::CBinId binId; (static_cast<CCDBStructNodeBranch*>(node))->buildBinIdFromLeaf( binId ); bitsize += binId.writeToBitMemStream( s ); //nlinfo( "CDB/ATOM: Written bin id %s", binId.toString().c_str() ); //_DataContainer.displayAtomChanges( node->getDataIndex() ); // Make room to store the atom bitfield uint bitposOfAtomBitfield = s.getPosInBit(); uint indexInAtom = 0; node->foreachLeafCall( cbNop, indexInAtom, NULL ); // count the number of siblings uint nbAtomElements = indexInAtom; s.reserveBits( nbAtomElements ); bitsize += nbAtomElements; //nlinfo( "CDB/ATOM: Reserved %u bits (%d)", nbAtomElements, s.getPosInBit()-bitposOfAtomBitfield ); // Browse the siblings of the atom node, and push the deltas for the properties marked as changes, updating the bitfield TPushAtomChangeStruct arg; arg.CdbSync = this; arg.BitSize = &bitsize; arg.S = &s; arg.AtomBitfield.resize( nbAtomElements ); indexInAtom = 0; node->foreachLeafCall( cbPushDeltaOfLeafInAtomIfChangedPermanent, indexInAtom, (void*)&arg ); // Fill the placeholder with the bitfield s.pokeBits( arg.AtomBitfield, bitposOfAtomBitfield ); if ( VerboseDatabase ) { nldebug( "CDB/ATOM: Bitfield: %s", arg.AtomBitfield.toString().c_str() ); } } else { #ifdef NL_DEBUG nlassert( dynamic_cast<CCDBStructNodeLeaf*>(node) ); #endif // Push the binary property id bitsize += static_cast<CCDBStructNodeLeaf*>(node)->binLeafId().writeToBitMemStream( s ); // Push the value pushDeltaPermanent( s, static_cast<CCDBStructNodeLeaf*>(node), bitsize ); } dataIndex = _DataContainer.getPermanentNextChanged( dataIndex ); ++nbChanges; } // Fill the placeholder with the number of changes s.poke( nbChanges, bitposOfNbChanges, CDBChangedPropertyCountBitSize ); //s.displayStream( "writeDelta" ); #ifdef TRACE_SET_VALUE if ( VerboseDatabase ) nldebug( "%u: CDB: Permanent Delta pushed (%u changes written, %u remaining)", CTickEventHandler::getGameCycle(), nbChanges, getChangedPropertyCount() ); #endif nldebug( "Filled %u permanent changes", nbPermaDeltaSent ); return true; }