Giter Site home page Giter Site logo

philipp15b / go-steam Goto Github PK

View Code? Open in Web Editor NEW
375.0 24.0 130.0 4.28 MB

Steam's protocol in Go to allow automation of different actions on the Steam network without running an actual Steam client. Includes APIs for friends, chatting, trading, trade offers and TF2 crafting.

Home Page: https://pkg.go.dev/github.com/Philipp15b/go-steam/v3

License: Other

Go 96.43% C# 3.57%
steam steamkit

go-steam's Introduction

Steam for Go

This library implements Steam's protocol to allow automation of different actions on Steam without running an actual Steam client. It is based on SteamKit2, a .NET library.

In addition, it contains APIs to Steam Community features, like trade offers and inventories.

Some of the currently implemented features:

  • Trading and trade offers, including inventories and notifications
  • Friend and group management
  • Chatting with friends
  • Persona states (online, offline, looking to trade, etc.)
  • SteamGuard with two-factor authentication
  • Team Fortress 2: Crafting, moving, naming and deleting items

If this is useful to you, there's also the go-steamapi package that wraps some of the official Steam Web API's types.

Installation

go get github.com/Philipp15b/go-steam

Usage

You can view the documentation with the godoc tool or online on godoc.org.

You should also take a look at the following sub-packages:

Working with go-steam

Whether you want to develop your own Steam bot or directly work on go-steam itself, there are are few things to know.

  • If something is not working, check first if the same operation works (under the same conditions!) in the Steam client on that account. Maybe there's something go-steam doesn't handle correctly or you're missing a warning that's not obviously shown in go-steam. This is particularly important when working with trading since there are restrictions, for example newly authorized devices will not be able to trade for seven days.
  • Since Steam does not maintain a public API for most of the things go-steam implements, you can expect that sometimes things break randomly. Especially the trade and tradeoffer packages have been affected in the past.
  • Always gather as much information as possible. When you file an issue, be as precise and complete as you can. This makes debugging way easier.
  • If you haven't noticed yet, expect to find lots of things out yourself. Debugging can be complicated and Steam's internals are too.
  • Sometimes things break and other SteamKit ports are fixed already. Maybe take a look what people are saying over there? There's also the SteamKit IRC channel.

Updating go-steam to a new SteamKit version

Go source code is generated with code in the generator directory. Look at generator/README.md for more information on how to use the generator.

Then, after generating new Go source files, update go-steam as necessary.

License

Steam for Go is licensed under the New BSD License. More information can be found in LICENSE.txt.

go-steam's People

Contributors

anasinnyk avatar b1naryth1ef avatar benpye avatar gamingrobot avatar henrikkv avatar inkp avatar jleagle avatar johanneskaufmann avatar kazhuravlev avatar looterz avatar macb avatar nexure avatar philipp15b avatar ralfizzle avatar slacki avatar softashell avatar tommy-42 avatar toothrot avatar vincentserpoul avatar yelloworwhite avatar zhuharev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-steam's Issues

Web: Error logging on: steam.Web.apiLogOn: request failed with status 403 Forbidden

Actually I didn't can to use function steam.Web.LogOn().

My code:
....
sentryData, _ = ioutil.ReadFile("sentryfile")

loginInfo := new(steam.LogOnDetails)
loginInfo.Username = os.Args[1]
loginInfo.Password = os.Args[2]
...
if (string(sentryData) == "") {
loginInfo.AuthCode = os.Args[4]
} else {
loginInfo.SentryFileHash = sentryData
}

client := steam.NewClient()
client.Connect()
.....
case *steam.WebSessionIdEvent:
client.Web.LogOn()
.....

Trading session times out

Hi, I'm working on a trading bot for accepting bets. I had no problem with getting the bot to add my account as a friend, but trading is getting frustrating.

I'm having the bot (which is running on a server) initiate a trade session with my steam account. After I accept the invite that is sent to my personal account, the trade box opens up, but it stalls for a few seconds while displaying "Waiting for BotAccountName" by the bot's inventory, then times out, and I'm sent to the "The trading session has expired." screen.

