diff options
Diffstat (limited to 'src/engine/client')
| -rw-r--r-- | src/engine/client/client.cpp | 3 | ||||
| -rw-r--r-- | src/engine/client/client.h | 1 | ||||
| -rw-r--r-- | src/engine/client/friends.cpp | 130 | ||||
| -rw-r--r-- | src/engine/client/friends.h | 32 | ||||
| -rw-r--r-- | src/engine/client/srvbrowse.cpp | 162 | ||||
| -rw-r--r-- | src/engine/client/srvbrowse.h | 1 |
6 files changed, 258 insertions, 71 deletions
diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index cb477304..3131afc1 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -36,6 +36,7 @@ #include <mastersrv/mastersrv.h> #include <versionsrv/versionsrv.h> +#include "friends.h" #include "srvbrowse.h" #include "client.h" @@ -1806,6 +1807,7 @@ void CClient::RegisterInterfaces() Kernel()->RegisterInterface(static_cast<IDemoRecorder*>(&m_DemoRecorder)); Kernel()->RegisterInterface(static_cast<IDemoPlayer*>(&m_DemoPlayer)); Kernel()->RegisterInterface(static_cast<IServerBrowser*>(&m_ServerBrowser)); + Kernel()->RegisterInterface(static_cast<IFriends*>(&m_Friends)); } void CClient::InitInterfaces() @@ -1823,6 +1825,7 @@ void CClient::InitInterfaces() // m_ServerBrowser.SetBaseInfo(&m_NetClient, m_pGameClient->NetVersion()); + m_Friends.Init(); } void CClient::Run() diff --git a/src/engine/client/client.h b/src/engine/client/client.h index b5be566b..31364cd2 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -105,6 +105,7 @@ class CClient : public IClient, public CDemoPlayer::IListner class CDemoPlayer m_DemoPlayer; class CDemoRecorder m_DemoRecorder; class CServerBrowser m_ServerBrowser; + class CFriends m_Friends; char m_aServerAddressStr[256]; diff --git a/src/engine/client/friends.cpp b/src/engine/client/friends.cpp new file mode 100644 index 00000000..26d70892 --- /dev/null +++ b/src/engine/client/friends.cpp @@ -0,0 +1,130 @@ +/* (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> + +#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)); +} + +void CFriends::ConAddFriend(IConsole::IResult *pResult, void *pUserData) +{ + CFriends *pSelf = (CFriends *)pUserData; + pSelf->AddFriend(pResult->GetString(0), pResult->GetString(1)); +} + +void CFriends::ConRemoveFriend(IConsole::IResult *pResult, void *pUserData) +{ + CFriends *pSelf = (CFriends *)pUserData; + pSelf->RemoveFriend(pResult->GetString(0), pResult->GetString(1)); +} + +void CFriends::Init() +{ + IConfig *pConfig = Kernel()->RequestInterface<IConfig>(); + if(pConfig) + pConfig->RegisterCallback(ConfigSaveCallback, this); + + IConsole *pConsole = Kernel()->RequestInterface<IConsole>(); + if(pConsole) + { + pConsole->Register("add_friend", "ss", CFGFLAG_CLIENT, ConAddFriend, this, "Add a friend"); + pConsole->Register("remove_Friend", "ss", CFGFLAG_CLIENT, ConRemoveFriend, this, "Remove a friend"); + } +} + +const CFriendInfo *CFriends::GetFriend(int Index) const +{ + return &m_aFriends[max(0, Index%m_NumFriends)]; +} + +bool CFriends::IsFriend(const char *pName, const char *pClan) const +{ + for(int i = 0; i < m_NumFriends; ++i) + { + if(!str_comp(m_aFriends[i].m_aName, pName) && !str_comp(m_aFriends[i].m_aClan, pClan)) + return true; + } + return false; +} + +void CFriends::AddFriend(const char *pName, const char *pClan) +{ + if(m_NumFriends == MAX_FRIENDS) + return; + + // make sure we don't have the friend already + for(int i = 0; i < m_NumFriends; ++i) + { + if(!str_comp(m_aFriends[i].m_aName, pName) && !str_comp(m_aFriends[i].m_aClan, pClan)) + 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)); + ++m_NumFriends; +} + +void CFriends::RemoveFriend(const char *pName, const char *pClan) +{ + for(int i = 0; i < m_NumFriends; ++i) + { + if(!str_comp(m_aFriends[i].m_aName, pName) && !str_comp(m_aFriends[i].m_aClan, pClan)) + { + 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; + } + return; +} + +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) + { + str_copy(aBuf, "add_friend ", sizeof(aBuf)); + + 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); + } +} diff --git a/src/engine/client/friends.h b/src/engine/client/friends.h new file mode 100644 index 00000000..e046fc20 --- /dev/null +++ b/src/engine/client/friends.h @@ -0,0 +1,32 @@ +/* (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. */ +#ifndef ENGINE_CLIENT_FRIENDS_H +#define ENGINE_CLIENT_FRIENDS_H + +#include <engine/friends.h> + +class CFriends : public IFriends +{ + CFriendInfo m_aFriends[MAX_FRIENDS]; + int m_NumFriends; + + static void ConAddFriend(IConsole::IResult *pResult, void *pUserData); + static void ConRemoveFriend(IConsole::IResult *pResult, void *pUserData); + + static void ConfigSaveCallback(IConfig *pConfig, void *pUserData); + +public: + CFriends(); + + void Init(); + + int NumFriends() const { return m_NumFriends; } + const CFriendInfo *GetFriend(int Index) const; + bool IsFriend(const char *pName, const char *pClan) const; + + void AddFriend(const char *pName, const char *pClan); + void RemoveFriend(const char *pName, const char *pClan); + void RemoveFriend(int Index); +}; + +#endif diff --git a/src/engine/client/srvbrowse.cpp b/src/engine/client/srvbrowse.cpp index b7c20ae4..be14eaa2 100644 --- a/src/engine/client/srvbrowse.cpp +++ b/src/engine/client/srvbrowse.cpp @@ -4,14 +4,16 @@ #include <base/math.h> #include <base/system.h> -#include <engine/shared/network.h> -#include <engine/shared/protocol.h> + #include <engine/shared/config.h> #include <engine/shared/memheap.h> +#include <engine/shared/network.h> +#include <engine/shared/protocol.h> -#include <engine/masterserver.h> -#include <engine/console.h> #include <engine/config.h> +#include <engine/console.h> +#include <engine/friends.h> +#include <engine/masterserver.h> #include <mastersrv/mastersrv.h> @@ -65,6 +67,7 @@ void CServerBrowser::SetBaseInfo(class CNetClient *pClient, const char *pNetVers str_copy(m_aNetVersion, pNetVersion, sizeof(m_aNetVersion)); m_pMasterServer = Kernel()->RequestInterface<IMasterServer>(); m_pConsole = Kernel()->RequestInterface<IConsole>(); + m_pFriends = Kernel()->RequestInterface<IFriends>(); IConfig *pConfig = Kernel()->RequestInterface<IConfig>(); if(pConfig) pConfig->RegisterCallback(ConfigSaveCallback, this); @@ -140,79 +143,95 @@ void CServerBrowser::Filter() for(i = 0; i < m_NumServers; i++) { int Filtered = 0; + bool FoundFriend = false; - if(g_Config.m_BrFilterEmpty && ((g_Config.m_BrFilterSpectators && m_ppServerlist[i]->m_Info.m_NumPlayers == 0) || m_ppServerlist[i]->m_Info.m_NumClients == 0)) - Filtered = 1; - else if(g_Config.m_BrFilterFull && ((g_Config.m_BrFilterSpectators && m_ppServerlist[i]->m_Info.m_NumPlayers == m_ppServerlist[i]->m_Info.m_MaxPlayers) || - m_ppServerlist[i]->m_Info.m_NumClients == m_ppServerlist[i]->m_Info.m_MaxClients)) - Filtered = 1; - else if(g_Config.m_BrFilterPw && m_ppServerlist[i]->m_Info.m_Flags&SERVER_FLAG_PASSWORD) - Filtered = 1; - else if(g_Config.m_BrFilterPure && - (str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "DM") != 0 && - str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "TDM") != 0 && - str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "CTF") != 0)) + if(g_Config.m_BrFilterFriends) { - Filtered = 1; - } - else if(g_Config.m_BrFilterPureMap && - !(str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm1") == 0 || - str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm2") == 0 || - str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm6") == 0 || - str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm7") == 0 || - str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm8") == 0 || - str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm9") == 0 || - str_comp(m_ppServerlist[i]->m_Info.m_aMap, "ctf1") == 0 || - str_comp(m_ppServerlist[i]->m_Info.m_aMap, "ctf2") == 0 || - str_comp(m_ppServerlist[i]->m_Info.m_aMap, "ctf3") == 0 || - str_comp(m_ppServerlist[i]->m_Info.m_aMap, "ctf4") == 0 || - str_comp(m_ppServerlist[i]->m_Info.m_aMap, "ctf5") == 0) - ) - { - Filtered = 1; + for(p = 0; p < m_ppServerlist[i]->m_Info.m_NumClients; p++) + { + if(m_pFriends->IsFriend(m_ppServerlist[i]->m_Info.m_aClients[p].m_aName, m_ppServerlist[i]->m_Info.m_aClients[p].m_aClan)) + { + FoundFriend = true; + break; + } + } } - else if(g_Config.m_BrFilterPing < m_ppServerlist[i]->m_Info.m_Latency) - Filtered = 1; - else if(g_Config.m_BrFilterCompatversion && str_comp_num(m_ppServerlist[i]->m_Info.m_aVersion, m_aNetVersion, 3) != 0) - Filtered = 1; - else if(g_Config.m_BrFilterServerAddress[0] && !str_find_nocase(m_ppServerlist[i]->m_Info.m_aAddress, g_Config.m_BrFilterServerAddress)) - Filtered = 1; - else if(g_Config.m_BrFilterGametype[0] && !str_find_nocase(m_ppServerlist[i]->m_Info.m_aGameType, g_Config.m_BrFilterGametype)) - Filtered = 1; - else if(g_Config.m_BrFilterString[0] != 0) - { - int MatchFound = 0; - - m_ppServerlist[i]->m_Info.m_QuickSearchHit = 0; - // match against server name - if(str_find_nocase(m_ppServerlist[i]->m_Info.m_aName, g_Config.m_BrFilterString)) + if(!FoundFriend) + { + if(g_Config.m_BrFilterEmpty && ((g_Config.m_BrFilterSpectators && m_ppServerlist[i]->m_Info.m_NumPlayers == 0) || m_ppServerlist[i]->m_Info.m_NumClients == 0)) + Filtered = 1; + else if(g_Config.m_BrFilterFull && ((g_Config.m_BrFilterSpectators && m_ppServerlist[i]->m_Info.m_NumPlayers == m_ppServerlist[i]->m_Info.m_MaxPlayers) || + m_ppServerlist[i]->m_Info.m_NumClients == m_ppServerlist[i]->m_Info.m_MaxClients)) + Filtered = 1; + else if(g_Config.m_BrFilterPw && m_ppServerlist[i]->m_Info.m_Flags&SERVER_FLAG_PASSWORD) + Filtered = 1; + else if(g_Config.m_BrFilterPure && + (str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "DM") != 0 && + str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "TDM") != 0 && + str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "CTF") != 0)) { - MatchFound = 1; - m_ppServerlist[i]->m_Info.m_QuickSearchHit |= IServerBrowser::QUICK_SERVERNAME; + Filtered = 1; } - - // match against players - for(p = 0; p < m_ppServerlist[i]->m_Info.m_NumPlayers; p++) + else if(g_Config.m_BrFilterPureMap && + !(str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm1") == 0 || + str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm2") == 0 || + str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm6") == 0 || + str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm7") == 0 || + str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm8") == 0 || + str_comp(m_ppServerlist[i]->m_Info.m_aMap, "dm9") == 0 || + str_comp(m_ppServerlist[i]->m_Info.m_aMap, "ctf1") == 0 || + str_comp(m_ppServerlist[i]->m_Info.m_aMap, "ctf2") == 0 || + str_comp(m_ppServerlist[i]->m_Info.m_aMap, "ctf3") == 0 || + str_comp(m_ppServerlist[i]->m_Info.m_aMap, "ctf4") == 0 || + str_comp(m_ppServerlist[i]->m_Info.m_aMap, "ctf5") == 0) + ) { - if(str_find_nocase(m_ppServerlist[i]->m_Info.m_aClients[p].m_aName, g_Config.m_BrFilterString) || - str_find_nocase(m_ppServerlist[i]->m_Info.m_aClients[p].m_aClan, g_Config.m_BrFilterString)) + Filtered = 1; + } + else if(g_Config.m_BrFilterPing < m_ppServerlist[i]->m_Info.m_Latency) + Filtered = 1; + else if(g_Config.m_BrFilterCompatversion && str_comp_num(m_ppServerlist[i]->m_Info.m_aVersion, m_aNetVersion, 3) != 0) + Filtered = 1; + else if(g_Config.m_BrFilterServerAddress[0] && !str_find_nocase(m_ppServerlist[i]->m_Info.m_aAddress, g_Config.m_BrFilterServerAddress)) + Filtered = 1; + else if(g_Config.m_BrFilterGametype[0] && !str_find_nocase(m_ppServerlist[i]->m_Info.m_aGameType, g_Config.m_BrFilterGametype)) + Filtered = 1; + else if(g_Config.m_BrFilterString[0] != 0) + { + int MatchFound = 0; + + m_ppServerlist[i]->m_Info.m_QuickSearchHit = 0; + + // match against server name + if(str_find_nocase(m_ppServerlist[i]->m_Info.m_aName, g_Config.m_BrFilterString)) { MatchFound = 1; - m_ppServerlist[i]->m_Info.m_QuickSearchHit |= IServerBrowser::QUICK_PLAYER; - break; + m_ppServerlist[i]->m_Info.m_QuickSearchHit |= IServerBrowser::QUICK_SERVERNAME; } - } - // match against map - if(str_find_nocase(m_ppServerlist[i]->m_Info.m_aMap, g_Config.m_BrFilterString)) - { - MatchFound = 1; - m_ppServerlist[i]->m_Info.m_QuickSearchHit |= IServerBrowser::QUICK_MAPNAME; - } + // match against players + for(p = 0; p < m_ppServerlist[i]->m_Info.m_NumClients; p++) + { + if(str_find_nocase(m_ppServerlist[i]->m_Info.m_aClients[p].m_aName, g_Config.m_BrFilterString) || + str_find_nocase(m_ppServerlist[i]->m_Info.m_aClients[p].m_aClan, g_Config.m_BrFilterString)) + { + MatchFound = 1; + m_ppServerlist[i]->m_Info.m_QuickSearchHit |= IServerBrowser::QUICK_PLAYER; + break; + } + } - if(!MatchFound) - Filtered = 1; + // match against map + if(str_find_nocase(m_ppServerlist[i]->m_Info.m_aMap, g_Config.m_BrFilterString)) + { + MatchFound = 1; + m_ppServerlist[i]->m_Info.m_QuickSearchHit |= IServerBrowser::QUICK_MAPNAME; + } + + if(!MatchFound) + Filtered = 1; + } } if(Filtered == 0) @@ -226,12 +245,13 @@ int CServerBrowser::SortHash() const i |= g_Config.m_BrFilterEmpty<<4; i |= g_Config.m_BrFilterFull<<5; i |= g_Config.m_BrFilterSpectators<<6; - i |= g_Config.m_BrFilterPw<<7; - i |= g_Config.m_BrSortOrder<<8; - i |= g_Config.m_BrFilterCompatversion<<9; - i |= g_Config.m_BrFilterPure<<10; - i |= g_Config.m_BrFilterPureMap<<11; - i |= g_Config.m_BrFilterPing<<17; + i |= g_Config.m_BrFilterFriends<<7; + i |= g_Config.m_BrFilterPw<<8; + i |= g_Config.m_BrSortOrder<<9; + i |= g_Config.m_BrFilterCompatversion<<10; + i |= g_Config.m_BrFilterPure<<11; + i |= g_Config.m_BrFilterPureMap<<12; + i |= g_Config.m_BrFilterPing<<18; return i; } diff --git a/src/engine/client/srvbrowse.h b/src/engine/client/srvbrowse.h index b3d0f9ed..876627bf 100644 --- a/src/engine/client/srvbrowse.h +++ b/src/engine/client/srvbrowse.h @@ -55,6 +55,7 @@ private: CNetClient *m_pNetClient; IMasterServer *m_pMasterServer; class IConsole *m_pConsole; + class IFriends *m_pFriends; char m_aNetVersion[128]; CHeap m_ServerlistHeap; |