2017-01-25 16:39:00 -05:00
# include "STDInclude.hpp"
namespace Components
{
2017-01-31 12:16:30 -05:00
bool Friends : : TriggerSort = false ;
2017-01-31 11:04:54 -05:00
bool Friends : : TriggerUpdate = false ;
2017-01-31 12:16:30 -05:00
2017-01-30 15:54:34 -05:00
int Friends : : InitialState ;
2017-01-25 16:39:00 -05:00
unsigned int Friends : : CurrentFriend ;
std : : recursive_mutex Friends : : Mutex ;
std : : vector < Friends : : Friend > Friends : : FriendsList ;
2017-01-29 11:16:09 -05:00
void Friends : : SortIndividualList ( std : : vector < Friends : : Friend > * list )
{
qsort ( list - > data ( ) , list - > size ( ) , sizeof ( Friends : : Friend ) , [ ] ( const void * first , const void * second )
{
const Friends : : Friend * friend1 = static_cast < const Friends : : Friend * > ( first ) ;
const Friends : : Friend * friend2 = static_cast < const Friends : : Friend * > ( second ) ;
2017-01-31 12:16:30 -05:00
return friend1 - > cleanName . compare ( friend2 - > cleanName ) ;
2017-01-29 11:16:09 -05:00
} ) ;
}
2017-01-31 12:16:30 -05:00
void Friends : : SortList ( bool force )
2017-01-29 11:16:09 -05:00
{
2017-01-31 12:16:30 -05:00
if ( ! force )
{
Friends : : TriggerSort = true ;
return ;
}
2017-01-29 11:16:09 -05:00
std : : lock_guard < std : : recursive_mutex > _ ( Friends : : Mutex ) ;
2017-01-29 12:06:48 -05:00
std : : vector < Friends : : Friend > connectedList ;
2017-01-29 11:16:09 -05:00
std : : vector < Friends : : Friend > playingList ;
std : : vector < Friends : : Friend > onlineList ;
std : : vector < Friends : : Friend > offlineList ;
// Split up the list
for ( auto entry : Friends : : FriendsList )
{
2017-01-30 15:13:30 -05:00
if ( ! entry . online ) offlineList . push_back ( entry ) ;
2017-01-31 04:20:28 -05:00
else if ( ! Friends : : IsOnline ( entry . lastTime ) ) onlineList . push_back ( entry ) ;
2017-01-30 15:13:30 -05:00
else if ( entry . server . getType ( ) = = Game : : NA_BAD ) playingList . push_back ( entry ) ;
else connectedList . push_back ( entry ) ;
2017-01-29 11:16:09 -05:00
}
2017-01-29 12:06:48 -05:00
Friends : : SortIndividualList ( & connectedList ) ;
2017-01-29 11:16:09 -05:00
Friends : : SortIndividualList ( & playingList ) ;
Friends : : SortIndividualList ( & onlineList ) ;
Friends : : SortIndividualList ( & offlineList ) ;
2017-01-31 10:20:49 -05:00
size_t count = Friends : : FriendsList . size ( ) ;
2017-01-29 11:16:09 -05:00
Friends : : FriendsList . clear ( ) ;
2017-01-31 10:20:49 -05:00
Friends : : FriendsList . reserve ( count ) ;
2017-01-29 11:16:09 -05:00
2017-01-29 12:06:48 -05:00
Utils : : Merge ( & Friends : : FriendsList , connectedList ) ;
2017-01-29 11:16:09 -05:00
Utils : : Merge ( & Friends : : FriendsList , playingList ) ;
Utils : : Merge ( & Friends : : FriendsList , onlineList ) ;
Utils : : Merge ( & Friends : : FriendsList , offlineList ) ;
}
2017-01-25 16:39:00 -05:00
void Friends : : UpdateUserInfo ( SteamID user )
{
2017-01-30 15:13:30 -05:00
std : : lock_guard < std : : recursive_mutex > _ ( Friends : : Mutex ) ;
auto entry = std : : find_if ( Friends : : FriendsList . begin ( ) , Friends : : FriendsList . end ( ) , [ user ] ( Friends : : Friend entry )
{
return ( entry . userId . Bits = = user . Bits ) ;
} ) ;
if ( entry = = Friends : : FriendsList . end ( ) | | ! Steam : : Proxy : : SteamFriends ) return ;
entry - > name = Steam : : Proxy : : SteamFriends - > GetFriendPersonaName ( user ) ;
entry - > online = Steam : : Proxy : : SteamFriends - > GetFriendPersonaState ( user ) ! = 0 ;
2017-01-31 12:16:30 -05:00
entry - > cleanName = Utils : : String : : ToLower ( Colors : : Strip ( entry - > name ) ) ;
2017-01-31 11:53:59 -05:00
std : : string guid = Steam : : Proxy : : SteamFriends - > GetFriendRichPresence ( user , " iw4x_guid " ) ;
std : : string name = Steam : : Proxy : : SteamFriends - > GetFriendRichPresence ( user , " iw4x_name " ) ;
std : : string experience = Steam : : Proxy : : SteamFriends - > GetFriendRichPresence ( user , " iw4x_experience " ) ;
std : : string prestige = Steam : : Proxy : : SteamFriends - > GetFriendRichPresence ( user , " iw4x_prestige " ) ;
if ( ! guid . empty ( ) ) entry - > guid . Bits = strtoull ( guid . data ( ) , nullptr , 16 ) ;
if ( ! name . empty ( ) ) entry - > playerName = name ;
if ( ! experience . empty ( ) ) entry - > experience = atoi ( experience . data ( ) ) ;
if ( ! prestige . empty ( ) ) entry - > prestige = atoi ( prestige . data ( ) ) ;
2017-01-28 18:31:11 -05:00
2017-01-30 15:13:30 -05:00
std : : string server = Steam : : Proxy : : SteamFriends - > GetFriendRichPresence ( user , " iw4x_server " ) ;
Network : : Address oldAddress = entry - > server ;
2017-02-12 07:07:14 -05:00
bool gotOnline = Friends : : IsOnline ( entry - > lastTime ) ;
2017-01-31 04:20:28 -05:00
entry - > lastTime = static_cast < unsigned int > ( atoi ( Steam : : Proxy : : SteamFriends - > GetFriendRichPresence ( user , " iw4x_playing " ) ) ) ;
2017-02-12 07:07:14 -05:00
gotOnline = ! gotOnline & & Friends : : IsOnline ( entry - > lastTime ) ;
2017-01-31 04:20:28 -05:00
2017-01-30 15:13:30 -05:00
if ( server . empty ( ) )
{
entry - > server . setType ( Game : : NA_BAD ) ;
entry - > serverName . clear ( ) ;
}
else if ( entry - > server ! = server )
{
entry - > server = server ;
entry - > serverName . clear ( ) ;
}
// Block localhost
2017-02-08 08:45:02 -05:00
if ( entry - > server . getType ( ) = = Game : : NA_LOOPBACK | | ( entry - > server . getType ( ) = = Game : : NA_IP & & entry - > server . getIP ( ) . full = = 0x0100007F ) ) entry - > server . setType ( Game : : NA_BAD ) ;
else if ( entry - > server . getType ( ) ! = Game : : NA_BAD & & entry - > server ! = oldAddress )
2017-01-30 15:13:30 -05:00
{
Node : : AddNode ( entry - > server ) ;
Network : : SendCommand ( entry - > server , " getinfo " , Utils : : Cryptography : : Rand : : GenerateChallenge ( ) ) ;
}
2017-01-28 18:31:11 -05:00
2017-01-30 15:13:30 -05:00
Friends : : SortList ( ) ;
2017-02-12 07:07:14 -05:00
if ( Dvar : : Var ( " cl_notifyFriendState " ) . get < bool > ( ) & & gotOnline )
{
2017-02-12 14:08:31 -05:00
Toast : : Show ( " cardicon_weed " , entry - > name , " Is playing IW4x " , 3000 ) ;
2017-02-12 07:07:14 -05:00
}
2017-01-25 16:39:00 -05:00
}
2017-01-31 11:04:54 -05:00
void Friends : : UpdateState ( bool force )
2017-01-29 09:10:54 -05:00
{
2017-02-01 15:08:59 -05:00
if ( Dvar : : Var ( " cl_anonymous " ) . get < bool > ( ) ) return ;
2017-01-31 11:04:54 -05:00
if ( force )
2017-01-30 15:13:30 -05:00
{
2017-01-31 11:04:54 -05:00
if ( Steam : : Proxy : : SteamLegacyFriends )
{
int state = Steam : : Proxy : : SteamLegacyFriends - > GetPersonaState ( ) ;
Steam : : Proxy : : SteamLegacyFriends - > SetPersonaState ( ( state = = 1 ? 2 : 1 ) ) ;
}
}
else
{
Friends : : TriggerUpdate = true ;
2017-01-30 15:13:30 -05:00
}
2017-01-29 09:10:54 -05:00
}
2017-01-29 11:16:09 -05:00
void Friends : : UpdateHostname ( Network : : Address server , std : : string hostname )
{
std : : lock_guard < std : : recursive_mutex > _ ( Friends : : Mutex ) ;
for ( auto & entry : Friends : : FriendsList )
{
if ( entry . server = = server )
{
entry . serverName = hostname ;
}
}
}
2017-01-31 11:04:54 -05:00
void Friends : : UpdateName ( )
{
Friends : : SetPresence ( " iw4x_name " , Steam : : SteamFriends ( ) - > GetPersonaName ( ) ) ;
Friends : : UpdateState ( ) ;
}
2017-01-29 15:49:48 -05:00
void Friends : : ClearPresence ( std : : string key )
2017-01-29 11:16:09 -05:00
{
2017-01-30 15:13:30 -05:00
if ( Steam : : Proxy : : SteamFriends )
{
Steam : : Proxy : : SteamFriends - > SetRichPresence ( key . data ( ) , nullptr ) ;
}
2017-01-29 11:16:09 -05:00
}
2017-01-29 15:49:48 -05:00
void Friends : : SetPresence ( std : : string key , std : : string value )
2017-01-29 11:16:09 -05:00
{
2017-02-01 15:08:59 -05:00
if ( Steam : : Proxy : : SteamFriends & & ! Dvar : : Var ( " cl_anonymous " ) . get < bool > ( ) )
2017-01-30 15:13:30 -05:00
{
Steam : : Proxy : : SteamFriends - > SetRichPresence ( key . data ( ) , value . data ( ) ) ;
}
2017-01-29 15:49:48 -05:00
}
void Friends : : SetServer ( )
{
Friends : : SetPresence ( " iw4x_server " , Network : : Address ( * Game : : connectedHost ) . getString ( ) ) ; // reinterpret_cast<char*>(0x7ED3F8)
Friends : : UpdateState ( ) ;
}
2017-01-29 11:16:09 -05:00
2017-01-29 15:49:48 -05:00
void Friends : : ClearServer ( )
{
Friends : : ClearPresence ( " iw4x_server " ) ;
2017-01-29 11:16:09 -05:00
Friends : : UpdateState ( ) ;
}
2017-01-29 15:49:48 -05:00
bool Friends : : IsClientInParty ( int /*controller*/ , int clientNum )
{
if ( clientNum < 0 | | clientNum > = ARRAYSIZE ( Dedicated : : PlayerGuids ) ) return false ;
std : : lock_guard < std : : recursive_mutex > _ ( Friends : : Mutex ) ;
SteamID guid = Dedicated : : PlayerGuids [ clientNum ] ;
for ( auto entry : Friends : : FriendsList )
{
2017-01-31 04:20:28 -05:00
if ( entry . guid . Bits = = guid . Bits & & Friends : : IsOnline ( entry . lastTime ) & & entry . online )
2017-01-29 15:49:48 -05:00
{
return true ;
}
}
return false ;
}
2017-01-29 09:10:54 -05:00
void Friends : : UpdateRank ( )
{
static Utils : : Value < int > levelVal ;
int experience = Game : : Live_GetXp ( 0 ) ;
int prestige = Game : : Live_GetPrestige ( 0 ) ;
int level = ( experience & 0xFFFFFF ) | ( ( prestige & 0xFF ) < < 24 ) ;
if ( ! levelVal . isValid ( ) | | levelVal . get ( ) ! = level )
{
levelVal . set ( level ) ;
2017-01-30 15:54:34 -05:00
Friends : : SetPresence ( " iw4x_experience " , Utils : : String : : VA ( " %d " , experience ) ) ;
Friends : : SetPresence ( " iw4x_prestige " , Utils : : String : : VA ( " %d " , prestige ) ) ;
2017-01-29 09:26:46 -05:00
Friends : : UpdateState ( ) ;
2017-01-29 09:10:54 -05:00
}
}
2017-01-25 16:39:00 -05:00
void Friends : : UpdateFriends ( )
{
2017-01-30 15:13:30 -05:00
std : : lock_guard < std : : recursive_mutex > _ ( Friends : : Mutex ) ;
if ( ! Steam : : Proxy : : SteamFriends ) return ;
2017-01-25 16:39:00 -05:00
2017-01-30 15:13:30 -05:00
int count = Steam : : Proxy : : SteamFriends - > GetFriendCount ( 4 ) ;
2017-01-31 11:53:59 -05:00
Proto : : Friends : : List list ;
list . ParseFromString ( Utils : : IO : : ReadFile ( " players/friends.dat " ) ) ;
2017-02-12 07:07:14 -05:00
std : : vector < Friends : : Friend > steamFriends ;
2017-01-30 15:13:30 -05:00
for ( int i = 0 ; i < count ; + + i )
{
SteamID id = Steam : : Proxy : : SteamFriends - > GetFriendByIndex ( i , 4 ) ;
Friends : : Friend entry ;
entry . userId = id ;
2017-01-31 11:53:59 -05:00
entry . guid . Bits = 0 ;
2017-01-30 15:13:30 -05:00
entry . online = false ;
2017-01-31 04:20:28 -05:00
entry . lastTime = 0 ;
2017-01-30 15:13:30 -05:00
entry . prestige = 0 ;
entry . experience = 0 ;
entry . server . setType ( Game : : NA_BAD ) ;
2017-01-31 11:53:59 -05:00
for ( auto storedFriend : list . friends ( ) )
{
if ( entry . userId . Bits = = strtoull ( storedFriend . steamid ( ) . data ( ) , nullptr , 16 ) )
{
entry . playerName = storedFriend . name ( ) ;
entry . experience = storedFriend . experience ( ) ;
entry . prestige = storedFriend . prestige ( ) ;
entry . guid . Bits = strtoull ( storedFriend . guid ( ) . data ( ) , nullptr , 16 ) ;
break ;
}
}
2017-02-12 07:07:14 -05:00
auto oldEntry = std : : find_if ( Friends : : FriendsList . begin ( ) , Friends : : FriendsList . end ( ) , [ id ] ( Friends : : Friend entry )
2017-01-30 15:13:30 -05:00
{
return ( entry . userId . Bits = = id . Bits ) ;
} ) ;
2017-02-12 07:07:14 -05:00
if ( oldEntry ! = Friends : : FriendsList . end ( ) ) entry = * oldEntry ;
else Friends : : FriendsList . push_back ( entry ) ;
steamFriends . push_back ( entry ) ;
}
for ( auto i = Friends : : FriendsList . begin ( ) ; i ! = Friends : : FriendsList . end ( ) ; )
{
SteamID id = i - > userId ;
2017-01-30 15:13:30 -05:00
2017-02-12 07:07:14 -05:00
auto oldEntry = std : : find_if ( steamFriends . begin ( ) , steamFriends . end ( ) , [ id ] ( Friends : : Friend entry )
{
return ( entry . userId . Bits = = id . Bits ) ;
} ) ;
2017-01-30 15:13:30 -05:00
2017-02-12 07:07:14 -05:00
if ( oldEntry = = steamFriends . end ( ) )
{
i = Friends : : FriendsList . erase ( i ) ;
}
else
{
* i = * oldEntry ;
+ + i ;
2017-01-30 15:13:30 -05:00
2017-02-12 07:07:14 -05:00
Friends : : UpdateUserInfo ( id ) ;
Steam : : Proxy : : SteamFriends - > RequestFriendRichPresence ( id ) ;
}
2017-01-30 15:13:30 -05:00
}
2017-01-25 16:39:00 -05:00
}
unsigned int Friends : : GetFriendCount ( )
{
return Friends : : FriendsList . size ( ) ;
}
const char * Friends : : GetFriendText ( unsigned int index , int column )
{
std : : lock_guard < std : : recursive_mutex > _ ( Friends : : Mutex ) ;
if ( index > = Friends : : FriendsList . size ( ) ) return " " ;
auto user = Friends : : FriendsList [ index ] ;
switch ( column )
{
case 0 :
{
static char buffer [ 0x100 ] ;
2017-01-26 06:42:42 -05:00
ZeroMemory ( buffer , sizeof ( buffer ) ) ;
2017-01-25 16:39:00 -05:00
2017-01-26 06:42:42 -05:00
Game : : Material * rankIcon = nullptr ;
int rank = Game : : CL_GetRankForXP ( user . experience ) ;
Game : : CL_GetRankIcon ( rank , user . prestige , & rankIcon ) ;
2017-01-29 09:10:54 -05:00
if ( ! rankIcon ) rankIcon = Game : : DB_FindXAssetDefaultHeaderInternal ( Game : : XAssetType : : ASSET_TYPE_MATERIAL ) . material ;
2017-01-25 16:39:00 -05:00
2017-01-26 06:42:42 -05:00
buffer [ 0 ] = ' ^ ' ;
buffer [ 1 ] = 2 ;
2017-01-25 16:39:00 -05:00
// Icon size
2017-01-26 06:42:42 -05:00
char size = 0x30 ;
buffer [ 2 ] = size ; // Width
buffer [ 3 ] = size ; // Height
2017-01-25 16:39:00 -05:00
// Icon name length
2017-01-26 06:42:42 -05:00
buffer [ 4 ] = static_cast < char > ( strlen ( rankIcon - > name ) ) ;
2017-01-25 16:39:00 -05:00
2017-01-26 06:42:42 -05:00
strcat_s ( buffer , rankIcon - > name ) ;
2017-01-29 09:10:54 -05:00
strcat_s ( buffer , Utils : : String : : VA ( " %i " , ( rank + 1 ) ) ) ;
2017-01-25 16:39:00 -05:00
return buffer ;
}
case 1 :
2017-01-31 11:04:54 -05:00
{
if ( user . playerName . empty ( ) )
{
return Utils : : String : : VA ( " %s " , user . name . data ( ) ) ;
}
else
{
return Utils : : String : : VA ( " %s ^7(%s^7) " , user . name . data ( ) , user . playerName . data ( ) ) ;
}
}
2017-01-25 16:39:00 -05:00
case 2 :
2017-01-29 11:16:09 -05:00
{
2017-01-30 15:13:30 -05:00
if ( ! user . online ) return " Offline " ;
2017-01-31 04:20:28 -05:00
if ( ! Friends : : IsOnline ( user . lastTime ) ) return " Online " ;
2017-01-30 15:13:30 -05:00
if ( user . server . getType ( ) = = Game : : NA_BAD ) return " Playing IW4x " ;
if ( user . serverName . empty ( ) ) return Utils : : String : : VA ( " Playing on %s " , user . server . getCString ( ) ) ;
return Utils : : String : : VA ( " Playing on %s " , user . serverName . data ( ) ) ;
2017-01-29 11:16:09 -05:00
}
2017-01-25 16:39:00 -05:00
default :
break ;
}
return " " ;
}
void Friends : : SelectFriend ( unsigned int index )
{
std : : lock_guard < std : : recursive_mutex > _ ( Friends : : Mutex ) ;
if ( index > = Friends : : FriendsList . size ( ) ) return ;
Friends : : CurrentFriend = index ;
}
2017-01-29 11:16:09 -05:00
__declspec ( naked ) void Friends : : DisconnectStub ( )
{
__asm
{
pushad
call Friends : : ClearServer
popad
push 467 CC0h
retn
}
}
2017-01-31 04:20:28 -05:00
void Friends : : UpdateTimeStamp ( )
{
2017-01-31 14:58:12 -05:00
Friends : : SetPresence ( " iw4x_playing " , Utils : : String : : VA ( " %d " , Steam : : SteamUtils ( ) - > GetServerRealTime ( ) ) ) ;
2017-02-02 14:53:43 -05:00
Friends : : SetPresence ( " iw4x_guid " , Utils : : String : : VA ( " %llX " , Steam : : SteamUser ( ) - > GetSteamID ( ) . Bits ) ) ;
2017-01-31 04:20:28 -05:00
}
2017-01-31 09:35:34 -05:00
bool Friends : : IsOnline ( unsigned __int64 timeStamp )
2017-01-31 04:20:28 -05:00
{
2017-01-31 09:35:34 -05:00
if ( ! Steam : : Proxy : : SteamUtils ) return false ;
static const unsigned __int64 duration = std : : chrono : : duration_cast < std : : chrono : : seconds > ( 5 min ) . count ( ) ;
2017-01-31 14:58:12 -05:00
return ( ( Steam : : SteamUtils ( ) - > GetServerRealTime ( ) - timeStamp ) < duration ) ;
2017-01-31 04:20:28 -05:00
}
2017-01-31 11:53:59 -05:00
void Friends : : StoreFriendsList ( )
{
std : : lock_guard < std : : recursive_mutex > _ ( Friends : : Mutex ) ;
Proto : : Friends : : List list ;
for ( auto entry : Friends : : FriendsList )
{
Proto : : Friends : : Friend * friendEntry = list . add_friends ( ) ;
friendEntry - > set_steamid ( Utils : : String : : VA ( " %llX " , entry . userId . Bits ) ) ;
friendEntry - > set_guid ( Utils : : String : : VA ( " %llX " , entry . guid . Bits ) ) ;
friendEntry - > set_name ( entry . playerName ) ;
friendEntry - > set_experience ( entry . experience ) ;
friendEntry - > set_prestige ( entry . prestige ) ;
}
Utils : : IO : : WriteFile ( " players/friends.dat " , list . SerializeAsString ( ) ) ;
}
2017-01-25 16:39:00 -05:00
Friends : : Friends ( )
{
2017-01-31 14:58:12 -05:00
if ( Dedicated : : IsEnabled ( ) | | ZoneBuilder : : IsEnabled ( ) ) return ;
2017-02-01 15:08:59 -05:00
Dvar : : Register < bool > ( " cl_anonymous " , false , Game : : DVAR_FLAG_SAVED , " " ) ;
2017-02-12 07:07:14 -05:00
Dvar : : Register < bool > ( " cl_notifyFriendState " , false , Game : : DVAR_FLAG_SAVED , " " ) ; // False by default, might set default to true and add that to the options!
2017-01-31 14:58:12 -05:00
2017-02-12 12:03:55 -05:00
// Hook Live_ShowFriendsList
Utils : : Hook ( 0x4D6C70 , [ ] ( )
{
Command : : Execute ( " openmenu popup_friends " , true ) ;
} , HOOK_JUMP ) . install ( ) - > quick ( ) ;
2017-01-25 16:39:00 -05:00
// Callback to update user information
2017-01-30 15:13:30 -05:00
Steam : : Proxy : : RegisterCallback ( 336 , [ ] ( void * data )
2017-01-25 16:39:00 -05:00
{
2017-01-30 15:13:30 -05:00
Friends : : FriendRichPresenceUpdate * update = static_cast < Friends : : FriendRichPresenceUpdate * > ( data ) ;
Friends : : UpdateUserInfo ( update - > m_steamIDFriend ) ;
2017-01-25 16:39:00 -05:00
} ) ;
// Persona state has changed
2017-01-30 15:13:30 -05:00
Steam : : Proxy : : RegisterCallback ( 304 , [ ] ( void * data )
2017-01-25 16:39:00 -05:00
{
2017-01-30 15:13:30 -05:00
Friends : : PersonaStateChange * state = static_cast < Friends : : PersonaStateChange * > ( data ) ;
if ( Steam : : Proxy : : SteamFriends ) Steam : : Proxy : : SteamFriends - > RequestFriendRichPresence ( state - > m_ulSteamID ) ;
2017-01-25 16:39:00 -05:00
} ) ;
2017-01-30 15:13:30 -05:00
// Update state when connecting/disconnecting
Utils : : Hook ( 0x403582 , Friends : : DisconnectStub , HOOK_CALL ) . install ( ) - > quick ( ) ;
Utils : : Hook ( 0x4CD023 , Friends : : SetServer , HOOK_JUMP ) . install ( ) - > quick ( ) ;
// Show blue icons on the minimap
Utils : : Hook ( 0x493130 , Friends : : IsClientInParty , HOOK_JUMP ) . install ( ) - > quick ( ) ;
2017-01-25 16:39:00 -05:00
UIScript : : Add ( " LoadFriends " , [ ] ( UIScript : : Token )
{
Friends : : UpdateFriends ( ) ;
} ) ;
2017-01-29 11:16:09 -05:00
UIScript : : Add ( " JoinFriend " , [ ] ( UIScript : : Token )
{
std : : lock_guard < std : : recursive_mutex > _ ( Friends : : Mutex ) ;
if ( Friends : : CurrentFriend > = Friends : : FriendsList . size ( ) ) return ;
auto & user = Friends : : FriendsList [ Friends : : CurrentFriend ] ;
if ( user . online & & user . server . getType ( ) ! = Game : : NA_BAD )
{
Party : : Connect ( user . server ) ;
}
else
{
Command : : Execute ( " snd_playLocal exit_prestige " , false ) ;
}
} ) ;
2017-01-29 09:10:54 -05:00
QuickPatch : : OnFrame ( [ ] ( )
{
2017-01-31 12:20:16 -05:00
static Utils : : Time : : Interval timeInterval ;
2017-01-31 12:16:30 -05:00
static Utils : : Time : : Interval sortInterval ;
static Utils : : Time : : Interval stateInterval ;
2017-01-31 11:04:54 -05:00
2017-01-31 12:20:16 -05:00
if ( * reinterpret_cast < bool * > ( 0x1AD5690 ) ) // LiveStorage_DoWeHaveStats
2017-01-31 11:04:54 -05:00
{
2017-01-31 12:20:16 -05:00
Friends : : UpdateRank ( ) ;
}
if ( timeInterval . elapsed ( 2 min ) )
{
timeInterval . update ( ) ;
2017-01-31 12:16:30 -05:00
Friends : : UpdateTimeStamp ( ) ;
Friends : : UpdateState ( ) ;
}
if ( stateInterval . elapsed ( 5 s ) )
{
stateInterval . update ( ) ;
2017-01-31 11:04:54 -05:00
if ( Friends : : TriggerUpdate )
{
Friends : : TriggerUpdate = false ;
Friends : : UpdateState ( true ) ;
}
}
2017-02-12 07:07:14 -05:00
if ( sortInterval . elapsed ( 1 s ) )
2017-01-31 12:16:30 -05:00
{
2017-01-31 12:20:16 -05:00
sortInterval . update ( ) ;
2017-01-31 12:16:30 -05:00
if ( Friends : : TriggerSort )
{
Friends : : TriggerSort = false ;
Friends : : SortList ( true ) ;
}
}
2017-01-29 09:10:54 -05:00
} ) ;
2017-02-06 15:23:15 -05:00
UIFeeder : : Add ( 61.0f , Friends : : GetFriendCount , Friends : : GetFriendText , Friends : : SelectFriend ) ;
2017-01-28 09:51:50 -05:00
2017-01-30 15:54:34 -05:00
QuickPatch : : OnShutdown ( [ ] ( )
{
Friends : : ClearPresence ( " iw4x_server " ) ;
Friends : : ClearPresence ( " iw4x_playing " ) ;
2017-01-31 09:56:24 -05:00
# ifdef DEBUG
2017-02-06 15:09:41 -05:00
if ( Steam : : Proxy : : SteamFriends )
{
Steam : : Proxy : : SteamFriends - > ClearRichPresence ( ) ;
}
2017-01-31 09:56:24 -05:00
# endif
2017-01-30 15:54:34 -05:00
if ( Steam : : Proxy : : SteamLegacyFriends )
{
Steam : : Proxy : : SteamLegacyFriends - > SetPersonaState ( Friends : : InitialState ) ;
}
} ) ;
QuickPatch : : Once ( [ ] ( )
{
if ( Steam : : Proxy : : SteamLegacyFriends )
{
Friends : : InitialState = Steam : : Proxy : : SteamLegacyFriends - > GetPersonaState ( ) ;
}
2017-02-01 15:08:59 -05:00
if ( Dvar : : Var ( " cl_anonymous " ) . get < bool > ( ) )
{
if ( Steam : : Proxy : : SteamFriends )
{
Steam : : Proxy : : SteamFriends - > ClearRichPresence ( ) ;
}
}
2017-01-31 04:20:28 -05:00
Friends : : UpdateTimeStamp ( ) ;
2017-01-31 11:04:54 -05:00
Friends : : UpdateName ( ) ;
Friends : : UpdateState ( ) ;
2017-01-31 10:20:49 -05:00
2017-01-30 15:54:34 -05:00
Friends : : UpdateFriends ( ) ;
} ) ;
2017-01-25 16:39:00 -05:00
}
Friends : : ~ Friends ( )
{
2017-01-31 14:58:12 -05:00
if ( Dedicated : : IsEnabled ( ) | | ZoneBuilder : : IsEnabled ( ) ) return ;
2017-01-31 11:53:59 -05:00
Friends : : StoreFriendsList ( ) ;
2017-01-30 16:13:57 -05:00
Steam : : Proxy : : UnregisterCallback ( 336 ) ;
Steam : : Proxy : : UnregisterCallback ( 304 ) ;
2017-02-06 15:09:41 -05:00
std : : lock_guard < std : : recursive_mutex > _ ( Friends : : Mutex ) ;
Friends : : FriendsList . clear ( ) ;
2017-01-25 16:39:00 -05:00
}
}