On the bot's end, TradeResultEvent is caught and handled, then TradeSessionStartEvent is caught and handled (kicking off the trade). The bot polls the event list but never finds anything (even if I send a chat message from my personal account).

All relevant cookies seem to be valid, and the bot calls Web.LogOn() (and waits for a WebSessionIdEvent) beforehand. Btw, I had to update trade.New() to include the SteamLoginSecure cookie as a parameter and to pass it into tradeapi.New(). Want a pull request for that?

Here's the code, please forgive the excessive logging:

func handleTrade(id steamid.SteamId) {
    gramboLogFile.WriteString("Handling trade\n")

    t := trade.New(client.Web.SessionId, client.Web.SteamLogin, client.Web.SteamLoginSecure, id)
    // t.Chat("Take a look at these fine goods")
    err := t.SetReady(true)
    if err != nil {
        panic("Error with trade.SetReady()")
    }

    for {
        eventList, err := t.Poll()
        if err != nil {
            gramboLogFile.WriteString("Error retreiving event list!\n")
            continue
        }

        gramboLogFile.WriteString("Retrieved event list!\n")

        for _, event := range eventList {
            switch e := event.(type) {
            case *trade.ChatEvent:
                // parrot back any chat message
                t.Chat(e.Message)
            case *trade.TradeEndedEvent:
                gramboLogFile.WriteString("Trade ended\n")
                return
            default:
                gramboLogFile.WriteString("Unhandled event type\n")
            }
        }
    }
}

After "Handling trade" prints, "Retrieved event list!" loops forever, even after the trade has timed out from the perspective of my personal account. No other events are caught, nothing panics, nothing prints to stdout. Any idea what is going on? Is there any way to debug this further?

Two other observations:

  1. After pulling your recent commits, I couldn't connect to the Steam CM servers (via Client.Connect()) despite many, many retries. I switched to Client.ConnectNorthAmerica() and replaced the NA server IPs with those found here: https://github.com/SteamRE/SteamKit/blob/master/SteamKit2/SteamKit2/Networking/Steam3/CMServerList.cs#L200-L233. Still lots of failures but I eventually get through.

  2. Sending a trade invite fails if the sender hasn't set himself to appear offline via SetPersonaState(steamlang.EPersonaState_Online). I had commented that line out due to the (now-fixed) internal package issues, which is why I noticed the problem.

Anyway, thanks for all your work on this library, go is a fun language. I was happy to see the updates last week, and if I come across anything I'll submit a pull request. Sorry for the long post.

Can the internal package be renamed?

Can't use Gamecoordinator or Steamlang package because of the semantic meaning internal now has in Go. Any information would be fantastic or proposed work arounds. Thanks.

steam.Web.apiLogOn - 403 Forbidden

When I use function client.Web.LogOn() I get 403 error.

If this problem occurs only for me, could you give an example of code using this function?

Type mismatch causing go-steam not to build.

Hi there,

Excuse me if I'm blatantly incorrect - this endeavour was my first time writing any Go.

I've got a source file which is simply a Hello World, but loads in go-steam as my first ask after Hello World is going to be logging into a Steam account.

package mmstats_provider

import (
    "fmt"
    "github.com/Philipp15b/go-steam"
    "github.com/Philipp15b/go-steam/internal/steamlang"
    "io/ioutil"
    "log"
)

func main() {
    fmt.Println("Hello World")
}

When attempting to build this little bit of code, I got the following error:

../../Philipp15b/go-steam/auth.go:50: cannot use steamlang.EAccountType_Individual (type steamlang.EAccountType) as type int32 in argument to steamid.NewIdAdv

