diff --git a/ryzom/server/src/entities_game_service/admin.cpp b/ryzom/server/src/entities_game_service/admin.cpp index faf29ecf4..69a3941be 100644 --- a/ryzom/server/src/entities_game_service/admin.cpp +++ b/ryzom/server/src/entities_game_service/admin.cpp @@ -449,7 +449,7 @@ bool checkBannerPriv(const string &sheetName, CEntityId eid) // Not a banner return true; } - + CPlayer* player = PlayerManager.getPlayer( PlayerManager.getPlayerId(eid) ); if (player == NULL) @@ -483,28 +483,28 @@ bool checkBannerPriv(const string &sheetName, CEntityId eid) return true; } // VG uses SG banner for now - if (player->havePriv(":VG:")) + if (player->havePriv(":VG:")) { return true; } } else if (sheetName.find("_vgu") != string::npos) { - if (player->havePriv(":VG:")) + if (player->havePriv(":VG:")) { return true; } } else if (sheetName.find("_gm") != string::npos) { - if (player->havePriv(":GM:")) + if (player->havePriv(":GM:")) { return true; } } else if (sheetName.find("_sgm") != string::npos) { - if (player->havePriv(":SGM:")) + if (player->havePriv(":SGM:")) { return true; } @@ -698,7 +698,7 @@ string getStringFromHash(const string &hash) { ucstring finaltext; getUCstringFromHash(hash, finaltext); - + return finaltext.toUtf8(); } @@ -721,7 +721,7 @@ void getUCstringFromHash(const string &hash, ucstring &finaltext) // Unexpected string format break; } - + finaltext.push_back((ucchar)ch); } } @@ -4579,9 +4579,12 @@ NLMISC_COMMAND (connectLangChannel, "Connect to lang channel", " string action; string lang = args[1]; - if (lang != "en" && lang != "fr" && lang != "de" && lang != "ru" && lang != "es" && lang != "rf") + if (lang != "en" && lang != "fr" && lang != "de" && lang != "ru" && lang != "es" && lang != "rf" + && lang != "rf-en" && lang != "rf-fr" && lang != "rf-de" && lang != "rf-ru" && lang != "rf-es") return false; - bool leave = false; + + bool leave = !c->havePriv(":DEV:"); // Since June 2020, no any lang channels, players only can leave it + if (args.size() > 2) leave = args[2] == "1"; TChanID channel = inst->getFactionDynChannel(lang); @@ -4613,7 +4616,7 @@ NLMISC_COMMAND (connectLangChannel, "Connect to lang channel", " NLMISC_COMMAND (setDontTranslateLangs, "Set langs that a player dont want to see translated", " ") { - if (args.size() != 2) + if (args.size() != 2) return false; GET_CHARACTER @@ -4875,7 +4878,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getSheetId() == sheetId) ) { - if (itemPtr->quality() == quality) + if (itemPtr->quality() == quality) numberEqualItem += itemPtr->getStackSize(); if (itemPtr->quality() >= quality) numberItem += itemPtr->getStackSize(); @@ -5090,7 +5093,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getId(), factionIndex, fame-value, false); - nlinfo("fame : %d => %d", fame, fame-value); + nlinfo("fame : %d => %d", fame, fame-value); } else if (command_args[2] == "set") { @@ -5133,12 +5136,12 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getTarget(); - + if (command_args.size () < 2) return false; if (command_args[1] == "leaguemate") @@ -5189,7 +5192,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " 7) { - + if (command_args[6] != "*") { float userX; NLMISC::fromString(command_args[6], userX); @@ -5491,7 +5494,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " 10) { @@ -5502,7 +5505,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " isSpawnValid(inVillage, inOutpost, inStable, inAtys)) return false; } @@ -5543,14 +5546,14 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getInstanceNumber(); + uint32 instanceNumber = c->getInstanceNumber(); uint32 nbString = (uint32)command_args.size(); - + // See if it needs another AI instance string botsName = command_args[1]; if ( ! getAIInstanceFromGroupName(botsName, instanceNumber)) @@ -5645,15 +5648,15 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getHomeMainlandSessionId(), command_args[1])); string name = command_args[2]; - + uint32 value; fromString(command_args[3], value); @@ -5854,12 +5857,12 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " 3) { - bool pvpFlagValid = (c->getPvPRecentActionFlag() == false || c->getPVPFlag() == false); + bool pvpFlagValid = (c->getPvPRecentActionFlag() == false || c->getPVPFlag() == false); if (command_args[3][0] == '1' && !pvpFlagValid) { CCharacter::sendDynamicSystemMessage(c->getEntityRowId(), "PVP_TP_FORBIDEN"); return true; } - + bool pvpTagValid = c->getPVPFlag() == false; if (command_args[3].length() > 1 && command_args[3][1] == '1' && !pvpTagValid) { @@ -5884,7 +5887,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " res; sint32 x = 0, y = 0, z = 0; float h = 0; @@ -6003,7 +6006,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " allowNearPetTp(); else - c->forbidNearPetTp(); + c->forbidNearPetTp(); // Respawn player if dead if (c->isDead()) @@ -6070,7 +6073,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " allowNearPetTp(); else - c->forbidNearPetTp(); + c->forbidNearPetTp(); IBuildingPhysical * building = CBuildingManager::getInstance()->getBuildingPhysicalsByName(command_args[2]); if ( building ) @@ -6116,7 +6119,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " setAnimalName(petIndex, customName); } - + //************************************************* //***************** organization //************************************************* @@ -6127,7 +6130,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " = 0) c->setOrganization((uint32)value); else if (action == "add_points") @@ -6137,7 +6140,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " changeOrganizationStatus(value); } - + //************************************************* //***************** buildings // /a webExecCommand debug 1 building!set_player_room!building_instance_ARCC_player_320 hmac 0 @@ -6147,16 +6150,16 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " addTriggerRequest(c->getEntityRowId(), liftId); } else if (action == "trigger_out") { CBuildingManager::getInstance()->removeTriggerRequest(c->getEntityRowId()); - + } else if (action == "add_guild_room" && command_args.size () == 3) { @@ -6210,24 +6213,24 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " addRoomAccessToPlayer(c->getId()); } - } - + } + //************************************************* //***************** Skill //************************************************* - + else if (command_args[0] == "skill") { if (command_args.size() < 4) return false; - + string action = command_args[1]; // check, best, add_xp - + if (action == "check") { SKILLS::ESkills skillEnum = SKILLS::toSkill( command_args[2] ); uint32 wantedValue; fromString(command_args[3], wantedValue); - + if (c->getSkillValue(skillEnum) < wantedValue) { if (send_url) c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=no_enough_skill"); @@ -6239,7 +6242,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getBestChildSkillValue(skillEnum) < wantedValue) { if (send_url) c->sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=no_best_skill"); @@ -6253,17 +6256,17 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " addXpToSkill(xp, command_args[2]); } } - + //************************************************* //***************** Dead //************************************************* - + else if (command_args[0] == "check_state") { if (command_args.size() < 3) return false; - + string action = command_args[1]; // dead, alive, tag, flag - + if (action == "dead") { if (!c->isDead()) { @@ -6297,17 +6300,17 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getGuildFromId(c->getGuildId()); if (guild == NULL) { @@ -6347,9 +6350,9 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " sendUrl(web_app_url+"&player_eid="+c->getId().toString()+"&event=failed&desc=no_guild"); return true; } - + string action = command_args[1]; // check, give, spend - + if (action == "check_money") { uint64 wantedMoney; @@ -6392,7 +6395,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " resetPVPTimers(); @@ -6422,10 +6425,10 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " PVP_CLAN::EndClans)) { @@ -6434,7 +6437,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getFactionPoint(clan) < value) @@ -6458,7 +6461,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " setFactionPoint(clan, 0, true); else c->setFactionPoint(clan, c->getFactionPoint(clan)-value, true); - } + } } //************************************************* @@ -6500,15 +6503,15 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " getHomeMainlandSessionId(), player)); destPlayer = dynamic_cast(CEntityBaseManager::getEntityBasePtr(entityBase->getId())); @@ -6573,10 +6576,10 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", " setCustomMissionParams(command_args[2], text); @@ -7919,7 +7922,7 @@ NLMISC_COMMAND(setFamePlayer, "set the fame value of a player in the given facti uint32 factionIndex =CStaticFames::getInstance().getFactionIndex(args[1]); if (factionIndex == CStaticFames::INVALID_FACTION_INDEX) - return false; + return false; sint32 fame; NLMISC::fromString(args[2], fame); @@ -7961,7 +7964,7 @@ NLMISC_COMMAND(setOrganization, "set the organization of a player to the given f uint32 factionIndex = CStaticFames::getInstance().getFactionIndex(args[1]); if (factionIndex == CStaticFames::INVALID_FACTION_INDEX) - return false; + return false; c->setOrganization(factionIndex); @@ -8168,7 +8171,7 @@ NLMISC_COMMAND(eScript, "executes a script on an event npc group", " uint32 instanceNumber = c->getInstanceNumber(); uint32 nbString = (uint32)args.size(); - + string botsName = args[1]; if ( ! getAIInstanceFromGroupName(botsName, instanceNumber)) { @@ -8506,7 +8509,7 @@ NLMISC_COMMAND(eventSpawnToxic, "Spawn a toxic cloud", " getX(); float y = (float)c->getY(); @@ -8538,7 +8541,7 @@ NLMISC_COMMAND(eventSpawnToxic, "Spawn a toxic cloud", " init( cloudPos, radius, dmgPerHit, updateFrequency, lifetime ); @@ -8572,9 +8575,9 @@ NLMISC_COMMAND(eventSpawnDamageLine, "Spawn a damage line", " string dammage = ""; if (args.size() > 3 ) dammage = args[3]; - + CZoneManager::getInstance().parseGooBorder( args[1], path, dammage ); - + return true; } @@ -8946,17 +8949,17 @@ NLMISC_COMMAND(leagueKick, "kick a player character from league", " setAfkState(false); - + CTeam * team = TeamManager.getTeam( user->getTeamId() ); if (!team) return true; - + if (team->getLeader() != eId ) return true; - + if (user->getLeagueId() != invitedCharacter->getLeagueId()) return true; - + team = TeamManager.getTeam( invitedCharacter->getTeamId() ); if (!team) { invitedCharacter->setLeagueId(DYN_CHAT_INVALID_CHAN); @@ -8964,7 +8967,7 @@ NLMISC_COMMAND(leagueKick, "kick a player character from league", " setLeagueId(DYN_CHAT_INVALID_CHAN); team->updateLeague(); } - + return true; } @@ -9058,7 +9061,7 @@ NLMISC_COMMAND(openTargetApp, "open target app", "") //---------------------------------------------------------------------------- // (ulukyn) Very special case to use with ARK. -// !!! Never let user call openTargetUrl with a custom url or player +// !!! Never let user call openTargetUrl with a custom url or player // will able to sign any url with server salt. // It's why the url are hardcoded here NLMISC_COMMAND(openTargetUrl, "Open target url", " [bullying]") @@ -9264,8 +9267,8 @@ NLMISC_COMMAND(characterInventoryDump, "Dump character inventory info", " < string sheet = itemPtr->getSheetId().toString(); uint32 quality = itemPtr->quality(); uint32 stacksize = itemPtr->getStackSize(); - - msg += NLMISC::toString("- Slot %3d: SHEETID: %s QUALITY: %d QUANTITY: %d\n", + + msg += NLMISC::toString("- Slot %3d: SHEETID: %s QUALITY: %d QUANTITY: %d\n", i, sheet.c_str(), quality, @@ -9273,7 +9276,7 @@ NLMISC_COMMAND(characterInventoryDump, "Dump character inventory info", " < ++j; if ( ! (j % 3)) { - log.displayNL(msg.c_str()); + log.displayNL(msg.c_str()); msg = ""; j = 0; } @@ -9340,7 +9343,7 @@ NLMISC_COMMAND(deleteInventoryItem, "Delete an item from a characters inventory" itemPtr->quality() == quality && itemPtr->getStackSize() >= quantity) { - log.displayNL("Deleted item '%s' in slot %d of inventory '%s'", + log.displayNL("Deleted item '%s' in slot %d of inventory '%s'", itemPtr->getSheetId().toString().c_str(), slot, INVENTORIES::toString(inventory->getInventoryId()).c_str() @@ -9454,7 +9457,7 @@ NLMISC_COMMAND (setLeague, "Set the League of the team", " []") CCharacter::sendDynamicSystemMessage( c->getId(),"LEAGUE_INVITOR_NOT_LEADER" ); return true; } - + if (team->getLeader() != c->getId()) { CCharacter::sendDynamicSystemMessage( c->getId(),"LEAGUE_INVITOR_NOT_LEADER" ); @@ -9472,10 +9475,10 @@ NLMISC_COMMAND (setLeague, "Set the League of the team", " []") NLMISC_COMMAND(eventGiveControl, "Give control of entity A to entity B", " ") { if (args.size() != 3) return false; - + CEntityId masterEid(args[1]); CEntityId slaveEid(args[2]); - + nlinfo("%s takes control of %s", args[1].c_str(), args[2].c_str()); CMessage msgout("ACQUIRE_CONTROL"); @@ -9494,9 +9497,9 @@ NLMISC_COMMAND(eventGiveControl, "Give control of entity A to entity B", " NLMISC_COMMAND(eventLeaveControl, "Leave control of entity", " ") { if (args.size() != 2) return false; - + CEntityId masterEid(args[1]); - + nlinfo("%s leaves control", args[1].c_str()); CMessage msgout("LEAVE_CONTROL"); @@ -9521,7 +9524,7 @@ NLMISC_COMMAND(setSimplePhrase, "Set an IOS phrase", " [::const_iterator TIterator;\ TIterator itBegin= target.getEntriesBegin();\ TIterator itEnd= target.getEntriesEnd();\ - + #define PERSISTENT_DATA\ FLAG0(CLEAR,while(target.getEntriesBegin()!=target.getEntriesEnd()) target.deleteFromEntries((*target.getEntriesBegin()).first))\ LSTRUCT_MAP2(_Fame,NLMISC::CSheetId,\ @@ -165,7 +165,7 @@ public: (*it).first,\ CFameContainerEntryProxy().store(pdr,(*it).second),\ CFameContainerEntryProxy().apply(pdr,*target.addToEntries(key)))\ - + //#pragma message( PERSISTENT_GENERATION_MESSAGE ) #include "game_share/persistent_data_template.h" @@ -371,7 +371,7 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons // when a character is 'EnterGame'. // Thus the following scheme is used: // - Load PositionStack -// - When character connects, apply top position +// - When character connects, apply top position // - Evenly overwrite the top position with the current position, and save the stack // Hence the "return to mainland" feature does not change the current position but // only pops and locks the stack (to prevent from overwriting it) so that the new top @@ -436,7 +436,7 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons PROP(uint32,_GuildPoints)\ PROP(uint8,_TodayGuildPoints)\ PROP_GAME_CYCLE_COMP(_NextTodayGuildPointsReset)\ - PROP2(_LangChannel,string,_LangChannel,_LangChannel=val)\ + PROP2(_LangChannel,string,_LangChannel,_LangChannel="rf")\ PROP(uint32,_Organization)\ PROP(uint32,_OrganizationStatus)\ PROP(uint32,_OrganizationPoints)\ @@ -831,7 +831,7 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons #define PERSISTENT_DATA\ LPROP2(ActivationDate, NLMISC::TGameCycle, if(ActivationDate >= CTickEventHandler::getGameCycle()), ActivationDate - CTickEventHandler::getGameCycle(), ActivationDate = val)\ PROP2(Family,string, CConsumable::getFamilyName(Family), Family=CConsumable::getFamilyIndex(val))\ - + //#pragma message( PERSISTENT_GENERATION_MESSAGE ) #include "game_share/persistent_data_template.h" @@ -1058,7 +1058,7 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons static void displayInfo(const std::string& s) { - + egs_ppdinfo("%s",s.c_str()); } @@ -1410,7 +1410,7 @@ private: PROP(bool, _Movable)\ PROP(bool, _UnMovable)\ PROP(bool, _LockedByOwner)\ - + //#pragma message( PERSISTENT_GENERATION_MESSAGE ) #include "game_share/persistent_data_template.h" @@ -1630,7 +1630,7 @@ private: PROP(uint32,LoginTime)\ PROP(uint32,Duration)\ PROP(uint32,LogoffTime)\ - + //#pragma message( PERSISTENT_GENERATION_MESSAGE ) #include "game_share/persistent_data_template.h" diff --git a/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp b/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp index 3a2c53a9e..f0d9e0b34 100644 --- a/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp +++ b/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp @@ -71,7 +71,7 @@ void CPVPManager2::init() /////////////////////////////////////////////////////////////////// // *** in first step, we just consider PVP Faction and PVP duel *** /////////////////////////////////////////////////////////////////// - + // instantiate pvp faction class IPVPInterface * pvpFaction = new CPVPFaction(); BOMB_IF(pvpFaction == 0, "Can't allocate CPVPFaction", nlstop ); @@ -97,7 +97,7 @@ void CPVPManager2::release() { if( _Instance != 0 ) { - + for( uint32 i = 0; i < _Instance->_PVPInterface.size(); ++i ) { delete _Instance->_PVPInterface[i]; @@ -120,7 +120,7 @@ CPVPManager2::~CPVPManager2() void CPVPManager2::tickUpdate() { SM_STATIC_PARAMS_1(params, STRING_MANAGER::player); - + // remove expired duel propositions while( !_DuelsAsked.empty() && _DuelsAsked.front().ExpirationDate <= CTickEventHandler::getGameCycle() ) { @@ -132,17 +132,17 @@ void CPVPManager2::tickUpdate() nlverify ( GenericMsgManager.pushNameToStream( "DUEL:CANCEL_INVITATION", bms) ); msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); sendMessageViaMirror( TServiceId(targetId.getDynamicId()), msgout ); - + // send chat infos CEntityId userId = getEntityIdFromRow (_DuelsAsked.front().Invitor); params[0].setEIdAIAlias( targetId, CAIAliasTranslator::getInstance()->getAIAlias(targetId) ); CCharacter::sendDynamicSystemMessage( userId, "DUEL_INVITATION_EXPIRE",params); params[0].setEIdAIAlias( userId, CAIAliasTranslator::getInstance()->getAIAlias(userId) ); CCharacter::sendDynamicSystemMessage( targetId, "DUEL_INVITATION_EXPIRE",params); - // remove duel + // remove duel _DuelsAsked.erase(_DuelsAsked.begin() ); } - + CPVPManager::getInstance()->tickUpdate(); } @@ -234,7 +234,7 @@ std::vector CPVPManager2::getCharacterChannels(CCharacter * user) if (it != _ExtraFactionChannel.end()) { result.push_back((*it).second); - } + } } PVP_CLAN::TPVPClan faction = user->getAllegiance().first; @@ -256,7 +256,7 @@ std::vector CPVPManager2::getCharacterChannels(CCharacter * user) result.push_back((*it).second); } } - + // Organizations if (user->getOrganization() == 5) // marauder { @@ -266,7 +266,7 @@ std::vector CPVPManager2::getCharacterChannels(CCharacter * user) result.push_back((*it).second); } } - + if (user->getOrganization() == 7) // ranger { TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("ranger"); @@ -377,7 +377,7 @@ void CPVPManager2::updateFactionChannel(CCharacter * user, bool b ) if (!have) removeFactionChannelForCharacter(channelsHave[i], user); } - + // Add wanted channels for (uint i = 0; i < channelsMustHave.size(); i++) { @@ -388,7 +388,7 @@ void CPVPManager2::updateFactionChannel(CCharacter * user, bool b ) if (!have) addFactionChannelToCharacter(channelsMustHave[i], user); } - + // Add wanted user channels for (uint i = 0; i < userChannelsMustHave.size(); i++) { @@ -399,7 +399,7 @@ void CPVPManager2::updateFactionChannel(CCharacter * user, bool b ) if (!have) addFactionChannelToCharacter(userChannelsMustHave[i], user); } - + /*if( b ) @@ -452,7 +452,7 @@ void CPVPManager2::sendChannelUsers(TChanID channel, CCharacter * user, bool out CMessage msgout("DYN_CHAT:SERVICE_TELL"); msgout.serial(channel); ucstring users = ucstring(""); - msgout.serial(const_cast(users)); + msgout.serial(const_cast(users)); msgout.serial(senderRow); ucstring txt = ucstring(players); msgout.serial(const_cast(txt)); @@ -598,7 +598,7 @@ void CPVPManager2::addRemoveFactionChannelToUserWithPriviledge(TChanID channel, const CAdminCommand * cmd = findAdminCommand("ShowFactionChannels"); if (!cmd) return; - + if (!user->havePriv(cmd->Priv)) return; @@ -664,7 +664,7 @@ void CPVPManager2::setPVPModeInMirror( const CCharacter * user ) const { nlassert(user); TYPE_PVP_MODE pvpMode = 0; - + // Full pvp if ( user->getFullPVP() ) { @@ -757,11 +757,11 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn // init reminders, these help to know if faction pvp recent action flag need to be set _Instance->_PVPFactionAllyReminder = false; _Instance->_PVPFactionEnemyReminder = false; - + // init reminders, these help to know if outpost leaving timer must be reset _Instance->_PVPOutpostAllyReminder = false; _Instance->_PVPOutpostEnemyReminder = false; - + PVP_RELATION::TPVPRelation relationTmp = PVP_RELATION::Neutral; CCharacter * pTarget = dynamic_cast(target); @@ -796,7 +796,7 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn if( CPVPManager2::getInstance()->inSafeZone( pTarget->getPosition() ) && pTarget->getSafeInPvPSafeZone() ) { relation = PVP_RELATION::NeutralPVP; - } + } else if( CPVPManager2::getInstance()->inSafeZone( actor->getPosition() ) && actor->getSafeInPvPSafeZone() ) { relation = PVP_RELATION::NeutralPVP; @@ -807,7 +807,7 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn } } } - } + } else if ( relationTmp != PVP_RELATION::Ally ) { relationTmp = PVP_RELATION::NeutralPVP; @@ -822,7 +822,7 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn { // Get relation for this Pvp Interface (faction, zone, outpost, ...) relationTmp = _PVPInterface[i]->getPVPRelation( actor, target, curative ); - + if( relationTmp == PVP_RELATION::Unknown ) return PVP_RELATION::Unknown; @@ -878,7 +878,7 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ if( actionValid && !checkMode ) { CCharacter * pTarget = dynamic_cast(target); - + //if(pTarget) // actor->clearSafeInPvPSafeZone(); @@ -898,7 +898,7 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ } } } - + // stop outpost leaving timer if( _PVPOutpostAllyReminder ) { @@ -945,7 +945,7 @@ bool CPVPManager2::isOffensiveActionValid( CCharacter * actor, CEntityBase * tar default: actionValid = false; } - + if( actionValid && !checkMode ) { CCharacter * pTarget = dynamic_cast(target); @@ -973,7 +973,7 @@ bool CPVPManager2::isOffensiveActionValid( CCharacter * actor, CEntityBase * tar actor->refreshOutpostLeavingTimer(); } } - + return actionValid; } @@ -1007,7 +1007,7 @@ bool CPVPManager2::canApplyAreaEffect(CCharacter* actor, CEntityBase * areaTarge default: actionValid = offensive; } - + if( actionValid ) { /* if ((pTarget->getGuildId() != 0) && (actor->getGuildId() != 0) && (actor->getGuildId() != pTarget->getGuildId())) @@ -1053,7 +1053,7 @@ bool CPVPManager2::canApplyAreaEffect(CCharacter* actor, CEntityBase * areaTarge } } } - + return actionValid; } @@ -1135,7 +1135,7 @@ bool CPVPManager2::addFactionWar( PVP_CLAN::TPVPClan clan1, PVP_CLAN::TPVPClan c // for( CPlayerManager::TMapPlayers::const_iterator it = PlayerManager.getPlayers().begin(); it != PlayerManager.getPlayers().end(); ++it ) // { // CPlayerManager::SCPlayer scPlayer=(*it).second; -// +// // if (scPlayer.Player) // { // CCharacter *activePlayer=scPlayer.Player->getActiveCharacter(); @@ -1185,7 +1185,12 @@ void CPVPManager2::onIOSMirrorUp() createExtraFactionChannel("ru", true); createExtraFactionChannel("es", true); createExtraFactionChannel("rf", true); - + createExtraFactionChannel("rf-fr", true); + createExtraFactionChannel("rf-en", true); + createExtraFactionChannel("rf-es", true); + createExtraFactionChannel("rf-ed", true); + createExtraFactionChannel("rf-ru", true); + #ifdef HAVE_MONGO CUniquePtr cursor = CMongo::query("ryzom_channels", toString("{}")); if (cursor.get()) @@ -1200,7 +1205,7 @@ void CPVPManager2::onIOSMirrorUp() name = obj.getStringField("name"); password = obj.getStringField("password"); - + createUserChannel(name, password); } } @@ -1211,11 +1216,11 @@ void CPVPManager2::onIOSMirrorUp() //createFactionChannel(PVP_CLAN::getClanFromIndex(i)); createFactionChannel((PVP_CLAN::TPVPClan)i); } - + for( CPlayerManager::TMapPlayers::const_iterator it = PlayerManager.getPlayers().begin(); it != PlayerManager.getPlayers().end(); ++it ) { CPlayerManager::SCPlayer scPlayer=(*it).second; - + if (scPlayer.Player) { CCharacter *activePlayer=scPlayer.Player->getActiveCharacter(); @@ -1271,7 +1276,7 @@ TChanID CPVPManager2::createUserChannel(const std::string & channelName, const s { return DYN_CHAT_INVALID_CHAN; } - + // Don't allow channels starting with "FACTION_" (to not clash with the faction channels) if (channelName.substr(0, 8) == "FACTION_") { @@ -1292,7 +1297,7 @@ TChanID CPVPManager2::createUserChannel(const std::string & channelName, const s else channelTitle = channelName; - + TChanID factionChannelId = DynChatEGS.addChan(channelName, channelTitle); if (factionChannelId != DYN_CHAT_INVALID_CHAN) { @@ -1374,7 +1379,7 @@ void CPVPManager2::sendFactionWarsToClient( CCharacter * user ) nlwarning(" Msg name PVP_FACTION:FACTION_WARS not found"); return; } - + CFactionWarsMsg factionWarsMsg; for( uint i=0; i<_FactionWarOccurs.size(); ++i ) { @@ -1422,9 +1427,9 @@ void CPVPManager2::askForDuel( const NLMISC::CEntityId & userId ) // test if duel is allowed in this place CMirrorPropValueRO mirrorCell( TheDataset, user->getEntityRowId(), DSPropertyCELL ); - sint32 cell1 = mirrorCell; + sint32 cell1 = mirrorCell; CMirrorPropValueRO mirrorCell2( TheDataset, target->getEntityRowId(), DSPropertyCELL ); - sint32 cell2 = mirrorCell2; + sint32 cell2 = mirrorCell2; if (cell1 <= -2 || cell2 <= -2 ) { @@ -1434,7 +1439,7 @@ void CPVPManager2::askForDuel( const NLMISC::CEntityId & userId ) // if target is already in duel then user cannot invite him if ( target->getDuelOpponent() != NULL ) - { + { params[0].setEIdAIAlias( target->getId(), CAIAliasTranslator::getInstance()->getAIAlias(target->getId()) ); CCharacter::sendDynamicSystemMessage( userId, "DUEL_TARGET_ALREADY_INVITED",params); return; @@ -1484,14 +1489,14 @@ void CPVPManager2::askForDuel( const NLMISC::CEntityId & userId ) else { if ( (*it).Invited == user->getEntityRowId() ) - { + { // user is already invited : he has to accept or refuse first CCharacter::sendDynamicSystemMessage( userId, "DUEL_ALREADY_INVITED",params); // dont bail out as we can enter in case "if ( (*it).Invitor == userId )" problem = true; } if ( (*it).Invited == target->getEntityRowId() ) - { + { // target is already invited : he has to accept or refuse first params[0].setEIdAIAlias( target->getId(), CAIAliasTranslator::getInstance()->getAIAlias(target->getId()) ); CCharacter::sendDynamicSystemMessage( userId, "DUEL_TARGET_ALREADY_INVITED",params); @@ -1499,7 +1504,7 @@ void CPVPManager2::askForDuel( const NLMISC::CEntityId & userId ) problem = true; } if ( (*it).Invitor == target->getEntityRowId() ) - { + { // target is inviting someone params[0].setEIdAIAlias( target->getId(), CAIAliasTranslator::getInstance()->getAIAlias(target->getId()) ); CCharacter::sendDynamicSystemMessage( userId, "DUEL_TARGET_ALREADY_INVITED",params); @@ -1512,14 +1517,14 @@ void CPVPManager2::askForDuel( const NLMISC::CEntityId & userId ) // problem occured : bail out if ( problem ) return; - + // create a new entry CDuelAsked duelAsked; duelAsked.Invitor = user->getEntityRowId(); duelAsked.Invited = target->getEntityRowId(); duelAsked.ExpirationDate = CTickEventHandler::getGameCycle() + DuelQueryDuration; _DuelsAsked.push_front( duelAsked ); - + // tell invited player params[0].setEIdAIAlias( userId, CAIAliasTranslator::getInstance()->getAIAlias(userId) ); uint32 txt = STRING_MANAGER::sendStringToClient( target->getEntityRowId(), "DUEL_INVITATION", params ); @@ -1553,7 +1558,7 @@ void CPVPManager2::refuseDuel( const NLMISC::CEntityId & userId ) return; } } - + } // refuseDuel // @@ -1563,12 +1568,12 @@ void CPVPManager2::refuseDuel( const NLMISC::CEntityId & userId ) //----------------------------------------------- void CPVPManager2::abandonDuel( const NLMISC::CEntityId & userId ) { - CCharacter * user = PlayerManager.getChar( userId ); + CCharacter * user = PlayerManager.getChar( userId ); if ( user ) { endDuel(user, "DUEL_YOU_ABANDON", "DUEL_ABANDON"); } - + } // abandonDuel // @@ -1579,8 +1584,8 @@ void CPVPManager2::abandonDuel( const NLMISC::CEntityId & userId ) void CPVPManager2::acceptDuel( const NLMISC::CEntityId & userId ) { SM_STATIC_PARAMS_1(params, STRING_MANAGER::player); - - CCharacter * invited = PlayerManager.getChar(userId ); + + CCharacter * invited = PlayerManager.getChar(userId ); if ( !invited ) { nlwarning("invalid user %s", userId.toString().c_str() ); @@ -1598,7 +1603,7 @@ void CPVPManager2::acceptDuel( const NLMISC::CEntityId & userId ) _DuelsAsked.erase(it); return; } - + params[0].setEIdAIAlias( userId, CAIAliasTranslator::getInstance()->getAIAlias(userId) ); CCharacter::sendDynamicSystemMessage( invitor->getId(), "DUEL_ACCEPTED", params); params[0].setEIdAIAlias( invitor->getId(), CAIAliasTranslator::getInstance()->getAIAlias(invitor->getId()) ); @@ -1606,7 +1611,7 @@ void CPVPManager2::acceptDuel( const NLMISC::CEntityId & userId ) invitor->setDuelOpponent( invited ); invited->setDuelOpponent( invitor ); - + std::list< CDuelAsked >::iterator itErase = it; ++it; _DuelsAsked.erase(itErase); @@ -1647,7 +1652,7 @@ void CPVPManager2::removeDuelInvitor( const NLMISC::CEntityId & userId ) for ( std::list< CDuelAsked >::iterator it = _DuelsAsked.begin(); it != _DuelsAsked.end();++it ) { if ( (*it).Invitor == row ) - { + { CMessage msgout( "IMPULSION_ID" ); CEntityId msgId = getEntityIdFromRow ( (*it).Invited ); msgout.serial( msgId ); @@ -1655,7 +1660,7 @@ void CPVPManager2::removeDuelInvitor( const NLMISC::CEntityId & userId ) nlverify ( GenericMsgManager.pushNameToStream( "DUEL:CANCEL_INVITATION", bms) ); msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); sendMessageViaMirror( NLNET::TServiceId(msgId.getDynamicId()), msgout ); - + CCharacter::sendDynamicSystemMessage( msgId, "DUEL_CANCEL_INVITATION",params); _DuelsAsked.erase(it); return; @@ -1679,13 +1684,13 @@ void CPVPManager2::endDuel( CCharacter * user, const string& userTxt, const stri CCharacter::sendDynamicSystemMessage( user->getEntityRowId(), userTxt ); if( !opponentTxt.empty() ) CCharacter::sendDynamicSystemMessage( duelOpponent->getEntityRowId(), opponentTxt ); - + // duelOpponent->_PropertyDatabase.setProp("USER:IN_DUEL",false ); CBankAccessor_PLR::getUSER().setIN_DUEL(duelOpponent->_PropertyDatabase, false ); // duelOpponent->removeAllSpells(); //< Spells should not be removed // duelOpponent->stopAllLinks(1.0f); //< Offensive links are automatically broken when PvP state change duelOpponent->setDuelOpponent( NULL ); - + // user->_PropertyDatabase.setProp("USER:IN_DUEL",false ); CBankAccessor_PLR::getUSER().setIN_DUEL(user->_PropertyDatabase, false ); // user->removeAllSpells(); //< Spells should not be removed diff --git a/ryzom/server/src/input_output_service/chat_manager.cpp b/ryzom/server/src/input_output_service/chat_manager.cpp index bda277c04..61639f6f2 100644 --- a/ryzom/server/src/input_output_service/chat_manager.cpp +++ b/ryzom/server/src/input_output_service/chat_manager.cpp @@ -569,21 +569,17 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) // info for log the chat message string senderName; - ucstring ucSenderName; - { - // ignore muted users -// if ( _MutedUsers.find( eid ) != _MutedUsers.end() ) -// return; + string fullName; - if (ci == NULL) - { - senderName = TheDataset.getEntityId(sender).toString(); - } - else - { - ucSenderName = ci->Name; - senderName = ucSenderName.toString(); - } + if (ci == NULL) + { + senderName = TheDataset.getEntityId(sender).toString(); + fullName = senderName; + } + else + { + fullName = IOS->getRocketName(ci->Name); + senderName = ci->Name.toString(); } static const char* groupNames[]= @@ -622,10 +618,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) CChatGroup::TMemberCont::iterator itA; string sender_lang = SM->getLanguageCodeString(ci->Language); - if (sender_lang == "en") // 'en' must be converted to 'us' because translation uses :us: code - sender_lang = "us"; - for( itA = itCl->second->getAudience().Members.begin(); itA != itCl->second->getAudience().Members.end(); ++itA ) @@ -644,8 +637,6 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) { receiverName = co->Name.toString(); receiver_lang = SM->getLanguageCodeString(co->Language); - if (receiver_lang == "en") // en must be converted to us because translation uses :us: code - receiver_lang = "us"; } if (EnableDeepL) @@ -654,17 +645,18 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) if (sender_lang == "wk") receiver_lang = sender_lang; - + if (ucstr[0] != '>' && client.haveDisabledTranslation(sender_lang)) receiver_lang = sender_lang; - + + if (ucstr[0] == '>') // Sent directly when prefixed by '>', it's the anti-translation code { if (ucstr.length() > 5 && ucstr[1] == ':' && ucstr[4] == ':') // check lang prefix { string usedlang = ucstr.toString().substr(2, 2); //nlinfo("used: %s, user: %s", usedlang.c_str(), receiver_lang.c_str()); - if (usedlang == receiver_lang) + if (usedlang == receiver_lang && !client.haveDisabledTranslation(sender_lang)) sendChat( itCl->second->getChatMode(), *itA, ucstr.substr(5), sender ); } else @@ -678,12 +670,11 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) } else { - if (!have_fr && receiver_lang == "fr") have_fr = true; if (!have_de && receiver_lang == "de") have_de = true; - if (!have_en && receiver_lang == "us") + if (!have_en && receiver_lang == "en") have_en = true; if (!have_ru && receiver_lang == "ru") have_ru = true; @@ -695,21 +686,21 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) else sendChat( itCl->second->getChatMode(), *itA, ucstr, sender ); } - + string langs = sender_lang; if (have_fr) langs += "-fr"; if (have_de) langs += "-de"; if (have_en) - langs += "-us"; + langs += "-en"; if (have_ru) langs += "-ru"; if (have_es) langs += "-es"; if (nbr_receiver > 0) - _Log.displayNL("|%s|(%s:%d:%s)|%s", IOS->getRocketName(senderName).c_str(), groupNames[itCl->second->getChatMode()], nbr_receiver, langs.c_str(), ucstr.toUtf8().c_str() ); + _Log.displayNL("%s|%s|%d|%s|%s", groupNames[itCl->second->getChatMode()], fullName.c_str(), nbr_receiver, langs.c_str(), ucstr.toUtf8().c_str() ); } break; case CChatGroup::region : @@ -723,10 +714,20 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) TGroupId grpId = itCl->second->getRegionChatGroup(); _DestUsers.push_back(grpId); - _Log.displayNL("'%s' (%s) : \t\"%s\"", senderName.c_str(), groupNames[itCl->second->getChatMode()], ucstr.toString().c_str() ); - chatInGroup( grpId, ucstr, sender ); - break; + if (EnableDeepL) + { + string sender_lang = SM->getLanguageCodeString(ci->Language); + if (ucstr[0] == '>') // Sent directly when prefixed by '>', it's the anti-translation code + chatInGroup( grpId, ucstr.substr(1), sender ); + else + _Log.displayNL("region:%s|%s|*|%s-*|%s", grpId.toString().c_str(), fullName.c_str(), sender_lang.c_str(), ucstr.toString().c_str() ); + } + else + chatInGroup( grpId, ucstr, sender ); } + break; + + case CChatGroup::universe: { CEntityId eid = TheDataset.getEntityId(sender); @@ -754,30 +755,98 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) // } TGroupId grpId = CEntityId(RYZOMID::chatGroup, 0); - - _Log.displayNL("'%s' (%s) : \t\"%s\"", senderName.c_str(), groupNames[itCl->second->getChatMode()], ucstr.toString().c_str() ); _DestUsers.push_back(grpId); double date = 1000.0*(double)CTime::getSecondsSince1970(); - string name; - if (!ucSenderName.empty()) - name = IOS->getRocketName(ucSenderName); + bool sendToMongo = true; + bool sendToAllUni = false; + string autosub = "1"; + uint8 startPos = 0; + string mongoText = ucstr.toUtf8(); + string chatId = "all"; + string chatType = "univers"; + string usedlang = SM->getLanguageCodeString(ci->Language); + + if (EnableDeepL) + { + chatType = "dynamic"; + if (ucstr[0] == '>') // Sent directly when prefixed by '>', it's the anti-translation code + { + startPos = 1; + mongoText = mongoText.substr(1); + string::size_type endOfOriginal = mongoText.find("}@{"); + if (mongoText.size() > 4 && mongoText[0] == ':' && mongoText[3] == ':') + { + startPos = 5; + usedlang = mongoText.substr(1, 2); + string source_lang = usedlang; + + if (endOfOriginal != string::npos) + { + if (mongoText.size() > 9) + source_lang = mongoText.substr(6, 2); + string sourceText = mongoText.substr(9, endOfOriginal-9); + strFindReplace(sourceText, ")", "}"); + mongoText = "["+source_lang+"](http://chatdev.ryzom.com/channel/pub-universe-"+source_lang+"? "+sourceText+") "+mongoText.substr(endOfOriginal+4, mongoText.size()-endOfOriginal-4); + } + else + { + usedlang = mongoText.substr(1, 2); + mongoText = mongoText.substr(4, mongoText.size()-4); + } + + if (source_lang == "en") // in RC the icon are :us: + mongoText = ":us:"+mongoText; + else + mongoText = ":"+source_lang+":"+mongoText; + + chatId = "FACTION_"+toUpper(usedlang); + if (usedlang != SM->getLanguageCodeString(ci->Language)) + autosub = "0"; + + } + else + sendToAllUni = true; + + chatInGroup( grpId, ucstr.substr(1), sender ); + } + else + { + string sender_lang = SM->getLanguageCodeString(ci->Language); + _Log.displayNL("%s|%s|*|%s-*|%s", "universe", fullName.c_str(), sender_lang.c_str(), ucstr.toUtf8().c_str()); + sendToMongo = false; + } + } else - name = senderName; + chatInGroup( grpId, ucstr, sender ); #ifdef HAVE_MONGO - CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'univers', 'chatId': 'all', 'date': %f, 'ig': true }", CMongo::quote(name).c_str(), CMongo::quote(ucstr.toUtf8()).c_str(), date)); + if (sendToMongo) // only send to mongo if it's not a translated message + { + if (sendToAllUni) + { + string userlang = SM->getLanguageCodeString(ci->Language); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': '%s', 'chatId': 'FACTION_EN', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), chatType.c_str(), date, userlang == "en"?"1":"0")); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': '%s', 'chatId': 'FACTION_DE', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), chatType.c_str(), date, userlang == "de"?"1":"0")); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': '%s', 'chatId': 'FACTION_ES', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), chatType.c_str(), date, userlang == "es"?"1":"0")); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': '%s', 'chatId': 'FACTION_FR', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), chatType.c_str(), date, userlang == "fr"?"1":"0")); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': '%s', 'chatId': 'FACTION_RU', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), chatType.c_str(), date, userlang == "ru"?"1":"0")); + } + else + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': '%s', 'chatId': '%s', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), chatType.c_str(), chatId.c_str(), date, autosub.c_str())); + } #endif - chatInGroup( grpId, ucstr, sender ); + } break; + case CChatGroup::team: { TGroupId grpId = itCl->second->getTeamChatGroup(); _DestUsers.push_back(grpId); - _Log.displayNL("'%s' (%s) : \t\"%s\"", senderName.c_str(), groupNames[itCl->second->getChatMode()], ucstr.toString().c_str() ); + _Log.displayNL("'%s' (%s) : %s", fullName.c_str(), groupNames[itCl->second->getChatMode()], ucstr.toString().c_str() ); chatInGroup( grpId, ucstr, sender ); } break; @@ -787,10 +856,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) TGroupId grpId = itCl->second->getGuildChatGroup(); _DestUsers.push_back(grpId); - _Log.displayNL("'%s' (%s) : \t\"%s\"", - senderName.c_str(), - groupNames[itCl->second->getChatMode()], - ucstr.toString().c_str() ); + _Log.displayNL("%s' (%s) : %s", fullName.c_str(), groupNames[itCl->second->getChatMode()], ucstr.toString().c_str() ); uint32 guildId = grpId.getShortId() - 0x10000000; @@ -799,14 +865,8 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) double date = 1000.0*(double)CTime::getSecondsSince1970(); - string name; - if (!ucSenderName.empty()) - name = IOS->getRocketName(ucSenderName); - else - name = senderName; - #ifdef HAVE_MONGO - CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'guildId', 'chatId': '%s', 'date': %f, 'ig': true }", CMongo::quote(name).c_str(), CMongo::quote(ucstr.toUtf8()).c_str(), sGuildId.str().c_str(), date)); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'guildId', 'chatId': '%s', 'date': %f, 'ig': true, 'autosub': 1 }", CMongo::quote(fullName).c_str(), CMongo::quote(ucstr.toUtf8()).c_str(), sGuildId.str().c_str(), date)); #endif chatInGroup( grpId, ucstr, sender ); } @@ -832,25 +892,88 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) } } -#ifdef HAVE_MONGO - const std::string *tmpChatId = _ChanNames.getB(chanId); - string chatId; - if (tmpChatId) - chatId = *tmpChatId; + const std::string *tmpChatId = _ChanNames.getB(chanId); + string chatId; + if (tmpChatId) + chatId = *tmpChatId; - nlinfo("CHAT : %s", chatId.c_str()); - double date = 1000.0*(double)CTime::getSecondsSince1970(); + double date = 1000.0*(double)CTime::getSecondsSince1970(); - string name; - if (!ucSenderName.empty()) - name = IOS->getRocketName(ucSenderName); - else - name = senderName; + bool sendToMongo = true; + bool sendToAllForge = false; + uint8 startPos = 0; + + string mongoText = ucstr.toUtf8(); + string usedlang = ""; + string autosub = "0"; + + if (EnableDeepL) + { + if (ucstr[0] == '>') // Sent directly when prefixed by '>', it's the anti-translation code + { + startPos = 1; + mongoText = mongoText.substr(1); + string::size_type endOfOriginal = mongoText.find("}@{"); + if (mongoText.size() > 4 && mongoText[0] == ':' && mongoText[3] == ':') + { + startPos = 5; + usedlang = mongoText.substr(1, 2); + string source_lang = usedlang; - CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'dynamic', 'chatId': '%s', 'date': %f, 'ig': true }", CMongo::quote(name).c_str(), CMongo::quote(ucstr.toUtf8()).c_str(), chatId.c_str(), date)); + if (endOfOriginal != string::npos) + { + if (mongoText.size() > 9) + source_lang = mongoText.substr(6, 2); + string sourceText = mongoText.substr(9, endOfOriginal-9); + strFindReplace(sourceText, ")", "}"); + mongoText = "["+source_lang+"](http://chatdev.ryzom.com/channel/pub-forge-"+source_lang+"? "+sourceText+") "+mongoText.substr(endOfOriginal+4, mongoText.size()-endOfOriginal-4); + } + else + { + usedlang = mongoText.substr(1, 2); + mongoText = mongoText.substr(4, mongoText.size()-4); + } + + if (source_lang == "en") // in RC the icon are :us: + mongoText = ":us:"+mongoText; + else + mongoText = ":"+source_lang+":"+mongoText; + } + else if (chatId == "FACTION_RF") + sendToAllForge = true; + + } + else if (chatId == "FACTION_RF" || chatId == "FACTION_EN" || chatId == "FACTION_DE" || chatId == "FACTION_FR" || chatId == "FACTION_ES" || chatId == "FACTION_RU") + { + usedlang = SM->getLanguageCodeString(ci->Language); + _Log.displayNL("%s|%s|*|%s-*|%s", string("#"+chatId).c_str(), fullName.c_str(), usedlang.c_str(), ucstr.toUtf8().c_str()); + sendToMongo = false; + } + } + +#ifdef HAVE_MONGO + if (sendToMongo) // only send to mongo if it's not a translated message + { + string userlang = SM->getLanguageCodeString(ci->Language); + if (sendToAllForge) + { + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'dynamic', 'chatId': 'FACTION_RF-EN', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), date, userlang == "en"?"1":"0")); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'dynamic', 'chatId': 'FACTION_RF-DE', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), date, userlang == "de"?"1":"0")); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'dynamic', 'chatId': 'FACTION_RF-ES', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), date, userlang == "es"?"1":"0")); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'dynamic', 'chatId': 'FACTION_RF-FR', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), date, userlang == "fr"?"1":"0")); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'dynamic', 'chatId': 'FACTION_RF-RU', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), date, userlang == "ru"?"1":"0")); + + } + else + { + if (chatId == "FACTION_RF") + chatId = "FACTION_RF-"+toUpper(usedlang); + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'dynamic', 'chatId': '%s', 'date': %f, 'ig': true, 'autosub': %s }", CMongo::quote(fullName).c_str(), CMongo::quote(mongoText).c_str(), chatId.c_str(), date, userlang == usedlang?"1":"0")); + } + } #endif - if (!session->getChan()->getDontBroadcastPlayerInputs()) + if (!session->getChan()->getDontBroadcastPlayerInputs() && startPos != 0) { // add msg to the historic CDynChatChan::CHistoricEntry entry; @@ -887,15 +1010,20 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr ) CDynChatSession *dcc = session->getChan()->getFirstSession(); while (dcc) { - sendChat(itCl->second->getChatMode(), dcc->getClient()->getID(), content, sender, chanId); + NLMISC::CEntityId receiverId = TheDataset.getEntityId(dcc->getClient()->getID()); + CCharacterInfos* co = IOS->getCharInfos(receiverId); + if (!EnableDeepL || usedlang.empty() || usedlang == SM->getLanguageCodeString(co->Language)) + sendChat(itCl->second->getChatMode(), dcc->getClient()->getID(), content.substr(startPos), sender, chanId); dcc = dcc->getNextChannelSession(); // next session in this channel } } else { // only send an echo to the sender - sendChat(itCl->second->getChatMode(), itCl->first, ucstr, sender, chanId); + if (!EnableDeepL || usedlang.empty()) // only send an echo to the sender + sendChat(itCl->second->getChatMode(), itCl->first, ucstr, sender, chanId); } + if (session->getChan()->getForwardPlayerIntputToOwnerService()) { // send player input to service owner @@ -968,10 +1096,27 @@ void CChatManager::chatInGroup( TGroupId& grpId, const ucstring& ucstr, const TD CChatGroup &chatGrp = itGrp->second; CChatGroup::TMemberCont::const_iterator itM; list logDest; + + uint8 startPos = 0; + string usedlang; + if (EnableDeepL && ucstr.length() > 4 && ucstr[0] == ':' && ucstr[3] == ':') // check lang prefix + { + usedlang = ucstr.toString().substr(1, 2); + startPos = 4; + } + for( itM = chatGrp.Members.begin(); itM != chatGrp.Members.end(); ++itM ) { CMirrorPropValueRO instanceId( TheDataset, *itM, DSPropertyAI_INSTANCE ); + if (EnableDeepL && !usedlang.empty()) + { + NLMISC::CEntityId receiverId = TheDataset.getEntityId(*itM); + CCharacterInfos* co = IOS->getCharInfos(receiverId); + if (usedlang != SM->getLanguageCodeString(co->Language)) + continue; + } + // check the ai instance for region chat if (chatGrp.Type != CChatGroup::region || instanceId == senderInstanceId) @@ -997,7 +1142,7 @@ void CChatManager::chatInGroup( TGroupId& grpId, const ucstring& ucstr, const TD // check the exclude list if ( std::find( excluded.begin(), excluded.end(), *itM ) == excluded.end() ) { - sendChat( itGrp->second.Type, *itM, ucstr, sender ); + sendChat( itGrp->second.Type, *itM, ucstr.substr(startPos), sender ); _DestUsers.push_back(TheDataset.getEntityId(*itM)); } } @@ -1011,7 +1156,7 @@ void CChatManager::chatInGroup( TGroupId& grpId, const ucstring& ucstr, const TD // forward to chat unifier to dispatch to other shards if (IChatUnifierClient::getInstance()) { - IChatUnifierClient::getInstance()->sendFarGuildChat(charInfos->Name, uint32(grpId.getShortId()), ucstr); + IChatUnifierClient::getInstance()->sendFarGuildChat(charInfos->Name, uint32(grpId.getShortId()), ucstr.substr(startPos)); } } } @@ -1026,7 +1171,7 @@ void CChatManager::chatInGroup( TGroupId& grpId, const ucstring& ucstr, const TD { // determine the session id as the home session id for normal players and the current session id for GMs uint32 sessionId= (charInfos->HavePrivilege && !IsRingShard)? IService::getInstance()->getShardId(): (uint32)charInfos->HomeSessionId; - IChatUnifierClient::getInstance()->sendUniverseChat(charInfos->Name, sessionId, ucstr); + IChatUnifierClient::getInstance()->sendUniverseChat(charInfos->Name, sessionId, ucstr.substr(startPos)); } } } @@ -1043,16 +1188,26 @@ void CChatManager::farChatInGroup(TGroupId &grpId, uint32 homeSessionId, const u map< TGroupId, CChatGroup >::iterator itGrp = _Groups.find( grpId ); if( itGrp != _Groups.end() ) { + + + uint8 startPos = 0; + string usedlang; + if (EnableDeepL && text.length() > 4 && text[0] == ':' && text[3] == ':') // check lang prefix + { + usedlang = text.toString().substr(1, 2); + startPos = 4; + } + CChatGroup &chatGrp = itGrp->second; CChatGroup::TMemberCont::const_iterator itM; for( itM = chatGrp.Members.begin(); itM != chatGrp.Members.end(); ++itM ) { + CCharacterInfos *charInfo = IOS->getCharInfos(TheDataset.getEntityId(*itM)); + if (charInfo==NULL) + continue; + if (homeSessionId != 0) { - CCharacterInfos *charInfo = IOS->getCharInfos(TheDataset.getEntityId(*itM)); - if (charInfo==NULL) - continue; - // determine the session id as the home session id for normal players and the current session id for GMs uint32 sessionId= (charInfo->HavePrivilege && !IsRingShard)? IService::getInstance()->getShardId(): (uint32)charInfo->HomeSessionId; @@ -1060,7 +1215,11 @@ void CChatManager::farChatInGroup(TGroupId &grpId, uint32 homeSessionId, const u if (sessionId != homeSessionId) continue; } - sendFarChat( itGrp->second.Type, *itM, text, senderName ); + + if (EnableDeepL && !usedlang.empty() && usedlang != SM->getLanguageCodeString(charInfo->Language)) + continue; + + sendFarChat( itGrp->second.Type, *itM, text.substr(startPos), senderName ); } } else @@ -1711,6 +1870,85 @@ void CChatManager::sendChat( CChatGroup::TGroupType senderChatMode, const TDataS } // sendChat // +void CChatManager::sendFarChat(const string &name, const ucstring& ucstr, const string &chan) +{ + const TChanID *chanId = _ChanNames.getA(chan); + if (chanId || chan == "universe") + { + + string usedlang = ""; + string mongoText = ucstr.toUtf8(); + + string::size_type endOfOriginal = mongoText.find("}@{"); + uint8 startPos = 0; + if (mongoText.length() > 4 && mongoText[0] == ':' && mongoText[3] == ':') // check lang prefix + { + startPos = 4; + double date = 1000.0*(double)CTime::getSecondsSince1970(); + string chatId; + usedlang = mongoText.substr(1, 2); + string rc_channel = ""; + if (chan == "FACTION_RF") + { + chatId = "FACTION_RF-"+toUpper(usedlang); + rc_channel = "pub-forge-"; + } + else if (chan == "universe") + { + chatId = "FACTION_"+toUpper(usedlang); + rc_channel = "pub-universe-"; + } + + string source_lang = usedlang; + + if (endOfOriginal != string::npos) + { + if (mongoText.size() > 9) + source_lang = mongoText.substr(6, 2); + string sourceText = mongoText.substr(9, endOfOriginal-9); + strFindReplace(sourceText, ")", "}"); + mongoText = "["+source_lang+"](http://chatdev.ryzom.com/channel/"+rc_channel+source_lang+"? "+sourceText+") "+mongoText.substr(endOfOriginal+4, mongoText.size()-endOfOriginal-4); + } + else + { + usedlang = mongoText.substr(1, 2); + mongoText = mongoText.substr(4, mongoText.size()-4); + } + + + if (source_lang == "en") // in RC the icon are :us: + mongoText = ":us:"+mongoText; + else + mongoText = ":"+source_lang+":"+mongoText; + +#ifdef HAVE_MONGO + if (endOfOriginal != string::npos) + CMongo::insert("ryzom_chats", toString("{ 'username': '%s', 'chat': '%s', 'chatType': 'dynamic', 'chatId': '%s', 'date': %f, 'ig': true }", CMongo::quote(name).c_str(), CMongo::quote(mongoText).c_str(), chatId.c_str(), date)); +#endif + } + + if (chan == "universe") + { + TGroupId grpId = CEntityId(RYZOMID::chatGroup, 0); + farChatInGroup(grpId, 0, ucstr, ucstring("~")+ucstring(name)); + } + else + { + + CDynChatSession *dcc = _DynChat.getChan(*chanId)->getFirstSession(); + while (dcc) + { + + NLMISC::CEntityId receiverId = TheDataset.getEntityId(dcc->getClient()->getID()); + CCharacterInfos* co = IOS->getCharInfos(receiverId); + if (!EnableDeepL || usedlang.empty() || usedlang == SM->getLanguageCodeString(co->Language)) + sendFarChat((CChatGroup::TGroupType)12, dcc->getClient()->getID(), ucstr.substr(startPos), ucstring("~")+ucstring(name), *chanId); + dcc = dcc->getNextChannelSession(); // next session in this channel + } + } + } +} + void CChatManager::sendFarChat( CChatGroup::TGroupType senderChatMode, const TDataSetRow &receiver, const ucstring& ucstr, const ucstring &senderName, TChanID chanID) { CCharacterInfos * receiverInfos = IOS->getCharInfos( TheDataset.getEntityId(receiver) ); @@ -2570,7 +2808,7 @@ ucstring CChatManager::filterClientInput(ucstring &text) // 1st, remove any beginning or ending white space ucstring::size_type pos = 0; - // skip begin white spaces + // skip begin white spaces or : (used by deepl) while (pos < text.size() && (text[pos] == ' ' || text[pos] == '\t')) ++pos; @@ -2578,6 +2816,12 @@ ucstring CChatManager::filterClientInput(ucstring &text) while (text.size() > 0 && (*(text.rbegin()) == ' ' || *(text.rbegin()) == '\t')) text.resize(text.size()-1); + if (pos < text.size() && text[pos] == ':') + ++pos; + + if (pos+1 < text.size() && text[pos] == '>' && text[pos+1] == ':') + pos += 2; + // copy string, removing multi white space between words // filter out color code bool lastIsWhite = false; @@ -2703,24 +2947,46 @@ void CChatManager::update() } else if (chatType == "dynamic") { - // broadcast to other client in the channel - const TChanID *chanId = _ChanNames.getA(chatId); - if (chanId) + if (EnableDeepL && chatId.size() >= 10 && (chatId.substr(0, 11) == "FACTION_RF-" || chatId == "FACTION_EN" || chatId == "FACTION_DE" || chatId == "FACTION_FR" || chatId == "FACTION_ES" || chatId == "FACTION_RU")) + { + string usedlang; + if (chatId.substr(0, 11) == "FACTION_RF-") + usedlang = chatId.substr(11, 2); + else + usedlang = chatId.substr(8, 2); + + _Log.displayNL("%s|%s|*|%s-*|%s", chatId.c_str(), string("~"+name).c_str(), toLower(usedlang).c_str(), text.toUtf8().c_str()); + } + else { - CDynChatSession *dcc = _DynChat.getChan(*chanId)->getFirstSession(); - while (dcc) + + // broadcast to other client in the channel + const TChanID *chanId = _ChanNames.getA(chatId); + if (chanId) { - sendFarChat((CChatGroup::TGroupType)12, dcc->getClient()->getID(), text, ucstring("~")+ucstring(name), *chanId); - dcc = dcc->getNextChannelSession(); // next session in this channel + CDynChatSession *dcc = _DynChat.getChan(*chanId)->getFirstSession(); + while (dcc) + { + sendFarChat((CChatGroup::TGroupType)12, dcc->getClient()->getID(), text, ucstring("~")+ucstring(name), *chanId); + dcc = dcc->getNextChannelSession(); // next session in this channel + } } } - // void CChatManager::sendFarChat( C const ucstring& ucstr, const ucstring &senderName, TChanID chanID) - continue; + // void CChatManager::sendFarChat( C const ucstring& ucstr, const ucstring &senderName, TChanID chanID) + continue; + } + else if (chatType == "univers") { + // Send to Deepl + if (EnableDeepL) + { + _Log.displayNL("%s|%s|wk|wk-*|%s", "universe", name.c_str(), chat.c_str()); + continue; + } } else if (chatType == "username") { - if (IService::getInstance()->getShardId() == 301) - chatId = chatId+"(Yubo)"; + if (IService::getInstance()->getShardId() == 501) + chatId = chatId+"(Gingo)"; else chatId = chatId+"(Atys)"; @@ -2736,3 +3002,7 @@ void CChatManager::update() } #endif } + +TChanID CChatManager::getChanId(const string name) { + return *_ChanNames.getA(name); +} diff --git a/ryzom/server/src/input_output_service/chat_manager.h b/ryzom/server/src/input_output_service/chat_manager.h index 372162e54..b3eeb8968 100644 --- a/ryzom/server/src/input_output_service/chat_manager.h +++ b/ryzom/server/src/input_output_service/chat_manager.h @@ -385,6 +385,7 @@ public: /** * Send a far chat message */ + void sendFarChat(const std::string &name, const ucstring& ucstr, const std::string &chan); void sendFarChat( CChatGroup::TGroupType senderChatMode, const TDataSetRow &receiver, const ucstring& ucstr, const ucstring &senderName, TChanID chanID = NLMISC::CEntityId::Unknown); /** @@ -417,6 +418,8 @@ public: void sendChatCustomEmote( const TDataSetRow &sender, const TDataSetRow &receiver, const ucstring& ucstr ); void update(); + + TChanID getChanId(const std::string name); }; diff --git a/ryzom/server/src/input_output_service/commands.cpp b/ryzom/server/src/input_output_service/commands.cpp index e74d7d66e..4d4080d22 100644 --- a/ryzom/server/src/input_output_service/commands.cpp +++ b/ryzom/server/src/input_output_service/commands.cpp @@ -688,21 +688,54 @@ NLMISC_COMMAND(chat, "send message chat", " ") return false; } - CChatGroup::TGroupType mode = CChatGroup::stringToGroupType(args[1]); + TChanID chanId = CEntityId::Unknown; + TGroupId groupId = CEntityId::Unknown; + + CChatGroup::TGroupType mode; + if (args[1] == "FACTION_RF") // The current only translated dynamic chat + { + chanId = IOS->getChatManager().getChanId("FACTION_RF"); + mode = CChatGroup::dyn_chat; + } + else if (args[1].substr(0, 7) == "region:") + { + mode = CChatGroup::region; + groupId.fromString(args[1].substr(7).c_str()); + } + else + { + mode = CChatGroup::stringToGroupType(args[1]); + } + + string chat_group = args[1]; ucstring ucstr; ucstr.fromUtf8(args[2]); TDataSetRow rowId = ci->DataSetIndex; try { CChatGroup::TGroupType oldMode = IOS->getChatManager().getClient(rowId).getChatMode(); + TChanID oldChanId = IOS->getChatManager().getClient(rowId).getDynChatChan(); + TGroupId oldRegionId =IOS->getChatManager().getClient(rowId).getRegionChatGroup(); + if (mode != oldMode) - IOS->getChatManager().getClient(rowId).setChatMode(mode); + IOS->getChatManager().getClient(rowId).setChatMode(mode, chanId); + + if (mode == CChatGroup::region) + IOS->getChatManager().getClient(rowId).setRegionChatGroup(groupId); + IOS->getChatManager().getClient(rowId).updateAudience(); IOS->getChatManager().chat(rowId, ucstr); if (oldMode != mode) - IOS->getChatManager().getClient(rowId).setChatMode(oldMode); + { + if (oldMode == CChatGroup::dyn_chat) + IOS->getChatManager().getClient(rowId).setChatMode(oldMode, oldChanId); + else if (oldMode == CChatGroup::region) + IOS->getChatManager().getClient(rowId).setRegionChatGroup(oldRegionId); + else + IOS->getChatManager().getClient(rowId).setChatMode(oldMode); + } } catch(const Exception &e) { @@ -712,6 +745,20 @@ NLMISC_COMMAND(chat, "send message chat", " ") return true; } +NLMISC_COMMAND(farChat, "send far message chat", " ") +{ + if (args.size() < 3) + return false; + + uint32 id; + ucstring ucstr; + + string name = args[0]; + ucstr.fromUtf8(args[2]); + + IOS->getChatManager().sendFarChat(name, ucstr, args[1]); +} + NLMISC_COMMAND(getRealName, "getRealName", "") { if (args.size() != 1) @@ -724,7 +771,7 @@ NLMISC_COMMAND(getRealName, "getRealName", "") return true; } - log.displayNL("%s", ci->ShortName.c_str()); + log.displayNL("%s", ci->ShortRealName.c_str()); return true; } diff --git a/ryzom/server/src/input_output_service/input_output_service.cpp b/ryzom/server/src/input_output_service/input_output_service.cpp index 5ceea4625..6199d4e11 100644 --- a/ryzom/server/src/input_output_service/input_output_service.cpp +++ b/ryzom/server/src/input_output_service/input_output_service.cpp @@ -68,7 +68,7 @@ using namespace std; CInputOutputService * IOS = NULL; -uint8 MaxDistSay = 1; +uint8 MaxDistSay = 1; uint8 MaxDistShout = 3; // true if we display all chat received @@ -84,8 +84,8 @@ CGenericXmlMsgHeaderManager GenericXmlMsgHeaderMngr; uint8 ticks_before_mongodb_check = 0; void CAIAliasManager::clear() -{ - _Translation.clear(); +{ + _Translation.clear(); } void CAIAliasManager::add(uint32 alias, const std::string &name) @@ -93,13 +93,13 @@ void CAIAliasManager::add(uint32 alias, const std::string &name) // _Translation[alias].first = name; //_Translation[alias].second = 0; //undef CCharacterInfos cInfo; - + std::string botName = name; ucstring ucname = botName; //addCharacterName - + ucstring title; // remove any $title$ specification in the short name @@ -122,10 +122,10 @@ void CAIAliasManager::add(uint32 alias, const std::string &name) // try to map a translated bot name on the short name cInfo.UntranslatedNameIndex = SM->storeString(ucname); cInfo.UntranslatedShortNameIndex = SM->storeString(cInfo.ShortName); - + cInfo.ShortNameIndex = SM->translateShortName(cInfo.UntranslatedShortNameIndex); - + cInfo.ShortName = SM->getString(cInfo.ShortNameIndex); // extract title from the translated bot name (if needed) @@ -147,7 +147,7 @@ void CAIAliasManager::add(uint32 alias, const std::string &name) - + // _Translation[alias].UntranslatedShortNameIndex = cInfo.ShortNameIndex; if (!cInfo.ShortName.empty()) @@ -162,19 +162,19 @@ void CAIAliasManager::add(uint32 alias, const std::string &name) _Translation[alias].ShortNameIndex = 0; } } - else + else { _Translation[alias].ShortNameIndex = 0; } - + if (!cInfo.Title.empty()) { // _Translation[alias].UntranslatedTitleIndex = cInfo.TitleIndex; unsigned int first = 0; unsigned int last = static_cast( CStringManager::NB_LANGUAGES ); for ( ;first != last; ++first) - { + { uint32 index = SM->translateTitle(cInfo.Title, static_cast(first));; if (index == cInfo.TitleIndex) { @@ -193,7 +193,7 @@ void CAIAliasManager::add(uint32 alias, const std::string &name) unsigned int first = 0; unsigned int last = static_cast( CStringManager::NB_LANGUAGES ); for ( ;first != last; ++first) - { + { _Translation[alias].TitleIndex[first] = 0; } } @@ -203,23 +203,23 @@ void CAIAliasManager::add(uint32 alias, const std::string &name) bool CAIAliasManager::is(uint32 alias) const { - return _Translation.find(alias) != _Translation.end(); + return _Translation.find(alias) != _Translation.end(); } /* -std::string CAIAliasManager::getShortName(uint32 alias) const -{ - return _Translation.find(alias)->second.ShortName; +std::string CAIAliasManager::getShortName(uint32 alias) const +{ + return _Translation.find(alias)->second.ShortName; }*/ -uint32 CAIAliasManager::getShortNameIndex(uint32 alias) const -{ - return _Translation.find(alias)->second.ShortNameIndex; +uint32 CAIAliasManager::getShortNameIndex(uint32 alias) const +{ + return _Translation.find(alias)->second.ShortNameIndex; } -uint32 CAIAliasManager::getTitleIndex(uint32 alias, CStringManager::TLanguages lang) const +uint32 CAIAliasManager::getTitleIndex(uint32 alias, CStringManager::TLanguages lang) const { nlassert( lang < CStringManager::NB_LANGUAGES ); - return _Translation.find(alias)->second.TitleIndex[lang]; + return _Translation.find(alias)->second.TitleIndex[lang]; } @@ -244,7 +244,7 @@ static void cbDisconnection( const string &serviceName, TServiceId serviceId, vo // warn the chat manager IOS->getChatManager().onServiceDown(serviceName); - + } // cbDisconnection // @@ -252,7 +252,7 @@ static void cbDisconnection( const string &serviceName, TServiceId serviceId, vo //--------------------------------------------------- // iosUpdate : -// +// //--------------------------------------------------- void iosUpdate() { @@ -270,7 +270,7 @@ void iosUpdate() //--------------------------------------------------- // iosSync : -// +// //--------------------------------------------------- void iosSync() { @@ -295,7 +295,7 @@ bool CInputOutputService::update() { // need to erase this one delete first->second.second; - + CEntityId id = first->first; _RemovedCharInfos.erase(first); @@ -349,7 +349,7 @@ void CInputOutputService::init() CStringManager::CParameterTraits::init(); setVersion (RYZOM_VERSION); - + IOS = this; setUpdateTimeout(100); @@ -364,7 +364,7 @@ void CInputOutputService::init() // CConfigFile::CVar& cvDynamicDB = ConfigFile.getVar("DynamicDB"); // dynamicDBFileName = cvDynamicDB.asString(); // } -// catch(const EUnknownVar &) +// catch(const EUnknownVar &) // { // nlwarning(" using default chat files"); // } @@ -376,7 +376,7 @@ void CInputOutputService::init() CConfigFile::CVar& cvMaxDistShout = ConfigFile.getVar("MaxDistShout"); MaxDistShout = cvMaxDistShout.asInt(); } - catch(const EUnknownVar &) + catch(const EUnknownVar &) { nlinfo(" using default chat max distance values"); } @@ -385,7 +385,7 @@ void CInputOutputService::init() SM->setTestOnly(); // init mission string manager. - SM->init(); + SM->init(); if (IService::getInstance()->haveArg('Q')) { @@ -410,7 +410,7 @@ void CInputOutputService::init() Mirror.init( datasetNames, cbMirrorIsReady, iosUpdate, iosSync ); CUnifiedNetwork::getInstance()->setServiceUpCallback( string("*"), cbConnection, 0); - CUnifiedNetwork::getInstance()->setServiceDownCallback( string("*"), cbDisconnection, 0); + CUnifiedNetwork::getInstance()->setServiceDownCallback( string("*"), cbDisconnection, 0); CShardNames::getInstance().init(ConfigFile); @@ -429,7 +429,7 @@ void CInputOutputService::init() // sn.DisplayName = sessionNames->asString(i*3+1); // sn.ShortName = sessionNames->asString(i*3+2); // sn.DisplayNameId = CStringMapper::map(sn.DisplayName); -// +// // // _SessionNames.push_back(sn); // } @@ -565,12 +565,14 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr { charInfos = new CCharacterInfos(); // store association - _IdToInfos.insert( make_pair(eid,charInfos) ); + _IdToInfos.insert( make_pair(eid, charInfos) ); } else { - // remove previous name association (because name have changed) - _NameToInfos.erase(charInfos->ShortName.toUtf8()); + // remove previous name only if it's different than real name (Real Name association can't be deleted) + if (charInfos->ShortName != charInfos->ShortRealName) + _NameToInfos.erase(charInfos->ShortName.toUtf8()); + oldname = charInfos->ShortName; // save the old name if (charInfos->EntityId != eid) @@ -588,7 +590,7 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr ucstring title; charInfos->EntityId = eid; charInfos->DataSetIndex = chId; - + // remove any $title$ specification in the short name ucstring::size_type pos = ucname.find('$'); if (pos != ucstring::npos) @@ -629,39 +631,21 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr // it will try to match it as a homeland name string::size_type pos = name.find('('); if (pos == string::npos) - { name = CShardNames::getInstance().makeFullName(name, charInfos->HomeSessionId); - } TCharInfoCont::iterator itInfos = _NameToInfos.find( name ); - if( itInfos == _NameToInfos.end() ) + if( itInfos == _NameToInfos.end() || name == charInfos->ShortRealName.toUtf8() ) { - // New name does not exist + // New name does not exist or is the real name charInfos->ShortName.fromUtf8(name); } - - TIdRealNames::iterator itRealName = _IdToRealName.find(eid); - if( itRealName != _IdToRealName.end() ) //Erase if found realname. New name will be added if need - _IdToRealName.erase(eid); - - // Lookup on _RenamedCharInfos about realname (if found => the player have a rename ) - itInfos = _RenamedCharInfos.find( charInfos->ShortName.toUtf8() ); - if( itInfos != _RenamedCharInfos.end() ) // New name was in the saved list; player is getting original name back - { - _RenamedCharInfos.erase(charInfos->ShortName.toUtf8()); - } - else // New name was not in the list, save old name (it's the real name) - { - _IdToRealName.insert(make_pair(eid, oldname.toUtf8())); - _RenamedCharInfos.insert( make_pair(oldname.toUtf8(), charInfos) ); - } } } // try to map a translated bot name on the short name charInfos->UntranslatedNameIndex = SM->storeString(ucname); charInfos->UntranslatedShortNameIndex = SM->storeString(charInfos->ShortName); - + // don't translate players names if (eid.getType() != RYZOMID::player) { @@ -669,7 +653,7 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr } else { - charInfos->ShortNameIndex = charInfos->UntranslatedShortNameIndex; + charInfos->ShortNameIndex = charInfos->UntranslatedShortNameIndex; } charInfos->ShortName = SM->getString(charInfos->ShortNameIndex); @@ -690,7 +674,7 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr charInfos->TitleIndex = SM->storeString(title); } } - + // build the translated name if (!charInfos->Title.empty()) charInfos->Name = charInfos->ShortName + "$" + charInfos->Title+"$"; @@ -733,10 +717,6 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr else { nlwarning( "ERROR: Received CHARACTER_NAME with null row!" ); - // Previously: not yet in the mirror - /*if ( ! charInfos->NameIndex.isReadable() ) - charInfos->NameIndex.tempAllocate(); - charInfos->NameIndex.tempReassign(SM->storeString(charInfos->Name));*/ } if (VerboseNameTranslation) { @@ -747,18 +727,18 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr chId.getIndex()); else nldebug("IOS: addCharacterName Adding name '%s' translated as '%s' for entity %s:%x", - ucname.toString().c_str(), - charInfos->Name.toString().c_str(), + ucname.toString().c_str(), + charInfos->Name.toString().c_str(), TheDataset.getEntityId(chId).toString().c_str(), chId.getIndex()); } - // store name assoc -// _NameToInfos.insert( make_pair(ucname,charInfos) ); + // Store realname only the first time (so never change) + if (charInfos->ShortRealName.empty()) + charInfos->ShortRealName = charInfos->ShortName; + // store the short name assoc. _NameToInfos.insert( make_pair(charInfos->ShortName.toUtf8(), charInfos) ); - // TODO : remove when dynDB removed -// charInfos->OldNameIndex = IOS->getChatManager().getDynamicDB().add(charInfos->ShortName, false); } // addCharacterName // @@ -770,56 +750,43 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr //----------------------------------------------- string CInputOutputService::getRocketName(const ucstring& chName) { - ucstring charname = chName; string realName; - string reName; - ucstring::size_type pos = charname.find('$'); - if (pos != string::npos) - charname = charname.substr(0, pos); - + string name; + TCharInfoCont::iterator itInfos; CCharacterInfos * charInfos = NULL; - TCharInfoCont::iterator itInfos = _NameToInfos.find(charname.toUtf8()); - if (itInfos != _NameToInfos.end()) // Char can have a rename, need found it on _IdToRealName + + ucstring::size_type pos = chName.find('$'); + if (pos != string::npos) + itInfos = _NameToInfos.find(chName.substr(0, pos).toUtf8()); + else + itInfos = _NameToInfos.find(chName.toUtf8()); + + // Get informations about a player. + if (itInfos != _NameToInfos.end()) { charInfos = itInfos->second; - realName = charInfos->Name.toString(); + realName = charInfos->ShortRealName.toUtf8(); + name = charInfos->ShortName.toUtf8(); } else { - itInfos = _RenamedCharInfos.find(charname.toUtf8()); - if (itInfos != _RenamedCharInfos.end()) // Char is renamed - { - realName = chName.toString(); - charInfos = itInfos->second; - if (charInfos != NULL) { - reName = charInfos->Name.toString(); - } - } + nlwarning("Name not found : %s", chName.toUtf8().c_str()); + return "unknown"; } - if (reName.empty() && charInfos != NULL) // Search for a rename - { - TIdRealNames::iterator itRealName = _IdToRealName.find(charInfos->EntityId); - if (itRealName != _IdToRealName.end()) - { - reName = realName; - realName = itRealName->second; - } - } - string::size_type spos = realName.find('('); if (spos != string::npos) realName = realName.substr(0, spos); - if (!reName.empty()) + if (!name.empty()) { - spos = reName.find('('); + spos = name.find('('); if (spos != string::npos) - reName = reName.substr(0, spos); + name = name.substr(0, spos); } - if (charInfos != NULL && !reName.empty() && !charInfos->HavePrivilege) - realName = reName+"@"+realName; + if (charInfos != NULL && !name.empty() && !charInfos->HavePrivilege) + realName = name+"@"+realName; return realName; @@ -864,13 +831,6 @@ CCharacterInfos * CInputOutputService::getCharInfos( const ucstring& chName ) { return itInfos->second; } - - // Not found so check any renamed players - itInfos = _RenamedCharInfos.find( chName.toUtf8() ); - if( itInfos != _RenamedCharInfos.end() ) - { - return itInfos->second; - } else { return NULL; @@ -888,7 +848,7 @@ void CInputOutputService::removeEntity( const TDataSetRow &chId ) if (_ChatManager.checkClient(chId)) { if (VerboseChatManagement) - nldebug("IOSCU: removeEntity : removing the client %s:%x from chat manager !", + nldebug("IOSCU: removeEntity : removing the client %s:%x from chat manager !", TheDataset.getEntityId(chId).toString().c_str(), chId.getIndex()); _ChatManager.removeClient( chId ); @@ -928,39 +888,14 @@ void CInputOutputService::removeEntity( const TDataSetRow &chId ) // index = itInfos->second->OldNameIndex; _NameToInfos.erase(itInfos->second->ShortName.toUtf8()); - TIdRealNames::iterator itRealName = _IdToRealName.find(eid); - if( itRealName != _IdToRealName.end() ) //Erase if found rename - { - _RenamedCharInfos.erase(itRealName->second); - _IdToRealName.erase(eid); - } + if (!itInfos->second->ShortRealName.empty() && itInfos->second->ShortRealName.toUtf8() != itInfos->second->ShortName.toUtf8()) + _NameToInfos.erase(itInfos->second->ShortRealName.toUtf8()); // erase the entry in _IdToInfos delete itInfos->second; itInfos->second = NULL; _IdToInfos.erase( itInfos ); - // erase the entry in _NameToInfos -/* CDynamicStringInfos * infos = _ChatManager.getDynamicDB().getInfos( index ); - if( infos ) - { - name = infos->Str; - map::iterator itInfos2 = _NameToInfos.find( name ); - if( itInfos2 != _NameToInfos.end() ) - { - _NameToInfos.erase( itInfos2 ); - } -*/ -/* else - { - nlwarning(" Unknown entity : %s",name.toString().c_str()); - } -*//* } - else - { - nlwarning(" Dynamic string %d unknown",index); - } -*/ } else { @@ -1008,14 +943,14 @@ void CInputOutputService::display(NLMISC::CLog &log) { // uint32 nameIndex = itInfos->second->OldNameIndex; // CDynamicStringInfos * infos = IOS->getChatManager().getDynamicDB().getInfos( nameIndex ); - log.displayNL("Name: %s \tentity: %s" /* \tindex: %d \tstr: %s"*/, - itInfos->first.c_str(), - itInfos->second->EntityId.toString().c_str() - /*, infos->Index, - infos->Str.toString().c_str()*/); + log.displayNL("Name: %s \tentity: %s" /* \tindex: %d \tstr: %s"*/, + itInfos->first.c_str(), + itInfos->second->EntityId.toString().c_str() + /*, infos->Index, + infos->Str.toString().c_str()*/); } log.displayNL("CHAT GROUPS : "); - IOS->getChatManager().displayChatGroups(log, false, false); + IOS->getChatManager().displayChatGroups(log, true, false); } // display // @@ -1062,7 +997,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdline, IOS->init(); return 1; - + } #endif @@ -1071,6 +1006,6 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdline, - + diff --git a/ryzom/server/src/input_output_service/input_output_service.h b/ryzom/server/src/input_output_service/input_output_service.h index 1ee4de12e..62842b34a 100644 --- a/ryzom/server/src/input_output_service/input_output_service.h +++ b/ryzom/server/src/input_output_service/input_output_service.h @@ -40,7 +40,7 @@ extern bool ShowChat; -extern uint8 MaxDistSay; +extern uint8 MaxDistSay; extern uint8 MaxDistShout; extern TPropertyIndex DSPropertyAI_INSTANCE; @@ -60,7 +60,7 @@ extern CGenericXmlMsgHeaderManager GenericXmlMsgHeaderMngr; // typedef uint32 TSessionId; - + /** * CCharacterInfos * \author Stephane Coutelas @@ -81,6 +81,10 @@ public: CMirrorPropValue< uint32, CPropLocationPacked<2> > NameIndex; /// Short name (ie name without the $title$ spec) ucstring ShortName; + + /// Short rename (ie name without the $title$ spec) + ucstring ShortRealName; + /// Short name index uint32 ShortNameIndex; /// The home mainland session id @@ -97,7 +101,7 @@ public: uint32 UntranslatedShortNameIndex; /// The untranslated event faction index. uint32 UntranslatedEventFactionId; - + /// Gender of the entity CMirrorPropValueRO< SPropVisualA > VisualPropertyA; @@ -123,7 +127,7 @@ public: /** * Default constructor */ - CCharacterInfos() + CCharacterInfos() : /*FrontendId(0),*/ HomeSessionId(0), HomeSessionNameId(0), @@ -169,7 +173,7 @@ public: bool is(uint32 alias) const; // std::string getName(uint32 alias) const; - + uint32 getShortNameIndex(uint32 alias) const; uint32 getTitleIndex(uint32 alias, CStringManager::TLanguages lang) const; @@ -202,12 +206,8 @@ private: /// infos on a character from his name TCharInfoCont _NameToInfos; - TIdRealNames _IdToRealName; - - /// Original information about renamed characters - TCharInfoCont _RenamedCharInfos; - typedef std::map > TTempCharInfoCont; + /// Temporary storage for removed entities, will survive here for 3000 ticks. TTempCharInfoCont _RemovedCharInfos; @@ -239,21 +239,21 @@ public: /// The list of named shard // CShardNames ChardNames; - /** + /** * init the service */ void init(); /// Init after the mirror init void initMirror(); - + void release(); /** * main loop */ bool update(); - + /** * get the alias manager */