deadlock

package module
v0.0.0-...-02f5705 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 12 Imported by: 0

README

Deadlock

Go Reference DeepWiki

Introduction

go-deadlock is a Deadlock client plugin for go-steam.

Games implemented:

Usage

cl := steam.NewClient(...)
dl := deadlock.New(cl, logrus.StandardLogger())

Implementation Progress

  • GC session state management
  • Request tracking (MakeRequest with response matching)
  • SOCache tracking / state management
  • Code generation for API
  • Code generation for events
  • Basic party operations
    • Read party state correctly
    • Implement normal party operations
  • Lobby tracking / state management

SOCache Mechanism

The caching mechanism makes it easy to watch for changes to common objects.

This mechanism is used everywhere, these objects are not exposed in their own events.

import (
	gcmm "github.com/paralin/go-deadlock/protocol"
	"github.com/paralin/go-deadlock/cso"
)

eventCh, eventCancel, err := dl.GetCache().SubscribeType(cso.EconItem)
if err != nil {
    return err
}

defer eventCancel()

itemEvent := <-eventCh
item := itemEvent.Object.(*gcmm.CSOEconItem)

Events for the object type are emitted on the eventCh. Be sure to call eventCancel once you are done with the channel to prevent resource leaks.

The cache object also adds interfaces to get and list the current objects in the cache.

Implementation Generation

This project makes use of a dynamic API generator (apigen) designed to automatically interpret Valve's various naming conventions into a intermediate API scheme representation, which is then converted into Go code.

The base API implementation is generated by the apigen code. Using heuristics, request IDs are matched to response IDs, and events and action-only requests are identified. Some manual tweaking is done in the overrides file.

Next, the API information is used to build a Go code-gen set of implementations around the MakeRequest request tracking mechanism.

This means that ALL of the Deadlock GC API will be available in this codebase, although only some of it is documented.

go-steam Dependency

This library depends on go-steam.

Documentation

Index

Constants

View Source
const AppID = 1422450

AppID is the ID for deadlock

Variables

View Source
var ErrNotReady = errors.New("the deadlock client is not ready to accept requests yet, or has just become unready")

ErrNotReady is returned when the deadlock client is not ready to accept requests yet, or has just become unready

Functions

This section is empty.

Types

type Deadlock

type Deadlock struct {
	// contains filtered or unexported fields
}

Deadlock handles the deadlock game handler.

func New

func New(client *steam.Client, le logrus.FieldLogger) *Deadlock

New builds a new Deadlock handler.

func (*Deadlock) CancelChallenge

func (d *Deadlock) CancelChallenge(
	ctx context.Context,
	challengeID uint64,
) (*protocol.CMsgClientToGCChallengeCancelResponse, error)

CancelChallenge cancels one of your active challenges.

The provided challenge must belong to your account. The response reports the result of the cancellation.

func (*Deadlock) ClaimChallenge

func (d *Deadlock) ClaimChallenge(
	ctx context.Context,
	challengeID uint64,
) (*protocol.CMsgClientToGCChallengeClaimResponse, error)

ClaimChallenge claims the reward for a completed challenge.

Only challenges that have reached the completed state can be claimed. The response reports the result of the claim.

func (*Deadlock) Close

func (d *Deadlock) Close()

Close kills any ongoing calls.

func (*Deadlock) CreateParty

CreateParty creates a new party with the given matchmaking options.

The party join code is returned in the response, unless party codes are disabled. The created party is also delivered through the SOCache as a CSOCitadelParty object.

func (*Deadlock) FindHeroBuilds

func (d *Deadlock) FindHeroBuilds(
	ctx context.Context,
	authorAccountID uint32,
	heroID uint32,
	language []int32,
	searchText string,
	heroBuildID uint32,
	tags []uint32,
) (*protocol.CMsgClientToGCFindHeroBuildsResponse, error)

FindHeroBuilds searches published hero builds.

At most one filter is meaningful per call: builds by author_account_id, for hero_id, or matching search_text. The response lists the matching builds with their metadata.

func (*Deadlock) GetAccountLeaderboards

func (d *Deadlock) GetAccountLeaderboards(
	ctx context.Context,
	accountID uint32,
) (*protocol.CMsgClientToGCGetAccountLeaderboardsResponse, error)

