forked from paralin/go-dota2
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement cache, chat, lobby, party (incomplete)
- Loading branch information
Showing
20 changed files
with
6,302 additions
and
329 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package dota2 | ||
|
||
import ( | ||
"github.com/Philipp15b/go-steam/protocol/gamecoordinator" | ||
gcsdkm "github.com/paralin/go-dota2/protocol/gcsdk_gcmessages" | ||
gcsm "github.com/paralin/go-dota2/protocol/gcsystemmsgs" | ||
) | ||
|
||
// RequestCacheSubscriptionRefresh requests a subscription refresh for a specific cache ID. | ||
func (d *Dota2) RequestCacheSubscriptionRefresh(ownerSoid *gcsdkm.CMsgSOIDOwner) { | ||
d.write(uint32(gcsm.ESOMsg_k_ESOMsg_CacheSubscriptionRefresh), &gcsdkm.CMsgSOCacheSubscriptionRefresh{ | ||
OwnerSoid: ownerSoid, | ||
}) | ||
} | ||
|
||
// handleCacheSubscribed handles a CacheSubscribed packet. | ||
func (d *Dota2) handleCacheSubscribed(packet *gamecoordinator.GCPacket) error { | ||
sub := &gcsdkm.CMsgSOCacheSubscribed{} | ||
if err := d.unmarshalBody(packet, sub); err != nil { | ||
return err | ||
} | ||
|
||
if err := d.cache.HandleSubscribed(sub); err != nil { | ||
d.le.WithError(err).Debug("unhandled cache issue (ignore)") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// handleCacheUnsubscribed handles a CacheUnsubscribed packet. | ||
func (d *Dota2) handleCacheUnsubscribed(packet *gamecoordinator.GCPacket) error { | ||
sub := &gcsdkm.CMsgSOCacheUnsubscribed{} | ||
if err := d.unmarshalBody(packet, sub); err != nil { | ||
return err | ||
} | ||
|
||
if err := d.cache.HandleUnsubscribed(sub); err != nil { | ||
d.le.WithError(err).Debug("unhandled cache issue (ignore)") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// handleCacheUpdateMultiple handles when one or more object(s) in a cache is/are updated. | ||
func (d *Dota2) handleCacheUpdateMultiple(packet *gamecoordinator.GCPacket) error { | ||
sub := &gcsdkm.CMsgSOMultipleObjects{} | ||
if err := d.unmarshalBody(packet, sub); err != nil { | ||
return err | ||
} | ||
|
||
if err := d.cache.HandleUpdateMultiple(sub); err != nil { | ||
d.le.WithError(err).Debug("unhandled cache issue (ignore)") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// handleCacheDestroy handles when an object in a cache is destroyed. | ||
func (d *Dota2) handleCacheDestroy(packet *gamecoordinator.GCPacket) error { | ||
sub := &gcsdkm.CMsgSOSingleObject{} | ||
if err := d.unmarshalBody(packet, sub); err != nil { | ||
return err | ||
} | ||
|
||
if err := d.cache.HandleDestroy(sub); err != nil { | ||
d.le.WithError(err).Debug("unhandled cache issue (ignore)") | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package dota2 | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/Philipp15b/go-steam/protocol/gamecoordinator" | ||
"github.com/paralin/go-dota2/events" | ||
gcmcc "github.com/paralin/go-dota2/protocol/dota_gcmessages_client_chat" | ||
gcm "github.com/paralin/go-dota2/protocol/dota_gcmessages_msgid" | ||
"github.com/paralin/go-dota2/protocol/dota_shared_enums" | ||
) | ||
|
||
// SendChannelMessage attempts to send a message in a channel. | ||
func (d *Dota2) SendChannelMessage(channelID uint64, message string) { | ||
d.write(uint32(gcm.EDOTAGCMsg_k_EMsgGCChatMessage), &gcmcc.CMsgDOTAChatMessage{ | ||
ChannelId: &channelID, | ||
Text: &message, | ||
}) | ||
|
||
} | ||
|
||
// SendChannelMessageEx attempts to send a message in a channel with explicit details. | ||
// At minimum ChannelId and Text must be set. | ||
func (d *Dota2) SendChannelMessageEx(channelID uint64, msg *gcmcc.CMsgDOTAChatMessage) { | ||
d.write(uint32(gcm.EDOTAGCMsg_k_EMsgGCChatMessage), msg) | ||
} | ||
|
||
// JoinChatChannel attempts to join a chat channel by name and type. | ||
func (d *Dota2) JoinChatChannel(ctx context.Context, name string, channelType dota_shared_enums.DOTAChatChannelTypeT) (*gcmcc.CMsgDOTAJoinChatChannelResponse, error) { | ||
d.write(uint32(gcm.EDOTAGCMsg_k_EMsgGCJoinChatChannel), &gcmcc.CMsgDOTAJoinChatChannel{ | ||
ChannelName: &name, | ||
ChannelType: &channelType, | ||
}) | ||
|
||
defer d.joinChatChannelHandlers.Delete(name) | ||
ch := make(chan *gcmcc.CMsgDOTAJoinChatChannelResponse, 1) | ||
d.joinChatChannelHandlers.Store(name, ch) | ||
select { | ||
case <-ctx.Done(): | ||
return nil, ctx.Err() | ||
case v := <-ch: | ||
return v, nil | ||
} | ||
} | ||
|
||
// handleJoinChatChannelResponse handles the response to the join chat channel request | ||
func (d *Dota2) handleJoinChatChannelResponse(packet *gamecoordinator.GCPacket) error { | ||
resp := &gcmcc.CMsgDOTAJoinChatChannelResponse{} | ||
if err := d.unmarshalBody(packet, resp); err != nil { | ||
return err | ||
} | ||
|
||
chanName := resp.GetChannelName() | ||
reqCh, ok := d.joinChatChannelHandlers.Load(chanName) | ||
if ok { | ||
reqCh.(chan *gcmcc.CMsgDOTAJoinChatChannelResponse) <- resp | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// handleChatMessage handles an incoming chat message. | ||
func (d *Dota2) handleChatMessage(packet *gamecoordinator.GCPacket) error { | ||
eve := &events.ChatMessage{} | ||
resp := &eve.CMsgDOTAChatMessage | ||
if err := d.unmarshalBody(packet, resp); err != nil { | ||
return err | ||
} | ||
|
||
d.emit(eve) | ||
return nil | ||
} | ||
|
||
// handleLeftChannel handles a channel leave event. | ||
func (d *Dota2) handleLeftChannel(packet *gamecoordinator.GCPacket) error { | ||
eve := &events.LeftChatChannel{} | ||
resp := &eve.CMsgDOTAOtherLeftChatChannel | ||
if err := d.unmarshalBody(packet, resp); err != nil { | ||
return err | ||
} | ||
|
||
d.emit(eve) | ||
return nil | ||
} | ||
|
||
// handleJoinedChannel handles a channel join event. | ||
func (d *Dota2) handleJoinedChannel(packet *gamecoordinator.GCPacket) error { | ||
eve := &events.JoinedChatChannel{} | ||
resp := &eve.CMsgDOTAOtherJoinedChatChannel | ||
if err := d.unmarshalBody(packet, resp); err != nil { | ||
return err | ||
} | ||
|
||
d.emit(eve) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package dota2 | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/paralin/go-dota2/cso" | ||
gccm "github.com/paralin/go-dota2/protocol/dota_gcmessages_client" | ||
gcccm "github.com/paralin/go-dota2/protocol/dota_gcmessages_client_match_management" | ||
gcmm "github.com/paralin/go-dota2/protocol/dota_gcmessages_common_match_management" | ||
gcm "github.com/paralin/go-dota2/protocol/dota_gcmessages_msgid" | ||
) | ||
|
||
// JoinLobby attempts to join a lobby by ID. | ||
func (d *Dota2) JoinLobby(lobbyID uint64, passKey string) { | ||
d.write(uint32(gcm.EDOTAGCMsg_k_EMsgGCPracticeLobbyJoin), &gcccm.CMsgPracticeLobbyJoin{ | ||
LobbyId: &lobbyID, | ||
PassKey: &passKey, | ||
}) | ||
} | ||
|
||
// CreateLobby attempts to create a lobby with details. | ||
func (d *Dota2) CreateLobby(details *gcccm.CMsgPracticeLobbySetDetails) { | ||
// TODO: investigate SearchKey | ||
d.write(uint32(gcm.EDOTAGCMsg_k_EMsgGCPracticeLobbyCreate), &gcccm.CMsgPracticeLobbyCreate{ | ||
PassKey: details.PassKey, | ||
LobbyDetails: details, | ||
}) | ||
} | ||
|
||
// LeaveCreateLobby attempts to leave any current lobby and creates a new one. | ||
func (d *Dota2) LeaveCreateLobby(ctx context.Context, details *gcccm.CMsgPracticeLobbySetDetails) error { | ||
cacheCtr, err := d.cache.GetContainerForTypeID(uint32(cso.Lobby)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
eventCh, eventCancel, err := cacheCtr.Subscribe() | ||
if err != nil { | ||
return err | ||
} | ||
defer eventCancel() | ||
|
||
var wasInNoLobby bool | ||
for { | ||
lobbyObj := cacheCtr.GetOne() | ||
if lobbyObj != nil { | ||
lob := lobbyObj.(*gcmm.CSODOTALobby) | ||
le := d.le.WithField("lobby-id", lob.GetLobbyId()) | ||
if wasInNoLobby { | ||
le.Debug("successfully created lobby") | ||
return nil | ||
} | ||
|
||
le.Debug("attempting to leave lobby") | ||
d.LeaveLobby() | ||
} else { | ||
wasInNoLobby = true | ||
d.le.Debug("creating lobby") | ||
d.CreateLobby(details) | ||
} | ||
|
||
select { | ||
case <-ctx.Done(): | ||
return ctx.Err() | ||
case event := <-eventCh: | ||
_ = event | ||
} | ||
} | ||
} | ||
|
||
// LeaveLobby attempts to leave the current lobby. | ||
func (d *Dota2) LeaveLobby() { | ||
d.write(uint32(gcm.EDOTAGCMsg_k_EMsgGCPracticeLobbyLeave), &gcccm.CMsgPracticeLobbyLeave{}) | ||
} | ||
|
||
// DestroyLobby attempts to destroy the lobby. | ||
func (d *Dota2) DestroyLobby() { | ||
d.write(uint32(gcm.EDOTAGCMsg_k_EMsgDestroyLobbyRequest), &gccm.CMsgDOTADestroyLobbyRequest{}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package dota2 | ||
|
||
import ( | ||
bgcm "github.com/paralin/go-dota2/protocol/base_gcmessages" | ||
) | ||
|
||
// LeaveParty attempts to leave the current party. | ||
func (d *Dota2) LeaveParty() { | ||
d.write(uint32(bgcm.EGCBaseMsg_k_EMsgGCLeaveParty), &bgcm.CMsgLeaveParty{}) | ||
} |
Oops, something went wrong.