Core/Commands: Add new spy command (#1263)
Add a new spy command for game masters and administrators to receive all conversations of followed players. How to use: - Use command .spy follow <characterName> with a GM - Make that player whisper another player - You (GM) should receive the message sent - Use command .spy status. You should get a list with the test subject's name in it. - Use command .spy unfollow <characterName> - You should not receive any more messages sent or received by that player * Core/Commands: Add new spy command * Importing pending sql * Fix missing comma in SQL * Fix travis compile: comment unused parameter
This commit is contained in:
@@ -0,0 +1,39 @@
|
|||||||
|
-- DB update 2019_01_10_00 -> 2019_01_11_00
|
||||||
|
DROP PROCEDURE IF EXISTS `updateDb`;
|
||||||
|
DELIMITER //
|
||||||
|
CREATE PROCEDURE updateDb ()
|
||||||
|
proc:BEGIN DECLARE OK VARCHAR(100) DEFAULT 'FALSE';
|
||||||
|
SELECT COUNT(*) INTO @COLEXISTS
|
||||||
|
FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'version_db_world' AND COLUMN_NAME = '2019_01_10_00';
|
||||||
|
IF @COLEXISTS = 0 THEN LEAVE proc; END IF;
|
||||||
|
START TRANSACTION;
|
||||||
|
ALTER TABLE version_db_world CHANGE COLUMN 2019_01_10_00 2019_01_11_00 bit;
|
||||||
|
SELECT sql_rev INTO OK FROM version_db_world WHERE sql_rev = '1547165890320901800'; IF OK <> 'FALSE' THEN LEAVE proc; END IF;
|
||||||
|
--
|
||||||
|
-- START UPDATING QUERIES
|
||||||
|
--
|
||||||
|
|
||||||
|
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1547165890320901800');
|
||||||
|
|
||||||
|
DELETE FROM `trinity_string` WHERE `entry` BETWEEN 5062 AND 5071;
|
||||||
|
INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES
|
||||||
|
(5062, 'You will now read %s conversations.'),
|
||||||
|
(5063, 'Stopped spying %s.'),
|
||||||
|
(5064, '%s is already being followed by: %s'),
|
||||||
|
(5065, 'Following %s\'s group, you will now read each player\'s conversations.'),
|
||||||
|
(5066, 'Stopped spying %s\'s group.'),
|
||||||
|
(5067, 'You are not spying %s\'s group.'),
|
||||||
|
(5068, 'Cleared all followed players.'),
|
||||||
|
(5069, '[ v ]==== Current spy list ====[ v ]'),
|
||||||
|
(5070, '[SPY] %s whispers %s: %s'),
|
||||||
|
(5071, '[SPY] %s tells group: %s');
|
||||||
|
|
||||||
|
--
|
||||||
|
-- END UPDATING QUERIES
|
||||||
|
--
|
||||||
|
COMMIT;
|
||||||
|
END //
|
||||||
|
DELIMITER ;
|
||||||
|
CALL updateDb();
|
||||||
|
DROP PROCEDURE IF EXISTS `updateDb`;
|
||||||
@@ -1146,7 +1146,19 @@ enum TrinityStrings
|
|||||||
LANG_COMMAND_MUTEHISTORY_EMPTY = 5060,
|
LANG_COMMAND_MUTEHISTORY_EMPTY = 5060,
|
||||||
LANG_COMMAND_MUTEHISTORY_OUTPUT = 5061,
|
LANG_COMMAND_MUTEHISTORY_OUTPUT = 5061,
|
||||||
|
|
||||||
// Room for more Trinity strings 5062-9999
|
// Spy command
|
||||||
|
LANG_COMMAND_SPY_FOLLOWING = 5062,
|
||||||
|
LANG_COMMAND_SPY_UNFOLLOW = 5063,
|
||||||
|
LANG_COMMAND_SPY_ALREADY_FOLLOWED_BY = 5064,
|
||||||
|
LANG_COMMAND_SPY_FOLLOWING_GROUP = 5065,
|
||||||
|
LANG_COMMAND_SPY_UNFOLLOW_GROUP = 5066,
|
||||||
|
LANG_COMMAND_SPY_NOT_FOLLOWING_GROUP = 5067,
|
||||||
|
LANG_COMMAND_SPY_CLEARED = 5068,
|
||||||
|
LANG_COMMAND_SPY_LIST = 5069,
|
||||||
|
LANG_COMMAND_SPY_WHISPERS_PLAYER = 5070,
|
||||||
|
LANG_COMMAND_SPY_TELLS_GROUP = 5071,
|
||||||
|
|
||||||
|
// Room for more Trinity strings 5072-9999
|
||||||
|
|
||||||
// Level requirement notifications
|
// Level requirement notifications
|
||||||
LANG_SAY_REQ = 6604,
|
LANG_SAY_REQ = 6604,
|
||||||
|
|||||||
@@ -37,8 +37,9 @@ set(scripts_STAT_SRCS
|
|||||||
Commands/cs_quest.cpp
|
Commands/cs_quest.cpp
|
||||||
Commands/cs_reload.cpp
|
Commands/cs_reload.cpp
|
||||||
Commands/cs_reset.cpp
|
Commands/cs_reset.cpp
|
||||||
Commands/cs_tele.cpp
|
Commands/cs_spy.cpp
|
||||||
Commands/cs_server.cpp
|
Commands/cs_server.cpp
|
||||||
|
Commands/cs_tele.cpp
|
||||||
Commands/cs_ticket.cpp
|
Commands/cs_ticket.cpp
|
||||||
Commands/cs_titles.cpp
|
Commands/cs_titles.cpp
|
||||||
Commands/cs_wp.cpp
|
Commands/cs_wp.cpp
|
||||||
|
|||||||
@@ -0,0 +1,279 @@
|
|||||||
|
#include "ScriptPCH.h"
|
||||||
|
#include "Channel.h"
|
||||||
|
#include "Language.h"
|
||||||
|
#include "Group.h"
|
||||||
|
|
||||||
|
// Maps to store followed players
|
||||||
|
std::map<uint32,uint32> gmListening;
|
||||||
|
std::map<uint32,uint32> gmListeningGroup;
|
||||||
|
|
||||||
|
class chat_spy_script : public PlayerScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
chat_spy_script() : PlayerScript("chat_spy_script") { }
|
||||||
|
|
||||||
|
void OnChat(Player *sender, uint32 /*type*/, uint32 lang, std::string& msg, Player *receiver)
|
||||||
|
{
|
||||||
|
if (gmListening.size() > 0 && lang != LANG_ADDON)
|
||||||
|
{
|
||||||
|
// if the sender or the receiver is being followed
|
||||||
|
Player* gm = GetGmFromList(sender);
|
||||||
|
if (!gm)
|
||||||
|
gm = GetGmFromList(receiver);
|
||||||
|
|
||||||
|
if (gm)
|
||||||
|
{
|
||||||
|
ChatHandler(gm->GetSession()).PSendSysMessage(LANG_COMMAND_SPY_WHISPERS_PLAYER,
|
||||||
|
sender->GetName().c_str(), receiver ? receiver->GetName().c_str() : "<unknown>", msg.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnChat(Player* sender, uint32 /*type*/, uint32 lang, std::string& msg, Group* group)
|
||||||
|
{
|
||||||
|
if(gmListeningGroup.size() > 0 && lang != LANG_ADDON)
|
||||||
|
if(Player* gm = GetGmFromGroupList(group))
|
||||||
|
ChatHandler(gm->GetSession()).PSendSysMessage(LANG_COMMAND_SPY_TELLS_GROUP,
|
||||||
|
sender->GetName().c_str(), msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
Player* GetGmFromList(Player* from)
|
||||||
|
{
|
||||||
|
std::map<uint32,uint32>::const_iterator itr = gmListening.find(from->GetGUIDLow());
|
||||||
|
return itr != gmListening.end() ? sObjectMgr->GetPlayerByLowGUID(itr->second) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player* GetGmFromGroupList(Group* group)
|
||||||
|
{
|
||||||
|
std::map<uint32,uint32>::const_iterator itr = gmListeningGroup.find(group->GetLowGUID());
|
||||||
|
return itr != gmListeningGroup.end() ? sObjectMgr->GetPlayerByLowGUID(itr->second) : NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class chat_spy_commandscript : public CommandScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
chat_spy_commandscript() : CommandScript("chat_spy_commandscript") { }
|
||||||
|
|
||||||
|
std::vector<ChatCommand> GetCommands() const override
|
||||||
|
{
|
||||||
|
static std::vector<ChatCommand> spyCommandTable =
|
||||||
|
{
|
||||||
|
{ "follow", SEC_GAMEMASTER, false, &HandleSpyFollowCommand, ""},
|
||||||
|
{ "groupfollow", SEC_ADMINISTRATOR, false, &HandleSpyFollowGroupCommand, ""},
|
||||||
|
{ "unfollow", SEC_GAMEMASTER, false, &HandleSpyUnFollowCommand, ""},
|
||||||
|
{ "groupunfollow", SEC_ADMINISTRATOR, false, &HandleSpyUnFollowGroupCommand, ""},
|
||||||
|
{ "clear", SEC_GAMEMASTER, false, &HandleSpyClearCommand, ""},
|
||||||
|
{ "status", SEC_GAMEMASTER, false, &HandleSpyStatusCommand, ""}
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<ChatCommand> commandTable =
|
||||||
|
{
|
||||||
|
{ "spy", SEC_GAMEMASTER, false, NULL, "", spyCommandTable}
|
||||||
|
};
|
||||||
|
|
||||||
|
return commandTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HandleSpyFollowCommand(ChatHandler* handler, const char* args)
|
||||||
|
{
|
||||||
|
if(!*args)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char *cName = strtok ((char*)args, " ");
|
||||||
|
if(!cName)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string pTarget = args;
|
||||||
|
if(!normalizePlayerName(pTarget))
|
||||||
|
{
|
||||||
|
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Player* target = ObjectAccessor::FindPlayer(sObjectMgr->GetPlayerGUIDByName(pTarget.c_str())))
|
||||||
|
{
|
||||||
|
std::map<uint32,uint32>::const_iterator itr = gmListening.find(target->GetGUIDLow());
|
||||||
|
if(itr != gmListening.end())
|
||||||
|
{
|
||||||
|
if(Player* gm = sObjectMgr->GetPlayerByLowGUID(itr->second))
|
||||||
|
{
|
||||||
|
handler->PSendSysMessage(LANG_COMMAND_SPY_ALREADY_FOLLOWED_BY, target->GetName().c_str(), gm->GetName().c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gmListening[target->GetGUIDLow()] = handler->GetSession()->GetPlayer()->GetGUIDLow();
|
||||||
|
handler->PSendSysMessage(LANG_COMMAND_SPY_FOLLOWING, target->GetName().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HandleSpyFollowGroupCommand(ChatHandler* handler, const char* args)
|
||||||
|
{
|
||||||
|
if(!*args)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char *cName = strtok ((char*)args," ");
|
||||||
|
if(!cName)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string pTarget = args;
|
||||||
|
if(!normalizePlayerName(pTarget))
|
||||||
|
{
|
||||||
|
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Player* target = ObjectAccessor::FindPlayer(sObjectMgr->GetPlayerGUIDByName(pTarget.c_str())))
|
||||||
|
{
|
||||||
|
if(Group* group = target->GetGroup())
|
||||||
|
{
|
||||||
|
std::map<uint32,uint32>::const_iterator itr = gmListeningGroup.find(group->GetLowGUID());
|
||||||
|
if(itr != gmListeningGroup.end())
|
||||||
|
{
|
||||||
|
if(Player* gm = sObjectMgr->GetPlayerByLowGUID(itr->second))
|
||||||
|
{
|
||||||
|
handler->PSendSysMessage(LANG_COMMAND_SPY_ALREADY_FOLLOWED_BY, target->GetName().c_str(), gm->GetName().c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gmListeningGroup[group->GetLowGUID()] = handler->GetSession()->GetPlayer()->GetGUIDLow();
|
||||||
|
handler->PSendSysMessage(LANG_COMMAND_SPY_FOLLOWING_GROUP, target->GetName().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
handler->PSendSysMessage(LANG_NOT_IN_GROUP, target->GetName().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HandleSpyUnFollowCommand(ChatHandler* handler, const char* args)
|
||||||
|
{
|
||||||
|
if(!*args)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char *cName = strtok ((char*)args," ");
|
||||||
|
if(!cName)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string pTarget = args;
|
||||||
|
if(!normalizePlayerName(pTarget))
|
||||||
|
{
|
||||||
|
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Player* target = ObjectAccessor::FindPlayer(sObjectMgr->GetPlayerGUIDByName(pTarget.c_str())))
|
||||||
|
{
|
||||||
|
handler->PSendSysMessage(LANG_COMMAND_SPY_UNFOLLOW, cName);
|
||||||
|
if(gmListening.find(target->GetGUIDLow()) != gmListening.end())
|
||||||
|
gmListening.erase(target->GetGUIDLow());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HandleSpyUnFollowGroupCommand(ChatHandler* handler, const char* args)
|
||||||
|
{
|
||||||
|
if(!*args)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char *cName = strtok ((char*)args," ");
|
||||||
|
if(!cName)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string pTarget = args;
|
||||||
|
if(!normalizePlayerName(pTarget))
|
||||||
|
{
|
||||||
|
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Player* target = ObjectAccessor::FindPlayer(sObjectMgr->GetPlayerGUIDByName(pTarget.c_str())))
|
||||||
|
{
|
||||||
|
if(Group* group = target->GetGroup())
|
||||||
|
{
|
||||||
|
if(gmListeningGroup.find(group->GetLowGUID()) != gmListening.end())
|
||||||
|
{
|
||||||
|
gmListeningGroup.erase(group->GetLowGUID());
|
||||||
|
handler->PSendSysMessage(LANG_COMMAND_SPY_UNFOLLOW_GROUP, cName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
handler->PSendSysMessage(LANG_COMMAND_SPY_NOT_FOLLOWING_GROUP, cName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
handler->PSendSysMessage(LANG_NOT_IN_GROUP, target->GetName().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HandleSpyClearCommand(ChatHandler* handler, const char* /*args*/)
|
||||||
|
{
|
||||||
|
gmListening.clear();
|
||||||
|
handler->SendSysMessage(LANG_COMMAND_SPY_CLEARED);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HandleSpyStatusCommand(ChatHandler* handler, const char* /*args*/)
|
||||||
|
{
|
||||||
|
uint32 guidlow = handler->GetSession()->GetPlayer()->GetGUIDLow();
|
||||||
|
std::map<uint32,uint32>::iterator next;
|
||||||
|
handler->SendSysMessage(LANG_COMMAND_SPY_LIST);
|
||||||
|
|
||||||
|
for(std::map<uint32,uint32>::iterator itr = gmListening.begin(); itr != gmListening.end(); itr = next)
|
||||||
|
{
|
||||||
|
// There's the possibility that itr is erased, so we save it
|
||||||
|
next = itr;
|
||||||
|
++next;
|
||||||
|
if(itr->second == guidlow)
|
||||||
|
{
|
||||||
|
if(Player* target = ObjectAccessor::FindPlayer(itr->first))
|
||||||
|
handler->PSendSysMessage("%s", target->GetName().c_str());
|
||||||
|
else // clear offline players
|
||||||
|
gmListening.erase(itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class chat_spy_logout_cleaner : public PlayerScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
chat_spy_logout_cleaner() : PlayerScript("chat_spy_logout_cleaner") { }
|
||||||
|
|
||||||
|
void OnLogout(Player* player)
|
||||||
|
{
|
||||||
|
if(player && player->IsGameMaster())
|
||||||
|
{
|
||||||
|
uint32 guidlow = player->GetGUIDLow();
|
||||||
|
std::map<uint32,uint32>::iterator next;
|
||||||
|
for(std::map<uint32,uint32>::iterator itr = gmListening.begin(); itr != gmListening.end(); itr = next)
|
||||||
|
{
|
||||||
|
next = itr; // Save a reference to the next one
|
||||||
|
++next;
|
||||||
|
if(itr->second == guidlow)
|
||||||
|
gmListening.erase(itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void AddSC_spy_scripts()
|
||||||
|
{
|
||||||
|
new chat_spy_script();
|
||||||
|
new chat_spy_commandscript();
|
||||||
|
new chat_spy_logout_cleaner();
|
||||||
|
}
|
||||||
@@ -54,6 +54,7 @@ void AddSC_reload_commandscript();
|
|||||||
void AddSC_reset_commandscript();
|
void AddSC_reset_commandscript();
|
||||||
void AddSC_server_commandscript();
|
void AddSC_server_commandscript();
|
||||||
void AddSC_spectator_commandscript();
|
void AddSC_spectator_commandscript();
|
||||||
|
void AddSC_spy_scripts();
|
||||||
void AddSC_tele_commandscript();
|
void AddSC_tele_commandscript();
|
||||||
void AddSC_ticket_commandscript();
|
void AddSC_ticket_commandscript();
|
||||||
void AddSC_titles_commandscript();
|
void AddSC_titles_commandscript();
|
||||||
|
|||||||
Reference in New Issue
Block a user