GetAccountLeaderboards returns the leaderboard placements of an account, one entry per ranked hero leaderboard the account appears on.

func (*Deadlock) GetAccountMatchReports

func (d *Deadlock) GetAccountMatchReports(
	ctx context.Context,
	matchID uint64,
) (*protocol.CMsgClientToGCGetAccountMatchReportsResponse, error)

GetAccountMatchReports fetches the conduct report information tied to a match. Supply the most recent known match_id to page through older entries.

func (*Deadlock) GetAccountStats

func (d *Deadlock) GetAccountStats(
	ctx context.Context,
	accountID uint32,
	devAccessHint bool,
	friendAccessHint bool,
) (*protocol.CMsgClientToGCGetAccountStatsResponse, error)

GetAccountStats returns the career statistics of an account: wins, losses, kills, deaths, and per-hero aggregates. Accounts other than your own require the owner's privacy settings to allow it.

func (*Deadlock) GetActiveMatches

GetActiveMatches returns the matches currently in progress that involve your account or party.

func (*Deadlock) GetBook

GetBook returns the full state of an account's hero book, including owned pages and unlock progress, as a CMsgAccountBook.

func (*Deadlock) GetCache

func (d *Deadlock) GetCache() *socache.SOCache

GetCache returns the SO Cache.

GetDiscordLink returns a single-use URL that links the account to the official Deadlock Discord, valid for the returned number of hours.

func (*Deadlock) GetFriendGameStatus

func (d *Deadlock) GetFriendGameStatus(
	ctx context.Context,
	includeInvited bool,
) (*protocol.CMsgClientToGCGetFriendGameStatusResponse, error)

GetFriendGameStatus returns what your Steam friends are currently doing in Deadlock: their game state, party, and lobby. Set include_invited to also see friends who have been invited to your group.

func (*Deadlock) GetHeroChoice

GetHeroChoice returns the hero you selected for the free hero rotation: the hero ID, its choice slot ID, and how many times the choice has been used.

func (*Deadlock) GetHeroMMRRankings

func (d *Deadlock) GetHeroMMRRankings(
	ctx context.Context,
	targetAccountID uint32,
) (*protocol.CMsgClientToGCGetHeroMMRRankingsResponse, error)

GetHeroMMRRankings returns the per-hero MMR of an account, relative to the ranked ladder.

func (*Deadlock) GetHideoutSDRTicket

func (d *Deadlock) GetHideoutSDRTicket(
	ctx context.Context,
	lobbyID uint64,
) (*protocol.CMsgClientToGCGetHideoutSDRTicketResponse, error)

GetHideoutSDRTicket requests a Steam Datagram Relay ticket for connecting to a hideout (sandbox lobby) server. The ticket is returned as raw bytes; an error message is set instead if the ticket cannot be issued.

func (*Deadlock) GetLeaderboard

func (d *Deadlock) GetLeaderboard(
	ctx context.Context,
	leaderboardRegion protocol.ECitadelLeaderboardRegion,
	heroID uint32,
) (*protocol.CMsgClientToGCGetLeaderboardResponse, error)

GetLeaderboard returns the calling account's placement on the leaderboard for the given region and hero: position, badge level, and display name.

func (*Deadlock) GetMatchHistory

func (d *Deadlock) GetMatchHistory(
	ctx context.Context,
	accountID uint32,
	continueCursor uint64,
	gameMode protocol.ECitadelGameMode,
	matchMode protocol.ECitadelMatchMode,
	rankedType protocol.ECitadelRankedType,
	rankInterval uint32,
) (*protocol.CMsgClientToGCGetMatchHistoryResponse, error)

GetMatchHistory returns a page of the account's match history with per-match statistics: result, duration, K/D/A, net worth, hero level, and objective masks. Pass the continue_cursor from the previous response to fetch older matches; game_mode and match_mode narrow the results.

func (*Deadlock) GetMatchMetaData

func (d *Deadlock) GetMatchMetaData(
	ctx context.Context,
	matchID uint64,
	metadataSalt uint32,
	targetAccountID uint32,
) (*protocol.CMsgClientToGCGetMatchMetaDataResponse, error)

GetMatchMetaData returns the replay metadata for a match, including the download details needed by replay tools. The metadata_salt is required for recent matches and is distributed with the match result.