If I understand correctly, this is because EAccountType_Individual is of type EAccountType (which is based upon int32, but I guess Go is pretty strict about it's types), whereas steamid.NewIdAdv is expecting a regular int32 for a user's account type. I can workaround this for now by casting EAccountType_Individual to int32, but I think the correct solution is to change NewIdAdv to accept an EAccountType value for accountType instead of int32 - and at present I don't know how to do that (importing steamlang errored out because of circular imports).

Thanks,

Unable to send trade, Error (26)

Getting error 26 when trying to create/send a trade offer (according to the enums this means revoked which isn't much information).

This is my params:

map[sessionid:[fom3oafmo] partner:[76561198102055159] tradeoffermessage:["hi"] json_tradeoffer:[{"me":{"assets":[{"appid":295110,"contextid":1,"amount":1,"assetid":169262651814793732}],"currency":[],"ready":false},"newversion":true,"them":{"assets":[],"currency":[],"ready":false},"version":"3"}] trade_offer_create_params:[{}] serverid:[1] captcha:[]]

{"strError":"There was an error sending your trade offer.  Please try again later. (26)"}
500
2015/09/10 23:27:42 create error: status code not 200

I know the assetids are right because they exist in the inventory: http://steamcommunity.com/id/sandboxx/inventory/json/295110/1 if I CTRL+F and find each AssetID individually.

I'm not sure why I'm getting this error 26

Authorization does not work.

I use this example:

	myLoginInfo := new(steam.LogOnDetails)
	myLoginInfo.Username = "Your username"
	myLoginInfo.Password = "Your password"

	client := steam.NewClient()
	client.Connect()
	for event := range client.Events() {
		switch e := event.(type) {
		case *steam.ConnectedEvent:
			client.Auth.LogOn(myLoginInfo)
		case *steam.MachineAuthUpdateEvent:
			ioutil.WriteFile("sentry", e.Hash, 0666)
		case *steam.LoggedOnEvent:
			client.Social.SetPersonaState(steamlang.EPersonaState_Online)
		case steam.FatalErrorEvent:
			log.Print(e)
		case error:
			log.Print(e)
		}
	}

But it does not work.
Can you help me please?

Sending trade offers?

I've spent some time browsing the code and docs because it seems like quite a neat solution in all.

I couldn't, however, find any implementation to send trade offers; I might have just missed something, but I'm fairly certain there's nothing.

Can you confirm this?

Cheers.

why offerResult.Sent show received items

    ```

nowTime:=uint32(time.Now().Unix()) - 1000

offerResult, err := offerClient.GetOffers(true, true, true, true, false, &nowTime)

log.Println(len(**offerResult.Sent**)) 
for _,elem := range **offerResult.Sent**{
    log.Println(*elem)
}
for _, elem := range offerResult.Received {
    log.Println("qq")
    if len(elem.ToReceive)==0 && len(elem.ToGive) != 0 && elem.EscrowEndDate == 0 && elem.State==2 {
        //log.Println(elem)
        checkOffer(elem.TradeOfferId,offerClient)
    } else {
        log.Println(elem.State)
        if elem.State==2 {
            declineOffer(elem.TradeOfferId,offerClient)
        }
    }
}
in offerResult.Sent show offers what i get from another ppl, and every element in offerResult.Sent, show othersteamid == my steam id,not partner WTF?

TradeOffer Create Error (Status code != 200)

Sample of code:

case *steam.WebLoggedOnEvent:
            log.Print("Successfully logged on web")

            token := "awajV_Bp"

            TOClient := tradeoffer.NewClient(SteamAPIKey, client.Web.SessionId, client.Web.SteamLogin, client.Web.SteamLoginSecure)
            Offers, _ := TOClient.GetOffers()

            for _, TOffer := range Offers.Received {
                if (TOffer.State == 2) {
                    log.Println("Starting processing TOffer")

                    myItems := make([]tradeoffer.TradeItem, len(TOffer.ToReceive))
                    theirItems := make([]tradeoffer.TradeItem, 0)
                    for k, Asset := range TOffer.ToReceive {
                        myItems[k] = tradeoffer.TradeItem{
                            AppId: uint32(Asset.AppId),
                            ContextId: uint64(Asset.ContextId),
                            Amount: uint(Asset.Amount),
                            AssetId: uint64(Asset.AssetId),
                        }
                    }

                    log.Println(TOClient.Accept(TOffer.TradeOfferId))
                    log.Println(TOClient.Create(TOffer.OtherAccountId, &token, myItems, theirItems, nil, ""))
                }
            }

And github.com/Philipp15b/tradeoffer/tradeoffer.go

// If we failed, error out
    if resp.StatusCode != 200 {
        return nil, errors.New("create error: status code not 200")
    }

replaced to (just for check body of result page)

// If we failed, error out
    if resp.StatusCode != 200 {
        data, _ := ioutil.ReadAll(resp.Body)
        fmt.Println(string(data))
        return nil, errors.New("create error: status code not 200")
    }

Result: http://i.imgur.com/fzEYOk3.png
(Checked on Windows and Mac)

tradeoffer.Accept working good, but tradeoffer.Create doesn't work

Connect

Connect failed: dial tcp 209.197.29.196:27017: getsockopt: connection timed out
and thats all

Is it possible to convert SteamId to SteamId64??

When getting trade offers OtherAccountId

It returns like a: STEAM_0:1:31561936

Is it possible to get a SteamId64 instead like:

76561198102055159

Any information would be great thanks looked through the steamid package but didn't see anything

Group Chat Support

Is group chat support planned for a future release? If not, would you have information on what files to look at to add the feature myself?

Not handled results in handleLogOnResponse

go-steam/auth.go

Lines 111 to 112 in ab14012

} else if result == EResult_Fail || result == EResult_ServiceUnavailable || result == EResult_TryAnotherCM {
// some error on Steam's side, we'll get an EOF later

As code in the link shows, some results are explicitly not handled. My understanding is that this leads to a panic in readLoop. Why not emit FatalErrorEvent instead?

Panic related to groups

It stopped happening after I removed all my groups from the account.

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x4ac6df]

goroutine 20 [running]:
runtime.panic(0x721960, 0x95a242)
        c:/go/src/pkg/runtime/panic.c:279 +0x11f
sync.(*RWMutex).Lock(0x0)
        c:/go/src/pkg/sync/rwmutex.go:78 +0xcf
github.com/Philipp15b/go-steam.(*GroupsList).add(0xc082008f80, 0xc082006b00)
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/social.go:297 +0x31
github.com/Philipp15b/go-steam.(*Social).handleFriendsList(0xc082006640, 0xc08204af00)
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/social.go:135 +0x3bf
github.com/Philipp15b/go-steam.(*Social).HandlePacket(0xc082006640, 0xc08204af00)
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/social.go:42 +0x42
github.com/Philipp15b/go-steam.(*Client).handlePacket(0xc08205e000, 0xc08204af00)
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/client.go:275 +0x11f
github.com/Philipp15b/go-steam.(*Client).handleMulti(0xc08205e000, 0xc08204b140)
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/client.go:349 +0x6f4
github.com/Philipp15b/go-steam.(*Client).handlePacket(0xc08205e000, 0xc08204b140)
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/client.go:267 +0x4f
github.com/Philipp15b/go-steam.(*Client).readLoop(0xc08205e000)
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/client.go:208 +0x184
created by github.com/Philipp15b/go-steam.(*Client).ConnectTo
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/client.go:156 +0x1a3

goroutine 16 [runnable]:
main.main()
        C:/Users/Zack/Documents/GitHub/kunkkabot/kunkkabot.go:50 +0x6bc

goroutine 19 [finalizer wait]:
runtime.park(0x416a10, 0x95f0a0, 0x95d1a9)
        c:/go/src/pkg/runtime/proc.c:1369 +0xac
runtime.parkunlock(0x95f0a0, 0x95d1a9)
        c:/go/src/pkg/runtime/proc.c:1385 +0x42
runfinq()
        c:/go/src/pkg/runtime/mgc0.c:2644 +0xdd
runtime.goexit()
        c:/go/src/pkg/runtime/proc.c:1445

goroutine 21 [chan receive]:
github.com/Philipp15b/go-steam.(*Client).writeLoop(0xc08205e000)
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/client.go:222 +0x115
created by github.com/Philipp15b/go-steam.(*Client).ConnectTo
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/client.go:157 +0x1be

goroutine 22 [runnable]:
github.com/Philipp15b/go-steam.(*Client).heartbeatLoop(0xc08205e000, 0x9)
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/client.go:245
created by github.com/Philipp15b/go-steam.(*Auth).handleClientLogOnResponse
        C:/Users/Zack/Documents/Go/src/github.com/Philipp15b/go-steam/auth.go:80 +0x1e7

UDP connection

Steam have two type of connection , UDP and TCP according to steamRE connection.cs

Do you wish to upgrade go-steam to include it as well ?
some code needed to be changed mainly on

client.go

  • read / write loop handling should be handle by connection.go

connection.go

  • connection interface to handle UDP and TCP

API provided by client.go should not be changed ( at least not to my knowledge )

what do you think ?

throw nil pointer error on windows 7 32 bit

autho.go
atomic.StoreUint64(&a.client.steamId, uint64(steamid.New(0, 1, int32(EUniverse_Public), EAccountType_Individual)))

then I change the code as:

uuu := uint64(steamid.New(0, 1, int32(EUniverse_Public), EAccountType_Individual))

fmt.Printf("a=%p,a.client=%p,a.client.steamId=%d\n",a,a.client,a.clien.steamId)

atomic.StoreUint64(&(a.client.steamId), uuu)

Printf: a has valid address, a.client also has valid address, and a.client.steamId=0

but atomic.StoreUint64(&(a.client.steamId), uuu) still painc nil pointer

SteamApps

Hello,

I just want to let you know that I am working on the SteamApps handler.
I got the KeyValue parsing in text and binary form done and uploaded here: https://github.com/marshauf/keyvalues
Would be nice if someone could check it for bugs.
A soon as I got the SteamApps handler working I will create a pull request.

An coding example

Is it possible to attach an example on how to code with go-steam / tf2 ?

I tried to code with dota2, but its seems not working the way I thought it would,

Why connect methods os.Exit on error?

It is very strange that connect methods do not return error. It is not possible to run multiple concurrent clients when any one of them can just os.Exit whole process. Is there any particular reason for such design?

Pointer receiver for named map type.

https://github.com/Philipp15b/go-steam/blob/master/economy/inventory/inventory_apps.go#L13-L15

Regarding spec, map and slice is reference types, so why go-steam use pointer receiver for named map type? It looks like overusing pointer without reason.

And I can't find of case for using this function.

So, my proposal is use value receiver for reference type in most cases because we don't change reference, we change data at reference. For example in go stdlib ip.go What do you think about it?

too many values in struct initializer errors

On install and when trying to compile any file that uses go-steam, I get these errors:

github.com/Philipp15b/go-steam/steamid

go/src/github.com/Philipp15b/go-steam/steamid/steamid.go:30: function ends without a return statement

github.com/Philipp15b/go-steam/netutil

go/src/github.com/Philipp15b/go-steam/netutil/addr.go:34: too many values in struct initializer
go/src/github.com/Philipp15b/go-steam/netutil/addr.go:38: too many values in struct initializer

Automated testing

There should be a test suite for automated testing, especially for trading/trade offers. Valve seems to like breaking stuff.

go-steam trade

Firstly, tradeapi needs steamLoginSecure but trade don't

replace in /trade/trade.go

func New(sessionId, steamLogin string, other steamid.SteamId) *Trade {
    return &Trade{
        other,
        false, false,
        time.Unix(0, 0),
        nil,
        tradeapi.New(sessionId, steamLogin, other),
    }
}

to

func New(sessionId, steamLogin, steamLoginSecure string, other steamid.SteamId) *Trade {
    return &Trade{
        other,
        false, false,
        time.Unix(0, 0),
        nil,
        tradeapi.New(sessionId, steamLogin, steamLoginSecure, other),
    }
}

Seconly, trade doesn't work. In Steam client on PC I got network error after RespondRequest(id, true)

Debug results:

request to t.baseUrl+"tradestatus/" returns

{"success":false,"error":"missing required parameter"}

Allow for handling of LoggedOnEvent manually

Currently, no matter what in the LoggedOnEvent if the result isn't "OK", a.client.Fatalf("Login error: %v", result) is called. There's no simple way to determine if it was a SteamAuth error or an invalid password. It would be nice to handle this in a way that wouldn't involve parsing the error or manually pulling the information out of the packet and ignoring an error.

TradeOffer not sending status code != 200

This is what I'm currently sending:

    token := "vome_AF4"
    log.Println(token)
    log.Println(itemsToSend)
    log.Println(itemsToReceive)
    log.Println(winner)

    result, err := Trader.Create(winner, &token, itemsToSend, itemsToReceive, nil, "")
    if err != nil {
            log.Println(err)
    }

    015/09/10 19:52:09 vome_AF4
    2015/09/10 19:52:09 [{295110 1 1 169261971528374824} {295110 1 1 169261971528374903} {295110 1 1 169261971528374832} {295110 1 1 169261971528374912}]
    2015/09/10 19:52:09 []
    2015/09/10 19:52:09 STEAM_0:1:70894715
    2015/09/10 19:52:09 create error: status code not 200

I'm not sure why I'm getting the error I'm getting everything is correctly entered into the .Create method any information would be fantastic cause I'm pullin my hair out!

Question on how to use Gamecoordinator to get game specific information

Hi guys,

I'm currently trying to implement some of the features provided by:

https://github.com/joshuaferrara/node-csgo which allows things like: getting players profile including rank

The only thing is I'm not sure exactly what needs to take place to successfully send and receive the answers I'm looking for, below is the code I'm using so far and I was wondering if anybody that's experienced in how this should actually operate could give me any information.. I'm currently trying to implement the playerProfileRequest

package steambot

import (
    "encoding/binary"
    "encoding/json"
    "io"
    "io/ioutil"
    "log"
    "time"

    "github.com/Philipp15b/go-steam"
    "github.com/Philipp15b/go-steam/internal/gamecoordinator"
    "github.com/Philipp15b/go-steam/internal/steamlang"
)

const AppId = 730

var (
    loggedIn = true
    csgo     *CSGO
)

type CSGO struct {
    client *steam.Client
}

type MsgGCRequestPlayerProfile struct {
    RequestIdDeprecated  *uint64 `protobuf:"varint,1,opt,name=request_id_deprecated" json:"request_id_deprecated,omitempty"`
    RequestIdsDeprecated *uint64 `protobuf:"varint,2,rep,name=request_ids_deprecated" json:"request_ids_deprecated,omitempty"`
    AccountId            *uint64 `protobuf:"varint,3,opt,name=account_id" json:"account_id,omitempty"`
    RequestLevel         *uint64 `protobuf:"varint,4,opt,name="request_level, json:"request_level,omitempty"`
}

func (m *MsgGCRequestPlayerProfile) Serialize(w io.Writer) error {
    log.Println(m)
    return binary.Write(w, binary.LittleEndian, m)
}

func newCSGO(client *steam.Client) *CSGO {
    c := &CSGO{client}
    client.GC.RegisterPacketHandler(c)
    return c
}

func (c *CSGO) SetPlaying(playing bool) {
    if playing {
        c.client.GC.SetGamesPlayed(AppId)
    } else {
        c.client.GC.SetGamesPlayed()
    }
}

func (c *CSGO) HandleGCPacket(packet *gamecoordinator.GCPacket) {
    if packet.AppId != AppId {
        log.Println("Here")
        return
    }

    log.Println(packet)

}

func (c *CSGO) GetPlayerProfile(accountid uint64) {
    newAccId := accountid - 76561197960265728
    var requestLevel uint64 = 32
    for {
        log.Println("Trying to communicate with GameCoordinator")
        c.client.GC.Write(gamecoordinator.NewGCMsg(AppId, 9127, &MsgGCRequestPlayerProfile{AccountId: &newAccId, RequestLevel: &requestLevel}))
        time.Sleep(5 * time.Second)

    }
}

func StartBot() {
    myLoginInfo := new(steam.LogOnDetails)

    jsonAccountInfo, err := ioutil.ReadFile("accountinfo.json")
    if err != nil {
        log.Println("Please create an accountinfo.json file with the fields `username` and `password`")
        return
    }

    err = json.Unmarshal(jsonAccountInfo, &myLoginInfo)
    if err != nil {
        log.Println(err)
    }

    if sentry, err := ioutil.ReadFile("sentry"); err == nil {
        myLoginInfo.SentryFileHash = sentry
    }

    client := steam.NewClient()
    client.ConnectNorthAmerica()

    for event := range client.Events() {
        switch e := event.(type) {
        case *steam.ConnectedEvent:
            log.Println("Connecting SteamBot")
            client.Auth.LogOn(myLoginInfo)
        case *steam.MachineAuthUpdateEvent:
            log.Println("Wrote Sentry")
            ioutil.WriteFile("sentry", e.Hash, 0666)
        case *steam.LoggedOnEvent:
            log.Println("SteamBot logged in")
            client.Social.SetPersonaState(steamlang.EPersonaState_Online)
            loggedIn = true

            csgo = newCSGO(client)
            csgo.SetPlaying(true)
            csgo.GetPlayerProfile(123123123123)
        case steam.FatalErrorEvent:
            log.Println(e)
        case error:
            log.Println(e)

        }
    }

}

the 9127 number I got from the protos here

but it mainly looks like he uses a payload with json to send it to the gamecoordinator but im not sure how to accomplish that?
if you need to ask anything at all please feel free.

I have also tried using NewClientMsgProtobuf instead like this:

package steambot

import (
    "encoding/binary"
    "encoding/json"
    "io"
    "io/ioutil"
    "log"
    "time"

    "github.com/Philipp15b/go-steam"
    "github.com/Philipp15b/go-steam/internal"
    "github.com/Philipp15b/go-steam/internal/gamecoordinator"
    "github.com/Philipp15b/go-steam/internal/steamlang"
    proto "github.com/golang/protobuf/proto"
)

const AppId = 730

var (
    loggedIn = true
    csgo     *CSGO
)

type CSGO struct {
    client *steam.Client
}

type MsgGCRequestPlayerProfile struct {
    RequestIdDeprecated  *uint64 `protobuf:"varint,1,opt,name=request_id_deprecated" json:"request_id_deprecated,omitempty"`
    RequestIdsDeprecated *uint64 `protobuf:"varint,2,rep,name=request_ids_deprecated" json:"request_ids_deprecated,omitempty"`
    AccountId            *uint64 `protobuf:"varint,3,opt,name=account_id" json:"account_id,omitempty"`
    RequestLevel         *uint64 `protobuf:"varint,4,opt,name="request_level, json:"request_level,omitempty"`
}

func (m *MsgGCRequestPlayerProfile) Reset()         { *m = MsgGCRequestPlayerProfile{} }
func (m *MsgGCRequestPlayerProfile) String() string { return proto.CompactTextString(m) }
func (*MsgGCRequestPlayerProfile) ProtoMessage()    {}

func (m *MsgGCRequestPlayerProfile) Serialize(w io.Writer) error {
    log.Println(m)
    return binary.Write(w, binary.LittleEndian, m)
}

func newCSGO(client *steam.Client) *CSGO {
    c := &CSGO{client}
    client.GC.RegisterPacketHandler(c)
    return c
}

func (c *CSGO) SetPlaying(playing bool) {
    if playing {
        c.client.GC.SetGamesPlayed(AppId)
    } else {
        c.client.GC.SetGamesPlayed()
    }
}

func (c *CSGO) HandleGCPacket(packet *gamecoordinator.GCPacket) {
    if packet.AppId != AppId {
        log.Println("Here")
        return
    }

    log.Println(packet)

}

func (c *CSGO) GetPlayerProfile(accountid uint64) {
    newAccId := accountid - 76561197960265728
    var requestLevel uint64 = 32
    for {
        log.Println("Trying to communicate with GameCoordinator")
        c.client.Write(internal.NewClientMsgProtobuf(steamlang.EMsg(9127), &MsgGCRequestPlayerProfile{AccountId: &newAccId, RequestLevel: &requestLevel}))
        time.Sleep(5 * time.Second)

    }
}

func StartBot() {
    myLoginInfo := new(steam.LogOnDetails)

    jsonAccountInfo, err := ioutil.ReadFile("accountinfo.json")
    if err != nil {
        log.Println("Please create an accountinfo.json file with the fields `username` and `password`")
        return
    }

    err = json.Unmarshal(jsonAccountInfo, &myLoginInfo)
    if err != nil {
        log.Println(err)
    }

    if sentry, err := ioutil.ReadFile("sentry"); err == nil {
        myLoginInfo.SentryFileHash = sentry
    }

    client := steam.NewClient()
    client.ConnectNorthAmerica()

    for event := range client.Events() {
        switch e := event.(type) {
        case *steam.ConnectedEvent:
            log.Println("Connecting SteamBot")
            client.Auth.LogOn(myLoginInfo)
        case *steam.MachineAuthUpdateEvent:
            log.Println("Wrote Sentry")
            ioutil.WriteFile("sentry", e.Hash, 0666)
        case *steam.LoggedOnEvent:
            log.Println("SteamBot logged in")
            client.Social.SetPersonaState(steamlang.EPersonaState_Online)
            loggedIn = true

            csgo = newCSGO(client)
            csgo.SetPlaying(true)
            csgo.GetPlayerProfile(123123123)
        case steam.FatalErrorEvent:
            log.Println(e)
        case error:
            log.Println(e)

        }
    }

}

but still not getting anything, I'm not sure if I should be listening in the packet response or where. Thanks.

How do I get SteamLogin / SteamLoginSecure

Looking at the API it says I need to call

web.LogOn()

but web takes 3 parameters to work but isn't one of those parameters returned in web.LogOn()??

Can somebody give me an example of how to get SteamLogin/SteamLoginSecure params? Thanks.

go-steam couldn't accept tradeoffers (fix)

#35

func (c *Client) Accept(id TradeOfferId) error {
    req := netutil.NewPostForm(fmt.Sprintf("https://steamcommunity.com/tradeoffer/%d/accept", id), netutil.ToUrlValues(map[string]string{
        "sessionid":    c.sessionId,
        "serverid":     "1",
    }))
    req.Header.Add("Referer", fmt.Sprintf("https://steamcommunity.com/tradeoffer/%d/", id))

    resp, err := c.client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    if resp.StatusCode != 200 {
        return errors.New("accept error: status code not 200")
    }
    return nil
}

I just sent pull request.

Is there an event for knowing if the bot has sent a chat message?

I've checked

ChatEnterEvent
ChatMsgEvent
ChatMemberInfoEvent

The only one that works for what I'm looking for is ChatMsgEvent the only problem is it only triggers on recieving a message and not on sending one

My problem is that I need to send a message to a friend and then remove them from friends list, the only problem is the remove friend happens before the chat message sends no matter what order they're in and I don't want to put in a time.Sleep so I was wondering if there was a way to listen for when my bot sends a chat message, and then act on that event to remove the friend from there. Any information would be great thanks.

Consistent line endings

I just found out that there's CLRF all over the place, something in my Git config does not seem to have worked. Everything should be converted to LF.

How to avoid changing import in go files when I fork your project

Hello Philipp15b

I fork your poject as http://github.com/smithfo/go-steam, then I use the smithfox go-steam as an submodule to my project。

/myproject/src/github.com/smithfox/go-steam/xxxx

when I compile my project, report more errors say package issue.

so I replace all import "github.com/Philipp15b/go-steam" as "github.com/smithfox/go-steam"

Compile OK, but it is difficult to merge your master code, and submit my effort to your branch.

Do you know how to avoid that?

Inconsistent usage of types

Some simple types, like economy.AssetId, economy.ClassId, economy.InstanceId, tradeoffer.TradeOfferId are used inconsistently.

For example:

  1. In tradeoffer package: TradeOfferId everywhere except for TradeCreateResult struct
  2. In tradeoffer package economy types are not used, in inventory package economy types are used.
  3. In inventory package: GetOwnInventory takes uint64 instead of ContextId type, but return structs with economy types.
    ... many more ...

Is economy types and TradeOfferId type really needed? Why not convert them to uint32/uint64?

Incorrect example.

Hi! Your example didn't work for me but I fixed it with:

        client.Social.SetPersonaState(steamlang.EPersonaState_Online)

Instead of

        client.Social.SetPersonaState(internal.EPersonaState_Online)

Tell me if this is wrong but it fixed the problem for me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.