// Ryzom - MMORPG Framework
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
//
// User Privilege set in the mysql database must be like that ":GM:" or "" or ":GM:ADMIN:" ....
//
//
//
//
// Includes
//
#include "stdpch.h"
#include "admin.h"
#include "nel/misc/common.h"
#include "nel/misc/command.h"
#include "nel/misc/variable.h"
#include "nel/misc/eid_translator.h"
#include "nel/misc/algo.h"
#include "nel/misc/sstring.h"
#include "nel/net/admin.h"
#include "nel/net/service.h"
#include "game_share/scores.h"
#include "game_share/send_chat.h"
#include "game_share/time_weather_season/time_date_season_manager.h"
#include "game_share/permanent_ban_magic_number.h"
#include "game_share/fame.h"
#include "game_share/visual_slot_manager.h"
#include "game_share/shard_names.h"
#include "server_share/log_command_gen.h"
#include "server_share/r2_vision.h"
#include "server_share/log_item_gen.h"
#include "server_share/log_character_gen.h"
#include "egs_sheets/egs_sheets.h"
#include "egs_sheets/egs_static_rolemaster_phrase.h"
#include "egs_sheets/egs_static_encyclo.h"
#include "player_manager/player_manager.h"
#include "player_manager/player.h"
#include "player_manager/character.h"
#include "player_manager/character_encyclopedia.h"
#include "creature_manager/creature_manager.h"
#include "phrase_manager/phrase_manager.h"
#include "mission_manager/mission_manager.h"
#include "mission_manager/mission_queue_manager.h"
#include "entities_game_service.h"
#include "player_manager/character_respawn_points.h"
#include "weather_everywhere.h"
#include "phrase_manager/fg_prospection_phrase.h"
#include "team_manager/team_manager.h"
#include "world_instances.h"
#include "egs_variables.h"
#include "player_manager/gm_tp_pending_command.h"
#include "guild_manager/guild_manager.h"
#include "guild_manager/guild.h"
#include "guild_manager/guild_member.h"
#include "guild_manager/guild_member_module.h"
#include "guild_manager/guild_char_proxy.h"
#include "guild_manager/fame_manager.h"
#include "mission_manager/mission_solo.h"
#include "mission_manager/mission_solo.h"
#include "position_flag_manager.h"
//#include "name_manager.h"
#include "zone_manager.h"
#include "player_manager/character_game_event.h"
#include "game_event_manager.h"
#include "dyn_chat_egs.h"
#include "pvp_manager/pvp.h"
#include "player_manager/admin_properties.h"
#include "shop_type/offline_character_command.h"
#include "player_manager/item_service_manager.h"
#include "outpost_manager/outpost_manager.h"
#include "primitives_parser.h"
#include "shop_type/named_items.h"
#include "progression/progression_pvp.h"
#include "modules/shard_unifier_client.h"
#include "modules/client_command_forwarder.h"
#include "modules/guild_unifier.h"
//
// Externs
//
extern CPlayerManager PlayerManager;
extern CCreatureManager CreatureManager;
extern CPlayerService *PS;
extern CGenericXmlMsgHeaderManager GenericMsgManager;
extern CBSAIDeathReport BotDeathReport;
extern NLMISC::CVariable FixedSessionId;
//
// Namespaces
//
using namespace NLMISC;
using namespace NLNET;
using namespace std;
extern CVariable BannerPriv;
//
// Functions
//
//
// ALL THESE COMMANDS ARE USED BY THE CLIENT *AND* THE ADMIN TOOL TO MANAGE A PLAYER
//
// You can assume here that the user can execute the command, you don't have to check it
//
// Don't forget to add your command in the AdminCommandsInit array if you want the command to be executed on the client
//
// If you change parameter or add/remove something, please update the wiki:
//
// http://www.nevrax.net/wiki/index.php/Main/CommandesAdmin
//
// AddEid must be true if you want to have the eid in the args[0] of the command
// Privileges are now stored in a text file (data_shard/client_commands_privileges.txt), do not forget to update it.
// please update the following stuff if you add new GM titles
// player_manager.cpp : NLMISC_COMMAND(setPriv,"set a privilege to a user using his user id, must be in form :priv1:priv2:priv3:"," ")
// player_manager.cpp : hasBetterCSRGrade
static const struct
{
const char * Name;
bool AddEId;
}
AdminCommandsInit[] =
{
// player character accessible commands
"teamInvite", true,
"guildInvite", true,
"setGuildMessage", true,
"clearGuildMessage", true,
"dodge", true,
"parry", true,
"respawnAfterDeath", true,
"resurrected", true,
"validateRespawnPoint", true,
"summonPet", true,
"addPetAnimal", true,
"addSkillPoints", true,
"addXPToSkill", true,
"changeMode", true,
"checkTargetSP", true,
"clearFriendsList", true,
"clearIgnoreList", true,
"clearIsFriendOfList", true,
"createItemInBag", true,
"createItemInInv", true,
"createItemInTmpInv", true,
"createNamedItemInBag", true,
"createFullArmorSet", true,
"displayInfosOnTarget", true,
"execPhrase", true,
"execMemorizedPhrase", true,
"executeSabrinaPhrase", true,
"forceTargetToDie", true,
"learnAllBricks", true,
"learnAllRolemasterBricks", true,
"learnAllPhrases", true,
"learnBrick", true,
"unlearnBrick", true,
"learnPhrase", true,
"learnAllForagePhrases", true,
"learnAllFaberPlans", true,
"logXpGain", true,
"memorizePhrase", true,
"resetPowerFlags", true,
"setSkillsToMaxValue", true,
"displayForageRM", true,
"setItemSapLoad", true,
"showFBT", true,
"allowSummonPet", true,
"setPetAnimalSatiety", true,
"getPetAnimalSatiety", true,
"taskPass", true,
"setFamePlayer", true,
"guildMOTD", true,
// CSR commands
"motd", false,
"broadcast", false,
"summon", true,
"dismiss", true,
"teleport", true,
"renamePlayerForEvent", true,
"renamePlayer", true,
"renameGuild", true,
"setGuildDescription", true,
"setGuildIcon", false,
"killMob", true,
"changeVar", true,
"root", true,
"unroot", true,
"ignoreTells", true, // hierarchy
"showCSR", true,
"monitorMissions", true,
"stopMonitorMissions", true,
"failMission", true,
"progressMission", true,
"mute", true,
"unmute", true,
"muteUniverse", true,
"unmuteUniverse", true,
"universe", true,
"setGMGuild", true,
"targetInfos", true,
"infos", true,
"addPosFlag", true,
"setPosFlag", true,
"delPosFlag", true,
"lPosFlags", true,
"listPosFlags", true,
"tpPosFlag", true,
"updateGuildMembersList", true,
"listGuildMembers", true,
"addGuildMember", true,
"setGuildMemberGrade", true,
"setGuildLeader", true,
"startEvent", true,
"stopEvent", true,
"getEventFaction", true,
"setEventFaction", true,
"clearEventFaction", true,
"giveRespawnPoint", true,
"provideItemService", true,
"dumpFactionPVPDamage", true,
"changeHairCut", true,
"farTPPush", true,
"farTPReplace", true,
"farTPReturn", true,
"resetPVPTimers", true,
"savePlayerActiveChar", false,
"reloadPlayer", false,
"characterMissionDump", true,
"removeMission", true,
"addMission", true,
// CSR variables
"Invisible", true, // not in /who; hierarchy except for user with privilege
"God", true,
"Invulnerable", true,
"ShowFactionChannels", true,
"CreateCharacterStartSkillsValue", false,
"HP", true,
"MaxHP", true,
"Speed", true,
"Money", true,
"MoneyGuild", true,
"FactionPoint", true,
"Name", true,
"Position", true,
"Priv", true,
"PriviledgePVP", true,
"FBT", true,
"RyzomDate", false,
"RyzomTime", false,
"addGuildXp", false,
"setGuildChargePoint", false,
// PUT HERE THE VARIABLE / COMMAND THAT ARE TEMPORARY
// remove when message of the day interface is ready
// remove this when death interface is ready
"respawnCharacter", true,
"buyPact", true,
"cancelTopPhrase", true, //temp : to remove
"EntitiesNoActionFailure", false,
"EntitiesNoCastBreak", false,
"EntitiesNoResist", false,
// aggroable state
"Aggro", true,
// outpost commands
"outpostBanGuild", false,
"outpostBanPlayer", false,
"outpostUnbanGuild", false,
"outpostUnbanPlayer", false,
"outpostChallengeByGuild", false,
"outpostSimulateTimer0End", false,
"outpostSimulateTimer1End", false,
"outpostSimulateTimer2End", false,
"outpostSetFightData", false,
"setOutpostLevel", false,
"outpostAccelerateConstruction", false,
"outpostSetOutpostOwner", false,
"outpostChallengeOutpost", true,
"outpostGiveupOutpost", true,
"outpostDisplayGuildOutposts", true,
"outpostForceOpenGuildInventory", true,
"outpostForceCloseGuildInventory", true,
"outpostSetPlayerPvpSide", true,
"outpostSetOutpostToPlayer", true,
"outpostSelectOutpost", true,
"outpostUnselectOutpost", true,
"setPvpClan", true, //remove it when interface fo choose pvp clan is ready
"setPvPTag", true, //set pvp tag to true or false
// stuff added by sadge for testing character read/ write stuff
"saveToXML", true,
"loadFromXML", true,
"saveToPDR", true,
"loadFromPDR", true,
// queues related stuff
"acceptProposalForQueue", true,
"awakePlayerInQueue", true,
"displayShopSelector", true,
"addFactionAttackableToTarget", true,
"eventCreateNpcGroup", true,
"eventNpcGroupScript", true,
"eventSetBotName", true,
"eventSetBotScale", true,
"eventSetNpcGroupAggroRange", true,
"eventSetFaunaBotAggroRange", true,
"eventResetFaunaBotAggroRange", true,
"eventSetBotCanAggro", true,
"eventSetItemCustomText", true,
"eventResetItemCustomText", true,
"eventSetBotSheet", true,
"eventSetBotFaction", true,
"eventSetBotFameByKill", true,
"dssTarget", true, //ring stuff
"forceMissionProgress", true,
"eventSetBotURL",true,
"eventSetBotURLName",true,
};
static vector AdminCommands;
static string CommandsPrivilegesFileName;
static string PositionFlagsFileName;
static const char * DefaultPriv = ":DEV:";
// forward declarations
static void loadCommandsPrivileges(const string & fileName, bool init);
void cbRemoteClientCallback (uint32 rid, const std::string &cmd, const std::string &entityNames);
//
CAdminCommand * findAdminCommand(const string & name)
{
H_AUTO(findAdminCommand);
const uint nbCommands = (uint)AdminCommands.size();
for (uint i = 0; i < nbCommands; i++)
{
if (name == AdminCommands[i].Name)
return &AdminCommands[i];
}
return NULL;
}
static void cbCommandsPrivilegesFileChange(const string & fileName)
{
H_AUTO(cbCommandsPrivilegesFileChange);
if (fileName != CommandsPrivilegesFileName)
return;
loadCommandsPrivileges(fileName, false);
}
void initAdmin ()
{
const uint nbCommands = sizeof(AdminCommandsInit) / sizeof(AdminCommandsInit[0]);
for (uint i = 0; i < nbCommands; i++)
{
CAdminCommand cmd;
cmd.Name = AdminCommandsInit[i].Name;
cmd.AddEId = AdminCommandsInit[i].AddEId;
cmd.Priv = DefaultPriv;
AdminCommands.push_back(cmd);
}
setRemoteClientCallback (cbRemoteClientCallback);
}
void initCommandsPrivileges(const std::string & fileName)
{
H_AUTO(initCommandsPrivileges);
loadCommandsPrivileges(fileName, true);
}
static void loadCommandsPrivileges(const string & fileName, bool init)
{
H_AUTO(loadCommandsPrivileges);
CIFile ifile;
if (!ifile.open(fileName))
{
nlwarning ("ADMIN: file '%s' cannot be opened", fileName.c_str());
return;
}
if (init)
{
const string filePath = CPath::getFullPath(fileName, false);
CFile::removeFileChangeCallback(CommandsPrivilegesFileName);
CFile::addFileChangeCallback(filePath, cbCommandsPrivilegesFileChange);
CommandsPrivilegesFileName = filePath;
}
// reset privileges with default value
const uint nbCommands = (uint)AdminCommands.size();
for (uint i = 0; i < nbCommands; i++)
{
AdminCommands[i].Priv = DefaultPriv;
}
// load file content
CSString fileContent;
uint32 fileSize = ifile.getFileSize();
uint8 * buf = new uint8[fileSize + 1];
ifile.serialBuffer(buf, fileSize);
ifile.close();
buf[fileSize] = 0;
fileContent = (char *)buf;
delete [] buf;
while (!fileContent.empty())
{
CSString line = fileContent.strtok("\r\n");
// remove any comment
line = line.splitTo("//");
if (line.strip().empty())
continue;
CSString fullLine = line;
// only extract the first 2 params
CVectorSString params;
for (uint i = 0; !line.empty() && i < 2; i++)
{
string param = line.strtok(" \t");
if (param.empty())
break;
params.push_back(param);
}
if (params.size() < 1)
{
nlwarning("ADMIN: invalid entry: '%s'.", fullLine.c_str());
continue;
}
// check second param if it is a forward info
if (params.size() > 1 && params[1][0] == '[')
{
// this is a forward
}
else if (params.size() > 2)
{
nlwarning("ADMIN: invalid entry: '%s'.", fullLine.c_str());
continue;
}
else
{
// no forward
params.insert(params.begin()+1, "[]");
}
if (params.size() < 3)
{
// no required privilege
params.push_back("");
}
const string & cmdName = params[0];
const string & forward = params[1];
const string & cmdPriv = params[2];
CAdminCommand * cmd = findAdminCommand(cmdName);
if (cmd)
{
cmd->Priv = cmdPriv;
cmd->ForwardToservice = forward.substr(1, forward.size()-2);
nlinfo("ADMIN: command '%s' forwarded to [%s] has new privileges '%s'.", cmdName.c_str(), cmd->ForwardToservice.c_str(), cmdPriv.c_str());
}
else
{
nlwarning("ADMIN: command '%s' is unknown.", cmdName.c_str());
}
}
}
void initPositionFlags(const std::string & fileName)
{
H_AUTO(initPositionFlags);
string fileNameAndPath = Bsi.getLocalPath() + fileName;
if (CFile::fileExists(fileNameAndPath))
{
CPositionFlagManager::getInstance().loadFromFile(fileName);
}
PositionFlagsFileName = fileName;
}
static void selectEntities (const string &entityName, vector &entities)
{
H_AUTO(selectEntities);
if (entityName.empty ())
return;
/*
*
* valid name formats:
*
* - * Select all entities
* - Select the specified entity using his eid
*/
if (entityName == "*")
{
// we want all entities
for (CPlayerManager::TMapPlayers::const_iterator it = PlayerManager.getPlayers().begin(); it != PlayerManager.getPlayers().end(); ++it)
{
if ((*it).second.Player != 0)
{
const CCharacter *c = (*it).second.Player->getActiveCharacter();
if (c != 0)
{
entities.push_back (c->getId());
}
}
}
}
else if (entityName[0] == '(')
{
// we want a specific entity id
CEntityId eid (entityName);
if (eid != CEntityId::Unknown)
entities.push_back (eid);
}
else
{
// try with the name
CEntityId eid = CEntityIdTranslator::getInstance()->getByEntity(CShardNames::getInstance().makeFullNameFromRelative(TSessionId(FixedSessionId), entityName));
if (eid != CEntityId::Unknown)
entities.push_back (eid);
}
}
#define ENTITY_VARIABLE(__name,__help) \
struct __name##Class : public NLMISC::ICommand \
{ \
__name##Class () : NLMISC::ICommand("variables",#__name, __help, " []") { Type = Variable; } \
virtual bool execute(const std::string &rawCommandString, const std::vector &args, NLMISC::CLog &log, bool quiet, bool human) \
{ \
if (args.size () != 1 && args.size () != 2) \
return false; \
\
vector entities; \
selectEntities (args[0], entities); \
\
for (uint i = 0; i < entities.size(); i++) \
{ \
string value; \
if (args.size()==2) \
value = args[1]; \
else \
value = "???"; \
pointer (entities[i], (args.size()==1), value); \
if (quiet) \
log.displayNL ("%s %s", entities[i].toString().c_str(), value.c_str()); \
else \
log.displayNL ("Entity %s Variable %s = %s", entities[i].toString().c_str(), _CommandName.c_str(), value.c_str()); \
} \
return true; \
} \
void pointer(CEntityId entity, bool get, std::string &value); \
}; \
__name##Class __name##Instance; \
void __name##Class::pointer(CEntityId entity, bool get, std::string &value)
//
// This macro get an eid and return c that is a pointer to a CCharacter.
//
#define ENTITY_GET_ENTITY \
TLogContext_Character_AdminCommand commandContext(entity); \
CEntityBase *e = CEntityBaseManager::getEntityBasePtr(entity); \
if(e == 0) \
{ \
nlwarning ("Unknown entity '%s'", entity.toString().c_str()); \
if(get) value = "UnknownEntity"; \
return; \
} \
if(!TheDataset.isAccessible(e->getEntityRowId())) \
{ \
nlwarning ("'%s' is not valid in mirror", entity.toString().c_str()); \
if(get) value = "NotValidInMirror"; \
return; \
}
#define ENTITY_GET_CHARACTER \
TLogContext_Character_AdminCommand commandContext(entity); \
CCharacter *c = PlayerManager.getChar(entity); \
if(c == 0) \
{ \
nlwarning ("Unknown player '%s'", entity.toString().c_str()); \
if(get) value = "UnknownPlayer"; \
return; \
} \
if(!c->getEnterFlag()) \
{ \
nlwarning ("'%s' is not entered", entity.toString().c_str()); \
if(get) value = "NotEntered"; \
return; \
} \
if(!TheDataset.isAccessible(c->getEntityRowId())) \
{ \
nlwarning ("'%s' is not valid in mirror", entity.toString().c_str()); \
if(get) value = "NotValidInMirror"; \
return; \
}
void GET_CHARACTER_Helper(std::string& command, const NLMISC::CEntityId& id, const std::string& adminCommand)
{
CAdminOfflineCommand::makeStringCommande( command, id, adminCommand );
COfflineCharacterCommand::getInstance()->addOfflineCommandWithoutApply( command );
}
#define GET_ENTITY \
if (args.size() < 1) { nlwarning ("Missing argument number 0 that should be the eid"); return false; } \
CEntityId eid(args[0]); \
if (eid == CEntityId::Unknown) \
return true; \
TLogContext_Character_AdminCommand commandContext(eid); \
CEntityBase *e = CEntityBaseManager::getEntityBasePtr(eid); \
if(e == 0) \
{ \
nlwarning ("Unknown entity '%s'", eid.toString().c_str()); \
return true; \
} \
if(!TheDataset.isAccessible(e->getEntityRowId())) \
{ \
nlwarning ("'%s' is not valid in mirror", eid.toString().c_str()); \
return true; \
}
#define TRY_GET_CHARACTER \
if (args.size() < 1) { nlwarning ("Missing argument number 0 that should be the eid"); return false; } \
CEntityId eid(args[0]); \
TLogContext_Character_AdminCommand commandContext(eid); \
CCharacter *c = PlayerManager.getChar(eid); \
if (!c) \
{ \
nlwarning("Unknown character '%s'", args[0].c_str()); \
return false; \
}
#define CHECK_RIGHT( csr, target ) \
{\
if ( !PlayerManager.hasBetterCSRGrade( csr, target ) )\
{\
if ( csr )\
CCharacter::sendDynamicSystemMessage( csr->getEntityRowId(), "CSR_BAD_RIGHTS" );\
return false;\
}\
}
#define GET_GUILD(argPos, onlyLocal, eId) \
CGuild * guild = CGuildManager::getInstance()->getGuildByName( args[argPos] );\
if ( guild == NULL )\
{\
/* try to find the guild with an id*/ \
uint32 shardId =0; \
uint32 guildId =0; \
sscanf(args[argPos].c_str(), "%u:%u", &shardId, &guildId); \
guild = CGuildManager::getInstance()->getGuildFromId((shardId<<20)+guildId); \
\
if (guild == NULL) \
{ \
if (eId != NLMISC::CEntityId::Unknown)\
{\
CCharacter::sendDynamicSystemMessage(eId, "GUILD_IS_PROXY");\
}\
log.displayNL("Invalid guild '%s'",args[argPos].c_str());\
return true;\
} \
} \
if (onlyLocal && guild->isProxy())\
{\
log.displayNL("The guild '%s' is a foreign guild, operation forbidden", guild->getName().toString().c_str());\
return true;\
}\
//
// You can here all variables for a player.
//
// Don't forget to add your command in the AdminCommandsInit array if you want the command to be executed on the client
//
ENTITY_VARIABLE(HP, "Hit points of a player")
{
ENTITY_GET_ENTITY
if (get)
{
value = toString (e->currentHp());
}
else
{
e->getScores()._PhysicalScores[SCORES::hit_points].Current = atoi(value.c_str());
}
}
ENTITY_VARIABLE(MaxHP, "Max hit points of a player")
{
ENTITY_GET_ENTITY
if (get)
{
value = toString (e->maxHp());
}
else
{
e->getScores()._PhysicalScores[SCORES::hit_points].Max = atoi(value.c_str());
}
}
ENTITY_VARIABLE(Speed, "Speed modifier of an entity")
{
ENTITY_GET_ENTITY
if (get)
{
value = toString (e->getEventSpeedVariationModifier());
}
else
{
e->setEventSpeedVariationModifier((float)atof(value.c_str()));
}
}
ENTITY_VARIABLE(Name, "Name of a player")
{
ENTITY_GET_ENTITY
if (get)
{
// value = CEntityIdTranslator::getInstance()->getByEntity(entity).toString();
value = e->getName ().toString();
}
else
{
}
}
ENTITY_VARIABLE(Money, "Money")
{
ENTITY_GET_CHARACTER
if (get)
{
value = toString("%"NL_I64"u", c->getMoney());
}
else
{
sint dir = 0;
if (!value.empty())
{
if(value[0] == '+') dir = +1;
else if(value[0] == '-') dir = -1;
else if(!isdigit(value[0]))
{
nlwarning ("Bad money format for %s right format is [] sign can be +,- or nothing to set the money", value.c_str());
return;
}
}
else
{
nlwarning ("You must provide a []");
return;
}
if(dir == 0)
{
c->setMoney(NLMISC::atoiInt64(value.c_str()));
}
else
{
uint64 val = NLMISC::atoiInt64(value.substr(1).c_str());
if(dir == 1)
c->giveMoney(val);
else
c->spendMoney(val);
}
nlinfo ("Player %s money is %"NL_I64"u", entity.toString().c_str(),c->getMoney());
}
}
ENTITY_VARIABLE(MoneyGuild, "MoneyGuild")
{
ENTITY_GET_CHARACTER
CGuild * guild = CGuildManager::getInstance()->getGuildFromId(c->getGuildId());
if (guild == NULL)
{
nlwarning("Invalid guild");
return;
}
if (get)
{
value = toString("%"NL_I64"u", guild->getMoney());
}
else
{
sint dir = 0;
if (!value.empty())
{
if(value[0] == '+') dir = +1;
else if(value[0] == '-') dir = -1;
else if(!isdigit(value[0]))
{
nlwarning ("Bad money format for %s right format is [] sign can be +,- or nothing to set the money", value.c_str());
return;
}
}
else
{
nlwarning ("You must provide a []");
return;
}
if(dir == 0)
{
guild->setMoney(NLMISC::atoiInt64(value.c_str()));
}
else
{
uint32 val = atoi(value.substr(1).c_str());
if(dir == 1)
guild->addMoney(val);
else
guild->spendMoney(val);
}
nlinfo ("Player %s guild money is %"NL_I64"u", entity.toString().c_str(),guild->getMoney());
}
}
ENTITY_VARIABLE(FactionPoint, "FactionPoint")
{
ENTITY_GET_CHARACTER
if (get)
{
string sTmp;
for (uint i = PVP_CLAN::BeginClans; i <= PVP_CLAN::EndClans; ++i)
sTmp += PVP_CLAN::toString((PVP_CLAN::TPVPClan)i) + " : " + toString(c->getFactionPoint((PVP_CLAN::TPVPClan)i)) + "\n";
value = sTmp;
}
else
{
string sFactionName = value.substr(0, value.find(','));
string sNumber = value.substr(value.find(',')+1);
if (value.empty() || sFactionName.empty() || sNumber.empty())
{
nlwarning ("You must provide : []");
return;
}
sint dir = 0;
if(sNumber[0] == '+') dir = +1;
else if(sNumber[0] == '-') dir = -1;
else if(!isdigit(sNumber[0]))
{
nlwarning ("Bad format for '%s' right format is [] sign can be +,- or nothing", sNumber.c_str());
return;
}
PVP_CLAN::TPVPClan clan = PVP_CLAN::fromString(sFactionName);
if ((clan < PVP_CLAN::BeginClans) || (clan > PVP_CLAN::EndClans))
{
nlwarning ("'%s' is not a valid faction name", sFactionName.c_str());
return;
}
if(dir == 0)
{
c->setFactionPoint(clan, atoi(sNumber.c_str()), true);
}
else
{
uint32 val = atoi(sNumber.substr(1).c_str());
if(dir == 1)
c->setFactionPoint(clan, c->getFactionPoint(clan)+val, true);
else
c->setFactionPoint(clan, c->getFactionPoint(clan)-val, true);
}
}
}
ENTITY_VARIABLE (Priv, "User privilege")
{
ENTITY_GET_CHARACTER
CPlayer *p = PlayerManager.getPlayer(PlayerManager.getPlayerId(c->getId()));
if (p == 0)
{
nlwarning ("Can't find player with UserId %d for checking privilege, assume no priv", PlayerManager.getPlayerId(c->getId()));
return;
}
if (get)
{
value = p->getUserPriv();
}
else
{
p->setUserPriv(value);
nlinfo ("%s have now this priv '%s'", entity.toString().c_str(), value.c_str());
}
return;
}
ENTITY_VARIABLE (FBT, "Focus Beta Tester")
{
ENTITY_GET_CHARACTER
CPlayer * p = PlayerManager.getPlayer(PlayerManager.getPlayerId( c->getId() ));
if (p == NULL)
{
nlwarning ("Can't find player with UserId %d", PlayerManager.getPlayerId( c->getId() ));
return;
}
if (get)
{
value = NLMISC::toString(p->isBetaTester());
}
else
{
if (value == "1" || value == "on" || strlwr(value) == "true")
{
p->isBetaTester(true);
}
else if (value == "0" || value == "off" || strlwr(value) == "false")
{
p->isBetaTester(false);
}
nlinfo ("%s %s now a Focus Beta Tester", entity.toString().c_str(), (p->isBetaTester() ? "is" : "isn't"));
}
}
ENTITY_VARIABLE(Position, "Position of a player (in meter) ,[,][,] | | | home | ")
{
H_AUTO(Position);
ENTITY_GET_ENTITY
vector res;
sint32 x = 0, y = 0, z = 0;
if (get)
{
x = e->getState().X() / 1000;
y = e->getState().Y() / 1000;
z = e->getState().Z() / 1000;
value = toString ("%d,%d,%d", x, y, z);
}
else
{
if ( value.find(',') != string::npos )
{
explode (value, string(","), res);
if (res.size() >= 2)
{
x = atoi (res[0].c_str()) * 1000;
y = atoi (res[1].c_str()) * 1000;
}
if (res.size() >= 3)
z = atoi (res[2].c_str()) * 1000;
}
else
{
if ( value.find(".creature") != string::npos )
{
CSheetId creatureSheetId(value);
if( creatureSheetId != CSheetId::Unknown )
{
double minDistance = -1.;
CCreature * creature = NULL;
TMapCreatures::const_iterator it;
const TMapCreatures& creatures = CreatureManager.getCreature();
for( it = creatures.begin(); it != creatures.end(); ++it )
{
CSheetId sheetId = (*it).second->getType();
if( sheetId == creatureSheetId )
{
double distance = PHRASE_UTILITIES::getDistance( e->getEntityRowId(), (*it).second->getEntityRowId() );
if( !creature || (creature && distance < minDistance) )
{
creature = (*it).second;
minDistance = distance;
}
}
}
if( creature )
{
x = creature->getState().X();
y = creature->getState().Y();
z = creature->getState().Z();
}
}
else
{
nlwarning (" '%s' is an invalid creature", value.c_str());
}
}
else
{
// try to find the player name
CCharacter *c = dynamic_cast(e);
if (c == NULL)
{
nlwarning (" '%s' is not a player", entity.toString().c_str());
return;
}
CEntityBase *entityBase = PlayerManager.getCharacterByName (CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(), value));
if (entityBase == 0)
{
// try to find the bot name
vector aliases;
CAIAliasTranslator::getInstance()->getNPCAliasesFromName( value, aliases );
if ( aliases.empty() )
{
nldebug (" Ignoring attempt to teleport because no NPC found matching name '%s'", value.c_str());
return;
}
TAIAlias alias = aliases[0];
const CEntityId & botId = CAIAliasTranslator::getInstance()->getEntityId (alias);
if ( botId != CEntityId::Unknown )
{
entityBase = CreatureManager.getCreature (botId);
}
else
{
nlwarning ("'%s' has no eId. Is it Spawned???", value.c_str());
return;
}
}
if (entityBase != 0)
{
x = entityBase->getState().X + sint32 (cos (entityBase->getState ().Heading) * 2000);
y = entityBase->getState().Y + sint32 (sin (entityBase->getState ().Heading) * 2000);
z = entityBase->getState().Z;
}
}
}
if (x == 0 && y == 0 && z == 0)
{
nlwarning ("'%s' is a bad value for position, don't change position", value.c_str());
return;
}
CCharacter * c = dynamic_cast(e);
if( c )
{
CContinent * cont = CZoneManager::getInstance().getContinent(x,y);
if(c->getCurrentContinent() == CONTINENT::NEWBIELAND )
{
if( cont == 0 || cont->getId() != CONTINENT::NEWBIELAND )
{
log_Command_TPOutsideNewbieland(c->getId());
// nlwarning("Position %s player outside NEWBIELAND, this is logged.", c->getId().toString().c_str());
}
}
c->allowNearPetTp();
if (res.size() >= 4)
{
// season included
c->teleportCharacter(x,y,z,true, false, 0.f, 0xFF, 0, (uint8) atoi(res[3].c_str()));
}
else
{
c->teleportCharacter(x,y,z,true);
}
if ( cont )
{
c->getRespawnPoints().addDefaultRespawnPoint( CONTINENT::TContinent(cont->getId()) );
}
}
else
{
e->tpWanted (x, y, z);
}
}
}
//-----------------------------------------------
// change_mode :
//-----------------------------------------------
NLMISC_COMMAND(changeMode," change_mode"," ")
{
if( args.size() == 2 )
{
CEntityId id;
id.fromString( args[0].c_str() );
MBEHAV::EMode mode = MBEHAV::EMode(atoi(args[1].c_str()));
CEntityBase *e = 0;
if( id.getType() == 0 )
{
e = PlayerManager.getChar(id);
}
if (e)
{
e->setMode( mode, true );
log.displayNL("Character %s mode changed to %d", id.toString().c_str(), mode);
}
else
{
log.displayNL("Unknown entity %s ",id.toString().c_str());
}
return true;
}
return false;
} // change_mode //
//-----------------------------------------------
// checkTargetSP :check target player SP
//-----------------------------------------------
NLMISC_COMMAND(checkTargetSP," check target player skill points (if there is lost SP)","")
{
if( args.size() < 1 )
return false;
GET_CHARACTER
CCharacter *targetPlayer = PlayerManager.getChar( c->getTargetDataSetRow() );
if (!targetPlayer)
{
log.displayNL("No target or invalid target");
return true;
}
uint32 totalEarnedSp = targetPlayer->getTotalEarnedSP();
uint32 spentSp = targetPlayer->getActionsSPValue() - targetPlayer->getStartActionsSPValue();
uint32 currentSp = (uint32) targetPlayer->getSP(EGSPD::CSPType::Craft);
currentSp += (uint32) targetPlayer->getSP(EGSPD::CSPType::Fight);
currentSp += (uint32) targetPlayer->getSP(EGSPD::CSPType::Magic);
currentSp += (uint32) targetPlayer->getSP(EGSPD::CSPType::Harvest);
// log result
log.displayNL("Player %s : Current SP total = %u, totalEarnedSp = %u, spentTotalSP = %u, MISSING SP = %d", targetPlayer->getId().toString().c_str(), currentSp, totalEarnedSp, spentSp, totalEarnedSp-spentSp-currentSp);
// send result to asker
string strTemp = NLMISC::toString("Player %s : Current SP total = %u, totalEarnedSp = %u, spentTotalSP = %d, MISSING SP = %d",targetPlayer->getId().toString().c_str(), currentSp, totalEarnedSp, spentSp, totalEarnedSp-spentSp-currentSp);
chatToPlayer(eid, strTemp);
return true;
} // checkSP //
NLMISC_COMMAND (createItemInBag, "Create an item and put it in the player bag", " | [force]")
{
if (args.size() < 4 || args.size() > 5) return false;
GET_CHARACTER
string sheetName = args[1];
CSheetId sheet;
uint32 sheetId = atoi(sheetName.c_str());
if (sheetId != 0)
{
sheet = CSheetId(sheetId);
}
else
{
if (sheetName.find(".") == string::npos)
sheetName += ".sitem";
sheet = CSheetId(sheetName.c_str());
}
if (sheet == CSheetId::Unknown)
{
log.displayNL("sheetId '%s' is Unknown", sheetName.c_str());
return false;
}
// banners are the only items in game which use privilege
if( sheetName.find("banner") != string::npos )
{
CPlayer * player = PlayerManager.getPlayer( PlayerManager.getPlayerId(eid) );
// if (player != NULL && !player->havePriv(":DEV:") )
if (player != NULL && player->havePriv(BannerPriv) )
{
if( sheetName.find("_gu") != string::npos && !player->havePriv(":G:") ) return false;
if( sheetName.find("_sgu") != string::npos && !player->havePriv(":SG:") ) return false;
if( sheetName.find("_vgu") != string::npos && !player->havePriv(":VG:") ) return false;
if( sheetName.find("_gm") != string::npos && !player->havePriv(":GM:") ) return false;
if( sheetName.find("_sgm") != string::npos && !player->havePriv(":SGM:") ) return false;
}
}
const CStaticItem *form = CSheets::getForm (sheet);
if (form == 0)
{
log.displayNL ("sheetId '%s' is not found", sheetName.c_str());
return false;
}
sint quantity = atoi(args[2].c_str());
if (quantity < 1)
{
log.displayNL ("Quantity must be > 0");
return false;
}
sint quality = atoi(args[3].c_str());
if (quality < 1)
{
log.displayNL ("Quality must be > 0");
return false;
}
bool res = c->createItemInInventory(INVENTORIES::bag, quality, quantity, sheet);
bool forceCreate;
if (args.size() == 5 && args[4] == "force")
forceCreate = true;
else
forceCreate = false;
if (!res && forceCreate)
{
CGameItemPtr item = GameItemManager.createItem(sheet, quality, true, true);
if (item != NULL)
{
res = c->addItemToInventory(INVENTORIES::bag, item);
if (!res)
item.deleteItem();
}
}
if (res)
log.displayNL ("Item '%s' created and set in the bag of the player %s", sheet.toString ().c_str(), eid.toString().c_str());
else
log.displayNL ("Failed to create and set the item '%s' for the player %s", sheet.toString ().c_str(), eid.toString().c_str());
return res;
}
NLMISC_COMMAND (createItemInTmpInv, "Create an item and put it in the player temp inventory", " | ")
{
if (args.size () != 4) return false;
GET_CHARACTER
string sheetName = args[1];
CSheetId sheet;
uint32 sheetId = atoi(sheetName.c_str());
if (sheetId != 0)
{
sheet = CSheetId(sheetId);
}
else
{
if (sheetName.find(".") == string::npos)
sheetName += ".item";
sheet = CSheetId(sheetName.c_str());
}
if (sheet == CSheetId::Unknown)
{
log.displayNL("sheetId '%s' is Unknown", sheetName.c_str());
return false;
}
// banners are the only items in game which use privilege
if( sheetName.find("banner") != string::npos )
{
CPlayer * player = PlayerManager.getPlayer( PlayerManager.getPlayerId(eid) );
if (player != NULL && player->havePriv(BannerPriv) )
{
if( sheetName.find("_gu") != string::npos && !player->havePriv(":G:") ) return false;
if( sheetName.find("_sgu") != string::npos && !player->havePriv(":SG:") ) return false;
if( sheetName.find("_vgu") != string::npos && !player->havePriv(":VG:") ) return false;
if( sheetName.find("_gm") != string::npos && !player->havePriv(":GM:") ) return false;
if( sheetName.find("_sgm") != string::npos && !player->havePriv(":SGM:") ) return false;
}
}
const CStaticItem *form = CSheets::getForm (sheet);
if (form == 0)
{
log.displayNL ("sheetId '%s' is not found", sheetName.c_str());
return false;
}
sint quantity = atoi(args[2].c_str());
if (quantity < 1)
{
log.displayNL ("Quantity must be > 0");
return false;
}
sint quality = atoi(args[3].c_str());
if (quality < 1)
{
log.displayNL ("Quality must be > 0");
return false;
}
bool res = c->createItemInInventory(INVENTORIES::temporary, quality, quantity, sheet);
if (res)
log.displayNL ("Item '%s' created and set in the temp inventory of the player %s", sheet.toString ().c_str(), eid.toString().c_str());
else
log.displayNL ("Failed to create and set the item '%s' for the player %s", sheet.toString ().c_str(), eid.toString().c_str());
return res;
}
NLMISC_COMMAND (createItemInInv, "Create items and put them in the given inventory", " | ")
{
if (args.size () != 6) return false;
GET_CHARACTER
string sheetName = args[2];
CSheetId sheet;
uint32 sheetId = atoi(sheetName.c_str());
if (sheetId != 0)
{
sheet = CSheetId(sheetId);
}
else
{
if (sheetName.find(".") == string::npos)
sheetName += ".sitem";
sheet = CSheetId(sheetName.c_str());
}
if (sheet == CSheetId::Unknown)
{
log.displayNL("sheetId '%s' is Unknown", sheetName.c_str());
return false;
}
// banners are the only items in game which use privilege
if( sheetName.find("banner") != string::npos )
{
CPlayer * player = PlayerManager.getPlayer( PlayerManager.getPlayerId(eid) );
if (player != NULL && player->havePriv(BannerPriv) )
{
if( sheetName.find("_gu") != string::npos && !player->havePriv(":G:") ) return false;
if( sheetName.find("_sgu") != string::npos && !player->havePriv(":SG:") ) return false;
if( sheetName.find("_vgu") != string::npos && !player->havePriv(":VG:") ) return false;
if( sheetName.find("_gm") != string::npos && !player->havePriv(":GM:") ) return false;
if( sheetName.find("_sgm") != string::npos && !player->havePriv(":SGM:") ) return false;
}
}
const CStaticItem *form = CSheets::getForm (sheet);
if (form == 0)
{
log.displayNL ("sheetId '%s' is not found", sheetName.c_str());
return false;
}
sint quantity = atoi(args[3].c_str());
if (quantity < 1)
{
log.displayNL ("Quantity must be > 0");
return false;
}
sint quality = atoi(args[4].c_str());
if (quality < 1)
{
log.displayNL ("Quality must be > 0");
return false;
}
uint nbItems = min(uint(atoi(args[5].c_str())), 1000U);
uint nbCreatedItems = 0;
for (uint i = 0; i < nbItems; i++)
{
if ( !c->createItemInInventory(INVENTORIES::toInventory(args[1]), quality, quantity, sheet, CEntityId::Unknown) )
break;
nbCreatedItems++;
}
log.displayNL("%u (of %u) items '%s' created and set in the inventory '%s' of the player %s", nbCreatedItems, nbItems, sheet.toString ().c_str(), args[1].c_str(), eid.toString().c_str());
return true;
}
NLMISC_COMMAND(createNamedItemInBag, "create a named item in bag", " - []")
{
if (args.size() > 3)
return false;
if (args.size() < 2 )
return false;
CCharacter * user = PlayerManager.getChar(CEntityId(args[0]));
if (!user)
{
log.displayNL("invalid char '%s'", args[0].c_str());
return true;
}
uint16 quantity;
if (args.size() == 3)
{
quantity = (uint16)atoi(args[2].c_str());
if (quantity == 0)
{
log.displayNL("invalid quantity '%s'", args[2].c_str());
return true;
}
}
else
{
quantity = 1;
}
CGameItemPtr item = CNamedItems::getInstance().createNamedItem(args[1], quantity);
if (item == NULL)
{
log.displayNL("invalid item '%s'", args[1].c_str());
return true;
}
user->addItemToInventory(INVENTORIES::bag, item);
return true;
}
NLMISC_COMMAND (createFullArmorSet, "Create and equip player with chosen full armor set"," ")
{
static string armors[]=
{
"boots",
"gloves",
"pants",
"sleeves",
"vest",
};
static string heavyArmors[]=
{
"boots",
"gloves",
"helmet",
"pants",
"sleeves",
"vest",
};
if (args.size () != 4) return false;
GET_CHARACTER
const string &race = args[1];
const string &type = args[2];
const uint16 quality = atoi(args[3].c_str());
const uint16 min = quality - (quality-1)%5;
const string minStr = (min < 10) ? string("0") + toString(min) : toString(min);
const uint16 max = min+4;
const string maxStr = (max < 10) ? string("0") + toString(max) : toString(max);
const string endName = string("_") + minStr + string("_") + maxStr + string(".item");
// create the armor pieces
if (type == "heavy")
{
for ( int i = 0 ; i < sizeof(heavyArmors)/sizeof(heavyArmors[0]) ; ++i)
{
const string sheetName = race + string("_") + type + string("_") + heavyArmors[i] + endName;
CSheetId sheetId(sheetName);
if ( !c->createItemInInventory(INVENTORIES::bag, quality, 1, sheetId, eid) )
{
log.displayNL ("For entity %s Failed to create item %s", eid.toString().c_str(), sheetName.c_str() );
}
}
}
else
{
for ( int i = 0 ; i < sizeof(armors)/sizeof(armors[0]) ; ++i)
{
const string sheetName = race + string("_") + type + string("_") + armors[i] + endName;
CSheetId sheetId(sheetName);
if ( !c->createItemInInventory(INVENTORIES::bag, quality, 1, sheetId, eid) )
{
log.displayNL ("For entity %s Failed to create item %s", eid.toString().c_str(), sheetName.c_str() );
}
}
}
return true;
}
NLMISC_COMMAND (displayInfosOnTarget, "display info on entity target", "")
{
if (args.size () < 1) return false;
GET_CHARACTER
TDataSetRow target = c->getTargetDataSetRow();
if (TheDataset.isAccessible(target))
{
// little slow but acceptable in command
CMirrorPropValueRO instanceNumber(TheDataset, target, DSPropertyAI_INSTANCE);
CAIAskForInfosOnEntityMsg msg;
msg.EntityRowId = target;
msg.AskerRowID = c->getEntityRowId();
CWorldInstances::instance().msgToAIInstance(instanceNumber, msg);
}
else
log.displayNL (" Entity %s has no valid target", eid.toString().c_str() );
return true;
}
NLMISC_COMMAND (forceTargetToDie, "(debug) Force entity target to die", "")
{
if (args.size () != 1)
return false;
GET_CHARACTER
// force sending of target as dead (can only be done on creature)
CCreature *target = CreatureManager.getCreature(c->getTargetDataSetRow());
if (target)
{
if (!target->isDead())
target->changeCurrentHp(-100000);
BotDeathReport.Bots.push_back(target->getEntityRowId());
TDataSetRow emptyRow;
BotDeathReport.Killers.push_back(emptyRow);
BotDeathReport.Zombies.push_back(true);
}
return true;
}
NLMISC_COMMAND (learnAllBricks, "Specified player learns all possible bricks for it's skill values", "")
{
H_AUTO(learnAllBricks);
if (args.size () != 1)
return false;
GET_CHARACTER
// get all phrases and bypass brick requirements
vector phrases;
vector tempPhrases;
static const EGSPD::CPeople::TPeople races[] =
{
EGSPD::CPeople::Common,
EGSPD::CPeople::Tryker,
EGSPD::CPeople::Fyros,
EGSPD::CPeople::Matis,
EGSPD::CPeople::Zorai
};
const uint nbRaces = sizeof(races) / sizeof(races[0]);
for (uint i = 0 ; i < nbRaces ; ++i)
{
// fight
string filter = "bf";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// magic
filter = "bm";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// craft
filter = "bc";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// harvest
filter = "bh";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// special powers
filter = "bs";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
}
// learn all bricks
uint nbBricks = 0;
for (uint i = 0; i < phrases.size() ; ++i)
{
const CStaticRolemasterPhrase *phrase = CSheets::getSRolemasterPhrase(phrases[i]);
if(phrase != NULL)
{
const uint size = (uint)phrase->Bricks.size();
for ( uint j = 0; j < size ; ++j)
{
c->addKnownBrick( phrase->Bricks[j] );
++nbBricks;
}
}
}
log.displayNL ("%s learnt %u bricks", eid.toString().c_str(), nbBricks);
return true;
}
NLMISC_COMMAND (learnAllRolemasterBricks, "Specified player learns all possible bricks sold by rolemaster for it's skill values", "")
{
H_AUTO(learnAllRolemasterBricks);
if (args.size () != 1)
return false;
GET_CHARACTER
// get all phrases and bypass brick requirements
vector phrases;
vector tempPhrases;
static const EGSPD::CPeople::TPeople races[] =
{
EGSPD::CPeople::Common,
EGSPD::CPeople::Tryker,
EGSPD::CPeople::Fyros,
EGSPD::CPeople::Matis,
EGSPD::CPeople::Zorai
};
const uint nbRaces = sizeof(races) / sizeof(races[0]);
for (uint i = 0 ; i < nbRaces ; ++i)
{
// fight
string filter = "bf";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true, false );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// magic
filter = "bm";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true, false );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// craft
filter = "bc";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true, false );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// harvest
filter = "bh";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true, false );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// special powers
filter = "bs";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true, false );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
}
// learn all bricks
uint nbBricks = 0;
for (uint i = 0; i < phrases.size() ; ++i)
{
const CStaticRolemasterPhrase *phrase = CSheets::getSRolemasterPhrase(phrases[i]);
if(phrase != NULL)
{
const uint size = (uint)phrase->Bricks.size();
for ( uint j = 0; j < size ; ++j)
{
c->addKnownBrick( phrase->Bricks[j] );
++nbBricks;
}
}
}
log.displayNL ("%s learnt %u bricks", eid.toString().c_str(), nbBricks);
return true;
}
NLMISC_COMMAND (learnAllPhrases, "Specified player learns all possible phrases for it's skill values", "")
{
H_AUTO(learnAllPhrases);
if (args.size () != 1)
return false;
GET_CHARACTER
// get all phrases and bypass brick requirements
vector phrases;
vector tempPhrases;
static const EGSPD::CPeople::TPeople races[] =
{
EGSPD::CPeople::Common,
EGSPD::CPeople::Tryker,
EGSPD::CPeople::Fyros,
EGSPD::CPeople::Matis,
EGSPD::CPeople::Zorai
};
const uint nbRaces = sizeof(races) / sizeof(races[0]);
for (uint i = 0 ; i < nbRaces ; ++i)
{
// fight
string filter = "bf";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// magic
filter = "bm";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// craft
filter = "bc";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// harvest
filter = "bh";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
// special powers
filter = "bs";
c->getAvailablePhrasesList( filter, tempPhrases, races[i], true );
phrases.insert( phrases.end(), tempPhrases.begin(), tempPhrases.end() );
tempPhrases.clear();
}
// learn all phrases
uint16 nbPhrases = 0;
for (uint i = 0; i < phrases.size() ; ++i)
{
uint16 index = c->getFirstFreeSlotInKnownPhrase();
if ( !c->learnPrebuiltPhrase(phrases[i], index) )
log.displayNL ("%s FAILED to learn phrase id %s", eid.toString().c_str(), phrases[i].toString().c_str());
else
++nbPhrases;
}
log.displayNL ("%s learnt %u phrases", eid.toString().c_str(), nbPhrases);
return true;
}
NLMISC_COMMAND(learnBrick, "Specified player learns given brick"," ")
{
if (args.size () != 2) return false;
GET_CHARACTER
CSheetId brickId(args[1]);
c->addKnownBrick(brickId);
log.displayNL ("%s learnt brick %s", eid.toString().c_str(), brickId.toString().c_str());
return true;
}
NLMISC_COMMAND(unlearnBrick, "Specified player unlearns given brick"," ")
{
if (args.size () != 2) return false;
GET_CHARACTER
CSheetId brickId(args[1]);
c->removeKnownBrick(brickId);
log.displayNL ("%s unlearnt brick %s", eid.toString().c_str(), brickId.toString().c_str());
return true;
}
NLMISC_COMMAND (learnPhrase, "Specified player learns a phrase and set it at index knownPhraseIndex", " ")
{
if (args.size () != 2) return false;
GET_CHARACTER
CSheetId phraseId(args[1]);
const CStaticRolemasterPhrase *phrase = CSheets::getSRolemasterPhrase( phraseId );
if (!phrase)
{
log.displayNL ("%s isn't a valid phrase !", phraseId.toString().c_str());
return false;
}
uint16 index = c->getFirstFreeSlotInKnownPhrase();
if ( c->learnPrebuiltPhrase(phraseId, index) )
log.displayNL ("%s learnt phrase id %s", eid.toString().c_str(), phraseId.toString().c_str());
else
log.displayNL ("%s FAILED to learn phrase id %s", eid.toString().c_str(), phraseId.toString().c_str());
return true;
}
NLMISC_COMMAND (logXpGain, "log or not xp gain infos for specified player", " ")
{
if (args.size () != 2) return false;
GET_CHARACTER
bool flag;
if (args[1]=="1" || strlwr(args[1])=="on" || strlwr(args[1])=="true" )
{
flag = true;
}
else if (args[1]=="0" || strlwr(args[1])=="off" || strlwr(args[1])=="false" )
{
flag = false;
}
else
return false;
PlayerManager.logXPGain(c->getEntityRowId(), flag);
log.displayNL ("Player %s. Flag logXpGain is now %s", eid.toString().c_str(), (flag?"ON":"OFF") );
return true;
}
NLMISC_COMMAND (learnAllForagePhrases, "Learn all forage phrase, begin at specified index", " " )
{
H_AUTO(learnAllForagePhrases);
if ( args.size() != 2 ) return false;
GET_CHARACTER
uint i = atoi( args[1].c_str() );
uint nbSuccess = 0, nbFail = 0;
const CAllRolemasterPhrases& phrases = CSheets::getSRolemasterPhrasesMap();
for ( CAllRolemasterPhrases::const_iterator ip=phrases.begin(); ip!=phrases.end(); ++ip )
{
const string phraseCode = (*ip).first.toString();
if ( phraseCode.find( "abhf" ) == 0 )
{
if ( c->learnPrebuiltPhrase( (*ip).first, i ) )
++nbSuccess;
else
++nbFail;
++i;
}
}
log.displayNL( "%u phrases learned, %u phrases failed", nbSuccess, nbFail );
return true;
}
/*
NLMISC_COMMAND (learnAllFaberPlans, "Specified player learns all faber plans", "")
{
if (args.size () != 1) return false;
GET_CHARACTER
c->learnAllFaberPlans();
log.displayNL ("%s learnt all faber plans", eid.toString().c_str());
return true;
}
*/
/* Don't use this command, use Money variable instead (same syntax for example "Money +10")
NLMISC_COMMAND(giveMoney, "Give money to a player"," ")
{
if (args.size () != 2) return false;
GET_CHARACTER
c->giveMoney ( NLMISC::atoiInt64( args[1].c_str() ) );
log.displayNL ("You gave money to player %s", eid.toString().c_str());
return true;
}*/
/* Don't use this command, use SP variable instead (same syntax for example "SP +10")
NLMISC_COMMAND(giveSP, "Give SP (skill points) to a player"," ")
{
if (args.size () != 2) return false;
GET_CHARACTER
uint32 nbSp = atol(args[1].c_str());
c->addSP( (double)nbSp );
log.displayNL ("You gave %u SP to player %s", nbSp, eid.toString().c_str());
return true;
}*/
NLMISC_COMMAND(respawn, "Same as '/a Position home' but without any privilege","")
{
if (args.size () != 1) return false;
GET_CHARACTER
//TODO rules of spawn point
// COfflineEntityState state = PlayerManager.getStartState (c->getActiveRole ());
COfflineEntityState state;
c->forbidNearPetTp();
c->tpWanted (state.X, state.Y, state.Z);
return true;
}
//-----------------------------------------------
// saveToXML
//-----------------------------------------------
NLMISC_CATEGORISED_COMMAND(pdr,saveToXML,"save a character to an XML file"," ")
{
if (args.size () < 2) return false;
GET_CHARACTER
std::string fileName = args[1];
if( c )
{
static CPersistentDataRecordRyzomStore pdr;
pdr.clear();
c->store(pdr);
pdr.writeToTxtFile((fileName+".xml").c_str());
return true;
}
return false;
}
//-----------------------------------------------
// loadFromXML
//-----------------------------------------------
NLMISC_CATEGORISED_COMMAND(pdr,loadFromXML,"load a character from an XML file"," ")
{
if (args.size () < 2) return false;
GET_CHARACTER
std::string fileName = args[1];
if( c )
{
ucstring name= c->getName();
uint32 guildId= c->getGuildId();
NLMISC::CEntityId id= c->getId();
static CPersistentDataRecord pdr;
pdr.clear();
pdr.readFromTxtFile((fileName+".xml").c_str());
c->apply(pdr);
c->setName(name);
c->setGuildId(guildId);
c->setId(id);
c->allowNearPetTp();
c->tpWanted(c->getX(), c->getY(), c->getZ(), true, c->getHeading());
return true;
}
return false;
}
//-----------------------------------------------
// saveToPDR
//-----------------------------------------------
NLMISC_CATEGORISED_COMMAND(pdr,saveToPDR,"save a character to a binary PDR file"," ")
{
if (args.size () < 2) return false;
GET_CHARACTER
std::string fileName = args[1];
if( c )
{
static CPersistentDataRecordRyzomStore pdr;
pdr.clear();
c->store(pdr);
pdr.writeToBinFile((fileName+".pdr").c_str());
return true;
}
return false;
}
//-----------------------------------------------
// loadFromPDR
//-----------------------------------------------
NLMISC_CATEGORISED_COMMAND(pdr,loadFromPDR,"load a character from a binary PDR file"," ")
{
if (args.size () < 2) return false;
GET_CHARACTER
std::string fileName = args[1];
if( c )
{
ucstring name= c->getName();
uint32 guildId= c->getGuildId();
NLMISC::CEntityId id= c->getId();
static CPersistentDataRecord pdr;
pdr.clear();
pdr.readFromBinFile((fileName+".pdr").c_str());
c->apply(pdr);
c->setName(name);
c->setGuildId(guildId);
c->setId(id);
c->allowNearPetTp();
c->tpWanted(c->getX(), c->getY(), c->getZ(), true, c->getHeading());
return true;
}
return false;
}
//-----------------------------------------------
// listPDRFiles
//-----------------------------------------------
NLMISC_CATEGORISED_COMMAND(pdr,listPDRFiles,"list files in the current directory","[]")
{
if (args.size()!=0)
return false;
std::vector files;
NLMISC::CPath::getPathContent(".",false,false,true,files);
for (uint32 i=(uint32)files.size();i--;)
{
if (!NLMISC::testWildCard(files[i],"*.xml") && !NLMISC::testWildCard(files[i],"*.pdr"))
{
files[i]=files.back();
files.pop_back();
}
}
std::sort(files.begin(),files.end());
for (uint32 i=0;i ")
{
if (args.size () < 2) return false;
GET_CHARACTER
CSheetId ticket = CSheetId( args[1] );
if( c )
{
if( ticket != CSheetId::Unknown )
{
CGameItemPtr item = c->createItemInInventoryFreeSlot(INVENTORIES::bag, 1, 1, ticket);
if( item != 0 )
c->addCharacterAnimal( ticket, 0, item );
return true;
}
else
{
log.displayNL(" command, unknown pet ticket '%s'", args[1].c_str() );
}
}
return false;
} // addPetAnimal //
NLMISC_COMMAND(setPetAnimalSatiety,"Set the satiety of pet animal (petIndex in 0..3)"," full| []")
{
if (args.size () < 3) return false;
GET_CHARACTER
if ( c )
{
// Set the new satiety
string result;
uint petIndex = atoi( args[1].c_str() );
float previousSatiety, maxSatiety;
if ( c->getAnimalSatiety( petIndex, previousSatiety, maxSatiety ) )
{
if ( args[2] == "full" )
c->setAnimalSatietyToMax( petIndex );
else
{
float value = (float)atof( args[2].c_str() );
c->setAnimalSatiety( petIndex, value );
}
float currentSatiety;
if ( c->getAnimalSatiety( petIndex, currentSatiety, maxSatiety ) )
result = toString( "Satiety changed from %.1f to %.1f / %.1f", previousSatiety, currentSatiety, maxSatiety );
else
result = toString( "Internal error" );
}
else
result = toString( "Pet %u not found", petIndex );
// Send result if requested
if ( args.size() > 3 )
{
CCharacter *addressee = PlayerManager.getCharacterByName( CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(), args[3]) );
if ( addressee )
{
CHECK_RIGHT( addressee, c );
CCharacter::sendDynamicSystemMessage( addressee->getId(), result );
}
else
result += " nameForAnswer not found";
}
log.displayNL( result.c_str() );
}
return true;
}
NLMISC_COMMAND(getPetAnimalSatiety,"Set the satiety of pet animal (petIndex in 0..3)"," []")
{
if (args.size () < 2) return false;
GET_CHARACTER
uint petIndex = atoi( args[1].c_str() );
if ( c )
{
// Get the satiety
string result;
float currentSatiety, maxSatiety;
if ( c->getAnimalSatiety( petIndex, currentSatiety, maxSatiety ) )
result = toString( "Satiety: %.1f / %.1f", currentSatiety, maxSatiety );
else
result = toString( "Pet %u not found", petIndex );
// Send result if requested
if ( args.size() > 2 )
{
CCharacter *addressee = PlayerManager.getCharacterByName( CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(), args[2] ));
if ( addressee )
{
CHECK_RIGHT( addressee, c );
CCharacter::sendDynamicSystemMessage( addressee->getId(), result );
}
else
result += " nameForAnswer not found";
}
log.displayNL( result.c_str() );
}
return true;
}
NLMISC_COMMAND (addSkillPoints, "add skill points of given type (Fight = 0, Magic = 1,Craft = 2, Harvest = 3)", " ")
{
if (args.size () < 3) return false;
GET_CHARACTER
EGSPD::CSPType::TSPType type = (EGSPD::CSPType::TSPType) atoi (args[1].c_str());
if (type >= EGSPD::CSPType::EndSPType)
{
log.displayNL ("Unknown SP type %u", atoi (args[1].c_str()) );
return false;
}
uint32 nbSP = atoi (args[2].c_str());
c->addSP( nbSP, type );
log.displayNL ("Added %d skill points of type %u (%s) to player %s", nbSP, (uint8) type, EGSPD::CSPType::toString(type).c_str(), eid.toString().c_str());
return true;
} // addSkillPoints //
NLMISC_COMMAND (addXPToSkill, "Gain experience in a given skills", " []")
{
if (args.size () < 3) return false;
GET_CHARACTER
uint32 xp = atoi (args[1].c_str());
string skill = args[2];
uint count;
if(args.size()==3)
count = 1;
else
count = atoi(args[3].c_str());
count = min( count, (uint)100);
uint i;
for( i=0; iaddXpToSkill( (double) xp, skill );
}
log.displayNL ("Added %d xp skill '%s' to player %s %d time(s)", xp, skill.c_str(), eid.toString().c_str(),count);
return true;
}
NLMISC_COMMAND(setSkillsToMaxValue, "Set skills character to max value of each skill","")
{
if (args.size () != 1) return false;
GET_CHARACTER
c->setSkillsToMaxValue();
log.displayNL ("You set skills of player %s to max value of each skill", eid.toString().c_str());
return true;
}
NLMISC_COMMAND(cancelTopPhrase, "cancelTopPhrase","")
{
if (args.size () != 1) return false;
GET_CHARACTER
CPhraseManager::getInstance().cancelTopPhrase( c->getEntityRowId());
return true;
}
NLMISC_COMMAND (clearFriendsList, "clear the friend list of a player", "")
{
if ( args.size() < 1 ) return false;
GET_CHARACTER
if(c != 0)
{
c->clearFriendList();
log.displayNL("player %s friends list cleared",eid.toString().c_str());
}
return true;
}
NLMISC_COMMAND (clearIgnoreList, "clear the ignore list of a player", "")
{
if ( args.size() < 1 ) return false;
GET_CHARACTER
if(c != 0)
{
c->clearIgnoreList();
log.displayNL("player %s ignore list cleared",eid.toString().c_str());
}
return true;
}
NLMISC_COMMAND (clearIsFriendOfList, "clear the ignore list of a player", "")
{
if ( args.size() < 1 ) return false;
GET_CHARACTER
if(c != 0)
{
c->clearFriendOfList();
log.displayNL("player %s 'IsFriendOf' list cleared",eid.toString().c_str());
}
return true;
}
//-----------------------------------------------
// set the defense mode to dodge
//-----------------------------------------------
NLMISC_COMMAND(dodge,"set the defense mode to dodge","")
{
if ( args.size() >= 1 )
{
GET_CHARACTER
c->dodgeAsDefense(true);
log.displayNL("player id %s defense mode is now dodge",eid.toString().c_str());
return true;
}
return false;
} // dodge //
//-----------------------------------------------
// set the defense mode to parry
//-----------------------------------------------
NLMISC_COMMAND(parry,"set the defense mode to parry","")
{
if ( args.size() >= 1 )
{
GET_CHARACTER
c->dodgeAsDefense(false);
log.displayNL("player id %s defense mode is now parry",c->getId().toString().c_str());
return true;
}
return false;
} // parry //
//-----------------------------------------------
// reset the ineffective aura and the power flags for given player
//-----------------------------------------------
NLMISC_COMMAND(resetPowerFlags,"reset the ineffective aura and the power flags for given character","")
{
if ( args.size() == 1)
{
GET_CHARACTER
c->resetPowerFlags();
log.displayNL("resetPowerFlags for character %s ", c->getId().toString().c_str());
return true;
}
return false;
} // resetPowerFlags
//-----------------------------------------------
// excute a sabrina phrase
//-----------------------------------------------
NLMISC_COMMAND(execPhrase,"execute a sabrina phrase"," [...]")
{
if ( args.size() >= 3 )
{
GET_CHARACTER
bool cyclic = atoi(args[1].c_str()) != 0;
vector brickIds;
for (uint i = 2 ; i < args.size() ; ++i)
{
CSheetId sheet(args[i]);
brickIds.push_back( sheet );
}
CPhraseManager::getInstance().executePhrase(c->getEntityRowId(), c->getTargetDataSetRow(), brickIds, cyclic);
return true;
}
return false;
} // execPhrase //
//-----------------------------------------------
// excute a sabrina phrase
//-----------------------------------------------
NLMISC_COMMAND(executeSabrinaPhrase,"execute a sabrina phrase, an sphrase"," ")
{
if ( args.size() == 3 )
{
GET_CHARACTER
bool cyclic = atoi(args[1].c_str()) != 0;
CSheetId phraseSheet(args[2]);
CPhraseManager::getInstance().executePhrase(c->getEntityRowId(), c->getTargetDataSetRow(), phraseSheet, cyclic);
return true;
}
return false;
} // executeSabrinaPhrase //
//-----------------------------------------------
// memorize a sabrina phrase
//-----------------------------------------------
NLMISC_COMMAND(memorizePhrase,"memorize a sabrina phrase"," [...]")
{
/* if ( args.size() >= 3 )
{
CEntityId id;
id.fromString(args[0].c_str());
uint8 index = (uint8) atoi(args[1].c_str());
CCharacter * c = PlayerManager.getChar( id );
if (c )
{
vector brickIds;
for (uint i = 2 ; i < args.size() ; ++i)
{
CSheetId sheet(args[i]);
brickIds.push_back( sheet );
}
c->memorize(index, brickIds );
}
else
{
log.displayNL("invalid player id %s",id.toString().c_str());
}
return true;
}
*/
return false;
} // memorizePhrase //
//-----------------------------------------------
// execute a memorized sabrina phrase
//-----------------------------------------------
NLMISC_COMMAND(execMemorizedPhrase,"memorize a memorized sabrina phrase"," ")
{
/* if ( args.size() >= 2 )
{
CEntityId id;
id.fromString(args[0].c_str());
uint8 index = (uint8) atoi(args[1].c_str());
bool cyclic = (atoi(args[2].c_str()) == 1);
CCharacter * c = PlayerManager.getChar( id );
if (c )
{
c->executeMemorizedPhrase(index, cyclic,false);
}
else
{
log.displayNL("invalid player id %s",id.toString().c_str());
}
return true;
}
*/ return false;
} // execMemorizedPhrase //
//////////////////////////////////////////////////////////////////////////////
// Death commands until client interface is ready //
//////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------
// Simulate character choice a re-spawn point until UI is ready
//-----------------------------------------------
NLMISC_COMMAND(respawnAfterDeath,"respawnAfterDeath at re-spawn point name, it must be valid (validated by PC and usable)","")
{
if ( args.size() == 2 )
{
GET_CHARACTER
// A death character can choose to re-spawn to a previously validated re-spawn point, a last of one re-spawn point is always valid
c->respawn( atoi(args[1].c_str() ) );
return true;
}
return false;
} // execMemorizedPhrase //
//-----------------------------------------------
// Simulate Resurrection by other PC until UI is ready
//-----------------------------------------------
NLMISC_COMMAND(resurrected,"Another PC resurrect PC by giving some energy","")
{
if( args.size() == 1 )
{
GET_CHARACTER
c->resurrected();
return true;
}
return false;
}
//-----------------------------------------------
// Simulate buy kami / karavan pact until UI is ready
//-----------------------------------------------
NLMISC_COMMAND(buyPact,"Buy Kami or Karavan pact","")
{
if( args.size() == 3 )
{
GET_CHARACTER
// Character buy pact with Kami / Karavan by botchat (same has trade)
// effect is validate re-spawn point for one use
c->buyPact( args[1] );
return true;
}
return false;
}
//-----------------------------------------------
// Simulate validate re-spawn point until UI is ready
//-----------------------------------------------
NLMISC_COMMAND(validateRespawnPoint,"Validate re-spawn point","")
{
if( args.size() == 2 )
{
GET_CHARACTER
c->getRespawnPoints().addRespawnPoint(atoi( args[1].c_str() ));
return true;
}
return false;
}
NLMISC_COMMAND(displayForageRM,"Display forageable raw materials near by or at the exact position of a player"," ")
{
if ( args.size() < 1 ) return false;
GET_CHARACTER
bool exactPos = ! ((args.size() > 1) && (args[1] == "0"));
bool extendedInfo = (args.size() > 2) && (args[2] == "1");
CFgProspectionPhrase::displayRMNearBy( c, exactPos, extendedInfo, &log );
return true;
}
NLMISC_COMMAND(setItemSapLoad,"set an item sap load","")
{
if ( args.size() != 3)
return false;
GET_CHARACTER
uint slot = atoi(args[1].c_str());
float value = (float)atof(args[2].c_str());
// vector& items = (vector &)c->getInventory()[INVENTORIES::bag]->getChildren();
CInventoryPtr invent = c->getInventory(INVENTORIES::bag);
// if ( slot >= invent->getNumChildren() )
if ( slot >= invent->getSlotCount() )
{
// log.displayNL("Invalid slot %u max = %u",slot, items.size()-1);
log.displayNL("Invalid slot %u max = %u",slot, invent->getSlotCount()-1);
return true;
}
// if( items[slot] == NULL )
if( invent->getItem(slot) == NULL )
{
log.displayNL("empty slot %u",slot);
return true;
}
uint32 sapLoad = 0;
// CGameItemPtr item = invent->getChildItem(slot);
CGameItemPtr item = invent->getItem(slot);
// if ( items[slot]->getSheetId() == CSheetId("stack.sitem") )
// if (item->getSheetId() == CSheetId("stack.sitem") )
// {
//// for ( uint i = 0; i < items[slot]->getChildren().size(); i++ )
// for ( uint i = 0; i < item->getNumChildren(); i++ )
// {
//// if ( items[slot]->getChildren()[i] != NULL)
// if ( item->getChildItem(i) != NULL)
// {
//// items[slot]->getChildren()[i]->setMaxSapLoad( value );
// item->getChildItem(i)->setMaxSapLoad( value );
//// sapLoad = items[slot]->getChildren()[i]->maxSapLoad();
// sapLoad = item->getChildItem(i)->maxSapLoad();
// }
// }
// }
// else
{
// items[slot]->setMaxSapLoad( value );
item->setMaxSapLoad( value );
// sapLoad = items[slot]->maxSapLoad();
sapLoad = item->maxSapLoad();
}
//trap c->incSlotVersion( INVENTORIES::bag,slot);
log.displayNL("item in slot %u has now a sap load of %u",slot,sapLoad);
return true;
}
NLMISC_COMMAND( showFBT, "show Focus Beta Tester title if the player is a FBT", "" )
{
if ( args.size() != 1 )
return false;
GET_CHARACTER
CPlayer * p = PlayerManager.getPlayer(PlayerManager.getPlayerId( c->getId() ) );
if (p == NULL)
{
nlwarning ("ADMIN: Can't find player with UserId %d", PlayerManager.getPlayerId(c->getId()));
return false;
}
if (!p->isBetaTester())
{
nlwarning ("ADMIN: UserId %d is not a FBT", PlayerManager.getPlayerId(c->getId()));
return false;
}
c->setTitle(CHARACTER_TITLE::FBT);
c->registerName();
return true;
}
NLMISC_COMMAND( summonPet, "player can summon it's pet one time only", "" )
{
if ( args.size() != 2 )
return false;
GET_CHARACTER
uint32 index = atoi(args[1].c_str()) - 1;
const std::vector< CPetAnimal >& pet = c->getPlayerPets();
if( index < pet.size() )
{
if( pet[ index ].PetStatus != CPetAnimal::not_present )
{
if( pet[ index ].IsTpAllowed )
{
c->sendPetCommand( CPetCommandMsg::DESPAWN, index, true );
c->setPetStatus( index, CPetAnimal::waiting_spawn );
c->setSpawnPetFlag( index );
c->petTpAllowed( index, false );
}
}
}
return true;
}
NLMISC_COMMAND( allowSummonPet, "autorize player summon it's pet one time only", "" )
{
if ( args.size() != 2 )
return false;
GET_CHARACTER
uint32 index = atoi(args[1].c_str()) - 1;
const std::vector< CPetAnimal >& pet = c->getPlayerPets();
if( index < pet.size() )
{
if( pet[ index ].PetStatus != CPetAnimal::not_present )
{
c->petTpAllowed( index, true );
}
}
return true;
}
//
//
// You can add here all variables to administrate this service.
//
//
NLMISC_DYNVARIABLE (float, RyzomTime, "Current ryzom time")
{
if (get)
{
*pointer = CTimeDateSeasonManager::getRyzomTimeReference().getRyzomTime ();
}
/* else
{
CMessage msgout ("SET_RYZOM_TIME");
msgout.serial (*pointer);
CUnifiedNetwork::getInstance()->send( "WOS", msgout );
}
*/
}
NLMISC_DYNVARIABLE (uint32, RyzomDate, "Current ryzom date")
{
if (get)
{
*pointer = CTimeDateSeasonManager::getRyzomTimeReference().getRyzomDay ();
}
/* else
{
CMessage msgout ("SET_RYZOM_DAY");
msgout.serial (*pointer);
CUnifiedNetwork::getInstance()->send( "WOS", msgout );
}
*/
}
//
//
//
//
// all admin /a /b commands executed by the client go in this callback
void cbClientAdmin (NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId)
{
H_AUTO(cbClientAdmin);
CEntityId eid;
msgin.serial (eid);
bool onTarget;
msgin.serial (onTarget);
CSString cmdName, arg;
msgin.serial (cmdName, arg);
nlinfo("ADMIN: Executing admin command: eid=%s onTarget=%s cmdName=%s arg=%s",eid.toString().c_str(),onTarget?"true":"false",cmdName.quote().c_str(),arg.quote().c_str());
TLogContext_Command_ExecCtx logContext(eid);
// find the character
CCharacter *c = PlayerManager.getChar( eid );
if (c == 0)
{
nlwarning ("ADMIN: Unknown player %s", eid.toString().c_str());
chatToPlayer (eid, "Unknown player");
return;
}
// test character is ready and valid
if (!c->getEnterFlag())
{
nlwarning("ADMIN: player %s not ready", eid.toString().c_str());
return;
}
if (!TheDataset.isAccessible(c->getEntityRowId()))
{
nlwarning("ADMIN: player %s not ready in mirror (invalid rowid)", eid.toString().c_str());
return;
}
// find if the command is available
const CAdminCommand * cmd = findAdminCommand(cmdName);
if (!cmd)
{
nlinfo("ADMIN: Player %s tried to execute a no valid client admin command '%s'", eid.toString().c_str(), cmdName.c_str());
chatToPlayer (eid, "Unknown command");
return;
}
if (!c->havePriv(cmd->Priv))
{
nlinfo("ADMIN: Player %s doesn't have privilege to execute the client admin command '%s' ", eid.toString().c_str(), cmdName.c_str());
chatToPlayer (eid, "You don't have privilege to execute this command");
return;
}
if (!cmd->ForwardToservice.empty())
{
// we need to forward the command to another service
if (IClientCommandForwader::getInstance())
{
IClientCommandForwader::getInstance()->sendCommand(cmd->ForwardToservice, cmdName, eid, onTarget, onTarget ? c->getTarget() : CEntityId::Unknown, arg);
}
}
else
{
// execute locally
// create the command line
string res = cmdName + " ";
if( cmdName == string("Position") )
{
// check validity of Position command
if( onTarget )
{
if( !c->havePriv(":DEV:SGM:GM:EM:") )
{
nlwarning ("ADMIN: Player %s doesn't have privilege to execute the client admin command /b '%s' ", eid.toString().c_str(), cmdName.c_str());
chatToPlayer (eid, "You don't have privilege to execute this command");
return;
}
}
}
std::string targetName = string("implicite");
// add the eid of the player or target if necessary
if (cmd->AddEId)
{
if(onTarget)
{
log_Command_ExecOnTarget(c->getTarget(), cmdName, arg);
res += c->getTarget().toString();
targetName = NLMISC::toString("(%s,%s)", c->getTarget().toString().c_str(), CEntityIdTranslator::getInstance()->getByEntity(c->getTarget()).toString().c_str());
}
else
{
log_Command_Exec(cmdName, arg);
res += eid.toString();
targetName = string("Himself");
}
res += " ";
}
res += arg;
TLogContext_Item_Command itemCtx(onTarget ? c->getTarget() : eid);
TLogContext_Character_BuyRolemasterPhrase characterCtx(onTarget ? c->getTarget() : eid);
std::string csName = CEntityIdTranslator::getInstance()->getByEntity(eid).toString();
nlinfo ("ADMIN: Player (%s,%s) will execute client admin command '%s' on target %s", eid.toString().c_str(), csName.c_str(), res.c_str(), targetName.c_str());
CLightMemDisplayer *CmdDisplayer = new CLightMemDisplayer("CmdDisplayer");
CLog *CmdLogger = new CLog( CLog::LOG_NO );
CmdLogger->addDisplayer( CmdDisplayer );
NLMISC::ICommand::execute(res, *CmdLogger, true);
const std::deque &strs = CmdDisplayer->lockStrings ();
for (uint i = 0; i < strs.size(); i++)
{
InfoLog->displayNL(trim(strs[i]).c_str());
SM_STATIC_PARAMS_1(params,STRING_MANAGER::literal);
params[0].Literal = trim(strs[i]);
CCharacter::sendDynamicSystemMessage( eid, "LITERAL", params );
}
CmdDisplayer->unlockStrings();
CmdLogger->removeDisplayer (CmdDisplayer);
delete CmdDisplayer;
delete CmdLogger;
}
}
// all admin /c commands executed by the client go in this callback
void cbClientAdminOffline (NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId)
{
H_AUTO(cbClientAdminOffline);
CEntityId eid;
msgin.serial (eid);
string characterName;
msgin.serial(characterName);
string cmdName, arg;
msgin.serial (cmdName, arg);
nlinfo("ADMIN: Executing admin /c command: eid=%s onTarget=%s cmdName=%s arg=%s",eid.toString().c_str(),characterName.c_str(),cmdName.c_str(),arg.c_str());
// find the character
CCharacter *c = PlayerManager.getChar( eid );
if (c == 0)
{
nlwarning ("ADMIN: Unknown player %s", eid.toString().c_str());
chatToPlayer (eid, "Unknown player");
return;
}
// test character is ready and valid
if (!c->getEnterFlag())
{
nlwarning("ADMIN: player %s not ready", eid.toString().c_str());
return;
}
if (!TheDataset.isAccessible(c->getEntityRowId()))
{
nlwarning("ADMIN: player %s not ready in mirror (invalid rowid)", eid.toString().c_str());
return;
}
// find if the command is available
const CAdminCommand * cmd = findAdminCommand(cmdName);
if (!cmd)
{
nlwarning ("ADMIN: Player %s tried to execute a no valid client admin command '%s'", eid.toString().c_str(), cmdName.c_str());
chatToPlayer (eid, "Unknown command");
return;
}
if (!c->havePriv(cmd->Priv))
{
nlwarning ("ADMIN: Player %s doesn't have privilege to execute the client admin command '%s' ", eid.toString().c_str(), cmdName.c_str());
chatToPlayer (eid, "You don't have privilege to execute this command");
return;
}
// find the character eid
CEntityId charEid = CEntityIdTranslator::getInstance()->getByEntity(characterName);
if (charEid == CEntityId::Unknown)
{
nlwarning ("ADMIN: Unknown character %s", characterName.c_str());
return;
}
if( cmdName == string("Position") )
{
// check validity of Position command
if( !c->havePriv(":DEV:SGM:GM:") )
{
nlwarning ("ADMIN: Player %s doesn't have privilege to execute the client admin command /c '%s' ", eid.toString().c_str(), cmdName.c_str());
chatToPlayer (eid, "You don't have privilege to execute this command");
return;
}
}
// create the command line
string res = cmdName + " ";
// add the eid of the player or target if necessary
if (cmd->AddEId)
{
res += charEid.toString();
res += " ";
}
res += arg;
std::string csName = CEntityIdTranslator::getInstance()->getByEntity(eid).toString();
std::string targetName = NLMISC::toString("(%s,%s)", CEntityIdTranslator::getInstance()->getByEntity( ucstring(characterName) ).toString().c_str(), characterName.c_str() );
nlinfo("ADMINOFFLINE: Player (%s,%s) will execute client admin command '%s' on target %s", eid.toString().c_str(), csName.c_str(), res.c_str(), targetName.c_str());
NLMISC::ICommand::execute(res, *InfoLog);
}
void cbRemoteClientCallback (uint32 rid, const std::string &cmd, const std::string &entityNames)
{
vector entities;
selectEntities (entityNames, entities);
for (uint i = 0; i < entities.size(); i++)
{
CCharacter *c = PlayerManager.getChar(entities[i]);
if (c != 0)
{
nlinfo ("ADMIN: I have to send a request for admin to a client : rid %d cmd '%s' eid %s", rid, cmd.c_str(), entities[i].toString().c_str());
CMessage msgout ("IMPULSION_ID");
msgout.serial (entities[i]);
CBitMemStream bms;
if (!GenericMsgManager.pushNameToStream ("COMMAND:REMOTE_ADMIN", bms))
nlstopex (("Missing a message in the msg.xml"));
bms.serial (rid);
bms.serial (const_cast(cmd));
msgout.serialBufferWithSize ((uint8*)bms.buffer(), bms.length());
sendMessageViaMirror (NLNET::TServiceId(entities[i].getDynamicId()), msgout);
}
}
}
void cbClientRemoteAdmin( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId)
{
H_AUTO(cbClientRemoteAdmin);
CEntityId eid;
msgin.serial (eid);
uint32 rid;
msgin.serial (rid);
string cmd;
msgin.serial (cmd);
string answer;
msgin.serial (answer);
vector vara, vala;
if (ICommand::isCommand(cmd))
{
vara.push_back ("__log");
vala.push_back ("----- Result from "+eid.toString()+" "+IService::getInstance()->getServiceUnifiedName()+" of command '"+cmd+"'\n");
vala.push_back (answer);
}
else
{
vara.push_back ("service");
vala.push_back (IService::getInstance ()->getServiceUnifiedName());
vara.push_back ("entity");
vala.push_back (eid.toString());
vara.push_back (cmd);
vala.push_back (answer);
}
nlinfo ("ADMIN: received an answer from %s for command '%s' that is '%s' for rid %d", eid.toString().c_str(), cmd.c_str(), answer.c_str(), rid);
addRequestAnswer (rid, vara, vala);
}
//----------------------------------------------------------------------------
NLMISC_COMMAND( displayWeather, "Display current weather at specified pos", " " )
{
if ( args.size() < 2 )
return false;
CVector pos;
pos.x = (float)atof( args[0].c_str() );
pos.y = (float)atof( args[1].c_str() );
pos.z = 0;
CRyzomTime::EWeather weather = WeatherEverywhere.getWeather( pos, CTimeDateSeasonManager::getRyzomTimeReference() );
log.displayNL( "Weather: %u", (uint)weather );
return true;
}
/***********************************************************************************************************************
BELOW ARE OFFICIAL CSR COMMANDS
***********************************************************************************************************************/
NLMISC_COMMAND( csrCmd, "Invoke a CSR command from service console or admin tool without the need to have a CSR logged in", " +" )
{
if (args.empty())
return false;
// build the command line
string command = args[0];
command += string(" (0x0000000000:00:00:00) ");
for (uint i=1; i" )
{
if ( args.empty() )
return false;
string msg = args[0];
for ( uint i = 1; i < args.size(); i++ )
{
msg+= " " + args[i];
}
MessageOfTheDay = msg;
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND( summon, "summon a player in front of the CSR", "" )
{
if ( args.size() !=2 )
return false;
GET_CHARACTER
CCharacter * target = PlayerManager.getCharacterByName( CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(), args[1]) );
if ( !target || !TheDataset.isAccessible( target->getEntityRowId() ) )
{
CCharacter::sendDynamicSystemMessage( eid, "CSR_PENDING_CHARACTER_LOG" );
COfflineEntityState state;
state.X = c->getState().X;
state.Y = c->getState().Y;
state.Z = c->getState().Z;
state.Heading = c->getState().Heading;
CGmTpPendingCommand::getInstance()->addTpPendingforCharacter( args[1], state );
return true;
}
CHECK_RIGHT( c,target );
if(target->getCurrentContinent() == CONTINENT::NEWBIELAND )
{
if( c->getCurrentContinent() != CONTINENT::NEWBIELAND )
{
log.displayNL( "Summon player outside NEWBIELAND is forbiden, try to made an illegal action, this is loged.", eid.toString().c_str());
chatToPlayer (eid, "You don't have privilege to execute this command");
return true;
}
}
COfflineEntityState state;
state.X = target->getState().X;
state.Y = target->getState().Y;
state.Z = target->getState().Z;
state.Heading = target->getState().Heading;
PlayerManager.addSummonnedUser( target->getEntityRowId(), state );
state.X = c->getState().X + sint32 (cos (c->getState().Heading) * 2000);
state.Y = c->getState().Y + sint32 (sin (c->getState().Heading) * 2000);
state.Z = c->getState().Z;
state.Heading = c->getState().Heading + (float)NLMISC::Pi;
if ( state.Heading >= (float)NLMISC::Pi )
state.Heading -= 2* (float)NLMISC::Pi;
target->allowNearPetTp();
target->tpWanted( state.X, state.Y, state.Z, true, state.Heading );
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND( dismiss, "teleport a player back to its former position ( before last call to summonPlayer )", "" )
{
if ( args.size() !=2 )
return false;
TRY_GET_CHARACTER
CCharacter * target = PlayerManager.getCharacterByName( CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(),args[1]) );
if ( !target || !TheDataset.isAccessible( target->getEntityRowId() ) )
{
CCharacter::sendDynamicSystemMessage( eid, "CSR_BAD_TARGET" );
return true;
}
CHECK_RIGHT( c,target );
COfflineEntityState state;
if ( PlayerManager.getDismissCoords( target->getEntityRowId(), state ) )
{
target->allowNearPetTp();
target->tpWanted( state.X, state.Y, state.Z, true, state.Heading );
CContinent * cont = CZoneManager::getInstance().getContinent(state.X, state.Y);
if ( cont )
{
target->getRespawnPoints().addDefaultRespawnPoint( CONTINENT::TContinent(cont->getId()) );
}
PlayerManager.removeSummonedUser( target->getEntityRowId() );
}
else
{
CCharacter::sendDynamicSystemMessage( eid, "CSR_NOT_SUMMONED" );
}
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND( teleport, "teleport the CSR in front of a player", "" )
{
if ( args.size() !=2 )
return false;
GET_CHARACTER
CCharacter * target = PlayerManager.getCharacterByName( CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(),args[1]) );
if ( !target || !TheDataset.isAccessible( target->getEntityRowId() ) )
{
CCharacter::sendDynamicSystemMessage( eid, "CSR_BAD_TARGET" );
return true;
}
float heading = target->getState().Heading;
sint32 x = target->getState().X + sint32 (cos (target->getState ().Heading) * 2000);
sint32 y = target->getState().Y + sint32 (sin (target->getState ().Heading) * 2000);
sint32 z = target->getState().Z;
heading += (float)NLMISC::Pi;
if ( heading >= (float)NLMISC::Pi )
heading -= 2* (float)NLMISC::Pi;
c->allowNearPetTp();
c->teleportCharacter(x, y, z, true, true, heading);
CContinent * continent = CZoneManager::getInstance().getContinent(x, y);
if (continent != NULL)
{
c->getRespawnPoints().addDefaultRespawnPoint( CONTINENT::TContinent(continent->getId()) );
}
return true;
}
//----------------------------------------------------------------------------
//static string capitalize(const string & s)
//{
// if ( s.empty() )
// return s;
//
// return toUpper( s.substr(0,1) ) + toLower( s.substr(1,string::npos) );
//}
//----------------------------------------------------------------------------
NLMISC_COMMAND( renamePlayerForEvent, "rename a player for the event", "" )
{
if ( args.size() != 3 )
return false;
ucstring newName( args[2] );
TRY_GET_CHARACTER
CCharacter * target = PlayerManager.getCharacterByName( CShardNames::getInstance().makeFullNameFromRelative(c->getHomeMainlandSessionId(),args[1]) );
if ( !target || !TheDataset.isAccessible( target->getEntityRowId() ) )
{
CCharacter::sendDynamicSystemMessage( eid, "CSR_BAD_TARGET" );
return true;
}
CHECK_RIGHT( c,target );
// assign new name to player
// PlayerManager.addEntityForStringIdRequest( target->getId() );
target->registerName(newName);
return true;
}
//----------------------------------------------------------------------------
//NLMISC_COMMAND( renamePlayer, "rename a player", "" )
//{
// if ( args.size() != 3 )
// return false;
//
// ucstring oldName( capitalize(args[1]) );
// ucstring newName( capitalize(args[2]) );
// TRY_GET_CHARACTER
// CCharacter * target = PlayerManager.getCharacterByName( args[1] );
// if ( !target || !TheDataset.isAccessible( target->getEntityRowId() ) )
// {
// CCharacter::sendDynamicSystemMessage( eid, "CSR_BAD_TARGET" );
// return true;
// }
// CHECK_RIGHT( c,target );
//
// if ( CEntityIdTranslator::getInstance()->entityNameExists( newName ) )
// {
// CCharacter::sendDynamicSystemMessage( eid, "CSR_NAME_EXISTS" );
// return true;
// }
//
// // assign new name to player
// bool result = CNameManager::getInstance()->assignName( target->getId(), newName );
// if ( !result )
// {
// CCharacter::sendDynamicSystemMessage( eid, "CSR_BAD_NAME" );
// nlwarning("assignName failed for name: %s", newName.toUtf8().c_str() );
// return true;
// }
// PlayerManager.addEntityForStringIdRequest( target->getId() );
// target->setName( newName );
// target->registerName();
//
// if ( toLower(newName) != toLower(oldName) )
// {
// // liberate old name
// CNameManager::getInstance()->liberateName( target->getId(), oldName );
// }
//
// return true;
//}
//----------------------------------------------------------------------------
NLMISC_COMMAND( renameGuild, "rename a guild", " | " )
{
if ( args.size() != 3 )
return false;
if (args[0]!="admin_tool")
{
TRY_GET_CHARACTER
}
GET_GUILD(1, true, NLMISC::CEntityId::Unknown);
ucstring name( args[2] );
// check if name already exists in the player list
if ( NLMISC::CEntityIdTranslator::getInstance()->entityNameExists( name ) /*|| EGSPD::PDSLib.getStringManager().stringExists(name, RYZOMID::guildName)*/ )
{
if (args[0]=="admin_tool")
{
log.displayNL("renameGuild failed because the name is already taken: ",args[2].c_str());
}
else
{
TRY_GET_CHARACTER
CCharacter::sendDynamicSystemMessage( eid,"CSR_NAME_EXISTS" );
}
return false;
}
guild->setName( name );
if (IGuildUnifier::getInstance() != NULL)
IGuildUnifier::getInstance()->broadcastGuildUpdate(guild);
// CGuildManager::getInstance()->addGuildsAwaitingString(name,guild->getId());
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND( setGuildDescription, "set a guild description", "| " )
{
if ( args.size() != 2)
return false;
GET_GUILD(0, true, NLMISC::CEntityId::Unknown);
ucstring desc( args[1] );
guild->setDescription( desc );
if (IGuildUnifier::getInstance() != NULL)
IGuildUnifier::getInstance()->broadcastGuildUpdate(guild);
// CGuildManager::getInstance()->addGuildsAwaitingString(desc,guild->getId());
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND( setGuildIcon, "set a guild icon", "| " )
{
if ( args.size() != 2)
return false;
GET_GUILD(0, true, NLMISC::CEntityId::Unknown);
uint64 icon = atoiInt64( args[1].c_str() );
guild->setIcon( icon );
if (IGuildUnifier::getInstance() != NULL)
IGuildUnifier::getInstance()->broadcastGuildUpdate(guild);
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND( killMob, "kill a mob ( /a killMob )", "" )
{
if ( args.size() != 1 )
return false;
TRY_GET_CHARACTER
CCreature * creature = CreatureManager.getCreature( c->getTarget() );
if( creature == 0 )
{
nlwarning ("Unknown creature '%s'", c->getTarget().toString().c_str() );
return false;
}
if(!TheDataset.isAccessible(creature->getEntityRowId()))
{
nlwarning ("'%s' is not valid in mirror", c->getTarget().toString().c_str());
return false;
}
if ( !creature->getContextualProperty().directAccessForStructMembers().attackable() )
{
CCharacter::sendDynamicSystemMessage( eid, "CSR_NOT_ATTACKABLE" );
return true;
}
creature->getScores()._PhysicalScores[SCORES::hit_points].Current = 0;
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND( dssTarget, "target a mob and send information to dss( /b dssTarget )", "[]" )
{
if ( args.size() < 1 )
return false;
TRY_GET_CHARACTER
CCreature * creature = CreatureManager.getCreature( c->getTarget() );
if( creature == 0 )
{
nlwarning ("Unknown creature '%s'", c->getTarget().toString().c_str() );
return false;
}
if(!TheDataset.isAccessible(creature->getEntityRowId()))
{
nlwarning ("'%s' is not valid in mirror", c->getTarget().toString().c_str());
return false;
}
NLMISC::CEntityId creatureId = creature->getId();
TAIAlias alias = CAIAliasTranslator::getInstance()->getAIAlias(creatureId);
TDataSetRow entityRowId = creature->getEntityRowId();
if (alias == CAIAliasTranslator::Invalid)
{
nlwarning ("'%s' has no alias translation", creatureId.toString().c_str());
return false;
}
CMessage msgout("DSS_TARGET");
msgout.serial(eid); //eid of the player
msgout.serial(creatureId); // eid of the mob
msgout.serial(alias); //mob targeted
msgout.serial(entityRowId); //datasetrow
uint32 args_size = (uint32)args.size() - 1;
uint32 i = 0;
msgout.serial(args_size);
for ( ; i != args_size ; ++i)
{
std::string str = args[1+i];
msgout.serial(str);
}
CUnifiedNetwork::getInstance()->send("DSS", msgout);
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND( root, "root a player", "