func (*Deadlock) GetProfileCard

func (d *Deadlock) GetProfileCard(
	accountID uint32,
	devAccessHint bool,
	friendAccessHint bool,
)

GetProfileCard requests the profile card of an account.

The card is not returned directly; watch for a ProfileCardUpdated event after sending this request.

func (*Deadlock) GetRankData

GetRankData returns the local account's ranked state: current rank confidence, calibrated rank confidence, and whether a calibration interval is still required.

func (*Deadlock) GetSurveyQuestion

GetSurveyQuestion returns the next survey question to show the player, if one is queued. Submit answers with SubmitSurvey.

func (*Deadlock) GrantForumAccess

func (d *Deadlock) GrantForumAccess(
	ctx context.Context,
	email string,
) (*protocol.CMsgClientToGCGrantForumAccessResponse, error)

GrantForumAccess sends a forum access grant request bound to the given email address.

func (*Deadlock) HandleGCPacket

func (d *Deadlock) HandleGCPacket(packet *gamecoordinator.GCPacket)

HandleGCPacket handles an incoming game coordinator packet.

func (*Deadlock) InviteLobbyMember

func (d *Deadlock) InviteLobbyMember(playerID steamid.SteamId)

InviteLobbyMember attempts to invite a player to the current lobby.

func (*Deadlock) JoinParty

func (d *Deadlock) JoinParty(
	ctx context.Context,
	partyID uint64,
	isRejoin bool,
	partyMmInfo protocol.CMsgPartyMMInfo,
) (*protocol.CMsgClientToGCPartyJoinResponse, error)

JoinParty joins an existing party by ID.

func (*Deadlock) JoinPartyViaCode

func (d *Deadlock) JoinPartyViaCode(
	ctx context.Context,
	joinCode uint64,
	partyMmInfo protocol.CMsgPartyMMInfo,
) (*protocol.CMsgClientToGCPartyJoinViaCodeResponse, error)

JoinPartyViaCode joins a party using its numeric join code. The matchmaking info describes your client state for the party leader.

func (*Deadlock) LeaveLobby

func (d *Deadlock) LeaveLobby(
	ctx context.Context,
	lobbyID uint64,
) (*protocol.CMsgClientToGCLeaveLobbyResponse, error)

LeaveLobby leaves the current lobby, if any.

func (*Deadlock) LeaveParty

func (d *Deadlock) LeaveParty(
	ctx context.Context,
	partyID uint64,
) (*protocol.CMsgClientToGCPartyLeaveResponse, error)

LeaveParty leaves a party.

Sends the GC message k_EMsgClientToGCPartyLeave (CMsgClientToGCPartyLeave) and awaits the response k_EMsgClientToGCPartyLeaveResponse, delivered as *CMsgClientToGCPartyLeaveResponse.

func (*Deadlock) MakeRequest

func (d *Deadlock) MakeRequest(
	ctx context.Context,
	reqMsgID uint32,
	request proto.Message,
	respMsgID uint32,
	response proto.Message,
	matchesRequest ...func(proto.Message) bool,
) (mrErr error)

MakeRequest starts and tracks a request given a context.

func (*Deadlock) RecordClientEvents

RecordClientEvents reports client-side account events to the GC for telemetry. The client_event_index and client_run_token de-duplicate retries within a client run.

func (*Deadlock) ReportPlayerFromMatch

func (d *Deadlock) ReportPlayerFromMatch(
	ctx context.Context,
	matchID uint64,
	targetAccountID uint32,
	reportType protocol.CMsgClientToGCReportPlayerFromMatch_EReportType,
	reportText string,
) (*protocol.CMsgClientToGCReportPlayerFromMatchResponse, error)

ReportPlayerFromMatch files a conduct report against a player from a match you participated in. The response confirms the report was recorded.

func (*Deadlock) RequestCacheSubscriptionRefresh

func (d *Deadlock) RequestCacheSubscriptionRefresh(ownerSoid *gcsdkm.CMsgSOIDOwner)

RequestCacheSubscriptionRefresh requests a subscription refresh for a specific cache ID.

func (*Deadlock) RequestDevCheatReports

func (d *Deadlock) RequestDevCheatReports(
	ctx context.Context,
) (*protocol.CMsgClientToGCRequestCheatReportsResponse, error)

