summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/Philipp15b/go-steam/social.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/Philipp15b/go-steam/social.go')
-rw-r--r--vendor/github.com/Philipp15b/go-steam/social.go624
1 files changed, 624 insertions, 0 deletions
diff --git a/vendor/github.com/Philipp15b/go-steam/social.go b/vendor/github.com/Philipp15b/go-steam/social.go
new file mode 100644
index 00000000..c61899cf
--- /dev/null
+++ b/vendor/github.com/Philipp15b/go-steam/social.go
@@ -0,0 +1,624 @@
+package steam
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/hex"
+ . "github.com/Philipp15b/go-steam/protocol"
+ . "github.com/Philipp15b/go-steam/protocol/protobuf"
+ . "github.com/Philipp15b/go-steam/protocol/steamlang"
+ . "github.com/Philipp15b/go-steam/rwu"
+ "github.com/Philipp15b/go-steam/socialcache"
+ . "github.com/Philipp15b/go-steam/steamid"
+ "github.com/golang/protobuf/proto"
+ "io"
+ "sync"
+ "time"
+)
+
+// Provides access to social aspects of Steam.
+type Social struct {
+ mutex sync.RWMutex
+
+ name string
+ avatar string
+ personaState EPersonaState
+
+ Friends *socialcache.FriendsList
+ Groups *socialcache.GroupsList
+ Chats *socialcache.ChatsList
+
+ client *Client
+}
+
+func newSocial(client *Client) *Social {
+ return &Social{
+ Friends: socialcache.NewFriendsList(),
+ Groups: socialcache.NewGroupsList(),
+ Chats: socialcache.NewChatsList(),
+ client: client,
+ }
+}
+
+// Gets the local user's avatar
+func (s *Social) GetAvatar() string {
+ s.mutex.RLock()
+ defer s.mutex.RUnlock()
+ return s.avatar
+}
+
+// Gets the local user's persona name
+func (s *Social) GetPersonaName() string {
+ s.mutex.RLock()
+ defer s.mutex.RUnlock()
+ return s.name
+}
+
+// Sets the local user's persona name and broadcasts it over the network
+func (s *Social) SetPersonaName(name string) {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ s.name = name
+ s.client.Write(NewClientMsgProtobuf(EMsg_ClientChangeStatus, &CMsgClientChangeStatus{
+ PersonaState: proto.Uint32(uint32(s.personaState)),
+ PlayerName: proto.String(name),
+ }))
+}
+
+// Gets the local user's persona state
+func (s *Social) GetPersonaState() EPersonaState {
+ s.mutex.RLock()
+ defer s.mutex.RUnlock()
+ return s.personaState
+}
+
+// Sets the local user's persona state and broadcasts it over the network
+func (s *Social) SetPersonaState(state EPersonaState) {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ s.personaState = state
+ s.client.Write(NewClientMsgProtobuf(EMsg_ClientChangeStatus, &CMsgClientChangeStatus{
+ PersonaState: proto.Uint32(uint32(state)),
+ }))
+}
+
+// Sends a chat message to ether a room or friend
+func (s *Social) SendMessage(to SteamId, entryType EChatEntryType, message string) {
+ //Friend
+ if to.GetAccountType() == int32(EAccountType_Individual) || to.GetAccountType() == int32(EAccountType_ConsoleUser) {
+ s.client.Write(NewClientMsgProtobuf(EMsg_ClientFriendMsg, &CMsgClientFriendMsg{
+ Steamid: proto.Uint64(to.ToUint64()),
+ ChatEntryType: proto.Int32(int32(entryType)),
+ Message: []byte(message),
+ }))
+ //Chat room
+ } else if to.GetAccountType() == int32(EAccountType_Clan) || to.GetAccountType() == int32(EAccountType_Chat) {
+ chatId := to.ClanToChat()
+ s.client.Write(NewClientMsg(&MsgClientChatMsg{
+ ChatMsgType: entryType,
+ SteamIdChatRoom: chatId,
+ SteamIdChatter: s.client.SteamId(),
+ }, []byte(message)))
+ }
+}
+
+// Adds a friend to your friends list or accepts a friend. You'll receive a FriendStateEvent
+// for every new/changed friend
+func (s *Social) AddFriend(id SteamId) {
+ s.client.Write(NewClientMsgProtobuf(EMsg_ClientAddFriend, &CMsgClientAddFriend{
+ SteamidToAdd: proto.Uint64(id.ToUint64()),
+ }))
+}
+
+// Removes a friend from your friends list
+func (s *Social) RemoveFriend(id SteamId) {
+ s.client.Write(NewClientMsgProtobuf(EMsg_ClientRemoveFriend, &CMsgClientRemoveFriend{
+ Friendid: proto.Uint64(id.ToUint64()),
+ }))
+}
+
+// Ignores or unignores a friend on Steam
+func (s *Social) IgnoreFriend(id SteamId, setIgnore bool) {
+ ignore := uint8(1) //True
+ if !setIgnore {
+ ignore = uint8(0) //False
+ }
+ s.client.Write(NewClientMsg(&MsgClientSetIgnoreFriend{
+ MySteamId: s.client.SteamId(),
+ SteamIdFriend: id,
+ Ignore: ignore,
+ }, make([]byte, 0)))
+}
+
+// Requests persona state for a list of specified SteamIds
+func (s *Social) RequestFriendListInfo(ids []SteamId, requestedInfo EClientPersonaStateFlag) {
+ var friends []uint64
+ for _, id := range ids {
+ friends = append(friends, id.ToUint64())
+ }
+ s.client.Write(NewClientMsgProtobuf(EMsg_ClientRequestFriendData, &CMsgClientRequestFriendData{
+ PersonaStateRequested: proto.Uint32(uint32(requestedInfo)),
+ Friends: friends,
+ }))
+}
+
+// Requests persona state for a specified SteamId
+func (s *Social) RequestFriendInfo(id SteamId, requestedInfo EClientPersonaStateFlag) {
+ s.RequestFriendListInfo([]SteamId{id}, requestedInfo)
+}
+
+// Requests profile information for a specified SteamId
+func (s *Social) RequestProfileInfo(id SteamId) {
+ s.client.Write(NewClientMsgProtobuf(EMsg_ClientFriendProfileInfo, &CMsgClientFriendProfileInfo{
+ SteamidFriend: proto.Uint64(id.ToUint64()),
+ }))
+}
+
+// Requests all offline messages and marks them as read
+func (s *Social) RequestOfflineMessages() {
+ s.client.Write(NewClientMsgProtobuf(EMsg_ClientFSGetFriendMessageHistoryForOfflineMessages, &CMsgClientFSGetFriendMessageHistoryForOfflineMessages{}))
+}
+
+// Attempts to join a chat room
+func (s *Social) JoinChat(id SteamId) {
+ chatId := id.ClanToChat()
+ s.client.Write(NewClientMsg(&MsgClientJoinChat{
+ SteamIdChat: chatId,
+ }, make([]byte, 0)))
+}
+
+// Attempts to leave a chat room
+func (s *Social) LeaveChat(id SteamId) {
+ chatId := id.ClanToChat()
+ payload := new(bytes.Buffer)
+ binary.Write(payload, binary.LittleEndian, s.client.SteamId().ToUint64()) // ChatterActedOn
+ binary.Write(payload, binary.LittleEndian, uint32(EChatMemberStateChange_Left)) // StateChange
+ binary.Write(payload, binary.LittleEndian, s.client.SteamId().ToUint64()) // ChatterActedBy
+ s.client.Write(NewClientMsg(&MsgClientChatMemberInfo{
+ SteamIdChat: chatId,
+ Type: EChatInfoType_StateChange,
+ }, payload.Bytes()))
+}
+
+// Kicks the specified chat member from the given chat room
+func (s *Social) KickChatMember(room SteamId, user SteamId) {
+ chatId := room.ClanToChat()
+ s.client.Write(NewClientMsg(&MsgClientChatAction{
+ SteamIdChat: chatId,
+ SteamIdUserToActOn: user,
+ ChatAction: EChatAction_Kick,
+ }, make([]byte, 0)))
+}
+
+// Bans the specified chat member from the given chat room
+func (s *Social) BanChatMember(room SteamId, user SteamId) {
+ chatId := room.ClanToChat()
+ s.client.Write(NewClientMsg(&MsgClientChatAction{
+ SteamIdChat: chatId,
+ SteamIdUserToActOn: user,
+ ChatAction: EChatAction_Ban,
+ }, make([]byte, 0)))
+}
+
+// Unbans the specified chat member from the given chat room
+func (s *Social) UnbanChatMember(room SteamId, user SteamId) {
+ chatId := room.ClanToChat()
+ s.client.Write(NewClientMsg(&MsgClientChatAction{
+ SteamIdChat: chatId,
+ SteamIdUserToActOn: user,
+ ChatAction: EChatAction_UnBan,
+ }, make([]byte, 0)))
+}
+
+func (s *Social) HandlePacket(packet *Packet) {
+ switch packet.EMsg {
+ case EMsg_ClientPersonaState:
+ s.handlePersonaState(packet)
+ case EMsg_ClientClanState:
+ s.handleClanState(packet)
+ case EMsg_ClientFriendsList:
+ s.handleFriendsList(packet)
+ case EMsg_ClientFriendMsgIncoming:
+ s.handleFriendMsg(packet)
+ case EMsg_ClientAccountInfo:
+ s.handleAccountInfo(packet)
+ case EMsg_ClientAddFriendResponse:
+ s.handleFriendResponse(packet)
+ case EMsg_ClientChatEnter:
+ s.handleChatEnter(packet)
+ case EMsg_ClientChatMsg:
+ s.handleChatMsg(packet)
+ case EMsg_ClientChatMemberInfo:
+ s.handleChatMemberInfo(packet)
+ case EMsg_ClientChatActionResult:
+ s.handleChatActionResult(packet)
+ case EMsg_ClientChatInvite:
+ s.handleChatInvite(packet)
+ case EMsg_ClientSetIgnoreFriendResponse:
+ s.handleIgnoreFriendResponse(packet)
+ case EMsg_ClientFriendProfileInfoResponse:
+ s.handleProfileInfoResponse(packet)
+ case EMsg_ClientFSGetFriendMessageHistoryResponse:
+ s.handleFriendMessageHistoryResponse(packet)
+ }
+}
+
+func (s *Social) handleAccountInfo(packet *Packet) {
+ //Just fire the personainfo, Auth handles the callback
+ flags := EClientPersonaStateFlag_PlayerName | EClientPersonaStateFlag_Presence | EClientPersonaStateFlag_SourceID
+ s.RequestFriendInfo(s.client.SteamId(), EClientPersonaStateFlag(flags))
+}
+
+func (s *Social) handleFriendsList(packet *Packet) {
+ list := new(CMsgClientFriendsList)
+ packet.ReadProtoMsg(list)
+ var friends []SteamId
+ for _, friend := range list.GetFriends() {
+ steamId := SteamId(friend.GetUlfriendid())
+ isClan := steamId.GetAccountType() == int32(EAccountType_Clan)
+
+ if isClan {
+ rel := EClanRelationship(friend.GetEfriendrelationship())
+ if rel == EClanRelationship_None {
+ s.Groups.Remove(steamId)
+ } else {
+ s.Groups.Add(socialcache.Group{
+ SteamId: steamId,
+ Relationship: rel,
+ })
+
+ }
+ if list.GetBincremental() {
+ s.client.Emit(&GroupStateEvent{steamId, rel})
+ }
+ } else {
+ rel := EFriendRelationship(friend.GetEfriendrelationship())
+ if rel == EFriendRelationship_None {
+ s.Friends.Remove(steamId)
+ } else {
+ s.Friends.Add(socialcache.Friend{
+ SteamId: steamId,
+ Relationship: rel,
+ })
+
+ }
+ if list.GetBincremental() {
+ s.client.Emit(&FriendStateEvent{steamId, rel})
+ }
+ }
+ if !list.GetBincremental() {
+ friends = append(friends, steamId)
+ }
+ }
+ if !list.GetBincremental() {
+ s.RequestFriendListInfo(friends, EClientPersonaStateFlag_DefaultInfoRequest)
+ s.client.Emit(&FriendsListEvent{})
+ }
+}
+
+func (s *Social) handlePersonaState(packet *Packet) {
+ list := new(CMsgClientPersonaState)
+ packet.ReadProtoMsg(list)
+ flags := EClientPersonaStateFlag(list.GetStatusFlags())
+ for _, friend := range list.GetFriends() {
+ id := SteamId(friend.GetFriendid())
+ if id == s.client.SteamId() { //this is our client id
+ s.mutex.Lock()
+ if friend.GetPlayerName() != "" {
+ s.name = friend.GetPlayerName()
+ }
+ avatar := hex.EncodeToString(friend.GetAvatarHash())
+ if ValidAvatar(avatar) {
+ s.avatar = avatar
+ }
+ s.mutex.Unlock()
+ } else if id.GetAccountType() == int32(EAccountType_Individual) {
+ if (flags & EClientPersonaStateFlag_PlayerName) == EClientPersonaStateFlag_PlayerName {
+ if friend.GetPlayerName() != "" {
+ s.Friends.SetName(id, friend.GetPlayerName())
+ }
+ }
+ if (flags & EClientPersonaStateFlag_Presence) == EClientPersonaStateFlag_Presence {
+ avatar := hex.EncodeToString(friend.GetAvatarHash())
+ if ValidAvatar(avatar) {
+ s.Friends.SetAvatar(id, avatar)
+ }
+ s.Friends.SetPersonaState(id, EPersonaState(friend.GetPersonaState()))
+ s.Friends.SetPersonaStateFlags(id, EPersonaStateFlag(friend.GetPersonaStateFlags()))
+ }
+ if (flags & EClientPersonaStateFlag_GameDataBlob) == EClientPersonaStateFlag_GameDataBlob {
+ s.Friends.SetGameAppId(id, friend.GetGamePlayedAppId())
+ s.Friends.SetGameId(id, friend.GetGameid())
+ s.Friends.SetGameName(id, friend.GetGameName())
+ }
+ } else if id.GetAccountType() == int32(EAccountType_Clan) {
+ if (flags & EClientPersonaStateFlag_PlayerName) == EClientPersonaStateFlag_PlayerName {
+ if friend.GetPlayerName() != "" {
+ s.Groups.SetName(id, friend.GetPlayerName())
+ }
+ }
+ if (flags & EClientPersonaStateFlag_Presence) == EClientPersonaStateFlag_Presence {
+ avatar := hex.EncodeToString(friend.GetAvatarHash())
+ if ValidAvatar(avatar) {
+ s.Groups.SetAvatar(id, avatar)
+ }
+ }
+ }
+ s.client.Emit(&PersonaStateEvent{
+ StatusFlags: flags,
+ FriendId: id,
+ State: EPersonaState(friend.GetPersonaState()),
+ StateFlags: EPersonaStateFlag(friend.GetPersonaStateFlags()),
+ GameAppId: friend.GetGamePlayedAppId(),
+ GameId: friend.GetGameid(),
+ GameName: friend.GetGameName(),
+ GameServerIp: friend.GetGameServerIp(),
+ GameServerPort: friend.GetGameServerPort(),
+ QueryPort: friend.GetQueryPort(),
+ SourceSteamId: SteamId(friend.GetSteamidSource()),
+ GameDataBlob: friend.GetGameDataBlob(),
+ Name: friend.GetPlayerName(),
+ Avatar: hex.EncodeToString(friend.GetAvatarHash()),
+ LastLogOff: friend.GetLastLogoff(),
+ LastLogOn: friend.GetLastLogon(),
+ ClanRank: friend.GetClanRank(),
+ ClanTag: friend.GetClanTag(),
+ OnlineSessionInstances: friend.GetOnlineSessionInstances(),
+ PublishedSessionId: friend.GetPublishedInstanceId(),
+ PersonaSetByUser: friend.GetPersonaSetByUser(),
+ FacebookName: friend.GetFacebookName(),
+ FacebookId: friend.GetFacebookId(),
+ })
+ }
+}
+
+func (s *Social) handleClanState(packet *Packet) {
+ body := new(CMsgClientClanState)
+ packet.ReadProtoMsg(body)
+ var name string
+ var avatar string
+ if body.GetNameInfo() != nil {
+ name = body.GetNameInfo().GetClanName()
+ avatar = hex.EncodeToString(body.GetNameInfo().GetShaAvatar())
+ }
+ var totalCount, onlineCount, chattingCount, ingameCount uint32
+ if body.GetUserCounts() != nil {
+ usercounts := body.GetUserCounts()
+ totalCount = usercounts.GetMembers()
+ onlineCount = usercounts.GetOnline()
+ chattingCount = usercounts.GetChatting()
+ ingameCount = usercounts.GetInGame()
+ }
+ var events, announcements []ClanEventDetails
+ for _, event := range body.GetEvents() {
+ events = append(events, ClanEventDetails{
+ Id: event.GetGid(),
+ EventTime: event.GetEventTime(),
+ Headline: event.GetHeadline(),
+ GameId: event.GetGameId(),
+ JustPosted: event.GetJustPosted(),
+ })
+ }
+ for _, announce := range body.GetAnnouncements() {
+ announcements = append(announcements, ClanEventDetails{
+ Id: announce.GetGid(),
+ EventTime: announce.GetEventTime(),
+ Headline: announce.GetHeadline(),
+ GameId: announce.GetGameId(),
+ JustPosted: announce.GetJustPosted(),
+ })
+ }
+ flags := EClientPersonaStateFlag(body.GetMUnStatusFlags())
+ //Add stuff to group
+ clanid := SteamId(body.GetSteamidClan())
+ if (flags & EClientPersonaStateFlag_PlayerName) == EClientPersonaStateFlag_PlayerName {
+ if name != "" {
+ s.Groups.SetName(clanid, name)
+ }
+ }
+ if (flags & EClientPersonaStateFlag_Presence) == EClientPersonaStateFlag_Presence {
+ if ValidAvatar(avatar) {
+ s.Groups.SetAvatar(clanid, avatar)
+ }
+ }
+ if body.GetUserCounts() != nil {
+ s.Groups.SetMemberTotalCount(clanid, totalCount)
+ s.Groups.SetMemberOnlineCount(clanid, onlineCount)
+ s.Groups.SetMemberChattingCount(clanid, chattingCount)
+ s.Groups.SetMemberInGameCount(clanid, ingameCount)
+ }
+ s.client.Emit(&ClanStateEvent{
+ ClandId: clanid,
+ StateFlags: EClientPersonaStateFlag(body.GetMUnStatusFlags()),
+ AccountFlags: EAccountFlags(body.GetClanAccountFlags()),
+ ClanName: name,
+ Avatar: avatar,
+ MemberTotalCount: totalCount,
+ MemberOnlineCount: onlineCount,
+ MemberChattingCount: chattingCount,
+ MemberInGameCount: ingameCount,
+ Events: events,
+ Announcements: announcements,
+ })
+}
+
+func (s *Social) handleFriendResponse(packet *Packet) {
+ body := new(CMsgClientAddFriendResponse)
+ packet.ReadProtoMsg(body)
+ s.client.Emit(&FriendAddedEvent{
+ Result: EResult(body.GetEresult()),
+ SteamId: SteamId(body.GetSteamIdAdded()),
+ PersonaName: body.GetPersonaNameAdded(),
+ })
+}
+
+func (s *Social) handleFriendMsg(packet *Packet) {
+ body := new(CMsgClientFriendMsgIncoming)
+ packet.ReadProtoMsg(body)
+ message := string(bytes.Split(body.GetMessage(), []byte{0x0})[0])
+ s.client.Emit(&ChatMsgEvent{
+ ChatterId: SteamId(body.GetSteamidFrom()),
+ Message: message,
+ EntryType: EChatEntryType(body.GetChatEntryType()),
+ Timestamp: time.Unix(int64(body.GetRtime32ServerTimestamp()), 0),
+ })
+}
+
+func (s *Social) handleChatMsg(packet *Packet) {
+ body := new(MsgClientChatMsg)
+ payload := packet.ReadClientMsg(body).Payload
+ message := string(bytes.Split(payload, []byte{0x0})[0])
+ s.client.Emit(&ChatMsgEvent{
+ ChatRoomId: SteamId(body.SteamIdChatRoom),
+ ChatterId: SteamId(body.SteamIdChatter),
+ Message: message,
+ EntryType: EChatEntryType(body.ChatMsgType),
+ })
+}
+
+func (s *Social) handleChatEnter(packet *Packet) {
+ body := new(MsgClientChatEnter)
+ payload := packet.ReadClientMsg(body).Payload
+ reader := bytes.NewBuffer(payload)
+ name, _ := ReadString(reader)
+ ReadByte(reader) //0
+ count := body.NumMembers
+ chatId := SteamId(body.SteamIdChat)
+ clanId := SteamId(body.SteamIdClan)
+ s.Chats.Add(socialcache.Chat{SteamId: chatId, GroupId: clanId})
+ for i := 0; i < int(count); i++ {
+ id, chatPerm, clanPerm := readChatMember(reader)
+ ReadBytes(reader, 6) //No idea what this is
+ s.Chats.AddChatMember(chatId, socialcache.ChatMember{
+ SteamId: SteamId(id),
+ ChatPermissions: chatPerm,
+ ClanPermissions: clanPerm,
+ })
+ }
+ s.client.Emit(&ChatEnterEvent{
+ ChatRoomId: SteamId(body.SteamIdChat),
+ FriendId: SteamId(body.SteamIdFriend),
+ ChatRoomType: EChatRoomType(body.ChatRoomType),
+ OwnerId: SteamId(body.SteamIdOwner),
+ ClanId: SteamId(body.SteamIdClan),
+ ChatFlags: byte(body.ChatFlags),
+ EnterResponse: EChatRoomEnterResponse(body.EnterResponse),
+ Name: name,
+ })
+}
+
+func (s *Social) handleChatMemberInfo(packet *Packet) {
+ body := new(MsgClientChatMemberInfo)
+ payload := packet.ReadClientMsg(body).Payload
+ reader := bytes.NewBuffer(payload)
+ chatId := SteamId(body.SteamIdChat)
+ if body.Type == EChatInfoType_StateChange {
+ actedOn, _ := ReadUint64(reader)
+ state, _ := ReadInt32(reader)
+ actedBy, _ := ReadUint64(reader)
+ ReadByte(reader) //0
+ stateChange := EChatMemberStateChange(state)
+ if stateChange == EChatMemberStateChange_Entered {
+ _, chatPerm, clanPerm := readChatMember(reader)
+ s.Chats.AddChatMember(chatId, socialcache.ChatMember{
+ SteamId: SteamId(actedOn),
+ ChatPermissions: chatPerm,
+ ClanPermissions: clanPerm,
+ })
+ } else if stateChange == EChatMemberStateChange_Banned || stateChange == EChatMemberStateChange_Kicked ||
+ stateChange == EChatMemberStateChange_Disconnected || stateChange == EChatMemberStateChange_Left {
+ s.Chats.RemoveChatMember(chatId, SteamId(actedOn))
+ }
+ stateInfo := StateChangeDetails{
+ ChatterActedOn: SteamId(actedOn),
+ StateChange: EChatMemberStateChange(stateChange),
+ ChatterActedBy: SteamId(actedBy),
+ }
+ s.client.Emit(&ChatMemberInfoEvent{
+ ChatRoomId: SteamId(body.SteamIdChat),
+ Type: EChatInfoType(body.Type),
+ StateChangeInfo: stateInfo,
+ })
+ }
+}
+
+func readChatMember(r io.Reader) (SteamId, EChatPermission, EClanPermission) {
+ ReadString(r) // MessageObject
+ ReadByte(r) // 7
+ ReadString(r) //steamid
+ id, _ := ReadUint64(r)
+ ReadByte(r) // 2
+ ReadString(r) //Permissions
+ chat, _ := ReadInt32(r)
+ ReadByte(r) // 2
+ ReadString(r) //Details
+ clan, _ := ReadInt32(r)
+ return SteamId(id), EChatPermission(chat), EClanPermission(clan)
+}
+
+func (s *Social) handleChatActionResult(packet *Packet) {
+ body := new(MsgClientChatActionResult)
+ packet.ReadClientMsg(body)
+ s.client.Emit(&ChatActionResultEvent{
+ ChatRoomId: SteamId(body.SteamIdChat),
+ ChatterId: SteamId(body.SteamIdUserActedOn),
+ Action: EChatAction(body.ChatAction),
+ Result: EChatActionResult(body.ActionResult),
+ })
+}
+
+func (s *Social) handleChatInvite(packet *Packet) {
+ body := new(CMsgClientChatInvite)
+ packet.ReadProtoMsg(body)
+ s.client.Emit(&ChatInviteEvent{
+ InvitedId: SteamId(body.GetSteamIdInvited()),
+ ChatRoomId: SteamId(body.GetSteamIdChat()),
+ PatronId: SteamId(body.GetSteamIdPatron()),
+ ChatRoomType: EChatRoomType(body.GetChatroomType()),
+ FriendChatId: SteamId(body.GetSteamIdFriendChat()),
+ ChatRoomName: body.GetChatName(),
+ GameId: body.GetGameId(),
+ })
+}
+
+func (s *Social) handleIgnoreFriendResponse(packet *Packet) {
+ body := new(MsgClientSetIgnoreFriendResponse)
+ packet.ReadClientMsg(body)
+ s.client.Emit(&IgnoreFriendEvent{
+ Result: EResult(body.Result),
+ })
+}
+
+func (s *Social) handleProfileInfoResponse(packet *Packet) {
+ body := new(CMsgClientFriendProfileInfoResponse)
+ packet.ReadProtoMsg(body)
+ s.client.Emit(&ProfileInfoEvent{
+ Result: EResult(body.GetEresult()),
+ SteamId: SteamId(body.GetSteamidFriend()),
+ TimeCreated: body.GetTimeCreated(),
+ RealName: body.GetRealName(),
+ CityName: body.GetCityName(),
+ StateName: body.GetStateName(),
+ CountryName: body.GetCountryName(),
+ Headline: body.GetHeadline(),
+ Summary: body.GetSummary(),
+ })
+}
+
+func (s *Social) handleFriendMessageHistoryResponse(packet *Packet) {
+ body := new(CMsgClientFSGetFriendMessageHistoryResponse)
+ packet.ReadProtoMsg(body)
+ steamid := SteamId(body.GetSteamid())
+ for _, message := range body.GetMessages() {
+ if !message.GetUnread() {
+ continue // Skip already read messages
+ }
+ s.client.Emit(&ChatMsgEvent{
+ ChatterId: steamid,
+ Message: message.GetMessage(),
+ EntryType: EChatEntryType_ChatMsg,
+ Timestamp: time.Unix(int64(message.GetTimestamp()), 0),
+ Offline: true, // GetUnread is true
+ })
+ }
+}