/// <summary> /// Logs the client into the Steam3 network as an anonymous game server. /// The client should already have been connected at this point. /// Results are returned in a <see cref="SteamUser.LoggedOnCallback"/>. /// </summary> /// <param name="appId">The AppID served by this game server, or 0 for the default.</param> public void LogOnAnonymous(uint appId = 0) { var logon = new ClientMsgProtobuf <CMsgClientLogon>(EMsg.ClientLogonGameServer); SteamID gsId = new SteamID(0, 0, Client.ConnectedUniverse, EAccountType.AnonGameServer); logon.ProtoHeader.client_sessionid = 0; logon.ProtoHeader.steamid = gsId.ConvertToUInt64(); uint localIp = NetHelpers.GetIPAddress(this.Client.LocalIP); logon.Body.obfustucated_private_ip = localIp ^ MsgClientLogon.ObfuscationMask; logon.Body.protocol_version = MsgClientLogon.CurrentProtocol; logon.Body.client_os_type = ( uint )Utils.GetOSType(); logon.Body.game_server_app_id = ( int )appId; logon.Body.machine_id = Utils.GenerateMachineID(); this.Client.Send(logon); }
void HandleUserJoinedLobby(IPacketMsg packetMsg) { var userJoinedLobby = new ClientMsgProtobuf <CMsgClientMMSUserJoinedLobby>(packetMsg); var body = userJoinedLobby.Body; var lobby = lobbyCache.GetLobby(body.app_id, body.steam_id_lobby); if (lobby != null && lobby.Members.Count > 0) { var joiningMember = lobbyCache.AddLobbyMember(body.app_id, lobby, body.steam_id_user, body.persona_name); if (joiningMember != null) { Client.PostCallback(new UserJoinedLobbyCallback( body.app_id, body.steam_id_lobby, joiningMember )); } } }
/// <summary> /// Invites a user to a chat room. /// The results of this action will be available through the <see cref="ChatActionResultCallback"/> callback. /// </summary> /// <param name="steamIdUser">The SteamID of the user to invite.</param> /// <param name="steamIdChat">The SteamID of the chat room to invite the user to.</param> public void InviteUserToChat(SteamID steamIdUser, SteamID steamIdChat) { SteamID chatId = steamIdChat.ConvertToUInt64(); // copy the steamid so we don't modify it if (chatId.IsClanAccount) { // this steamid is incorrect, so we'll fix it up chatId.AccountInstance = (uint)SteamID.ChatInstanceFlags.Clan; chatId.AccountType = EAccountType.Chat; } var inviteMsg = new ClientMsgProtobuf <CMsgClientChatInvite>(EMsg.ClientChatInvite); inviteMsg.Body.steam_id_chat = chatId; inviteMsg.Body.steam_id_invited = steamIdUser; // steamclient also sends the steamid of the user that did the invitation // we'll mimic that behavior inviteMsg.Body.steam_id_patron = Client.SteamID; this.Client.Send(inviteMsg); }
void HandleSetLobbyOwnerResponse(IPacketMsg packetMsg) { var setLobbyOwnerResponse = new ClientMsgProtobuf <CMsgClientMMSSetLobbyOwnerResponse>(packetMsg); var body = setLobbyOwnerResponse.Body; if (lobbyManipulationRequests.TryRemove(setLobbyOwnerResponse.TargetJobID, out var request)) { if (body.eresult == ( int )EResult.OK && request != null) { var setLobbyOwner = ( CMsgClientMMSSetLobbyOwner )request; lobbyCache.UpdateLobbyOwner(body.app_id, body.steam_id_lobby, setLobbyOwner.steam_id_new_owner); } } Client.PostCallback(new SetLobbyOwnerCallback( setLobbyOwnerResponse.TargetJobID, body.app_id, ( EResult )body.eresult, body.steam_id_lobby )); }
void HandleCreateLobbyResponse(IPacketMsg packetMsg) { var lobbyListResponse = new ClientMsgProtobuf <CMsgClientMMSCreateLobbyResponse>(packetMsg); var body = lobbyListResponse.Body; if (lobbyManipulationRequests.TryRemove(lobbyListResponse.TargetJobID, out var request)) { if (body.eresult == ( int )EResult.OK && request != null) { var createLobby = ( CMsgClientMMSCreateLobby )request; var members = new List <Lobby.Member>(1) { new Lobby.Member(Client.SteamID, createLobby.persona_name_owner) }; lobbyCache.CacheLobby( createLobby.app_id, new Lobby( body.steam_id_lobby, ( ELobbyType )createLobby.lobby_type, createLobby.lobby_flags, Client.SteamID, Lobby.DecodeMetadata(createLobby.metadata), createLobby.max_members, 1, members.AsReadOnly(), null, null ) ); } } Client.PostCallback(new CreateLobbyCallback( lobbyListResponse.TargetJobID, body.app_id, ( EResult )body.eresult, body.steam_id_lobby )); }
/// <summary> /// Requests a list of servers from the Steam game master server. /// Results are returned in a <see cref="QueryCallback"/>. /// </summary> /// <param name="details">The details for the request.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="QueryCallback"/>.</returns> public JobID ServerQuery(QueryDetails details) { var query = new ClientMsgProtobuf <CMsgClientGMSServerQuery>(EMsg.ClientGMSServerQuery); query.SourceJobID = Client.GetNextJobID(); query.Body.app_id = details.AppID; if (details.GeoLocatedIP != null) { query.Body.geo_location_ip = NetHelpers.GetIPAddress(details.GeoLocatedIP); } query.Body.filter_text = details.Filter; query.Body.region_code = ( uint )details.Region; query.Body.max_servers = details.MaxServers; this.Client.Send(query); return(query.SourceJobID); }
/// <summary> /// Logs onto the Steam network as a persistent game server. /// The client should already have been connected at this point. /// Results are return in a <see cref="SteamUser.LoggedOnCallback"/>. /// </summary> /// <param name="details">The details to use for logging on.</param> /// <exception cref="System.ArgumentNullException">No logon details were provided.</exception> /// <exception cref="System.ArgumentException">Username or password are not set within <paramref name="details"/>.</exception> public void LogOn(LogOnDetails details) { if (details == null) { throw new ArgumentNullException("details"); } if (string.IsNullOrEmpty(details.Token)) { throw new ArgumentException("LogOn requires a game server token to be set in 'details'."); } if (!this.Client.IsConnected) { this.Client.PostCallback(new SteamUser.LoggedOnCallback(EResult.NoConnection)); return; } var logon = new ClientMsgProtobuf <CMsgClientLogon>(EMsg.ClientLogonGameServer); SteamID gsId = new SteamID(0, 0, Client.Universe, EAccountType.GameServer); logon.ProtoHeader.client_sessionid = 0; logon.ProtoHeader.steamid = gsId.ConvertToUInt64(); uint localIp = NetHelpers.GetIPAddress(this.Client.LocalIP); logon.Body.obfustucated_private_ip = localIp ^ MsgClientLogon.ObfuscationMask; logon.Body.protocol_version = MsgClientLogon.CurrentProtocol; logon.Body.client_os_type = ( uint )Utils.GetOSType(); logon.Body.game_server_app_id = ( int )details.AppID; logon.Body.machine_id = HardwareUtils.GetMachineID(); logon.Body.game_server_token = details.Token; this.Client.Send(logon); }
/// <summary> /// Uploads the actual contents of a file to the UFS. /// The <see cref="UFSClient"/> should be logged on before this point, and the previous request to upload a file must have completed successfully. /// Results are returned in a <see cref="UploadFileFinishedCallback"/>. /// </summary> /// <param name="details">The details to use for uploading the file.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="UploadFileFinishedCallback"/>.</returns> public void UploadFile(UploadDetails details) { if (details == null) { throw new ArgumentNullException(nameof(details)); } const uint MaxBytesPerChunk = 10240; byte[] compressedData = ZipUtil.Compress(details.FileData); byte[] fileHash = CryptoHelper.SHAHash(details.FileData); var buffer = new byte[MaxBytesPerChunk]; using (var ms = new MemoryStream(compressedData)) { for (long readIndex = 0; readIndex < ms.Length; readIndex += buffer.Length) { var msg = new ClientMsgProtobuf <CMsgClientUFSFileChunk>(EMsg.ClientUFSUploadFileChunk); msg.TargetJobID = details.RemoteJobID; var bytesRead = ms.Read(buffer, 0, buffer.Length); if (bytesRead < buffer.Length) { msg.Body.data = buffer.Take(bytesRead).ToArray(); } else { msg.Body.data = buffer; } msg.Body.file_start = ( uint )readIndex; msg.Body.sha_file = fileHash; Send(msg); } } }
/// <summary> /// Enumerates the list of all published files on the Steam workshop. /// Results are returned in a <see cref="PublishedFilesCallback"/> from a <see cref="SteamClient.JobCallback<T>"/>. /// </summary> /// <param name="details">The specific details of the request.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="SteamClient.JobCallback<T>"/>.</returns> public JobID EnumeratePublishedFiles(EnumerationDetails details) { var enumRequest = new ClientMsgProtobuf <CMsgCREEnumeratePublishedFiles>(EMsg.CREEnumeratePublishedFiles); enumRequest.SourceJobID = Client.GetNextJobID(); enumRequest.Body.app_id = details.AppID; enumRequest.Body.query_type = ( int )details.Type; enumRequest.Body.start_index = details.StartIndex; enumRequest.Body.days = details.Days; enumRequest.Body.count = details.Count; enumRequest.Body.tags.AddRange(details.Tags); enumRequest.Body.user_tags.AddRange(details.UserTags); Client.Send(enumRequest); return(enumRequest.SourceJobID); }
/// <summary> /// Attempt to logon to the UFS and authorize the client for the given AppIDs. /// The <see cref="UFSClient"/> should be connected before this point. /// Results are returned in a <see cref="LoggedOnCallback"/>. /// </summary> /// <param name="appIds">The AppIDs to authorize when connecting to the UFS.</param> /// <returns>The Job ID of the request. This can be used to find the appropriate <see cref="LoggedOnCallback"/>.</returns> public JobID Logon(IEnumerable <uint> appIds) { var jobId = steamClient.GetNextJobID(); if (!steamClient.IsConnected) { var callback = new LoggedOnCallback(jobId, EResult.NoConnection); steamClient.PostCallback(callback); return(jobId); } var loginReq = new ClientMsgProtobuf <CMsgClientUFSLoginRequest>(EMsg.ClientUFSLoginRequest); loginReq.SourceJobID = jobId; loginReq.Body.apps.AddRange(appIds); loginReq.Body.protocol_version = MsgClientLogon.CurrentProtocol; loginReq.Body.am_session_token = steamClient.SessionToken; Send(loginReq); return(loginReq.SourceJobID); }
/// <summary> /// Sends a request to update a lobby. /// </summary> /// <param name="appId">ID of app the lobby belongs to.</param> /// <param name="lobbySteamId">The SteamID of the lobby that should be updated.</param> /// <param name="lobbyType">The new lobby type.</param> /// <param name="maxMembers">The new maximum number of members that may occupy the lobby.</param> /// <param name="lobbyFlags">The new lobby flags. Defaults to 0.</param> /// <param name="metadata">The new metadata for the lobby. Defaults to <c>null</c> (treated as an empty dictionary).</param> /// <returns>An <see cref="AsyncJob{SetLobbyDataCallback}"/>.</returns> public AsyncJob <SetLobbyDataCallback> SetLobbyData(uint appId, SteamID lobbySteamId, ELobbyType lobbyType, int maxMembers, int lobbyFlags = 0, IReadOnlyDictionary <string, string> metadata = null) { var setLobbyData = new ClientMsgProtobuf <CMsgClientMMSSetLobbyData>(EMsg.ClientMMSSetLobbyData) { Body = { app_id = appId, steam_id_lobby = lobbySteamId, steam_id_member = 0, lobby_type = ( int )lobbyType, max_members = maxMembers, lobby_flags = lobbyFlags, metadata = Lobby.EncodeMetadata(metadata), }, SourceJobID = Client.GetNextJobID() }; Send(setLobbyData, appId); lobbyManipulationRequests[setLobbyData.SourceJobID] = setLobbyData.Body; return(AttachIncompleteManipulationHandler(new AsyncJob <SetLobbyDataCallback>(Client, setLobbyData.SourceJobID))); }
void HandleUserLeftLobby(IPacketMsg packetMsg) { var userLeftLobby = new ClientMsgProtobuf <CMsgClientMMSUserLeftLobby>(packetMsg); var body = userLeftLobby.Body; var lobby = lobbyCache.GetLobby(body.app_id, body.steam_id_lobby); if (lobby != null && lobby.Members.Count > 0) { var leavingMember = lobbyCache.RemoveLobbyMember(body.app_id, lobby, body.steam_id_user); if (leavingMember?.SteamID == Client.SteamID) { lobbyCache.ClearLobbyMembers(body.app_id, body.steam_id_lobby); } Client.PostCallback(new UserLeftLobbyCallback( body.app_id, body.steam_id_lobby, leavingMember )); } }
/// <summary> /// Sends a request to update the current user's lobby metadata. /// </summary> /// <param name="appId">ID of app the lobby belongs to.</param> /// <param name="lobbySteamId">The SteamID of the lobby that should be updated.</param> /// <param name="metadata">The new metadata for the lobby.</param> /// <returns><c>null</c>, if the request could not be submitted i.e. not yet logged in. Otherwise, an <see cref="AsyncJob{SetLobbyDataCallback}"/>.</returns> public AsyncJob <SetLobbyDataCallback> SetLobbyMemberData(uint appId, SteamID lobbySteamId, IReadOnlyDictionary <string, string> metadata) { if (Client.SteamID == null) { return(null); } var setLobbyData = new ClientMsgProtobuf <CMsgClientMMSSetLobbyData>(EMsg.ClientMMSSetLobbyData) { Body = { app_id = appId, steam_id_lobby = lobbySteamId, steam_id_member = Client.SteamID, metadata = Lobby.EncodeMetadata(metadata) } }; Send(setLobbyData, appId); lobbyManipulationRequests[setLobbyData.SourceJobID] = setLobbyData.Body; return(AttachIncompleteManipulationHandler(new AsyncJob <SetLobbyDataCallback>(Client, setLobbyData.SourceJobID))); }
void HandleGetLobbyListResponse(IPacketMsg packetMsg) { var lobbyListResponse = new ClientMsgProtobuf <CMsgClientMMSGetLobbyListResponse>(packetMsg); var body = lobbyListResponse.Body; var lobbyList = body.lobbies.ConvertAll(lobby => { var existingLobby = lobbyCache.GetLobby(body.app_id, lobby.steam_id); var members = existingLobby?.Members; return(new Lobby( lobby.steam_id, ( ELobbyType )lobby.lobby_type, lobby.lobby_flags, existingLobby?.OwnerSteamID, Lobby.DecodeMetadata(lobby.metadata), lobby.max_members, lobby.num_members, members, lobby.distance, lobby.weight )); }); foreach (var lobby in lobbyList) { lobbyCache.CacheLobby(body.app_id, lobby); } Client.PostCallback(new GetLobbyListCallback( body.app_id, ( EResult )body.eresult, lobbyList )); }
/// <summary> /// Sends a request to join a lobby. /// </summary> /// <param name="appId">ID of app the lobby belongs to.</param> /// <param name="lobbySteamId">The SteamID of the lobby that should be joined.</param> /// <returns><c>null</c>, if the request could not be submitted i.e. not yet logged in. Otherwise, an <see cref="AsyncJob{JoinLobbyCallback}"/>.</returns> public AsyncJob <JoinLobbyCallback> JoinLobby(uint appId, SteamID lobbySteamId) { var personaName = Client.GetHandler <SteamFriends>()?.GetPersonaName(); if (personaName == null) { return(null); } var joinLobby = new ClientMsgProtobuf <CMsgClientMMSJoinLobby>(EMsg.ClientMMSJoinLobby) { Body = { app_id = appId, persona_name = personaName, steam_id_lobby = lobbySteamId }, SourceJobID = Client.GetNextJobID() }; Send(joinLobby, appId); return(new AsyncJob <JoinLobbyCallback>(Client, joinLobby.SourceJobID)); }
/// <summary> /// Sends a machine auth response. /// This should normally be used in response to a <see cref="UpdateMachineAuthCallback"/>. /// </summary> /// <param name="details">The details pertaining to the response.</param> public void SendMachineAuthResponse(MachineAuthDetails details) { var response = new ClientMsgProtobuf <CMsgClientUpdateMachineAuthResponse>(EMsg.ClientUpdateMachineAuthResponse); // so we respond to the correct message response.ProtoHeader.jobid_target = details.JobID; response.Body.cubwrote = ( uint )details.BytesWritten; response.Body.eresult = ( uint )details.Result; response.Body.filename = details.FileName; response.Body.filesize = ( uint )details.FileSize; response.Body.getlasterror = ( uint )details.LastError; response.Body.offset = ( uint )details.Offset; response.Body.sha_file = details.SentryFileHash; response.Body.otp_identifier = details.OneTimePassword.Identifier; response.Body.otp_type = ( int )details.OneTimePassword.Type; response.Body.otp_value = details.OneTimePassword.Value; this.Client.Send(response); }
/// <summary> /// Logs the client into the Steam3 network as an anonymous user. /// The client should already have been connected at this point. /// Results are returned in a <see cref="LoggedOnCallback"/>. /// </summary> /// <param name="details">The details to use for logging on.</param> public void LogOnAnonymous(AnonymousLogOnDetails details) { if (!this.Client.IsConnected) { this.Client.PostCallback(new LoggedOnCallback(EResult.NoConnection)); return; } var logon = new ClientMsgProtobuf <CMsgClientLogon>(EMsg.ClientLogon); SteamID auId = new SteamID(0, 0, Client.ConnectedUniverse, EAccountType.AnonUser); logon.ProtoHeader.client_sessionid = 0; logon.ProtoHeader.steamid = auId.ConvertToUInt64(); logon.Body.protocol_version = MsgClientLogon.CurrentProtocol; logon.Body.client_os_type = ( uint )details.ClientOSType; logon.Body.client_language = details.ClientLanguage; logon.Body.cell_id = details.CellID; logon.Body.machine_id = HardwareUtils.GetMachineID(); this.Client.Send(logon); }
/// <summary> /// Logs the client into the Steam3 network as an anonymous user. /// The client should already have been connected at this point. /// Results are returned in a <see cref="LoggedOnCallback"/>. /// </summary> public void LogOnAnonymous() { if (!this.Client.IsConnected) { this.Client.PostCallback(new LoggedOnCallback(EResult.NoConnection)); return; } var logon = new ClientMsgProtobuf <CMsgClientLogon>(EMsg.ClientLogon); SteamID auId = new SteamID(0, 0, Client.ConnectedUniverse, EAccountType.AnonUser); logon.ProtoHeader.client_sessionid = 0; logon.ProtoHeader.steamid = auId.ConvertToUInt64(); logon.Body.protocol_version = MsgClientLogon.CurrentProtocol; logon.Body.client_os_type = ( uint )Utils.GetOSType(); // this is not a proper machine id that Steam accepts // but it's good enough for identifying a machine logon.Body.machine_id = Utils.GenerateMachineID(); this.Client.Send(logon); }
void HandlePlayingSessionState(IPacketMsg packetMsg) { var playingSessionState = new ClientMsgProtobuf <CMsgClientPlayingSessionState>(packetMsg); this.Client.PostCallback(new PlayingSessionStateCallback(packetMsg.TargetJobID, playingSessionState.Body)); }
/// <summary> /// Logs the client into the Steam3 network. /// The client should already have been connected at this point. /// Results are returned in a <see cref="LoggedOnCallback"/>. /// </summary> /// <param name="details">The details to use for logging on.</param> /// <exception cref="ArgumentNullException">No logon details were provided.</exception> /// <exception cref="ArgumentException">Username or password are not set within <paramref name="details"/>.</exception> public void LogOn(LogOnDetails details) { if (details == null) { throw new ArgumentNullException("details"); } if (string.IsNullOrEmpty(details.Username) || (string.IsNullOrEmpty(details.Password) && string.IsNullOrEmpty(details.LoginKey))) { throw new ArgumentException("LogOn requires a username and password to be set in 'details'."); } if (!string.IsNullOrEmpty(details.LoginKey) && !details.ShouldRememberPassword) { // Prevent consumers from screwing this up. // If should_remember_password is false, the login_key is ignored server-side. // The inverse is not applicable (you can log in with should_remember_password and no login_key). throw new ArgumentException("ShouldRememberPassword is required to be set to true in order to use LoginKey."); } if (!this.Client.IsConnected) { this.Client.PostCallback(new LoggedOnCallback(EResult.NoConnection)); return; } var logon = new ClientMsgProtobuf <CMsgClientLogon>(EMsg.ClientLogon); SteamID steamId = new SteamID(details.AccountID, details.AccountInstance, Client.ConnectedUniverse, EAccountType.Individual); if (details.LoginID.HasValue) { logon.Body.obfustucated_private_ip = details.LoginID.Value; } else { uint localIp = NetHelpers.GetIPAddress(this.Client.LocalIP); logon.Body.obfustucated_private_ip = localIp ^ MsgClientLogon.ObfuscationMask; } logon.ProtoHeader.client_sessionid = 0; logon.ProtoHeader.steamid = steamId.ConvertToUInt64(); logon.Body.account_name = details.Username; logon.Body.password = details.Password; logon.Body.should_remember_password = details.ShouldRememberPassword; logon.Body.protocol_version = MsgClientLogon.CurrentProtocol; logon.Body.client_os_type = ( uint )details.ClientOSType; logon.Body.client_language = details.ClientLanguage; logon.Body.cell_id = details.CellID; logon.Body.steam2_ticket_request = details.RequestSteam2Ticket; // we're now using the latest steamclient package version, this is required to get a proper sentry file for steam guard logon.Body.client_package_version = 1771; // todo: determine if this is still required logon.Body.machine_id = HardwareUtils.GetMachineID(); // steam guard logon.Body.auth_code = details.AuthCode; logon.Body.two_factor_code = details.TwoFactorCode; logon.Body.login_key = details.LoginKey; logon.Body.sha_sentryfile = details.SentryFileHash; logon.Body.eresult_sentryfile = ( int )(details.SentryFileHash != null ? EResult.OK : EResult.FileNotFound); this.Client.Send(logon); }
void HandleFriendsList(IPacketMsg packetMsg) { var list = new ClientMsgProtobuf <CMsgClientFriendsList>(packetMsg); cache.LocalUser.SteamID = this.Client.SteamID; if (!list.Body.bincremental) { // if we're not an incremental update, the message contains all friends, so we should clear our current list lock ( listLock ) { friendList.Clear(); clanList.Clear(); } } // we have to request information for all of our friends because steam only sends persona information for online friends var reqInfo = new ClientMsgProtobuf <CMsgClientRequestFriendData>(EMsg.ClientRequestFriendData); reqInfo.Body.persona_state_requested = ( uint )Client.Configuration.DefaultPersonaStateFlags; lock ( listLock ) { List <SteamID> friendsToRemove = new List <SteamID>(); List <SteamID> clansToRemove = new List <SteamID>(); foreach (var friendObj in list.Body.friends) { SteamID friendId = friendObj.ulfriendid; if (friendId.IsIndividualAccount) { var user = cache.GetUser(friendId); user.Relationship = ( EFriendRelationship )friendObj.efriendrelationship; if (friendList.Contains(friendId)) { // if this is a friend on our list, and they removed us, mark them for removal if (user.Relationship == EFriendRelationship.None) { friendsToRemove.Add(friendId); } } else { // we don't know about this friend yet, lets add them friendList.Add(friendId); } } else if (friendId.IsClanAccount) { var clan = cache.Clans.GetAccount(friendId); clan.Relationship = ( EClanRelationship )friendObj.efriendrelationship; if (clanList.Contains(friendId)) { // mark clans we were removed/kicked from // note: not actually sure about the kicked relationship, but i'm using it for good measure if (clan.Relationship == EClanRelationship.None || clan.Relationship == EClanRelationship.Kicked) { clansToRemove.Add(friendId); } } else { // don't know about this clan, add it clanList.Add(friendId); } } if (!list.Body.bincremental) { // request persona state for our friend & clan list when it's a non-incremental update reqInfo.Body.friends.Add(friendId); } } // remove anything we marked for removal friendsToRemove.ForEach(f => friendList.Remove(f)); clansToRemove.ForEach(c => clanList.Remove(c)); } if (reqInfo.Body.friends.Count > 0) { this.Client.Send(reqInfo); } var callback = new FriendsListCallback(list.Body); this.Client.PostCallback(callback); }
/// <summary> /// Requests all offline messages. /// This also marks them as read server side. /// Results are returned in a <see cref="FriendMsgHistoryCallback"/>. /// </summary> public void RequestOfflineMessages() { var request = new ClientMsgProtobuf <CMsgClientChatGetFriendMessageHistoryForOfflineMessages>(EMsg.ClientFSGetFriendMessageHistoryForOfflineMessages); this.Client.Send(request); }
void HandleAccountInfo(IPacketMsg packetMsg) { var accInfo = new ClientMsgProtobuf <CMsgClientAccountInfo>(packetMsg); cache.LocalUser.Name = accInfo.Body.persona_name; }
void HandlePersonaState(IPacketMsg packetMsg) { var perState = new ClientMsgProtobuf <CMsgClientPersonaState>(packetMsg); EClientPersonaStateFlag flags = ( EClientPersonaStateFlag )perState.Body.status_flags; foreach (var friend in perState.Body.friends) { SteamID friendId = friend.friendid; SteamID sourceId = friend.steamid_source; if (friendId.IsIndividualAccount) { User cacheFriend = cache.GetUser(friendId); if ((flags & EClientPersonaStateFlag.PlayerName) == EClientPersonaStateFlag.PlayerName) { cacheFriend.Name = friend.player_name; } if ((flags & EClientPersonaStateFlag.Presence) == EClientPersonaStateFlag.Presence) { cacheFriend.AvatarHash = friend.avatar_hash; cacheFriend.PersonaState = ( EPersonaState )friend.persona_state; cacheFriend.PersonaStateFlags = ( EPersonaStateFlag )friend.persona_state_flags; } if ((flags & EClientPersonaStateFlag.GameExtraInfo) == EClientPersonaStateFlag.GameExtraInfo) { cacheFriend.GameName = friend.game_name; cacheFriend.GameID = friend.gameid; cacheFriend.GameAppID = friend.game_played_app_id; } } else if (friendId.IsClanAccount) { Clan cacheClan = cache.Clans.GetAccount(friendId); if ((flags & EClientPersonaStateFlag.PlayerName) == EClientPersonaStateFlag.PlayerName) { cacheClan.Name = friend.player_name; } if ((flags & EClientPersonaStateFlag.Presence) == EClientPersonaStateFlag.Presence) { cacheClan.AvatarHash = friend.avatar_hash; } } else { } // todo: cache other details/account types? } foreach (var friend in perState.Body.friends) { var callback = new PersonaStateCallback(friend); this.Client.PostCallback(callback); } }
void HandleCMList(IPacketMsg packetMsg) { var cmMsg = new ClientMsgProtobuf <CMsgClientCMList>(packetMsg); PostCallback(new CMListCallback(cmMsg.Body)); }
/// <summary> /// Logs the user off of the Steam3 network. /// This method does not disconnect the client. /// Results are returned in a <see cref="LoggedOffCallback"/>. /// </summary> public void LogOff() { var logOff = new ClientMsgProtobuf <CMsgClientLogOff>(EMsg.ClientLogOff); this.Client.Send(logOff); }
void HandleServerList(IPacketMsg packetMsg) { var listMsg = new ClientMsgProtobuf <CMsgClientServerList>(packetMsg); PostCallback(new ServerListCallback(listMsg.Body)); }