RequestDevCheatReports asks the GC for cheat-detection data about recent matches. Developer accounts only.

func (*Deadlock) RequestHeroReleaseVoteTally

func (d *Deadlock) RequestHeroReleaseVoteTally(
	voteRounds []uint32,
)

RequestHeroReleaseVoteTally returns the current tally of the community hero release vote.

func (*Deadlock) RequestModerator

func (d *Deadlock) RequestModerator(
	ctx context.Context,
	accountID uint32,
) (*protocol.CMsgClientToGCModeratorRequestResponse, error)

RequestModerator submits a moderator action request against an account.

func (*Deadlock) RespondLobbyInvite

func (d *Deadlock) RespondLobbyInvite(lobbyId uint64, accept bool)

RespondLobbyInvite responds to a lobby invite.

func (*Deadlock) RespondPartyInvite

func (d *Deadlock) RespondPartyInvite(partyId uint64, accept bool)

RespondPartyInvite attempts to respond to a party invite.

func (*Deadlock) SayHello

func (d *Deadlock) SayHello(haveCacheVersions ...*gcsdkm.CMsgSOCacheHaveVersion)

SayHello says hello to the deadlock server, in an attempt to get a session.

func (*Deadlock) SendBookUnlock

func (d *Deadlock) SendBookUnlock(
	ctx context.Context,
	bookID uint32,
	unlockID uint32,
	expectedCost uint32,
) (*protocol.CMsgClientToGCBookUnlockResponse, error)

SendBookUnlock purchases an unlock from the hero book. The expected_cost is checked server-side; the purchase fails if it does not match.

func (*Deadlock) SendChallengeActivate

func (d *Deadlock) SendChallengeActivate(
	ctx context.Context,
	challengeID uint64,
) (*protocol.CMsgClientToGCChallengeActivateResponse, error)

SendChallengeActivate activates one of your generated challenge choices so it starts tracking progress.

func (*Deadlock) SendCommendPlayerFromMatch

func (d *Deadlock) SendCommendPlayerFromMatch(
	ctx context.Context,
	matchID uint64,
	targetAccountID uint32,
	commendType protocol.ECommendType,
	fakeCommendHeroID uint32,
) (*protocol.CMsgClientToGCCommendPlayerFromMatchResponse, error)

SendCommendPlayerFromMatch sends a commend for a player from a match you played together. The GC delivers a CommendNotification event to the target.

func (*Deadlock) SendDeleteHeroBuild

func (d *Deadlock) SendDeleteHeroBuild(
	ctx context.Context,
	authorAccountID uint32,
	heroBuildID uint32,
) (*protocol.CMsgClientToGCDeleteHeroBuildResponse, error)

SendDeleteHeroBuild deletes one of your published hero builds. You must be the author of the build.

func (*Deadlock) SendDevAction

func (d *Deadlock) SendDevAction(
	ctx context.Context,
	action protocol.CMsgClientToGCDevAction_EAction,
	accountID uint32,
	uintValue uint32,
	intValue int32,
	boolValue bool,
	strValue string,
	matchID uint64,
) (*protocol.CMsgClientToGCDevActionResponse, error)

SendDevAction runs a developer-only GC action. Developer accounts only.

func (*Deadlock) SendIsInMatchmaking

func (d *Deadlock) SendIsInMatchmaking(
	ctx context.Context,
) (*protocol.CMsgClientToGCIsInMatchmakingResponse, error)

SendIsInMatchmaking checks whether the account is currently in the matchmaking queue. The response carries the queue state.

func (*Deadlock) SendModifyDevAnnouncements

func (d *Deadlock) SendModifyDevAnnouncements(
	ctx context.Context,
	operation protocol.CMsgClientToGCModifyDevAnnouncements_EOperation,
	targetID uint32,
	priority uint32,
	title string,
	message string,
	uRL string,
	patchVersion string,
) (*protocol.CMsgClientToGCModifyDevAnnouncementsResponse, error)

SendModifyDevAnnouncements creates, updates, or removes in-client announcements. Developer accounts only.

func (*Deadlock) SendPartyAction

