Merge branch 'deepl'

feature/prepare-cross-merge
Ulukyn 4 years ago committed by kaetemi
parent ea095ca4f3
commit e6bb1f2f54
No known key found for this signature in database
GPG Key ID: 9873C4D40BB479BC

@ -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", "<user id> <lang>
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", "<user id> <lang>
NLMISC_COMMAND (setDontTranslateLangs, "Set langs that a player dont want to see translated", "<user id> <langs>")
{
if (args.size() != 2)
if (args.size() != 2)
return false;
GET_CHARACTER
@ -4875,7 +4878,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
{
if ( (itemPtr->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", "<user id> <web_app_url
}
}
//*************************************************
//***************** set_fame (need x6000 to change 1 point)
//*************************************************
@ -5114,7 +5117,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
else if (command_args[2] == "del")
{
CFameManager::getInstance().setEntityFame(c->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", "<user id> <web_app_url
}
//*************************************************
//***************** check_target
//***************** check_target
//*************************************************
else if (command_args[0] == "check_target")
{
const CEntityId &target = c->getTarget();
if (command_args.size () < 2) return false;
if (command_args[1] == "leaguemate")
@ -5189,7 +5192,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
return false;
}
}
if (command_args.size () < 3) return false;
if (command_args[1] == "sheet")
@ -5251,7 +5254,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
}
//*************************************************
//***************** check_brick
//***************** check_brick
//*************************************************
else if (command_args[0] == "check_brick")
{
@ -5266,7 +5269,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
}
//*************************************************
//***************** set_brick
//***************** set_brick
//*************************************************
else if (command_args[0] == "set_brick")
{
@ -5381,12 +5384,12 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
CSheetId outpostSheet(command_args[1]);
outpost = COutpostManager::getInstance().getOutpostFromSheet(outpostSheet);
}
if (outpost == NULL)
{
return false;
}
if ((command_args[2] != "attacker") && (command_args[2] != "defender") && (command_args[2] != "attack") && (command_args[2] != "defend"))
return false;
@ -5459,7 +5462,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
if (command_args.size() > 7)
{
if (command_args[6] != "*") {
float userX;
NLMISC::fromString(command_args[6], userX);
@ -5491,7 +5494,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
}
}
//[[inVillage=0/1][inOutpost=0/1][inStable=0/1][InAtys=0/1]]
//[[inVillage=0/1][inOutpost=0/1][inStable=0/1][InAtys=0/1]]
std::string validation;
if (command_args.size() > 10)
{
@ -5502,7 +5505,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
bool inOutpost = validation[1] == '1';
bool inStable = validation[2] == '1';
bool inAtys = validation[3] == '1';
if (!c->isSpawnValid(inVillage, inOutpost, inStable, inAtys))
return false;
}
@ -5543,14 +5546,14 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
//*************************************************
//***************** group_script
//*************************************************
else if (command_args[0] == "group_script")
{
if (command_args.size () < 3) return false;
uint32 instanceNumber = c->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", "<user id> <web_app_url
//*************************************************
//***************** change_vpx
//*************************************************
else if (command_args[0] == "change_vpx")
{
if (command_args.size () != 4) return false;
CCharacter *target = PlayerManager.getCharacterByName(CShardNames::getInstance().makeFullNameFromRelative(c->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", "<user id> <web_app_url
// Checks : PvP Flag, PvP Tag, Sitting, Water, Mount, Fear, Sleep, Invu, Stun
if (command_args.size () > 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", "<user id> <web_app_url
}
string value = command_args[1];
vector<string> res;
sint32 x = 0, y = 0, z = 0;
float h = 0;
@ -6003,7 +6006,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
if (allowPetTp)
c->allowNearPetTp();
else
c->forbidNearPetTp();
c->forbidNearPetTp();
// Respawn player if dead
if (c->isDead())
@ -6070,7 +6073,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
if (allowPetTp)
c->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", "<user id> <web_app_url
ucstring customName = ucstring(command_args[2]);
c->setAnimalName(petIndex, customName);
}
//*************************************************
//***************** organization
//*************************************************
@ -6127,7 +6130,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
string action = command_args[1]; // change, add_points, set_status, add_status
sint32 value;
fromString(command_args[2], value);
if (action == "change" && value >= 0)
c->setOrganization((uint32)value);
else if (action == "add_points")
@ -6137,7 +6140,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
else if (action == "add_status")
c->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", "<user id> <web_app_url
if (command_args.size() < 2) return false;
string action = command_args[1]; // trigger_in, trigger_out, add_guild_room, add_player_room
if (action == "trigger_in" && command_args.size () == 3)
{
uint32 liftId = atoi(command_args[2].c_str());
uint32 liftId = atoi(command_args[2].c_str());
CBuildingManager::getInstance()->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", "<user id> <web_app_url
if (owner)
owner->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", "<user id> <web_app_url
SKILLS::ESkills skillEnum = SKILLS::toSkill( command_args[2] );
uint32 wantedValue;
fromString(command_args[3], wantedValue);
if (c->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", "<user id> <web_app_url
c->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", "<user id> <web_app_url
}
}
}
//*************************************************
//***************** Money
//*************************************************
else if (command_args[0] == "money")
{
if (command_args.size() < 3) return false;
string action = command_args[1]; // check, give, spend
if (action == "check")
{
uint64 wantedMoney;
@ -6339,7 +6342,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
else if (command_args[0] == "guild")
{
if (command_args.size() < 3) return false;
CGuild * guild = CGuildManager::getInstance()->getGuildFromId(c->getGuildId());
if (guild == NULL)
{
@ -6347,9 +6350,9 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
c->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", "<user id> <web_app_url
return true;
}
}
}
//*************************************************
@ -6402,9 +6405,9 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
else if (command_args[0] == "reset")
{
if (command_args.size() < 2) return false;
string action = command_args[1]; // pvp, powers
if (action == "pvp")
{
c->resetPVPTimers();
@ -6422,10 +6425,10 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
else if (command_args[0] == "faction_points")
{
if (command_args.size() < 4) return false;
string action = command_args[1]; // check, set, add, remove
PVP_CLAN::TPVPClan clan = PVP_CLAN::fromString(command_args[2]);
if ((clan < PVP_CLAN::BeginClans) || (clan > PVP_CLAN::EndClans))
{
@ -6434,7 +6437,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
uint32 value;
fromString(command_args[3], value);
if (action=="check")
{
if (c->getFactionPoint(clan) < value)
@ -6458,7 +6461,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
c->setFactionPoint(clan, 0, true);
else
c->setFactionPoint(clan, c->getFactionPoint(clan)-value, true);
}
}
}
//*************************************************
@ -6500,15 +6503,15 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
//*************************************************
//***************** ios
//*************************************************
else if (command_args[0] == "ios")
{
if (command_args.size() < 4)
return false;
string action = command_args[1]; // single_phrase
if (action == "single_phrase")
{
string phraseName = command_args[2];
@ -6518,7 +6521,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
phraseContent += "(){[";
phraseContent += phraseText;
phraseContent += "]}";
string msgname = "SET_PHRASE";
bool withLang = false;
string lang = "";
@ -6545,10 +6548,10 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
//*************************************************
//***************** sendurl
//*************************************************
else if (command_args[0] == "sendurl")
{
if (command_args.size() != 4)
return false;
@ -6556,7 +6559,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
string app = command_args[2]; // app
string params = command_args[3]; // params
CCharacter *destPlayer;
if (player != "_target_") {
CEntityBase *entityBase = PlayerManager.getCharacterByName(CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(), player));
destPlayer = dynamic_cast<CCharacter*>(CEntityBaseManager::getEntityBasePtr(entityBase->getId()));
@ -6573,10 +6576,10 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
//***************** dt_bot
// /a webExecCommand debug 1 dt_bot!bejc hmac 0
//*************************************************
/* else if (command_args[0] == "dt_bot")
{
if (command_args.size() != 2)
return false;
@ -6612,7 +6615,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
nlwarning ("'%s' has no eId. Is it Spawned???", botname.c_str());
return true;
}
}*/
//*************************************************
@ -6709,7 +6712,7 @@ NLMISC_COMMAND (webExecCommand, "Execute a web command", "<user id> <web_app_url
{
uint32 nbString = (uint32)command_args.size();
string text = getStringFromHash(command_args[3]);
for (uint32 i=4; i<nbString; ++i)
text += "\n"+getStringFromHash(command_args[i]);
c->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", "<player eid>
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", "<player eid> <posXm> <po
return false;
GET_CHARACTER
float x = (float)c->getX();
float y = (float)c->getY();
@ -8538,7 +8541,7 @@ NLMISC_COMMAND(eventSpawnToxic, "Spawn a toxic cloud", "<player eid> <posXm> <po
}
}
}
CToxicCloud *tc = new CToxicCloud();
float radius = (float)(iRadius*2 + 1); // {1, 3, 5} corresponding to the 3 sheets
tc->init( cloudPos, radius, dmgPerHit, updateFrequency, lifetime );
@ -8572,9 +8575,9 @@ NLMISC_COMMAND(eventSpawnDamageLine, "Spawn a damage line", "<player eid> <name>
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", "<eid> <member
// Kick
user->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", "<eid> <member
team->setLeagueId(DYN_CHAT_INVALID_CHAN);
team->updateLeague();
}
return true;
}
@ -9058,7 +9061,7 @@ NLMISC_COMMAND(openTargetApp, "open target app", "<user_id>")
//----------------------------------------------------------------------------
// (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", "<user_id> [bullying]")
@ -9264,8 +9267,8 @@ NLMISC_COMMAND(characterInventoryDump, "Dump character inventory info", "<eid> <
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", "<eid> <
++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", "<user id> [<name>]")
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", "<user id> [<name>]")
NLMISC_COMMAND(eventGiveControl, "Give control of entity A to entity B", "<eid> <master eid> <slave eid>")
{
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", "<eid>
NLMISC_COMMAND(eventLeaveControl, "Leave control of entity", "<eid> <master eid>")
{
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", "<id> <phrase> [<language c
string msgname = "SET_PHRASE";
bool withLang = false;
string lang = "";
if (args.size() == 3)
if (args.size() == 3)
{
lang = args[2];
if (lang != "all")

@ -645,7 +645,7 @@ CCharacter::CCharacter()
_LastUrlIndex = 0;
_CustomMissionsParams.clear();
_FriendVisibility = VisibleToAll;
_LangChannel = "en";
_LangChannel = "rf";
_NewTitle = "Refugee";
initDatabase();

@ -157,7 +157,7 @@ public:
typedef std::map<NLMISC::CSheetId, CFameContainerEntryPD>::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"

@ -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<TChanID> 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<TChanID> CPVPManager2::getCharacterChannels(CCharacter * user)
result.push_back((*it).second);
}
}
// Organizations
if (user->getOrganization() == 5) // marauder
{
@ -266,7 +266,7 @@ std::vector<TChanID> 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("<USERS>");
msgout.serial(const_cast<ucstring&>(users));
msgout.serial(const_cast<ucstring&>(users));
msgout.serial(senderRow);
ucstring txt = ucstring(players);
msgout.serial(const_cast<ucstring&>(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<CCharacter*>(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<CCharacter*>(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<CCharacter*>(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<DBClientCursor> 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("<CPVPManager2::sendFactionWarsToClient> 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<TYPE_CELL> mirrorCell( TheDataset, user->getEntityRowId(), DSPropertyCELL );
sint32 cell1 = mirrorCell;
sint32 cell1 = mirrorCell;
CMirrorPropValueRO<TYPE_CELL> 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("<PVP>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

@ -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<CEntityId> 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<uint32> 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);
}

@ -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);
};

@ -688,21 +688,54 @@ NLMISC_COMMAND(chat, "send message chat", "<char_name> <chat_group> <message>")
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", "<char_name> <chat_group> <message>")
return true;
}
NLMISC_COMMAND(farChat, "send far message chat", "<char_name> <chat_id> <message>")
{
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", "<char_name>")
{
if (args.size() != 1)
@ -724,7 +771,7 @@ NLMISC_COMMAND(getRealName, "getRealName", "<char_name>")
return true;
}
log.displayNL("%s", ci->ShortName.c_str());
log.displayNL("%s", ci->ShortRealName.c_str());
return true;
}

@ -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<unsigned int>( CStringManager::NB_LANGUAGES );
for ( ;first != last; ++first)
{
{
uint32 index = SM->translateTitle(cInfo.Title, static_cast<CStringManager::TLanguages>(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<unsigned int>( 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("<CInputOutputService::init> 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("<CInputOutputService::init> 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<ucstring,CCharacterInfos *>::iterator itInfos2 = _NameToInfos.find( name );
if( itInfos2 != _NameToInfos.end() )
{
_NameToInfos.erase( itInfos2 );
}
*/
/* else
{
nlwarning("<CInputOutputService::removeEntity> Unknown entity : %s",name.toString().c_str());
}
*//* }
else
{
nlwarning("<CInputOutputService::removeEntity> 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,

@ -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<NLMISC::CEntityId, std::pair<NLMISC::TGameCycle, CCharacterInfos*> > 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
*/

Loading…
Cancel
Save