2011-03-23 12:06:35 +00:00
|
|
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
|
|
|
#include <base/math.h>
|
2011-06-26 15:10:13 +00:00
|
|
|
#include <base/system.h>
|
2011-03-23 12:06:35 +00:00
|
|
|
|
|
|
|
#include <engine/config.h>
|
|
|
|
#include <engine/console.h>
|
|
|
|
#include <engine/shared/config.h>
|
|
|
|
|
|
|
|
#include "friends.h"
|
|
|
|
|
|
|
|
CFriends::CFriends()
|
|
|
|
{
|
|
|
|
mem_zero(m_aFriends, sizeof(m_aFriends));
|
2011-07-30 23:38:45 +00:00
|
|
|
m_NumFriends = 0;
|
2015-07-22 20:16:49 +00:00
|
|
|
m_Foes = false;
|
2011-03-23 12:06:35 +00:00
|
|
|
}
|
|
|
|
|
2011-08-13 00:11:06 +00:00
|
|
|
void CFriends::ConAddFriend(IConsole::IResult *pResult, void *pUserData)
|
2011-03-23 12:06:35 +00:00
|
|
|
{
|
|
|
|
CFriends *pSelf = (CFriends *)pUserData;
|
|
|
|
pSelf->AddFriend(pResult->GetString(0), pResult->GetString(1));
|
|
|
|
}
|
|
|
|
|
2011-08-13 00:11:06 +00:00
|
|
|
void CFriends::ConRemoveFriend(IConsole::IResult *pResult, void *pUserData)
|
2011-03-23 12:06:35 +00:00
|
|
|
{
|
|
|
|
CFriends *pSelf = (CFriends *)pUserData;
|
|
|
|
pSelf->RemoveFriend(pResult->GetString(0), pResult->GetString(1));
|
|
|
|
}
|
|
|
|
|
2015-07-28 14:13:29 +00:00
|
|
|
void CFriends::ConFriends(IConsole::IResult *pResult, void *pUserData)
|
|
|
|
{
|
|
|
|
CFriends *pSelf = (CFriends *)pUserData;
|
|
|
|
pSelf->Friends();
|
|
|
|
}
|
|
|
|
|
2015-07-22 20:16:49 +00:00
|
|
|
void CFriends::Init(bool Foes)
|
2011-03-23 12:06:35 +00:00
|
|
|
{
|
2015-07-22 20:16:49 +00:00
|
|
|
m_Foes = Foes;
|
|
|
|
|
2011-03-23 12:06:35 +00:00
|
|
|
IConfig *pConfig = Kernel()->RequestInterface<IConfig>();
|
|
|
|
if(pConfig)
|
|
|
|
pConfig->RegisterCallback(ConfigSaveCallback, this);
|
|
|
|
|
|
|
|
IConsole *pConsole = Kernel()->RequestInterface<IConsole>();
|
|
|
|
if(pConsole)
|
|
|
|
{
|
2015-07-22 20:16:49 +00:00
|
|
|
if(Foes)
|
|
|
|
{
|
2015-12-28 15:14:52 +00:00
|
|
|
pConsole->Register("add_foe", "s[name] ?s[clan]", CFGFLAG_CLIENT, ConAddFriend, this, "Add a foe");
|
|
|
|
pConsole->Register("remove_foe", "s[name] ?s[clan]", CFGFLAG_CLIENT, ConRemoveFriend, this, "Remove a foe");
|
2015-07-28 14:13:29 +00:00
|
|
|
pConsole->Register("foes", "", CFGFLAG_CLIENT, ConFriends, this, "List foes");
|
2015-07-22 20:16:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-12-28 15:14:52 +00:00
|
|
|
pConsole->Register("add_friend", "s[name] ?s[clan]", CFGFLAG_CLIENT, ConAddFriend, this, "Add a friend");
|
|
|
|
pConsole->Register("remove_friend", "s[name] ?s[clan]", CFGFLAG_CLIENT, ConRemoveFriend, this, "Remove a friend");
|
2015-07-28 14:13:29 +00:00
|
|
|
pConsole->Register("friends", "", CFGFLAG_CLIENT, ConFriends, this, "List friends");
|
2015-07-22 20:16:49 +00:00
|
|
|
}
|
2011-03-23 12:06:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const CFriendInfo *CFriends::GetFriend(int Index) const
|
|
|
|
{
|
|
|
|
return &m_aFriends[max(0, Index%m_NumFriends)];
|
|
|
|
}
|
|
|
|
|
2011-06-26 15:10:13 +00:00
|
|
|
int CFriends::GetFriendState(const char *pName, const char *pClan) const
|
|
|
|
{
|
|
|
|
int Result = FRIEND_NO;
|
|
|
|
unsigned NameHash = str_quickhash(pName);
|
|
|
|
unsigned ClanHash = str_quickhash(pClan);
|
|
|
|
for(int i = 0; i < m_NumFriends; ++i)
|
|
|
|
{
|
2017-04-12 09:04:20 +00:00
|
|
|
if((g_Config.m_ClFriendsIgnoreClan && m_aFriends[i].m_aName[0]) || (m_aFriends[i].m_ClanHash == ClanHash && !str_comp(m_aFriends[i].m_aClan, pClan)))
|
2011-06-26 15:10:13 +00:00
|
|
|
{
|
|
|
|
if(m_aFriends[i].m_aName[0] == 0)
|
|
|
|
Result = FRIEND_CLAN;
|
2017-04-12 09:04:20 +00:00
|
|
|
else if(m_aFriends[i].m_NameHash == NameHash && !str_comp(m_aFriends[i].m_aName, pName))
|
2011-06-26 15:10:13 +00:00
|
|
|
{
|
|
|
|
Result = FRIEND_PLAYER;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2011-04-02 17:51:05 +00:00
|
|
|
bool CFriends::IsFriend(const char *pName, const char *pClan, bool PlayersOnly) const
|
2011-03-23 12:06:35 +00:00
|
|
|
{
|
2011-06-26 15:10:13 +00:00
|
|
|
unsigned NameHash = str_quickhash(pName);
|
|
|
|
unsigned ClanHash = str_quickhash(pClan);
|
2011-03-23 12:06:35 +00:00
|
|
|
for(int i = 0; i < m_NumFriends; ++i)
|
|
|
|
{
|
2017-04-12 09:04:20 +00:00
|
|
|
if(((g_Config.m_ClFriendsIgnoreClan && m_aFriends[i].m_aName[0]) || (m_aFriends[i].m_ClanHash == ClanHash && !str_comp(m_aFriends[i].m_aClan, pClan))) &&
|
|
|
|
((!PlayersOnly && m_aFriends[i].m_aName[0] == 0) || (m_aFriends[i].m_NameHash == NameHash && !str_comp(m_aFriends[i].m_aName, pName))))
|
2011-03-23 12:06:35 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFriends::AddFriend(const char *pName, const char *pClan)
|
|
|
|
{
|
2011-03-31 19:30:28 +00:00
|
|
|
if(m_NumFriends == MAX_FRIENDS || (pName[0] == 0 && pClan[0] == 0))
|
2011-03-23 12:06:35 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// make sure we don't have the friend already
|
2011-06-26 15:10:13 +00:00
|
|
|
unsigned NameHash = str_quickhash(pName);
|
|
|
|
unsigned ClanHash = str_quickhash(pClan);
|
2011-03-23 12:06:35 +00:00
|
|
|
for(int i = 0; i < m_NumFriends; ++i)
|
|
|
|
{
|
2017-04-12 09:04:20 +00:00
|
|
|
if((m_aFriends[i].m_NameHash == NameHash && !str_comp(m_aFriends[i].m_aName, pName)) && ((g_Config.m_ClFriendsIgnoreClan && m_aFriends[i].m_aName[0]) || (m_aFriends[i].m_ClanHash == ClanHash && !str_comp(m_aFriends[i].m_aClan, pClan))))
|
2011-03-23 12:06:35 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
str_copy(m_aFriends[m_NumFriends].m_aName, pName, sizeof(m_aFriends[m_NumFriends].m_aName));
|
|
|
|
str_copy(m_aFriends[m_NumFriends].m_aClan, pClan, sizeof(m_aFriends[m_NumFriends].m_aClan));
|
2011-06-26 15:10:13 +00:00
|
|
|
m_aFriends[m_NumFriends].m_NameHash = NameHash;
|
|
|
|
m_aFriends[m_NumFriends].m_ClanHash = ClanHash;
|
2011-03-23 12:06:35 +00:00
|
|
|
++m_NumFriends;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFriends::RemoveFriend(const char *pName, const char *pClan)
|
|
|
|
{
|
2011-06-26 15:10:13 +00:00
|
|
|
unsigned NameHash = str_quickhash(pName);
|
|
|
|
unsigned ClanHash = str_quickhash(pClan);
|
2011-03-23 12:06:35 +00:00
|
|
|
for(int i = 0; i < m_NumFriends; ++i)
|
|
|
|
{
|
2017-04-12 09:04:20 +00:00
|
|
|
if((m_aFriends[i].m_NameHash == NameHash && !str_comp(m_aFriends[i].m_aName, pName)) &&
|
|
|
|
((g_Config.m_ClFriendsIgnoreClan && m_aFriends[i].m_aName[0]) || (m_aFriends[i].m_ClanHash == ClanHash && !str_comp(m_aFriends[i].m_aClan, pClan))))
|
2011-03-23 12:06:35 +00:00
|
|
|
{
|
|
|
|
RemoveFriend(i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFriends::RemoveFriend(int Index)
|
|
|
|
{
|
|
|
|
if(Index >= 0 && Index < m_NumFriends)
|
|
|
|
{
|
|
|
|
mem_move(&m_aFriends[Index], &m_aFriends[Index+1], sizeof(CFriendInfo)*(m_NumFriends-(Index+1)));
|
|
|
|
--m_NumFriends;
|
|
|
|
}
|
2015-07-28 14:13:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CFriends::Friends()
|
|
|
|
{
|
|
|
|
char aBuf[128];
|
|
|
|
IConsole *pConsole = Kernel()->RequestInterface<IConsole>();
|
|
|
|
if(pConsole)
|
|
|
|
{
|
|
|
|
for(int i = 0; i < m_NumFriends; ++i)
|
|
|
|
{
|
|
|
|
str_format(aBuf, sizeof(aBuf), "Name: %s, Clan: %s", m_aFriends[i].m_aName, m_aFriends[i].m_aClan);
|
|
|
|
pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, m_Foes?"foes":"friends", aBuf, true);
|
|
|
|
}
|
|
|
|
}
|
2011-03-23 12:06:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CFriends::ConfigSaveCallback(IConfig *pConfig, void *pUserData)
|
|
|
|
{
|
|
|
|
CFriends *pSelf = (CFriends *)pUserData;
|
|
|
|
char aBuf[128];
|
|
|
|
const char *pEnd = aBuf+sizeof(aBuf)-4;
|
|
|
|
for(int i = 0; i < pSelf->m_NumFriends; ++i)
|
|
|
|
{
|
2015-07-22 20:16:49 +00:00
|
|
|
str_copy(aBuf, pSelf->m_Foes ? "add_foe " : "add_friend ", sizeof(aBuf));
|
2011-03-23 12:06:35 +00:00
|
|
|
|
|
|
|
const char *pSrc = pSelf->m_aFriends[i].m_aName;
|
|
|
|
char *pDst = aBuf+str_length(aBuf);
|
|
|
|
*pDst++ = '"';
|
|
|
|
while(*pSrc && pDst < pEnd)
|
|
|
|
{
|
|
|
|
if(*pSrc == '"' || *pSrc == '\\') // escape \ and "
|
|
|
|
*pDst++ = '\\';
|
|
|
|
*pDst++ = *pSrc++;
|
|
|
|
}
|
|
|
|
*pDst++ = '"';
|
|
|
|
*pDst++ = ' ';
|
|
|
|
|
|
|
|
pSrc = pSelf->m_aFriends[i].m_aClan;
|
|
|
|
*pDst++ = '"';
|
|
|
|
while(*pSrc && pDst < pEnd)
|
|
|
|
{
|
|
|
|
if(*pSrc == '"' || *pSrc == '\\') // escape \ and "
|
|
|
|
*pDst++ = '\\';
|
|
|
|
*pDst++ = *pSrc++;
|
|
|
|
}
|
|
|
|
*pDst++ = '"';
|
|
|
|
*pDst++ = 0;
|
|
|
|
|
|
|
|
pConfig->WriteLine(aBuf);
|
|
|
|
}
|
|
|
|
}
|