func (d *Deadlock) SendPartyAction(
	ctx context.Context,
	partyID uint64,
	targetAccountID uint32,
	actionID protocol.CMsgClientToGCPartyAction_EAction,
	uintValue uint64,
	boolValue bool,
	strValue string,
) (*protocol.CMsgClientToGCPartyActionResponse, error)

SendPartyAction performs an action on a party member, such as kicking or promoting. See CMsgClientToGCPartyAction.EAction for the available actions; the response reports the outcome.

func (*Deadlock) SendPartyChatMsg

func (d *Deadlock) SendPartyChatMsg(
	ctx context.Context,
	partyID uint64,
	chatMsg string,
) (*protocol.CMsgClientToGCPartySendChatMsgResponse, error)

SendPartyChatMsg sends a chat line to your party members.

func (*Deadlock) SendPartyInviteUser

func (d *Deadlock) SendPartyInviteUser(
	ctx context.Context,
	partyID uint64,
	inviteAccountID uint32,
) (*protocol.CMsgClientToGCPartyInviteUserResponse, error)

SendPartyInviteUser invites an account to your party. The invitee responds through the party invite flow.

func (*Deadlock) SendReplacementSDRTicket

func (d *Deadlock) SendReplacementSDRTicket(
	ctx context.Context,
	lobbyID uint64,
) (*protocol.CMsgClientToGCReplacementSDRTicketResponse, error)

SendReplacementSDRTicket requests a replacement Steam Datagram Relay ticket for a match or lobby connection whose ticket expired or was lost.

func (*Deadlock) SendUnlockHero

func (d *Deadlock) SendUnlockHero(
	ctx context.Context,
	heroIDs []uint32,
	heroChoiceID uint32,
) (*protocol.CMsgClientToGCUnlockHeroResponse, error)

SendUnlockHero spends a hero unlock credit on the chosen hero.

func (*Deadlock) SendUpdateAccountSync

func (d *Deadlock) SendUpdateAccountSync(
	ctx context.Context,
	ids []uint32,
	values []uint32,
) (*protocol.CMsgClientToGCUpdateAccountSyncResponse, error)

SendUpdateAccountSync pushes updated CSOAccountSyncStorage values to the GC. The response confirms the sync.

func (*Deadlock) SendUpdateHeroBuild

func (d *Deadlock) SendUpdateHeroBuild(
	ctx context.Context,
	heroBuild protocol.CMsgHeroBuild,
) (*protocol.CMsgClientToGCUpdateHeroBuildResponse, error)

SendUpdateHeroBuild creates or updates one of your published hero builds.

func (*Deadlock) SendUpdateHeroBuildPreference

func (d *Deadlock) SendUpdateHeroBuildPreference(
	ctx context.Context,
	heroBuildID uint32,
	preference protocol.CMsgHeroBuildPreference,
) (*protocol.CMsgClientToGCUpdateHeroBuildPreferenceResponse, error)

SendUpdateHeroBuildPreference sets which published build you follow for a hero.

func (*Deadlock) SendUpdateRoster

SendUpdateRoster updates your hero selection roster before entering a matchmaking queue.

func (*Deadlock) SendUpdateSpectatorStatus

func (d *Deadlock) SendUpdateSpectatorStatus(
	spectatingLobbyID uint64,
	stoppedSpectating bool,
)

SendUpdateSpectatorStatus tells the GC which lobby you are spectating, or clears it with stopped_spectating.

func (*Deadlock) SetAccountPrivacySetting

SetAccountPrivacySetting changes who can view your profile card and stats.

func (*Deadlock) SetChallengeGenerate

SetChallengeGenerate generates a fresh set of challenge choices to replace your current ones.

func (*Deadlock) SetDevMMBias

func (d *Deadlock) SetDevMMBias(
	accountID uint32,
	value uint32,
)

SetDevMMBias biases matchmaking for an account toward a skill value. Developer accounts only.

func (*Deadlock) SetNewPlayerProgress

SetNewPlayerProgress marks a new-player progression milestone complete, such as finishing the tutorial or unlocking ranked play.

func (*Deadlock) SetPartyMode

func (d *Deadlock) SetPartyMode(
	ctx context.Context,
	partyID uint64,
	matchMode protocol.ECitadelMatchMode,
	gameMode protocol.ECitadelGameMode,
	botDifficulty protocol.ECitadelBotDifficulty,
	devServerCommand string,
	regionMode protocol.ECitadelRegionMode,
) (*protocol.CMsgClientToGCPartySetModeResponse, error)

