mirror of
https://github.com/42wim/matterbridge.git
synced 2024-12-10 19:22:00 -08:00
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
|
||
|
})
|
||
|
}
|
||
|
}
|