forked from lug/matterbridge
		
	
		
			
				
	
	
		
			625 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			625 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
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
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 |