SetPartyMode configures the party's matchmaking settings: match mode, game mode, bot difficulty, and region.

func (*Deadlock) SetPartyReadyState

func (d *Deadlock) SetPartyReadyState(
	ctx context.Context,
	partyID uint64,
	readyState bool,
	heroRoster protocol.CMsgHeroSelectionMatchInfo,
) (*protocol.CMsgClientToGCPartySetReadyStateResponse, error)

SetPartyReadyState marks you ready (or not ready) for the party's next match, along with the hero roster you intend to play.

func (*Deadlock) SetPlaying

func (d *Deadlock) SetPlaying(playing bool)

SetPlaying informs Steam we are playing / not playing Deadlock.

func (*Deadlock) SetServerConVar

func (d *Deadlock) SetServerConVar(
	ctx context.Context,
	convarName string,
	convarValue string,
	lobbyID uint64,
) (*protocol.CMsgClientToGCSetServerConVarResponse, error)

SetServerConVar sets a console variable on a practice lobby server. Developer accounts only.

func (*Deadlock) SpectateLobby

func (d *Deadlock) SpectateLobby(
	ctx context.Context,
	lobbyID uint64,
	clientPlatform protocol.EGCPlatform,
	matchID uint64,
) (*protocol.CMsgClientToGCSpectateLobbyResponse, error)

SpectateLobby requests to spectate a lobby. The response carries the connection details for the spectator broadcast.

func (*Deadlock) SpectateUser

func (d *Deadlock) SpectateUser(
	ctx context.Context,
	spectateAccountID uint32,
	clientPlatform protocol.EGCPlatform,
) (*protocol.CMsgClientToGCSpectateUserResponse, error)

SpectateUser requests to spectate the live game of an account. The response carries the connection details, or an error if no game is running.

func (*Deadlock) StartMatchmaking

StartMatchmaking enters the matchmaking queue with the given match info, region ping times, and hero roster. The response confirms the queue state. Watch for MatchmakingStopped events for asynchronous cancellation.

func (*Deadlock) StartPartyMatch

func (d *Deadlock) StartPartyMatch(
	ctx context.Context,
	partyID uint64,
) (*protocol.CMsgClientToGCPartyStartMatchResponse, error)

StartPartyMatch starts the search for a match on behalf of the whole party. Party leaders only.

func (*Deadlock) StartRankedInterval

func (d *Deadlock) StartRankedInterval(
	ctx context.Context,
	rankType protocol.ECitadelRankedType,
	interval uint32,
) (*protocol.CMsgClientToGCStartRankedIntervalResponse, error)

StartRankedInterval begins a ranked calibration interval. The response reports the new ranked state.

func (*Deadlock) StopMatchmaking

StopMatchmaking leaves the matchmaking queue. A MatchmakingStopped event confirms the exit.

func (*Deadlock) SubmitHeroReleaseVote

func (d *Deadlock) SubmitHeroReleaseVote(
	voteRound uint32,
	voteOption uint32,
)

SubmitHeroReleaseVote casts a vote in the community hero release vote for the given round.

func (*Deadlock) SubmitPlaytestUser

func (d *Deadlock) SubmitPlaytestUser(
	ctx context.Context,
	location string,
	targetAccountID uint32,
) (*protocol.CMsgClientToGCSubmitPlaytestUserResponse, error)

SubmitPlaytestUser registers an account for a playtest session at the given location. Developer accounts only.

func (*Deadlock) SubmitSurvey

func (d *Deadlock) SubmitSurvey(
	ctx context.Context,
	questionID uint32,
	isSkip bool,
	responseValue uint32,
	devForceNewQuestionType protocol.CMsgSurveyQuestion_EQuestionType,
) (*protocol.CMsgClientToGCSubmitSurveyResponse, error)

SubmitSurvey answers a survey question previously delivered through GetSurveyQuestion. Set is_skip to decline without answering.

Directories

Path Synopsis
cmd
generate command
Command generate updates Deadlock protobuf sources, regenerates Go protobufs, and refreshes the generated API wrappers.
Command generate updates Deadlock protobuf sources, regenerates Go protobufs, and refreshes the generated API wrappers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL