diff --git a/code/ryzom/server/src/entities_game_service/admin.cpp b/code/ryzom/server/src/entities_game_service/admin.cpp index e4b4075b6..5db31d071 100644 --- a/code/ryzom/server/src/entities_game_service/admin.cpp +++ b/code/ryzom/server/src/entities_game_service/admin.cpp @@ -4284,11 +4284,11 @@ NLMISC_COMMAND (connectUserChannel, "Connect to user channels", " getUserDynChannel(name); if (args.size() < 3) - pass = name; + pass = toLower(name); else pass = args[2]; diff --git a/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp b/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp index c64d84c98..7c6a85b0c 100644 --- a/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp +++ b/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp @@ -231,7 +231,7 @@ void cbClientConnection(CMessage& msgin, const std::string &serviceName, NLNET:: const bool betaTester = (userExtended.find(":FBT:") != string::npos); const bool preOrder = (userExtended.find(":PO:") != string::npos); const bool windermeerCommunity = (userExtended.find(":WIND:") != string::npos); - const bool trialPlayer = (userExtended.find(":TRIAL:") != string::npos); + const bool trialPlayer = (userExtended.find(":TRB:") != string::npos); // load player infos player = new CPlayer; diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp b/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp index cfadf3967..56a2606dd 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp @@ -807,6 +807,16 @@ void CGuild::takeItem( CCharacter * user, uint32 slot, uint32 quantity, uint16 s return; } + // check if user is trial + CPlayer * p = PlayerManager.getPlayer(PlayerManager.getPlayerId( user->getId() )); + BOMB_IF(p == NULL, "Failed to find player record for character: " << user->getId().toString(), return); + if ( p->isTrialPlayer() ) + { + user->sendDynamicSystemMessage( user->getId(), "EGS_CANT_USE_GUILD_INV_IS_TRIAL_PLAYER" ); + return; + } + + CGuildMemberModule * module; if ( !user->getModuleParent().getModule(module) || !module->canTakeGuildItem() ) { diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.cpp b/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.cpp index 69798924a..a9016a376 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.cpp +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.cpp @@ -90,6 +90,14 @@ void CGuildCharProxy::spendMoney(uint64 money) _ModuleCore->spendMoney( money ); } +//---------------------------------------------------------------------------- +bool CGuildCharProxy::isTrialPlayer() +{ + CPlayer * p = PlayerManager.getPlayer(PlayerManager.getPlayerId( getId() )); + BOMB_IF(p == NULL, "Failed to find player record for character: " << getId().toString(), return true); + return p->isTrialPlayer(); +} + //---------------------------------------------------------------------------- void CGuildCharProxy::endBotChat() { diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.h b/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.h index 5713c7b48..fd4fe1c0b 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.h +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild_char_proxy.h @@ -55,6 +55,7 @@ public: void sendDynamicMessageToChatGroup( const std::string & msg, CChatGroup::TGroupType type, const TVectorParamCheck & params = TVectorParamCheck() ); uint64 getMoney(); void spendMoney(uint64 money); + bool isTrialPlayer(); void endBotChat(); bool getTarget(CGuildCharProxy & proxy); void setGuildId(uint32 guildId ); diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp index dc71e5e58..dfd516b45 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp @@ -28,6 +28,7 @@ #include "mission_log.h" #include "mission_manager/mission_manager.h" #include "mission_manager/mission_parser.h" +#include "player_manager/player_manager.h" #include "player_manager/character.h" #include "player_manager/character_encyclopedia.h" #include "mission_item.h" @@ -44,8 +45,9 @@ using namespace std; using namespace NLMISC; -extern CVariable MissionForcedSeason; -extern CVariable MissionPrerequisitsEnabled; +extern CVariable MissionForcedSeason; +extern CVariable MissionPrerequisitsEnabled; +extern CPlayerManager PlayerManager; NL_INSTANCE_COUNTER_IMPL(CMissionTemplate); @@ -179,7 +181,9 @@ bool CMissionTemplate::build(const NLLIGO::IPrimitive* prim,CMissionGlobalParsin Prerequisits.GuildGrade = EGSPD::CGuildGrade::Unknown; Prerequisits.TeamSize = 0; Prerequisits.Season = EGSPD::CSeason::Invalid; - + Prerequisits.CharacterMinAge = 0; + Prerequisits.MaxPlayerID = 0; + // init parsing vars bool ret = true; string value; @@ -528,7 +532,30 @@ bool CMissionTemplate::build(const NLLIGO::IPrimitive* prim,CMissionGlobalParsin if (ret) Prerequisits.EventFaction = CMissionParser::getNoBlankString( script[1] ); } - + // character oldness check loading + else if ( script[0] == "req_character_age" ) + { + sint age; + ret = parseInt( i+1, script,age ) && ret; + Prerequisits.CharacterMinAge = (uint32)age; + if ( Prerequisits.CharacterMinAge < 0 ) + { + MISLOGERROR1("character minimum age is %d. Must be >= 0", Prerequisits.CharacterMinAge ); + ret = false; + } + } + // maximum player ID check loading + else if ( script[0] == "req_max_player_id" ) + { + sint max_id; + ret = parseInt( i+1, script,max_id ) && ret; + Prerequisits.MaxPlayerID = (uint32)max_id; + if ( Prerequisits.MaxPlayerID < 0 ) + { + MISLOGERROR1("Maximum player ID is %u. Must be >= 0", Prerequisits.MaxPlayerID ); + ret = false; + } + } // update next step step text else if ( script[0] == "set_obj" ) { @@ -2281,6 +2308,82 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos prereqInfos.Prerequisits.push_back(prereqDesc); } } + + // check character minimum oldness + if( Prerequisits.CharacterMinAge > 0 ) + { + prereqDesc.Validated = true; + + uint32 minimumAge = Prerequisits.CharacterMinAge * 24 * 3600; // oldness required is given in days + uint32 characterAge = NLMISC::CTime::getSecondsSince1970() - user->getFirstConnectedTime(); + nlwarning("%s Require character age of %d days (%ds) and current character age is %d", sDebugPrefix.c_str(), + Prerequisits.CharacterMinAge, minimumAge, characterAge); + + if (characterAge < minimumAge) + { + if (logOnFail) + MISDBG("%s Require character age of %d days (%ds) and current character age is %d", sDebugPrefix.c_str(), + Prerequisits.CharacterMinAge, minimumAge, characterAge); + + if (returnValue == MISSION_DESC::PreReqSuccess) + { + if (!fillPrereqInfos) + {return MISSION_DESC::PreReqFail;} + + returnValue = MISSION_DESC::PreReqFail; + logOnFail = false; + } + prereqDesc.Validated = false; + } + if (fillPrereqInfos) + { + if (addedPrereqTexts.find("MISSION_PREREQ_CHARACTER_MIN_AGE") == addedPrereqTexts.end()) + { + SM_STATIC_PARAMS_2(params, STRING_MANAGER::integer, STRING_MANAGER::integer); + params[0].Int = (uint32) (characterAge / (24 * 3600) ); + params[1].Int = (uint32) Prerequisits.CharacterMinAge; + prereqDesc.Description = STRING_MANAGER::sendStringToClient(user->getEntityRowId(), "MISSION_PREREQ_CHARACTER_MIN_AGE", params); + prereqDesc.IsMandatory = true; + prereqInfos.Prerequisits.push_back(prereqDesc); + } + } + } + + // check maximum player ID + if (Prerequisits.MaxPlayerID > 0) + { + prereqDesc.Validated = true; + + uint32 playerId = PlayerManager.getPlayerId(user->getId()); + nlwarning("%s Require player ID of %d and player's ID is %d", sDebugPrefix.c_str(), + Prerequisits.MaxPlayerID, playerId); + + if (playerId > Prerequisits.MaxPlayerID ) + { + if (logOnFail) + MISDBG("%s Require player ID of %d and player's ID is %d", sDebugPrefix.c_str(), + Prerequisits.MaxPlayerID, playerId); + + if (returnValue == MISSION_DESC::PreReqSuccess) + { + if (!fillPrereqInfos) + {return MISSION_DESC::PreReqFail;} + + returnValue = MISSION_DESC::PreReqFail; + logOnFail = false; + } + prereqDesc.Validated = false; + } + if (fillPrereqInfos) + { + if (addedPrereqTexts.find("MISSION_PREREQ_MAX_PLAYER_ID") == addedPrereqTexts.end()) + { + prereqDesc.Description = STRING_MANAGER::sendStringToClient(user->getEntityRowId(), "MISSION_PREREQ_MAX_PLAYER_ID", TVectorParamCheck()); + prereqDesc.IsMandatory = true; + prereqInfos.Prerequisits.push_back(prereqDesc); + } + } + } } if (returnValue == MISSION_DESC::PreReqSuccess) diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.h b/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.h index 5593243ae..3509b3257 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.h +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.h @@ -242,13 +242,17 @@ public: /// true if the player must be in a guild bool Guild; /// minimum guild grade displayed by the player - EGSPD::CGuildGrade::TGuildGrade GuildGrade; + EGSPD::CGuildGrade::TGuildGrade GuildGrade; /// minimum team size uint8 TeamSize; /// actions that the player must know std::vector KnownActions; /// The season that must be current - EGSPD::CSeason::TSeason Season; + EGSPD::CSeason::TSeason Season; + /// Character minimum oldness + uint32 CharacterMinAge; + /// minimum account id + uint32 MaxPlayerID; // Requesite a specific thema of a specific album that all of its tasks are done // or if TaskDone is false check if at least one is not done diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character.cpp b/code/ryzom/server/src/entities_game_service/player_manager/character.cpp index 8cec0423e..0d244fb46 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/character.cpp @@ -207,7 +207,7 @@ extern vector Mainlands; CVariable SpawnedDeadMektoubDelay("egs","SpawnedDeadMektoubDelay", "nb tick before a dead mektoub despawn)", 2592000, 0, true ); CVariable ForceQuarteringRight("egs","ForceQuarteringRight", "Allow anyone to quarter a dead creature", false, 0, true ); CVariable AllowAnimalInventoryAccessFromAnyStable("egs", "AllowAnimalInventoryAccessFromAnyStable", "If true a player can access to his animal inventory (if the animal is inside a stable) from any stable over the world", true, 0, true ); -CVariable FreeTrialSkillLimit("egs", "FreeTrialSkillLimit", "Level limit for characters belonging to free trial accounts", 19,0,true); +CVariable FreeTrialSkillLimit("egs", "FreeTrialSkillLimit", "Level limit for characters belonging to free trial accounts", 125,0,true); CVariable CraftFailureProbaMpLost("egs", "CraftFailureProbaMpLost", "Probabilité de destruction de chaque MP en cas d'echec du craft", 50,0,true); @@ -4050,6 +4050,7 @@ void CCharacter::initDatabase() // combat flags //_ForbidPowerDates.writeUsablePowerFlags(_UsablePowerFlags); setPowerFlagDates(); + setAuraFlagDates(); updateBrickFlagsDBEntry(); // defense interface @@ -5262,6 +5263,17 @@ bool CCharacter::checkAnimalCount( const CSheetId& PetTicket, bool sendMessage, } return false; } + + CPlayer * p = PlayerManager.getPlayer(PlayerManager.getPlayerId( getId() )); + BOMB_IF(p == NULL,"Failed to find player record for character: "<isTrialPlayer() ) + { + if( sendMessage ) + { + sendDynamicSystemMessage( _Id, "EGS_CANT_BUY_PACKER_IS_TRIAL_PLAYER" ); + } + return false; + } } else { @@ -13885,7 +13897,7 @@ void CCharacter::setAuraFlagDates() const NLMISC::TGameCycle time = CTickEventHandler::getGameCycle(); uint32 flag = BRICK_FLAGS::Aura - BRICK_FLAGS::BeginPowerFlags; - if ( _ForbidAuraUseEndDate > time ) + if ( (_ForbidAuraUseEndDate > time) && (_ForbidAuraUseEndDate - time < 72000) ) { _PowerFlagTicks[flag].StartTick = _ForbidAuraUseStartDate; _PowerFlagTicks[flag].EndTick = _ForbidAuraUseEndDate; @@ -13895,7 +13907,6 @@ void CCharacter::setAuraFlagDates() _PowerFlagTicks[flag].StartTick = 0; _PowerFlagTicks[flag].EndTick = 0; } - } // setAuraFlagDates // @@ -15687,10 +15698,15 @@ void CCharacter::sendCustomEmote( const NLMISC::CEntityId& id, MBEHAV::EBehaviou if( behaviour != MBEHAV::IDLE ) { setEmote( behaviour ); - setAfkState(false); } string sEmoteCustomText = emoteCustomText.toUtf8(); + + if ((behaviour != MBEHAV::IDLE) || (sEmoteCustomText == "none")) + { + setAfkState(false); + } + if( sEmoteCustomText == "none" ) { return; diff --git a/code/ryzom/server/src/entities_game_service/player_manager/player_room.cpp b/code/ryzom/server/src/entities_game_service/player_manager/player_room.cpp index b12d8ce5f..19d622e4f 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/player_room.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/player_room.cpp @@ -221,6 +221,14 @@ bool CPlayerRoomInterface::canUseInventory(const CCharacter * owner, const CChar if (owner != user) return false; + CPlayer * p = PlayerManager.getPlayer(PlayerManager.getPlayerId( user->getId() )); + BOMB_IF(p == NULL, "Failed to find player record for character: " << user->getId().toString(), return true); + if ( p->isTrialPlayer() ) + { + user->sendDynamicSystemMessage( user->getId(), "EGS_CANT_USE_ROOM_INV_IS_TRIAL_PLAYER" ); + return false; + } + CMirrorPropValueRO mirrorCell( TheDataset, user->getEntityRowId(), DSPropertyCELL ); const sint32 cell = mirrorCell; if ( !CBuildingManager::getInstance()->isRoomCell(cell) ) diff --git a/code/ryzom/server/src/entities_game_service/player_manager/powers_and_auras.cpp b/code/ryzom/server/src/entities_game_service/player_manager/powers_and_auras.cpp index 253994bec..5e91311e8 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/powers_and_auras.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/powers_and_auras.cpp @@ -20,6 +20,8 @@ #include "powers_and_auras.h" #include "egs_sheets/egs_static_game_item.h" +#define MAX_ACTIVATION_DATE 72000 // 2h +#define MAX_DEACTIVATION_DATE 72000 // 2h //----------------------------------------------------------------------------- // CPowerActivationDate @@ -156,8 +158,24 @@ void CPowerActivationDateVector::activate() while (it != PowerActivationDates.end()) { - (*it).DeactivationDate = time - (*it).DeactivationDate; // the value saved is time length since deactivation, here we transform length into a date - (*it).ActivationDate += time; + if ( ((*it).DeactivationDate >= 0) && ((*it).DeactivationDate < MAX_DEACTIVATION_DATE) ) + { + (*it).DeactivationDate = time - (*it).DeactivationDate; // the value saved is time length since deactivation, here we transform length into a date + } + else + { + nlinfo("POWER_AURA_CONTROL : Bad Deactivation date : %d", (*it).DeactivationDate); + (*it).DeactivationDate = time - MAX_DEACTIVATION_DATE; + } + if ((*it).ActivationDate < MAX_ACTIVATION_DATE) + { + (*it).ActivationDate += time; + } + else + { + nlinfo("POWER_AURA_CONTROL : Bad Activation date : %d", (*it).ActivationDate); + (*it).ActivationDate = time; + } ++it; } doNotClear = false; @@ -214,7 +232,8 @@ void CAuraActivationDateVector::cleanVector() } else { - ++it;++itUser; + ++it; + ++itUser; } } } @@ -226,7 +245,7 @@ bool CAuraActivationDateVector::isAuraEffective(POWERS::TPowerType type, const N const NLMISC::TGameCycle time = CTickEventHandler::getGameCycle(); std::vector ::iterator it = _AuraActivationDates.begin(); std::vector ::iterator itUser = _AuraUsers.begin(); - + while (it != _AuraActivationDates.end()) { if ( (*it).ActivationDate <= time ) @@ -249,7 +268,6 @@ bool CAuraActivationDateVector::isAuraEffective(POWERS::TPowerType type, const N return result; } - //----------------------------------------------------------------------------- void CAuraActivationDateVector::activate() { @@ -258,7 +276,17 @@ void CAuraActivationDateVector::activate() while (it != _AuraActivationDates.end()) { - (*it).ActivationDate += time; + (*it).DeactivationDate = time - (*it).DeactivationDate; // the value saved is time length since deactivation, here we transform length into a date + + if ((*it).ActivationDate < MAX_ACTIVATION_DATE) + { + (*it).ActivationDate += time; + } + else + { + nlinfo("POWER_AURA_CONTROL : Bad Activation date : %d", (*it).ActivationDate); + (*it).ActivationDate = time; + } ++it; } } @@ -321,7 +349,15 @@ void CConsumableOverdoseTimerVector::activate() while (it != Dates.end()) { - (*it).ActivationDate += time; + if ((*it).ActivationDate < MAX_ACTIVATION_DATE) + { + (*it).ActivationDate += time; + } + else + { + nlinfo("POWER_AURA_CONTROL : Bad Activation date : %d", (*it).ActivationDate); + (*it).ActivationDate = time; + } ++it; } } diff --git a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.h b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.h index 2b68d9d7a..41d70edc8 100644 --- a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.h +++ b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.h @@ -29,6 +29,26 @@ class CEntityBase; class CGameItemPtr; class IPVPInterface; +// Comparator for case-insensitive comparison in STL assos. containers +struct ci_less : std::binary_function +{ + // case-independent (ci) compare_less binary function + struct nocase_compare : public std::binary_function + { + bool operator() (const unsigned char& c1, const unsigned char& c2) const + { + return tolower (c1) < tolower (c2); + } + }; + bool operator() (const std::string & s1, const std::string & s2) const + { + return std::lexicographical_compare( + s1.begin (), s1.end (), // source range + s2.begin (), s2.end (), // dest range + nocase_compare ()); // comparison + } +}; + /** * CPVPManager2 singleton. * @@ -41,7 +61,7 @@ class CPVPManager2 NL_INSTANCE_COUNTER_DECL(CPVPManager2); public: typedef std::map< PVP_CLAN::TPVPClan, TChanID > TMAPFactionChannel; - typedef std::map< std::string, TChanID > TMAPExtraFactionChannel; + typedef std::map< std::string, TChanID, ci_less > TMAPExtraFactionChannel; // Names are case-rententive but not case-sensitive typedef std::map< TChanID, std::string > TMAPPassChannel; ///\name LOW LEVEL MANAGEMENT diff --git a/code/ryzom/server/src/input_output_service/input_output_service.cpp b/code/ryzom/server/src/input_output_service/input_output_service.cpp index 546bc5681..0a9c193e8 100644 --- a/code/ryzom/server/src/input_output_service/input_output_service.cpp +++ b/code/ryzom/server/src/input_output_service/input_output_service.cpp @@ -541,6 +541,7 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr CEntityId eid = TheDataset.getEntityId(chId); + ucstring oldname; CCharacterInfos * charInfos = IOS->getCharInfos( eid, false ); if( charInfos == NULL ) { @@ -553,6 +554,7 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr // remove previous name association // _NameToInfos.erase(ucname); _NameToInfos.erase(charInfos->ShortName.toUtf8()); + oldname = charInfos->ShortName; if (charInfos->EntityId != eid) { @@ -599,6 +601,42 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr break; } } + + // See if an existing player was renamed + if (!oldname.empty()) + { + TSessionId sessionid; + string name = charInfos->ShortName.toUtf8(); + // Make sure that the short name contains the home session name, but only if the new name does not exist yet + // otherwise we will have problems. If the new name contains opening parentheses then don't add it because + // 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() ) + { + // New name does not exist + charInfos->ShortName = ucstring(name); + } + + // Save the old name only if new name is not found (and the player is getting original name back) + itInfos = _RenamedCharInfos.find( charInfos->ShortName.toUtf8() ); + if( itInfos != _RenamedCharInfos.end() ) + { + // New name was in the saved list; player is getting original name back. + // Remove the new name + _RenamedCharInfos.erase(charInfos->ShortName.toUtf8()); + } + else + { + // New name was not in the list, save old name + _RenamedCharInfos.insert( make_pair(oldname.toUtf8(), charInfos) ); + } + } } // try to map a translated bot name on the short name @@ -745,6 +783,13 @@ CCharacterInfos * CInputOutputService::getCharInfos( const ucstring& chName ) { return itInfos->second; } + + // Not found so check any renamed players + itInfos = _RenamedCharInfos.find( chName.toUtf8() ); + if( itInfos != _NameToInfos.end() ) + { + return itInfos->second; + } else { return NULL; diff --git a/code/ryzom/server/src/input_output_service/input_output_service.h b/code/ryzom/server/src/input_output_service/input_output_service.h index e1c21a7c2..618c1761e 100644 --- a/code/ryzom/server/src/input_output_service/input_output_service.h +++ b/code/ryzom/server/src/input_output_service/input_output_service.h @@ -201,7 +201,9 @@ private: /// infos on a character from his name TCharInfoCont _NameToInfos; - + /// Original information about renamed characters + TCharInfoCont _RenamedCharInfos; + typedef std::map > TTempCharInfoCont; /// Temporary storage for removed entities, will survive here for 3000 ticks. TTempCharInfoCont _RemovedCharInfos; diff --git a/code/ryzom/server/src/input_output_service/string_manager.cpp b/code/ryzom/server/src/input_output_service/string_manager.cpp index 2e598f70b..dcea3f2b0 100644 --- a/code/ryzom/server/src/input_output_service/string_manager.cpp +++ b/code/ryzom/server/src/input_output_service/string_manager.cpp @@ -68,6 +68,7 @@ std::string CStringManager::_LanguageCode[NB_LANGUAGES] = "de", "fr", "ru", + "es", /* ace: currently, we only want english, i remove other language to remove warning during IOS launch "fr", // french diff --git a/code/ryzom/server/src/input_output_service/string_manager.h b/code/ryzom/server/src/input_output_service/string_manager.h index bbc5ec442..d860df126 100644 --- a/code/ryzom/server/src/input_output_service/string_manager.h +++ b/code/ryzom/server/src/input_output_service/string_manager.h @@ -62,6 +62,7 @@ public: german, french, russian, + spanish, NB_LANGUAGES }; diff --git a/code/ryzom/server/src/shard_unifier_service/login_service.cpp b/code/ryzom/server/src/shard_unifier_service/login_service.cpp index bdad5e0d9..7612d51bb 100644 --- a/code/ryzom/server/src/shard_unifier_service/login_service.cpp +++ b/code/ryzom/server/src/shard_unifier_service/login_service.cpp @@ -366,10 +366,12 @@ namespace LS { nlwarning("on_login : Can't find ring user %u from account %u with GMId", otherUserId, userId); } - else if (otherRu->getCurrentStatus() != TCurrentStatus::cs_offline) // cs_logged and cs_online + //else if (otherRu->getCurrentStatus() != TCurrentStatus::cs_offline) // cs_logged and cs_online + else if (otherRu->getCurrentStatus() == TCurrentStatus::cs_online) // less strict check, only avoid csr/player account logged on the same time { // DON'T check in the entity locator that the player is really online //if (IEntityLocator::getInstance() && IEntityLocator::getInstance()->isUserOnline(otherUserId)) + if (IEntityLocator::getInstance() && IEntityLocator::getInstance()->isUserOnline(otherUserId)) { nldebug("LS : on_login : user %u already connected, rejecting login of %u with GMId", otherUserId, userId); loginResult(from, userId, "", 3, toString("User %u (%u's GMId) already online", otherUserId, userId)); @@ -392,10 +394,12 @@ namespace LS { nlwarning("on_login : Can't find ring user %u which GMID is account %u", otherUserId, userId); } - else if (otherRu->getCurrentStatus() != TCurrentStatus::cs_offline) // cs_logged and cs_online + //else if (otherRu->getCurrentStatus() != TCurrentStatus::cs_offline) // cs_logged and cs_online + else if (otherRu->getCurrentStatus() == TCurrentStatus::cs_online) // less strict check, only avoid csr/player account logged on the same time { // DON'T check in the entity locator that the player is really online //if (IEntityLocator::getInstance() && IEntityLocator::getInstance()->isUserOnline(otherUserId)) + if (IEntityLocator::getInstance() && IEntityLocator::getInstance()->isUserOnline(otherUserId)) { nldebug("LS : on_login : user %u already connected, rejecting login of %u which is the GMId of it", otherUserId, userId); loginResult(from, userId, "", 4, toString("GM user %u (having GMId=%u) already online", otherUserId, userId));