Update dependencies (#886)

This commit is contained in:
Wim 2019-09-07 22:46:58 +02:00 committed by GitHub
parent 1dc93ec4f0
commit a3bee01e0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
145 changed files with 24283 additions and 16572 deletions

View File

@ -85,7 +85,7 @@ func (b *Bsteam) handleEvents() {
func (b *Bsteam) handleLogOnFailed(e *steam.LogOnFailedEvent, myLoginInfo *steam.LogOnDetails) error {
switch e.Result {
case steamlang.EResult_AccountLogonDeniedNeedTwoFactorCode:
case steamlang.EResult_AccountLoginDeniedNeedTwoFactor:
b.Log.Info("Steam guard isn't letting me in! Enter 2FA code:")
var code string
fmt.Scanf("%s", &code)

View File

@ -9,9 +9,9 @@ fi
# Run the linter.
golangci-lint run
if [[ "${GO111MODULE-off}" == "on" ]]; then
# If Go modules are active then check that dependencies are correctly maintained.
go mod tidy
go mod vendor
git diff --exit-code --quiet || (echo "Please run 'go mod tidy' to clean up the 'go.mod' and 'go.sum' files."; false)
fi
# if [[ "${GO111MODULE-off}" == "on" ]]; then
# # If Go modules are active then check that dependencies are correctly maintained.
# go mod tidy
# go mod vendor
# git diff --exit-code --quiet || (echo "Please run 'go mod tidy' to clean up the 'go.mod' and 'go.sum' files."; false)
# fi

26
go.mod
View File

@ -4,11 +4,11 @@ require (
github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f
github.com/Jeffail/gabs v1.1.1 // indirect
github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0
github.com/Rhymen/go-whatsapp v0.0.3-0.20190729104911-5c79b2cf277a
github.com/bwmarrin/discordgo v0.19.0
// github.com/bwmarrin/discordgo v0.19.0
github.com/d5/tengo v1.24.1
github.com/d5/tengo v1.24.3
github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec
github.com/fsnotify/fsnotify v1.4.7
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible
@ -16,16 +16,14 @@ require (
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 // indirect
github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f // indirect
github.com/gorilla/schema v1.1.0
github.com/gorilla/websocket v1.4.0
github.com/hashicorp/golang-lru v0.5.1
github.com/gorilla/websocket v1.4.1
github.com/hashicorp/golang-lru v0.5.3
github.com/hpcloud/tail v1.0.0 // indirect
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7
github.com/jtolds/gls v4.2.1+incompatible // indirect
github.com/keybase/go-keybase-chat-bot v0.0.0-20190816161829-561f10822eb2
github.com/labstack/echo/v4 v4.1.6
github.com/labstack/echo/v4 v4.1.10
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 // indirect
github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6 // indirect
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91
github.com/matterbridge/gomatrix v0.0.0-20190102230110-6f9631ca6dea
@ -37,7 +35,7 @@ require (
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9
github.com/nicksnyder/go-i18n v1.4.0 // indirect
github.com/nlopes/slack v0.5.0
github.com/nlopes/slack v0.6.0
github.com/onsi/ginkgo v1.6.0 // indirect
github.com/onsi/gomega v1.4.1 // indirect
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c
@ -47,11 +45,12 @@ require (
github.com/russross/blackfriday v1.5.2
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
github.com/shazow/ssh-chat v0.0.0-20190125184227-81d7e1686296
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/sirupsen/logrus v1.4.2
github.com/smartystreets/assertions v0.0.0-20180803164922-886ec427f6b9 // indirect
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a // indirect
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.3.0
github.com/stretchr/testify v1.4.0
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2
@ -62,12 +61,17 @@ require (
gitlab.com/golang-commonmark/puny v0.0.0-20180912090636-2cd490539afe // indirect
gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638 // indirect
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 // indirect
golang.org/x/image v0.0.0-20190616094056-33659d3de4f5
golang.org/x/image v0.0.0-20190902063713-cb417be4ba39
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 // indirect
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // indirect
golang.org/x/text v0.3.2 // indirect
gopkg.in/fsnotify.v1 v1.4.7 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/russross/blackfriday.v2 v2.0.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
)
replace github.com/bwmarrin/discordgo v0.19.0 => github.com/matterbridge/discordgo v0.0.0-20190818085008-57c6e0fc2f40
replace gopkg.in/russross/blackfriday.v2 v2.0.1 => github.com/russross/blackfriday/v2 v2.0.1
go 1.13

61
go.sum
View File

@ -8,8 +8,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329 h1:xZBoq249G9MSt+XuY7sVQzcfONJ6IQuwpCK+KAaOpnY=
github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329/go.mod h1:HuVM+sZFzumUdKPWiz+IlCMb4RdsKdT3T+nQBKL+sYg=
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0 h1:TO7d4rocnNFng6ZQrPe7U6WqHtK5eHEMrgrnnM/72IQ=
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0/go.mod h1:HuVM+sZFzumUdKPWiz+IlCMb4RdsKdT3T+nQBKL+sYg=
github.com/Rhymen/go-whatsapp v0.0.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA=
github.com/Rhymen/go-whatsapp v0.0.3-0.20190729104911-5c79b2cf277a h1:umvfZW+YE+ynhYwsyheyunB/3xRK68kNFMRNUMQxzJI=
github.com/Rhymen/go-whatsapp v0.0.3-0.20190729104911-5c79b2cf277a/go.mod h1:qf/2PQi82Okxw/igghu/oMGzTeUYuKBq1JNo3tdQyNg=
@ -17,6 +17,7 @@ github.com/Rhymen/go-whatsapp/examples/echo v0.0.0-20190325075644-cc2581bbf24d/g
github.com/Rhymen/go-whatsapp/examples/restoreSession v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:5sCUSpG616ZoSJhlt9iBNI/KXBqrVLcNUJqg7J9+8pU=
github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:RdiyhanVEGXTam+mZ3k6Y3VDCCvXYCwReOoxGozqhHw=
github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:suwzklatySS3Q0+NCxCDh5hYfgXdQUWU1DNcxwAxStM=
github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e h1:IHXQQIpxASe3m0Jtcd3XongL+lxHNd5nUmvHxJARUmg=
github.com/StackExchange/wmi v0.0.0-20170410192909-ea383cf3ba6e/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -31,8 +32,8 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/d5/tengo v1.24.1 h1:b+epGF5Qi0XUkYUUl8y6hVzLxg/eu9FYUAdb4H/KieY=
github.com/d5/tengo v1.24.1/go.mod h1:gsbjo7lBXzBIWBd6NQp1lRKqqiDDANqBOyhW8rTlFsY=
github.com/d5/tengo v1.24.3 h1:wp44VW7fdfzMzIDT19tT5uNeGnm2UMd6s3TLAahrwSU=
github.com/d5/tengo v1.24.3/go.mod h1:VhLq8Q2QFhCIJO3NhvM934qOThykMqJi9y9Siqd1ocQ=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -47,6 +48,7 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible h1:i64CCJcSqkRIkm5OSdZQjZq84/gJsk2zNwHWIRYWlKE=
@ -71,13 +73,16 @@ github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f h1:FDM3EtwZLyhW4
github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
@ -106,16 +111,12 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/labstack/echo/v4 v4.1.6 h1:WOvLa4T1KzWCRpANwz0HGgWDelXSSGwIKtKBbFdHTv4=
github.com/labstack/echo/v4 v4.1.6/go.mod h1:kU/7PwzgNxZH4das4XNsSpBSOD09XIF5YEPzjpkGnGE=
github.com/labstack/gommon v0.2.9 h1:heVeuAYtevIQVYkGj6A41dtfT91LrvFG220lavpWhrU=
github.com/labstack/gommon v0.2.9/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/NKavGG4=
github.com/labstack/echo/v4 v4.1.10 h1:/yhIpO50CBInUbE/nHJtGIyhBv0dJe2cDAYxc3V3uMo=
github.com/labstack/echo/v4 v4.1.10/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7 h1:BS9tqL0OCiOGuy/CYYk2gc33fxqaqh5/rhqMKu4tcYA=
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7/go.mod h1:liX5MxHPrwgHaKowoLkYGwbXfYABh1jbZ6FpElbGF1I=
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 h1:AsEBgzv3DhuYHI/GiQh2HxvTP71HCCE9E/tzGUzGdtU=
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5/go.mod h1:c2mYKRyMb1BPkO5St0c/ps62L4S0W2NAkaTXj9qEI+0=
github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6 h1:iOAVXzZyXtW408TMYejlUPo6BIn92HmOacWtIfNyYns=
github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d h1:F+Sr+C0ojSlYQ37BLylQtSFmyQULe3jbAygcyXQ9mVs=
@ -140,6 +141,8 @@ github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@ -154,8 +157,8 @@ github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9 h1:mp6tU1r0xLostUGL
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9/go.mod h1:A5SRAcpTemjGgIuBq6Kic2yHcoeUFWUinOAlMP/i9xo=
github.com/nicksnyder/go-i18n v1.4.0 h1:AgLl+Yq7kg5OYlzCgu9cKTZOyI4tD/NgukKqLqC8E+I=
github.com/nicksnyder/go-i18n v1.4.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
github.com/nlopes/slack v0.5.0 h1:NbIae8Kd0NpqaEI3iUrsuS0KbcEDhzhc939jLW5fNm0=
github.com/nlopes/slack v0.5.0/go.mod h1:jVI4BBK3lSktibKahxBF74txcK2vyvkza1z/+rRnVAM=
github.com/nlopes/slack v0.6.0 h1:jt0jxVQGhssx1Ib7naAOZEZcGdtIhTzkP0nopK0AsRA=
github.com/nlopes/slack v0.6.0/go.mod h1:JzQ9m3PMAqcpeCam7UaHSuBuupz7CmpjehYMayT6YOk=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -188,6 +191,8 @@ github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
github.com/shazow/rateio v0.0.0-20150116013248-e8e00881e5c1 h1:Lx3BlDGFElJt4u/zKc9A3BuGYbQAGlEFyPuUA3jeMD0=
@ -196,7 +201,10 @@ github.com/shazow/ssh-chat v0.0.0-20190125184227-81d7e1686296 h1:8RLq547MSVc6vhO
github.com/shazow/ssh-chat v0.0.0-20190125184227-81d7e1686296/go.mod h1:1GLXsL4esywkpNId3v4QWuMf3THtWGitWvtQ/L3aSA4=
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7 h1:80VN+vGkqM773Br/uNNTSheo3KatTgV8IpjIKjvVLng=
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@ -220,11 +228,9 @@ github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@ -265,12 +271,11 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/image v0.0.0-20190616094056-33659d3de4f5 h1:ngW7cqsJcNIFizl289rKwy+nVvw7TQS8z3ejrra6syo=
golang.org/x/image v0.0.0-20190616094056-33659d3de4f5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20190902063713-cb417be4ba39 h1:4dQcAORh9oYBwVSBVIkP489LUPC+f1HBkTYXgmqfR+o=
golang.org/x/image v0.0.0-20190902063713-cb417be4ba39/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -280,8 +285,6 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190607181551-461777fb6f67 h1:rJJxsykSlULwd2P2+pg/rtnwN2FrWp4IuCxOSyS0V00=
golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -289,8 +292,6 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20171017063910-8dbc5d05d6ed/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -300,9 +301,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190609082536-301114b31cce h1:CQakrGkKbydnUmt7cFIlmQ4lNQiqdTPt6xzXij4nYCc=
golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
@ -314,7 +312,6 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=

View File

@ -45,20 +45,11 @@ Whether you want to develop your own Steam bot or directly work on go-steam itse
## Updating go-steam to a new SteamKit version
To update go-steam to a new version of SteamKit, do the following:
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.
go get github.com/golang/protobuf/protoc-gen-go/
git submodule init && git submodule update
cd generator
go run generator.go clean proto steamlang
Make sure that `$GOPATH/bin` / `protoc-gen-go` is in your `$PATH`. You'll also need [`protoc`](https://developers.google.com/protocol-buffers/docs/downloads), the protocol buffer compiler. At the moment, we use Protocol Buffers 2.6.1 with `proco-gen-go`-[2402d76](https://github.com/golang/protobuf/tree/2402d76f3d41f928c7902a765dfc872356dd3aad).
To compile the Steam Language files, you also need the [.NET Framework](https://www.microsoft.com/net/downloads)
on Windows or [mono](http://www.go-mono.com/mono-downloads/download.html) on other operating systems.
Apply the protocol changes where necessary.
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.
Steam for Go is licensed under the New BSD License. More information can be found in LICENSE.txt.

View File

@ -94,9 +94,6 @@ func (a *Auth) HandlePacket(packet *Packet) {
a.handleUpdateMachineAuth(packet)
case EMsg_ClientAccountInfo:
a.handleAccountInfo(packet)
case EMsg_ClientWalletInfoUpdate:
case EMsg_ClientRequestWebAPIAuthenticateUserNonceResponse:
case EMsg_ClientMarketingMessageUpdate:
}
}

View File

@ -133,11 +133,17 @@ func (c *Client) Connected() bool {
// If you want to connect to a specific server, use `ConnectTo`.
func (c *Client) Connect() *netutil.PortAddr {
var server *netutil.PortAddr
// try to initialize the directory cache
if !steamDirectoryCache.IsInitialized() {
_ = steamDirectoryCache.Initialize()
}
if steamDirectoryCache.IsInitialized() {
server = steamDirectoryCache.GetRandomCM()
} else {
server = GetRandomCM()
}
c.ConnectTo(server)
return server
}

View File

@ -1,6 +1,7 @@
package protocol
import (
"encoding/hex"
"io"
"math"
"strconv"
@ -42,6 +43,7 @@ const EClientPersonaStateFlag_DefaultInfoRequest = EClientPersonaStateFlag_Playe
const DefaultAvatar = "fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb"
func ValidAvatar(avatar string) bool {
return !(avatar == "0000000000000000000000000000000000000000" || len(avatar) != 40)
func ValidAvatar(avatar []byte) bool {
str := hex.EncodeToString(avatar)
return !(str == "0000000000000000000000000000000000000000" || len(str) != 40)
}

View File

@ -1,31 +1,60 @@
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: encrypted_app_ticket.proto
// DO NOT EDIT!
package protobuf
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package protobuf is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package protobuf to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type EncryptedAppTicket struct {
TicketVersionNo *uint32 `protobuf:"varint,1,opt,name=ticket_version_no" json:"ticket_version_no,omitempty"`
CrcEncryptedticket *uint32 `protobuf:"varint,2,opt,name=crc_encryptedticket" json:"crc_encryptedticket,omitempty"`
CbEncrypteduserdata *uint32 `protobuf:"varint,3,opt,name=cb_encrypteduserdata" json:"cb_encrypteduserdata,omitempty"`
CbEncryptedAppownershipticket *uint32 `protobuf:"varint,4,opt,name=cb_encrypted_appownershipticket" json:"cb_encrypted_appownershipticket,omitempty"`
EncryptedTicket []byte `protobuf:"bytes,5,opt,name=encrypted_ticket" json:"encrypted_ticket,omitempty"`
XXX_unrecognized []byte `json:"-"`
TicketVersionNo *uint32 `protobuf:"varint,1,opt,name=ticket_version_no" json:"ticket_version_no,omitempty"`
CrcEncryptedticket *uint32 `protobuf:"varint,2,opt,name=crc_encryptedticket" json:"crc_encryptedticket,omitempty"`
CbEncrypteduserdata *uint32 `protobuf:"varint,3,opt,name=cb_encrypteduserdata" json:"cb_encrypteduserdata,omitempty"`
CbEncryptedAppownershipticket *uint32 `protobuf:"varint,4,opt,name=cb_encrypted_appownershipticket" json:"cb_encrypted_appownershipticket,omitempty"`
EncryptedTicket []byte `protobuf:"bytes,5,opt,name=encrypted_ticket" json:"encrypted_ticket,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EncryptedAppTicket) Reset() { *m = EncryptedAppTicket{} }
func (m *EncryptedAppTicket) String() string { return proto.CompactTextString(m) }
func (*EncryptedAppTicket) ProtoMessage() {}
func (*EncryptedAppTicket) Descriptor() ([]byte, []int) { return app_ticket_fileDescriptor0, []int{0} }
func (m *EncryptedAppTicket) Reset() { *m = EncryptedAppTicket{} }
func (m *EncryptedAppTicket) String() string { return proto.CompactTextString(m) }
func (*EncryptedAppTicket) ProtoMessage() {}
func (*EncryptedAppTicket) Descriptor() ([]byte, []int) {
return fileDescriptor_c6d69fd1cac4e8d5, []int{0}
}
func (m *EncryptedAppTicket) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EncryptedAppTicket.Unmarshal(m, b)
}
func (m *EncryptedAppTicket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EncryptedAppTicket.Marshal(b, m, deterministic)
}
func (m *EncryptedAppTicket) XXX_Merge(src proto.Message) {
xxx_messageInfo_EncryptedAppTicket.Merge(m, src)
}
func (m *EncryptedAppTicket) XXX_Size() int {
return xxx_messageInfo_EncryptedAppTicket.Size(m)
}
func (m *EncryptedAppTicket) XXX_DiscardUnknown() {
xxx_messageInfo_EncryptedAppTicket.DiscardUnknown(m)
}
var xxx_messageInfo_EncryptedAppTicket proto.InternalMessageInfo
func (m *EncryptedAppTicket) GetTicketVersionNo() uint32 {
if m != nil && m.TicketVersionNo != nil {
@ -66,17 +95,19 @@ func init() {
proto.RegisterType((*EncryptedAppTicket)(nil), "EncryptedAppTicket")
}
var app_ticket_fileDescriptor0 = []byte{
// 162 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0x4a, 0xcd, 0x4b, 0x2e,
func init() { proto.RegisterFile("encrypted_app_ticket.proto", fileDescriptor_c6d69fd1cac4e8d5) }
var fileDescriptor_c6d69fd1cac4e8d5 = []byte{
// 164 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4a, 0xcd, 0x4b, 0x2e,
0xaa, 0x2c, 0x28, 0x49, 0x4d, 0x89, 0x4f, 0x2c, 0x28, 0x88, 0x2f, 0xc9, 0x4c, 0xce, 0x4e, 0x2d,
0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x5a, 0xcb, 0xc8, 0x25, 0xe4, 0x0a, 0x93, 0x76, 0x2c,
0x28, 0x08, 0x01, 0x4b, 0x0a, 0x49, 0x72, 0x09, 0x42, 0x94, 0xc5, 0x97, 0xa5, 0x16, 0x15, 0x67,
0xe6, 0xe7, 0xc5, 0xe7, 0xe5, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x0a, 0x49, 0x73, 0x09, 0x27,
0x17, 0x25, 0xc7, 0xc3, 0xcd, 0x84, 0xa8, 0x93, 0x60, 0x02, 0x4b, 0xca, 0x70, 0x89, 0x24, 0x27,
0x21, 0xe4, 0x4a, 0x8b, 0x53, 0x8b, 0x52, 0x12, 0x4b, 0x12, 0x25, 0x98, 0xc1, 0xb2, 0xea, 0x5c,
0xf2, 0xc8, 0xb2, 0x20, 0xd7, 0xe4, 0x97, 0xe7, 0x01, 0x2d, 0xc8, 0xc8, 0x2c, 0x80, 0x1a, 0xc3,
0x02, 0x56, 0x28, 0xc1, 0x25, 0x80, 0x50, 0x05, 0x95, 0x61, 0x05, 0xca, 0xf0, 0x38, 0xb1, 0x7a,
0x30, 0x36, 0x30, 0x32, 0x00, 0x02, 0x00, 0x00, 0xff, 0xff, 0x03, 0x8c, 0xdb, 0x92, 0xd3, 0x00,
0x00, 0x00,
0xf2, 0xc8, 0xb2, 0x20, 0xd7, 0xe4, 0x97, 0xe7, 0xa5, 0x16, 0x15, 0x67, 0x64, 0x16, 0x40, 0x8d,
0x61, 0x01, 0x2b, 0x94, 0xe0, 0x12, 0x40, 0xa8, 0x82, 0xca, 0xb0, 0x2a, 0x30, 0x6a, 0xf0, 0x38,
0xb1, 0x7a, 0x30, 0x36, 0x30, 0x32, 0x00, 0x02, 0x00, 0x00, 0xff, 0xff, 0x03, 0x8c, 0xdb, 0x92,
0xd3, 0x00, 0x00, 0x00,
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,397 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: steammessages_sitelicenseclient.proto
package protobuf
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package protobuf is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package protobuf to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type CMsgClientSiteInfo struct {
SiteId *uint64 `protobuf:"varint,1,opt,name=site_id" json:"site_id,omitempty"`
SiteName *string `protobuf:"bytes,2,opt,name=site_name" json:"site_name,omitempty"`
AllowCachedCredentials *bool `protobuf:"varint,3,opt,name=allow_cached_credentials" json:"allow_cached_credentials,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CMsgClientSiteInfo) Reset() { *m = CMsgClientSiteInfo{} }
func (m *CMsgClientSiteInfo) String() string { return proto.CompactTextString(m) }
func (*CMsgClientSiteInfo) ProtoMessage() {}
func (*CMsgClientSiteInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_0a32817a56a37a6e, []int{0}
}
func (m *CMsgClientSiteInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CMsgClientSiteInfo.Unmarshal(m, b)
}
func (m *CMsgClientSiteInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CMsgClientSiteInfo.Marshal(b, m, deterministic)
}
func (m *CMsgClientSiteInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_CMsgClientSiteInfo.Merge(m, src)
}
func (m *CMsgClientSiteInfo) XXX_Size() int {
return xxx_messageInfo_CMsgClientSiteInfo.Size(m)
}
func (m *CMsgClientSiteInfo) XXX_DiscardUnknown() {
xxx_messageInfo_CMsgClientSiteInfo.DiscardUnknown(m)
}
var xxx_messageInfo_CMsgClientSiteInfo proto.InternalMessageInfo
func (m *CMsgClientSiteInfo) GetSiteId() uint64 {
if m != nil && m.SiteId != nil {
return *m.SiteId
}
return 0
}
func (m *CMsgClientSiteInfo) GetSiteName() string {
if m != nil && m.SiteName != nil {
return *m.SiteName
}
return ""
}
func (m *CMsgClientSiteInfo) GetAllowCachedCredentials() bool {
if m != nil && m.AllowCachedCredentials != nil {
return *m.AllowCachedCredentials
}
return false
}
type CMsgClientSiteLicenseCheckout struct {
Appid *uint32 `protobuf:"varint,1,opt,name=appid" json:"appid,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CMsgClientSiteLicenseCheckout) Reset() { *m = CMsgClientSiteLicenseCheckout{} }
func (m *CMsgClientSiteLicenseCheckout) String() string { return proto.CompactTextString(m) }
func (*CMsgClientSiteLicenseCheckout) ProtoMessage() {}
func (*CMsgClientSiteLicenseCheckout) Descriptor() ([]byte, []int) {
return fileDescriptor_0a32817a56a37a6e, []int{1}
}
func (m *CMsgClientSiteLicenseCheckout) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CMsgClientSiteLicenseCheckout.Unmarshal(m, b)
}
func (m *CMsgClientSiteLicenseCheckout) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CMsgClientSiteLicenseCheckout.Marshal(b, m, deterministic)
}
func (m *CMsgClientSiteLicenseCheckout) XXX_Merge(src proto.Message) {
xxx_messageInfo_CMsgClientSiteLicenseCheckout.Merge(m, src)
}
func (m *CMsgClientSiteLicenseCheckout) XXX_Size() int {
return xxx_messageInfo_CMsgClientSiteLicenseCheckout.Size(m)
}
func (m *CMsgClientSiteLicenseCheckout) XXX_DiscardUnknown() {
xxx_messageInfo_CMsgClientSiteLicenseCheckout.DiscardUnknown(m)
}
var xxx_messageInfo_CMsgClientSiteLicenseCheckout proto.InternalMessageInfo
func (m *CMsgClientSiteLicenseCheckout) GetAppid() uint32 {
if m != nil && m.Appid != nil {
return *m.Appid
}
return 0
}
type CMsgClientSiteLicenseCheckoutResponse struct {
Eresult *int32 `protobuf:"varint,1,opt,name=eresult,def=2" json:"eresult,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CMsgClientSiteLicenseCheckoutResponse) Reset() { *m = CMsgClientSiteLicenseCheckoutResponse{} }
func (m *CMsgClientSiteLicenseCheckoutResponse) String() string { return proto.CompactTextString(m) }
func (*CMsgClientSiteLicenseCheckoutResponse) ProtoMessage() {}
func (*CMsgClientSiteLicenseCheckoutResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_0a32817a56a37a6e, []int{2}
}
func (m *CMsgClientSiteLicenseCheckoutResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CMsgClientSiteLicenseCheckoutResponse.Unmarshal(m, b)
}
func (m *CMsgClientSiteLicenseCheckoutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CMsgClientSiteLicenseCheckoutResponse.Marshal(b, m, deterministic)
}
func (m *CMsgClientSiteLicenseCheckoutResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_CMsgClientSiteLicenseCheckoutResponse.Merge(m, src)
}
func (m *CMsgClientSiteLicenseCheckoutResponse) XXX_Size() int {
return xxx_messageInfo_CMsgClientSiteLicenseCheckoutResponse.Size(m)
}
func (m *CMsgClientSiteLicenseCheckoutResponse) XXX_DiscardUnknown() {
xxx_messageInfo_CMsgClientSiteLicenseCheckoutResponse.DiscardUnknown(m)
}
var xxx_messageInfo_CMsgClientSiteLicenseCheckoutResponse proto.InternalMessageInfo
const Default_CMsgClientSiteLicenseCheckoutResponse_Eresult int32 = 2
func (m *CMsgClientSiteLicenseCheckoutResponse) GetEresult() int32 {
if m != nil && m.Eresult != nil {
return *m.Eresult
}
return Default_CMsgClientSiteLicenseCheckoutResponse_Eresult
}
type CMsgClientSiteLicenseGetAvailableSeats struct {
Appid *uint32 `protobuf:"varint,1,opt,name=appid" json:"appid,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CMsgClientSiteLicenseGetAvailableSeats) Reset() {
*m = CMsgClientSiteLicenseGetAvailableSeats{}
}
func (m *CMsgClientSiteLicenseGetAvailableSeats) String() string { return proto.CompactTextString(m) }
func (*CMsgClientSiteLicenseGetAvailableSeats) ProtoMessage() {}
func (*CMsgClientSiteLicenseGetAvailableSeats) Descriptor() ([]byte, []int) {
return fileDescriptor_0a32817a56a37a6e, []int{3}
}
func (m *CMsgClientSiteLicenseGetAvailableSeats) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeats.Unmarshal(m, b)
}
func (m *CMsgClientSiteLicenseGetAvailableSeats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeats.Marshal(b, m, deterministic)
}
func (m *CMsgClientSiteLicenseGetAvailableSeats) XXX_Merge(src proto.Message) {
xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeats.Merge(m, src)
}
func (m *CMsgClientSiteLicenseGetAvailableSeats) XXX_Size() int {
return xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeats.Size(m)
}
func (m *CMsgClientSiteLicenseGetAvailableSeats) XXX_DiscardUnknown() {
xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeats.DiscardUnknown(m)
}
var xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeats proto.InternalMessageInfo
func (m *CMsgClientSiteLicenseGetAvailableSeats) GetAppid() uint32 {
if m != nil && m.Appid != nil {
return *m.Appid
}
return 0
}
type CMsgClientSiteLicenseGetAvailableSeatsResponse struct {
Eresult *int32 `protobuf:"varint,1,opt,name=eresult,def=2" json:"eresult,omitempty"`
Seats *uint32 `protobuf:"varint,2,opt,name=seats" json:"seats,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CMsgClientSiteLicenseGetAvailableSeatsResponse) Reset() {
*m = CMsgClientSiteLicenseGetAvailableSeatsResponse{}
}
func (m *CMsgClientSiteLicenseGetAvailableSeatsResponse) String() string {
return proto.CompactTextString(m)
}
func (*CMsgClientSiteLicenseGetAvailableSeatsResponse) ProtoMessage() {}
func (*CMsgClientSiteLicenseGetAvailableSeatsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_0a32817a56a37a6e, []int{4}
}
func (m *CMsgClientSiteLicenseGetAvailableSeatsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeatsResponse.Unmarshal(m, b)
}
func (m *CMsgClientSiteLicenseGetAvailableSeatsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeatsResponse.Marshal(b, m, deterministic)
}
func (m *CMsgClientSiteLicenseGetAvailableSeatsResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeatsResponse.Merge(m, src)
}
func (m *CMsgClientSiteLicenseGetAvailableSeatsResponse) XXX_Size() int {
return xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeatsResponse.Size(m)
}
func (m *CMsgClientSiteLicenseGetAvailableSeatsResponse) XXX_DiscardUnknown() {
xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeatsResponse.DiscardUnknown(m)
}
var xxx_messageInfo_CMsgClientSiteLicenseGetAvailableSeatsResponse proto.InternalMessageInfo
const Default_CMsgClientSiteLicenseGetAvailableSeatsResponse_Eresult int32 = 2
func (m *CMsgClientSiteLicenseGetAvailableSeatsResponse) GetEresult() int32 {
if m != nil && m.Eresult != nil {
return *m.Eresult
}
return Default_CMsgClientSiteLicenseGetAvailableSeatsResponse_Eresult
}
func (m *CMsgClientSiteLicenseGetAvailableSeatsResponse) GetSeats() uint32 {
if m != nil && m.Seats != nil {
return *m.Seats
}
return 0
}
type CMsgClientSiteLicenseGetContentCacheInfo struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CMsgClientSiteLicenseGetContentCacheInfo) Reset() {
*m = CMsgClientSiteLicenseGetContentCacheInfo{}
}
func (m *CMsgClientSiteLicenseGetContentCacheInfo) String() string { return proto.CompactTextString(m) }
func (*CMsgClientSiteLicenseGetContentCacheInfo) ProtoMessage() {}
func (*CMsgClientSiteLicenseGetContentCacheInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_0a32817a56a37a6e, []int{5}
}
func (m *CMsgClientSiteLicenseGetContentCacheInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfo.Unmarshal(m, b)
}
func (m *CMsgClientSiteLicenseGetContentCacheInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfo.Marshal(b, m, deterministic)
}
func (m *CMsgClientSiteLicenseGetContentCacheInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfo.Merge(m, src)
}
func (m *CMsgClientSiteLicenseGetContentCacheInfo) XXX_Size() int {
return xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfo.Size(m)
}
func (m *CMsgClientSiteLicenseGetContentCacheInfo) XXX_DiscardUnknown() {
xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfo.DiscardUnknown(m)
}
var xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfo proto.InternalMessageInfo
type CMsgClientSiteLicenseGetContentCacheInfoResponse struct {
UseCache *bool `protobuf:"varint,1,opt,name=use_cache" json:"use_cache,omitempty"`
Ipv4Address *uint32 `protobuf:"varint,2,opt,name=ipv4_address" json:"ipv4_address,omitempty"`
PortNumber *uint32 `protobuf:"varint,3,opt,name=port_number" json:"port_number,omitempty"`
P2PGroup *uint32 `protobuf:"varint,4,opt,name=p2p_group" json:"p2p_group,omitempty"`
IpAddress *string `protobuf:"bytes,5,opt,name=ip_address" json:"ip_address,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) Reset() {
*m = CMsgClientSiteLicenseGetContentCacheInfoResponse{}
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) String() string {
return proto.CompactTextString(m)
}
func (*CMsgClientSiteLicenseGetContentCacheInfoResponse) ProtoMessage() {}
func (*CMsgClientSiteLicenseGetContentCacheInfoResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_0a32817a56a37a6e, []int{6}
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfoResponse.Unmarshal(m, b)
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfoResponse.Marshal(b, m, deterministic)
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfoResponse.Merge(m, src)
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) XXX_Size() int {
return xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfoResponse.Size(m)
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) XXX_DiscardUnknown() {
xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfoResponse.DiscardUnknown(m)
}
var xxx_messageInfo_CMsgClientSiteLicenseGetContentCacheInfoResponse proto.InternalMessageInfo
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) GetUseCache() bool {
if m != nil && m.UseCache != nil {
return *m.UseCache
}
return false
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) GetIpv4Address() uint32 {
if m != nil && m.Ipv4Address != nil {
return *m.Ipv4Address
}
return 0
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) GetPortNumber() uint32 {
if m != nil && m.PortNumber != nil {
return *m.PortNumber
}
return 0
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) GetP2PGroup() uint32 {
if m != nil && m.P2PGroup != nil {
return *m.P2PGroup
}
return 0
}
func (m *CMsgClientSiteLicenseGetContentCacheInfoResponse) GetIpAddress() string {
if m != nil && m.IpAddress != nil {
return *m.IpAddress
}
return ""
}
func init() {
proto.RegisterType((*CMsgClientSiteInfo)(nil), "CMsgClientSiteInfo")
proto.RegisterType((*CMsgClientSiteLicenseCheckout)(nil), "CMsgClientSiteLicenseCheckout")
proto.RegisterType((*CMsgClientSiteLicenseCheckoutResponse)(nil), "CMsgClientSiteLicenseCheckoutResponse")
proto.RegisterType((*CMsgClientSiteLicenseGetAvailableSeats)(nil), "CMsgClientSiteLicenseGetAvailableSeats")
proto.RegisterType((*CMsgClientSiteLicenseGetAvailableSeatsResponse)(nil), "CMsgClientSiteLicenseGetAvailableSeatsResponse")
proto.RegisterType((*CMsgClientSiteLicenseGetContentCacheInfo)(nil), "CMsgClientSiteLicenseGetContentCacheInfo")
proto.RegisterType((*CMsgClientSiteLicenseGetContentCacheInfoResponse)(nil), "CMsgClientSiteLicenseGetContentCacheInfoResponse")
}
func init() {
proto.RegisterFile("steammessages_sitelicenseclient.proto", fileDescriptor_0a32817a56a37a6e)
}
var fileDescriptor_0a32817a56a37a6e = []byte{
// 335 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0x41, 0x4b, 0xfb, 0x40,
0x14, 0xc4, 0xff, 0xfb, 0xb7, 0xa1, 0xed, 0xd3, 0x20, 0x5d, 0x3d, 0x04, 0x41, 0x08, 0x81, 0x4a,
0xf0, 0x50, 0xa4, 0x08, 0x82, 0x9e, 0x34, 0x07, 0x15, 0xf4, 0x62, 0x6f, 0x5e, 0xc2, 0x36, 0x79,
0xb6, 0x8b, 0x9b, 0xdd, 0x25, 0x6f, 0x53, 0xaf, 0x7e, 0x0b, 0xbf, 0xae, 0x64, 0x5b, 0x0a, 0x15,
0x2d, 0xbd, 0xee, 0xce, 0x6f, 0x66, 0x98, 0x07, 0x43, 0x72, 0x28, 0xaa, 0x0a, 0x89, 0xc4, 0x0c,
0x29, 0x27, 0xe9, 0x50, 0xc9, 0x02, 0x35, 0x61, 0xa1, 0x24, 0x6a, 0x37, 0xb2, 0xb5, 0x71, 0xe6,
0x24, 0xda, 0x94, 0x4d, 0x05, 0xe1, 0xf2, 0x27, 0x79, 0x05, 0x9e, 0x3d, 0xd3, 0x2c, 0xf3, 0xea,
0x89, 0x74, 0xf8, 0xa8, 0xdf, 0x0c, 0x3f, 0x84, 0x6e, 0x6b, 0x95, 0xcb, 0x32, 0x62, 0x31, 0x4b,
0x3b, 0x7c, 0x00, 0x7d, 0xff, 0xa0, 0x45, 0x85, 0xd1, 0xff, 0x98, 0xa5, 0x7d, 0x1e, 0x43, 0x24,
0x94, 0x32, 0x1f, 0x79, 0x21, 0x8a, 0x39, 0x96, 0x79, 0x51, 0x63, 0x89, 0xda, 0x49, 0xa1, 0x28,
0xda, 0x8b, 0x59, 0xda, 0x4b, 0x46, 0x70, 0xba, 0xe9, 0xfd, 0xb4, 0xac, 0x96, 0xcd, 0xb1, 0x78,
0x37, 0x8d, 0xe3, 0x21, 0x04, 0xc2, 0xda, 0x55, 0x48, 0x98, 0xdc, 0xc0, 0x70, 0xab, 0xfe, 0x05,
0xc9, 0x1a, 0x4d, 0xc8, 0x39, 0x74, 0xb1, 0x46, 0x6a, 0x94, 0xf3, 0x64, 0x70, 0xcd, 0xc6, 0xc9,
0x15, 0x9c, 0xfd, 0x0a, 0xdf, 0xa3, 0xbb, 0x5d, 0x08, 0xa9, 0xc4, 0x54, 0xe1, 0x04, 0x85, 0xa3,
0x9f, 0xa9, 0x13, 0x18, 0xed, 0x06, 0x6e, 0x8b, 0x6f, 0x4d, 0xa9, 0x15, 0xf9, 0x71, 0xc2, 0xe4,
0x1c, 0xd2, 0xbf, 0x4c, 0x33, 0xa3, 0x1d, 0x6a, 0x97, 0xb5, 0xab, 0xb5, 0x63, 0x27, 0x5f, 0x0c,
0x2e, 0x76, 0x15, 0xaf, 0x3b, 0x0c, 0xa0, 0xdf, 0x10, 0x2e, 0xb7, 0xf7, 0x2d, 0x7a, 0xfc, 0x18,
0x0e, 0xa4, 0x5d, 0x5c, 0xe6, 0xa2, 0x2c, 0x6b, 0xa4, 0x55, 0x13, 0x7e, 0x04, 0xfb, 0xd6, 0xd4,
0x2e, 0xd7, 0x4d, 0x35, 0xc5, 0xda, 0x5f, 0x26, 0x6c, 0x69, 0x3b, 0xb6, 0xf9, 0xac, 0x36, 0x8d,
0x8d, 0x3a, 0xfe, 0x89, 0x03, 0x48, 0xbb, 0x66, 0x83, 0xf6, 0xc4, 0x77, 0xc1, 0x03, 0xfb, 0x64,
0xff, 0xbe, 0x03, 0x00, 0x00, 0xff, 0xff, 0x09, 0x2f, 0x9f, 0xe9, 0x65, 0x02, 0x00, 0x00,
}

View File

@ -1,27 +1,56 @@
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: content_manifest.proto
// DO NOT EDIT!
package protobuf
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package protobuf is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package protobuf to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type ContentManifestPayload struct {
Mappings []*ContentManifestPayload_FileMapping `protobuf:"bytes,1,rep,name=mappings" json:"mappings,omitempty"`
XXX_unrecognized []byte `json:"-"`
Mappings []*ContentManifestPayload_FileMapping `protobuf:"bytes,1,rep,name=mappings" json:"mappings,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ContentManifestPayload) Reset() { *m = ContentManifestPayload{} }
func (m *ContentManifestPayload) String() string { return proto.CompactTextString(m) }
func (*ContentManifestPayload) ProtoMessage() {}
func (*ContentManifestPayload) Descriptor() ([]byte, []int) { return content_manifest_fileDescriptor0, []int{0} }
func (m *ContentManifestPayload) Reset() { *m = ContentManifestPayload{} }
func (m *ContentManifestPayload) String() string { return proto.CompactTextString(m) }
func (*ContentManifestPayload) ProtoMessage() {}
func (*ContentManifestPayload) Descriptor() ([]byte, []int) {
return fileDescriptor_e3cda137a29253ba, []int{0}
}
func (m *ContentManifestPayload) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ContentManifestPayload.Unmarshal(m, b)
}
func (m *ContentManifestPayload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ContentManifestPayload.Marshal(b, m, deterministic)
}
func (m *ContentManifestPayload) XXX_Merge(src proto.Message) {
xxx_messageInfo_ContentManifestPayload.Merge(m, src)
}
func (m *ContentManifestPayload) XXX_Size() int {
return xxx_messageInfo_ContentManifestPayload.Size(m)
}
func (m *ContentManifestPayload) XXX_DiscardUnknown() {
xxx_messageInfo_ContentManifestPayload.DiscardUnknown(m)
}
var xxx_messageInfo_ContentManifestPayload proto.InternalMessageInfo
func (m *ContentManifestPayload) GetMappings() []*ContentManifestPayload_FileMapping {
if m != nil {
@ -31,23 +60,43 @@ func (m *ContentManifestPayload) GetMappings() []*ContentManifestPayload_FileMap
}
type ContentManifestPayload_FileMapping struct {
Filename *string `protobuf:"bytes,1,opt,name=filename" json:"filename,omitempty"`
Size *uint64 `protobuf:"varint,2,opt,name=size" json:"size,omitempty"`
Flags *uint32 `protobuf:"varint,3,opt,name=flags" json:"flags,omitempty"`
ShaFilename []byte `protobuf:"bytes,4,opt,name=sha_filename" json:"sha_filename,omitempty"`
ShaContent []byte `protobuf:"bytes,5,opt,name=sha_content" json:"sha_content,omitempty"`
Chunks []*ContentManifestPayload_FileMapping_ChunkData `protobuf:"bytes,6,rep,name=chunks" json:"chunks,omitempty"`
Linktarget *string `protobuf:"bytes,7,opt,name=linktarget" json:"linktarget,omitempty"`
XXX_unrecognized []byte `json:"-"`
Filename *string `protobuf:"bytes,1,opt,name=filename" json:"filename,omitempty"`
Size *uint64 `protobuf:"varint,2,opt,name=size" json:"size,omitempty"`
Flags *uint32 `protobuf:"varint,3,opt,name=flags" json:"flags,omitempty"`
ShaFilename []byte `protobuf:"bytes,4,opt,name=sha_filename" json:"sha_filename,omitempty"`
ShaContent []byte `protobuf:"bytes,5,opt,name=sha_content" json:"sha_content,omitempty"`
Chunks []*ContentManifestPayload_FileMapping_ChunkData `protobuf:"bytes,6,rep,name=chunks" json:"chunks,omitempty"`
Linktarget *string `protobuf:"bytes,7,opt,name=linktarget" json:"linktarget,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ContentManifestPayload_FileMapping) Reset() { *m = ContentManifestPayload_FileMapping{} }
func (m *ContentManifestPayload_FileMapping) String() string { return proto.CompactTextString(m) }
func (*ContentManifestPayload_FileMapping) ProtoMessage() {}
func (*ContentManifestPayload_FileMapping) Descriptor() ([]byte, []int) {
return content_manifest_fileDescriptor0, []int{0, 0}
return fileDescriptor_e3cda137a29253ba, []int{0, 0}
}
func (m *ContentManifestPayload_FileMapping) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ContentManifestPayload_FileMapping.Unmarshal(m, b)
}
func (m *ContentManifestPayload_FileMapping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ContentManifestPayload_FileMapping.Marshal(b, m, deterministic)
}
func (m *ContentManifestPayload_FileMapping) XXX_Merge(src proto.Message) {
xxx_messageInfo_ContentManifestPayload_FileMapping.Merge(m, src)
}
func (m *ContentManifestPayload_FileMapping) XXX_Size() int {
return xxx_messageInfo_ContentManifestPayload_FileMapping.Size(m)
}
func (m *ContentManifestPayload_FileMapping) XXX_DiscardUnknown() {
xxx_messageInfo_ContentManifestPayload_FileMapping.DiscardUnknown(m)
}
var xxx_messageInfo_ContentManifestPayload_FileMapping proto.InternalMessageInfo
func (m *ContentManifestPayload_FileMapping) GetFilename() string {
if m != nil && m.Filename != nil {
return *m.Filename
@ -98,12 +147,14 @@ func (m *ContentManifestPayload_FileMapping) GetLinktarget() string {
}
type ContentManifestPayload_FileMapping_ChunkData struct {
Sha []byte `protobuf:"bytes,1,opt,name=sha" json:"sha,omitempty"`
Crc *uint32 `protobuf:"fixed32,2,opt,name=crc" json:"crc,omitempty"`
Offset *uint64 `protobuf:"varint,3,opt,name=offset" json:"offset,omitempty"`
CbOriginal *uint32 `protobuf:"varint,4,opt,name=cb_original" json:"cb_original,omitempty"`
CbCompressed *uint32 `protobuf:"varint,5,opt,name=cb_compressed" json:"cb_compressed,omitempty"`
XXX_unrecognized []byte `json:"-"`
Sha []byte `protobuf:"bytes,1,opt,name=sha" json:"sha,omitempty"`
Crc *uint32 `protobuf:"fixed32,2,opt,name=crc" json:"crc,omitempty"`
Offset *uint64 `protobuf:"varint,3,opt,name=offset" json:"offset,omitempty"`
CbOriginal *uint32 `protobuf:"varint,4,opt,name=cb_original" json:"cb_original,omitempty"`
CbCompressed *uint32 `protobuf:"varint,5,opt,name=cb_compressed" json:"cb_compressed,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ContentManifestPayload_FileMapping_ChunkData) Reset() {
@ -114,9 +165,27 @@ func (m *ContentManifestPayload_FileMapping_ChunkData) String() string {
}
func (*ContentManifestPayload_FileMapping_ChunkData) ProtoMessage() {}
func (*ContentManifestPayload_FileMapping_ChunkData) Descriptor() ([]byte, []int) {
return content_manifest_fileDescriptor0, []int{0, 0, 0}
return fileDescriptor_e3cda137a29253ba, []int{0, 0, 0}
}
func (m *ContentManifestPayload_FileMapping_ChunkData) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ContentManifestPayload_FileMapping_ChunkData.Unmarshal(m, b)
}
func (m *ContentManifestPayload_FileMapping_ChunkData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ContentManifestPayload_FileMapping_ChunkData.Marshal(b, m, deterministic)
}
func (m *ContentManifestPayload_FileMapping_ChunkData) XXX_Merge(src proto.Message) {
xxx_messageInfo_ContentManifestPayload_FileMapping_ChunkData.Merge(m, src)
}
func (m *ContentManifestPayload_FileMapping_ChunkData) XXX_Size() int {
return xxx_messageInfo_ContentManifestPayload_FileMapping_ChunkData.Size(m)
}
func (m *ContentManifestPayload_FileMapping_ChunkData) XXX_DiscardUnknown() {
xxx_messageInfo_ContentManifestPayload_FileMapping_ChunkData.DiscardUnknown(m)
}
var xxx_messageInfo_ContentManifestPayload_FileMapping_ChunkData proto.InternalMessageInfo
func (m *ContentManifestPayload_FileMapping_ChunkData) GetSha() []byte {
if m != nil {
return m.Sha
@ -153,22 +222,44 @@ func (m *ContentManifestPayload_FileMapping_ChunkData) GetCbCompressed() uint32
}
type ContentManifestMetadata struct {
DepotId *uint32 `protobuf:"varint,1,opt,name=depot_id" json:"depot_id,omitempty"`
GidManifest *uint64 `protobuf:"varint,2,opt,name=gid_manifest" json:"gid_manifest,omitempty"`
CreationTime *uint32 `protobuf:"varint,3,opt,name=creation_time" json:"creation_time,omitempty"`
FilenamesEncrypted *bool `protobuf:"varint,4,opt,name=filenames_encrypted" json:"filenames_encrypted,omitempty"`
CbDiskOriginal *uint64 `protobuf:"varint,5,opt,name=cb_disk_original" json:"cb_disk_original,omitempty"`
CbDiskCompressed *uint64 `protobuf:"varint,6,opt,name=cb_disk_compressed" json:"cb_disk_compressed,omitempty"`
UniqueChunks *uint32 `protobuf:"varint,7,opt,name=unique_chunks" json:"unique_chunks,omitempty"`
CrcEncrypted *uint32 `protobuf:"varint,8,opt,name=crc_encrypted" json:"crc_encrypted,omitempty"`
CrcClear *uint32 `protobuf:"varint,9,opt,name=crc_clear" json:"crc_clear,omitempty"`
XXX_unrecognized []byte `json:"-"`
DepotId *uint32 `protobuf:"varint,1,opt,name=depot_id" json:"depot_id,omitempty"`
GidManifest *uint64 `protobuf:"varint,2,opt,name=gid_manifest" json:"gid_manifest,omitempty"`
CreationTime *uint32 `protobuf:"varint,3,opt,name=creation_time" json:"creation_time,omitempty"`
FilenamesEncrypted *bool `protobuf:"varint,4,opt,name=filenames_encrypted" json:"filenames_encrypted,omitempty"`
CbDiskOriginal *uint64 `protobuf:"varint,5,opt,name=cb_disk_original" json:"cb_disk_original,omitempty"`
CbDiskCompressed *uint64 `protobuf:"varint,6,opt,name=cb_disk_compressed" json:"cb_disk_compressed,omitempty"`
UniqueChunks *uint32 `protobuf:"varint,7,opt,name=unique_chunks" json:"unique_chunks,omitempty"`
CrcEncrypted *uint32 `protobuf:"varint,8,opt,name=crc_encrypted" json:"crc_encrypted,omitempty"`
CrcClear *uint32 `protobuf:"varint,9,opt,name=crc_clear" json:"crc_clear,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ContentManifestMetadata) Reset() { *m = ContentManifestMetadata{} }
func (m *ContentManifestMetadata) String() string { return proto.CompactTextString(m) }
func (*ContentManifestMetadata) ProtoMessage() {}
func (*ContentManifestMetadata) Descriptor() ([]byte, []int) { return content_manifest_fileDescriptor0, []int{1} }
func (m *ContentManifestMetadata) Reset() { *m = ContentManifestMetadata{} }
func (m *ContentManifestMetadata) String() string { return proto.CompactTextString(m) }
func (*ContentManifestMetadata) ProtoMessage() {}
func (*ContentManifestMetadata) Descriptor() ([]byte, []int) {
return fileDescriptor_e3cda137a29253ba, []int{1}
}
func (m *ContentManifestMetadata) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ContentManifestMetadata.Unmarshal(m, b)
}
func (m *ContentManifestMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ContentManifestMetadata.Marshal(b, m, deterministic)
}
func (m *ContentManifestMetadata) XXX_Merge(src proto.Message) {
xxx_messageInfo_ContentManifestMetadata.Merge(m, src)
}
func (m *ContentManifestMetadata) XXX_Size() int {
return xxx_messageInfo_ContentManifestMetadata.Size(m)
}
func (m *ContentManifestMetadata) XXX_DiscardUnknown() {
xxx_messageInfo_ContentManifestMetadata.DiscardUnknown(m)
}
var xxx_messageInfo_ContentManifestMetadata proto.InternalMessageInfo
func (m *ContentManifestMetadata) GetDepotId() uint32 {
if m != nil && m.DepotId != nil {
@ -234,14 +325,36 @@ func (m *ContentManifestMetadata) GetCrcClear() uint32 {
}
type ContentManifestSignature struct {
Signature []byte `protobuf:"bytes,1,opt,name=signature" json:"signature,omitempty"`
XXX_unrecognized []byte `json:"-"`
Signature []byte `protobuf:"bytes,1,opt,name=signature" json:"signature,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ContentManifestSignature) Reset() { *m = ContentManifestSignature{} }
func (m *ContentManifestSignature) String() string { return proto.CompactTextString(m) }
func (*ContentManifestSignature) ProtoMessage() {}
func (*ContentManifestSignature) Descriptor() ([]byte, []int) { return content_manifest_fileDescriptor0, []int{2} }
func (m *ContentManifestSignature) Reset() { *m = ContentManifestSignature{} }
func (m *ContentManifestSignature) String() string { return proto.CompactTextString(m) }
func (*ContentManifestSignature) ProtoMessage() {}
func (*ContentManifestSignature) Descriptor() ([]byte, []int) {
return fileDescriptor_e3cda137a29253ba, []int{2}
}
func (m *ContentManifestSignature) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ContentManifestSignature.Unmarshal(m, b)
}
func (m *ContentManifestSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ContentManifestSignature.Marshal(b, m, deterministic)
}
func (m *ContentManifestSignature) XXX_Merge(src proto.Message) {
xxx_messageInfo_ContentManifestSignature.Merge(m, src)
}
func (m *ContentManifestSignature) XXX_Size() int {
return xxx_messageInfo_ContentManifestSignature.Size(m)
}
func (m *ContentManifestSignature) XXX_DiscardUnknown() {
xxx_messageInfo_ContentManifestSignature.DiscardUnknown(m)
}
var xxx_messageInfo_ContentManifestSignature proto.InternalMessageInfo
func (m *ContentManifestSignature) GetSignature() []byte {
if m != nil {
@ -250,40 +363,184 @@ func (m *ContentManifestSignature) GetSignature() []byte {
return nil
}
type ContentDeltaChunks struct {
DepotId *uint32 `protobuf:"varint,1,opt,name=depot_id" json:"depot_id,omitempty"`
ManifestIdSource *uint64 `protobuf:"varint,2,opt,name=manifest_id_source" json:"manifest_id_source,omitempty"`
ManifestIdTarget *uint64 `protobuf:"varint,3,opt,name=manifest_id_target" json:"manifest_id_target,omitempty"`
DeltaChunks []*ContentDeltaChunks_DeltaChunk `protobuf:"bytes,4,rep,name=deltaChunks" json:"deltaChunks,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ContentDeltaChunks) Reset() { *m = ContentDeltaChunks{} }
func (m *ContentDeltaChunks) String() string { return proto.CompactTextString(m) }
func (*ContentDeltaChunks) ProtoMessage() {}
func (*ContentDeltaChunks) Descriptor() ([]byte, []int) {
return fileDescriptor_e3cda137a29253ba, []int{3}
}
func (m *ContentDeltaChunks) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ContentDeltaChunks.Unmarshal(m, b)
}
func (m *ContentDeltaChunks) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ContentDeltaChunks.Marshal(b, m, deterministic)
}
func (m *ContentDeltaChunks) XXX_Merge(src proto.Message) {
xxx_messageInfo_ContentDeltaChunks.Merge(m, src)
}
func (m *ContentDeltaChunks) XXX_Size() int {
return xxx_messageInfo_ContentDeltaChunks.Size(m)
}
func (m *ContentDeltaChunks) XXX_DiscardUnknown() {
xxx_messageInfo_ContentDeltaChunks.DiscardUnknown(m)
}
var xxx_messageInfo_ContentDeltaChunks proto.InternalMessageInfo
func (m *ContentDeltaChunks) GetDepotId() uint32 {
if m != nil && m.DepotId != nil {
return *m.DepotId
}
return 0
}
func (m *ContentDeltaChunks) GetManifestIdSource() uint64 {
if m != nil && m.ManifestIdSource != nil {
return *m.ManifestIdSource
}
return 0
}
func (m *ContentDeltaChunks) GetManifestIdTarget() uint64 {
if m != nil && m.ManifestIdTarget != nil {
return *m.ManifestIdTarget
}
return 0
}
func (m *ContentDeltaChunks) GetDeltaChunks() []*ContentDeltaChunks_DeltaChunk {
if m != nil {
return m.DeltaChunks
}
return nil
}
type ContentDeltaChunks_DeltaChunk struct {
ShaSource []byte `protobuf:"bytes,1,opt,name=sha_source" json:"sha_source,omitempty"`
ShaTarget []byte `protobuf:"bytes,2,opt,name=sha_target" json:"sha_target,omitempty"`
SizeOriginal *uint32 `protobuf:"varint,3,opt,name=size_original" json:"size_original,omitempty"`
PatchMethod *uint32 `protobuf:"varint,4,opt,name=patch_method" json:"patch_method,omitempty"`
Chunk []byte `protobuf:"bytes,5,opt,name=chunk" json:"chunk,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ContentDeltaChunks_DeltaChunk) Reset() { *m = ContentDeltaChunks_DeltaChunk{} }
func (m *ContentDeltaChunks_DeltaChunk) String() string { return proto.CompactTextString(m) }
func (*ContentDeltaChunks_DeltaChunk) ProtoMessage() {}
func (*ContentDeltaChunks_DeltaChunk) Descriptor() ([]byte, []int) {
return fileDescriptor_e3cda137a29253ba, []int{3, 0}
}
func (m *ContentDeltaChunks_DeltaChunk) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ContentDeltaChunks_DeltaChunk.Unmarshal(m, b)
}
func (m *ContentDeltaChunks_DeltaChunk) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ContentDeltaChunks_DeltaChunk.Marshal(b, m, deterministic)
}
func (m *ContentDeltaChunks_DeltaChunk) XXX_Merge(src proto.Message) {
xxx_messageInfo_ContentDeltaChunks_DeltaChunk.Merge(m, src)
}
func (m *ContentDeltaChunks_DeltaChunk) XXX_Size() int {
return xxx_messageInfo_ContentDeltaChunks_DeltaChunk.Size(m)
}
func (m *ContentDeltaChunks_DeltaChunk) XXX_DiscardUnknown() {
xxx_messageInfo_ContentDeltaChunks_DeltaChunk.DiscardUnknown(m)
}
var xxx_messageInfo_ContentDeltaChunks_DeltaChunk proto.InternalMessageInfo
func (m *ContentDeltaChunks_DeltaChunk) GetShaSource() []byte {
if m != nil {
return m.ShaSource
}
return nil
}
func (m *ContentDeltaChunks_DeltaChunk) GetShaTarget() []byte {
if m != nil {
return m.ShaTarget
}
return nil
}
func (m *ContentDeltaChunks_DeltaChunk) GetSizeOriginal() uint32 {
if m != nil && m.SizeOriginal != nil {
return *m.SizeOriginal
}
return 0
}
func (m *ContentDeltaChunks_DeltaChunk) GetPatchMethod() uint32 {
if m != nil && m.PatchMethod != nil {
return *m.PatchMethod
}
return 0
}
func (m *ContentDeltaChunks_DeltaChunk) GetChunk() []byte {
if m != nil {
return m.Chunk
}
return nil
}
func init() {
proto.RegisterType((*ContentManifestPayload)(nil), "ContentManifestPayload")
proto.RegisterType((*ContentManifestPayload_FileMapping)(nil), "ContentManifestPayload.FileMapping")
proto.RegisterType((*ContentManifestPayload_FileMapping_ChunkData)(nil), "ContentManifestPayload.FileMapping.ChunkData")
proto.RegisterType((*ContentManifestMetadata)(nil), "ContentManifestMetadata")
proto.RegisterType((*ContentManifestSignature)(nil), "ContentManifestSignature")
proto.RegisterType((*ContentDeltaChunks)(nil), "ContentDeltaChunks")
proto.RegisterType((*ContentDeltaChunks_DeltaChunk)(nil), "ContentDeltaChunks.DeltaChunk")
}
var content_manifest_fileDescriptor0 = []byte{
// 409 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x91, 0xbd, 0x8e, 0xd4, 0x30,
0x14, 0x85, 0xc9, 0xfc, 0x26, 0x37, 0x09, 0x5a, 0xbc, 0xb0, 0x58, 0x43, 0x83, 0x96, 0x66, 0x9b,
0x4d, 0x81, 0x44, 0x49, 0xc3, 0x22, 0x44, 0x33, 0x12, 0x12, 0x0f, 0x10, 0x5d, 0x1c, 0x27, 0x6b,
0x4d, 0x62, 0x07, 0xdb, 0x29, 0x96, 0x8a, 0x17, 0xe1, 0x0d, 0x91, 0x78, 0x05, 0x6c, 0x27, 0x99,
0x1d, 0x8d, 0x28, 0x28, 0xcf, 0xf1, 0xb5, 0xcf, 0x77, 0x8f, 0xe1, 0x8a, 0x29, 0x69, 0xb9, 0xb4,
0x65, 0x87, 0x52, 0xd4, 0xdc, 0xd8, 0xa2, 0xd7, 0xca, 0xaa, 0xeb, 0x3f, 0x0b, 0xb8, 0xba, 0x1b,
0x8f, 0xf6, 0xd3, 0xc9, 0x17, 0x7c, 0x68, 0x15, 0x56, 0xe4, 0x1d, 0xc4, 0x1d, 0xf6, 0xbd, 0x90,
0x8d, 0xa1, 0xd1, 0xeb, 0xe5, 0x4d, 0xfa, 0xf6, 0x4d, 0xf1, 0xef, 0xd1, 0xe2, 0x93, 0x68, 0xf9,
0x7e, 0x9c, 0xdd, 0xfd, 0x5a, 0x40, 0x7a, 0xa2, 0xc9, 0x05, 0xc4, 0xb5, 0x93, 0x12, 0x3b, 0xee,
0x9e, 0x89, 0x6e, 0x12, 0x92, 0xc1, 0xca, 0x88, 0x1f, 0x9c, 0x2e, 0x9c, 0x5a, 0x91, 0x1c, 0xd6,
0x75, 0x8b, 0x2e, 0x63, 0xe9, 0x64, 0x4e, 0x9e, 0x43, 0x66, 0xee, 0xb1, 0x3c, 0x5e, 0x59, 0x39,
0x37, 0x23, 0x97, 0x90, 0x7a, 0x77, 0x5a, 0x82, 0xae, 0x83, 0xf9, 0x1e, 0x36, 0xec, 0x7e, 0x90,
0x07, 0x43, 0x37, 0x01, 0xef, 0xf6, 0x3f, 0xf0, 0x8a, 0x3b, 0x7f, 0xe3, 0x23, 0x5a, 0x24, 0x04,
0xa0, 0x15, 0xf2, 0x60, 0x51, 0x37, 0xdc, 0xd2, 0xad, 0x47, 0xdb, 0x21, 0x24, 0x8f, 0x03, 0x29,
0x2c, 0x5d, 0x68, 0x80, 0xce, 0xbc, 0x60, 0x9a, 0x05, 0xe6, 0x2d, 0x79, 0x0a, 0x1b, 0x55, 0xd7,
0xc6, 0x5d, 0x5b, 0x86, 0x1d, 0x1c, 0x1e, 0xfb, 0x56, 0x2a, 0x2d, 0x1a, 0x21, 0xb1, 0x0d, 0xcc,
0x39, 0x79, 0x01, 0xb9, 0x33, 0x99, 0xea, 0x7a, 0xcd, 0x8d, 0xe1, 0x55, 0xa0, 0xce, 0xaf, 0x7f,
0x47, 0xf0, 0xf2, 0x8c, 0x73, 0xcf, 0x2d, 0x56, 0x3e, 0xd1, 0x75, 0x55, 0xf1, 0x5e, 0xd9, 0x52,
0x54, 0x21, 0x36, 0xd4, 0xd1, 0x88, 0xea, 0xf8, 0x6b, 0x53, 0x67, 0xfe, 0x69, 0xcd, 0xd1, 0x0a,
0x25, 0x4b, 0x2b, 0x5c, 0x4b, 0x63, 0x77, 0xaf, 0xe0, 0x72, 0xee, 0xcd, 0x94, 0x5c, 0x32, 0xfd,
0xd0, 0x5b, 0x97, 0xeb, 0x71, 0x62, 0x42, 0xe1, 0xc2, 0xe1, 0x54, 0xc2, 0x1c, 0x1e, 0x41, 0xd7,
0xe1, 0xb5, 0x1d, 0x90, 0xf9, 0xe4, 0x84, 0x76, 0x33, 0x27, 0x0d, 0x52, 0x7c, 0x1f, 0x78, 0x39,
0x55, 0xbd, 0x3d, 0xee, 0xa6, 0xd9, 0x49, 0x46, 0x1c, 0xec, 0x67, 0x90, 0x78, 0x9b, 0xb5, 0x1c,
0x35, 0x4d, 0xc2, 0xba, 0xb7, 0x40, 0xcf, 0xb6, 0xfd, 0x2a, 0x1a, 0x89, 0x76, 0xd0, 0xdc, 0x8f,
0x9b, 0x59, 0x8c, 0x35, 0x7f, 0x58, 0x7f, 0x8e, 0x7e, 0x46, 0x4f, 0xfe, 0x06, 0x00, 0x00, 0xff,
0xff, 0xc6, 0x87, 0xdb, 0xe6, 0xaf, 0x02, 0x00, 0x00,
func init() { proto.RegisterFile("content_manifest.proto", fileDescriptor_e3cda137a29253ba) }
var fileDescriptor_e3cda137a29253ba = []byte{
// 508 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcd, 0x8e, 0xd3, 0x30,
0x10, 0xc7, 0x49, 0xbf, 0x3b, 0x6d, 0x50, 0xf1, 0xb2, 0x8b, 0x55, 0x24, 0x54, 0x95, 0x4b, 0x2f,
0x9b, 0x03, 0x88, 0x23, 0x17, 0x76, 0x85, 0xb8, 0x54, 0x42, 0xe2, 0x01, 0x2c, 0xd7, 0x76, 0x53,
0xab, 0x89, 0x1d, 0x6c, 0xe7, 0xb0, 0x9c, 0xb8, 0xf0, 0x18, 0xbc, 0x21, 0x12, 0xaf, 0x80, 0xec,
0x38, 0x4d, 0x55, 0xf6, 0xb0, 0xb7, 0xcc, 0x47, 0x3c, 0xbf, 0xf9, 0xcf, 0x1f, 0x6e, 0x98, 0x56,
0x4e, 0x28, 0x47, 0x4a, 0xaa, 0xe4, 0x5e, 0x58, 0x97, 0x55, 0x46, 0x3b, 0xbd, 0xfe, 0xdb, 0x83,
0x9b, 0xbb, 0xa6, 0xb4, 0x8d, 0x95, 0xaf, 0xf4, 0xa1, 0xd0, 0x94, 0xa3, 0x0f, 0x30, 0x29, 0x69,
0x55, 0x49, 0x95, 0x5b, 0x9c, 0xac, 0xfa, 0x9b, 0xd9, 0xbb, 0xb7, 0xd9, 0xe3, 0xad, 0xd9, 0x67,
0x59, 0x88, 0x6d, 0xd3, 0xbb, 0xfc, 0xdd, 0x83, 0xd9, 0x59, 0x8c, 0x16, 0x30, 0xd9, 0xcb, 0x42,
0x28, 0x5a, 0x0a, 0x9c, 0xac, 0x92, 0xcd, 0x14, 0xcd, 0x61, 0x60, 0xe5, 0x0f, 0x81, 0x7b, 0xab,
0x64, 0x33, 0x40, 0x29, 0x0c, 0xf7, 0x05, 0xcd, 0x2d, 0xee, 0xaf, 0x92, 0x4d, 0x8a, 0x5e, 0xc2,
0xdc, 0x1e, 0x28, 0x39, 0xfd, 0x32, 0x58, 0x25, 0x9b, 0x39, 0xba, 0x82, 0x99, 0xcf, 0xc6, 0x25,
0xf0, 0x30, 0x24, 0x3f, 0xc2, 0x88, 0x1d, 0x6a, 0x75, 0xb4, 0x78, 0x14, 0xf0, 0x6e, 0x9f, 0x80,
0x97, 0xdd, 0xf9, 0x3f, 0xee, 0xa9, 0xa3, 0x08, 0x01, 0x14, 0x52, 0x1d, 0x1d, 0x35, 0xb9, 0x70,
0x78, 0xec, 0xd1, 0x96, 0x14, 0xa6, 0x5d, 0xc3, 0x0c, 0xfa, 0xf6, 0x40, 0x03, 0xf4, 0xdc, 0x07,
0xcc, 0xb0, 0xc0, 0x3c, 0x46, 0xcf, 0x61, 0xa4, 0xf7, 0x7b, 0x2b, 0x5c, 0x80, 0x1e, 0x78, 0x3c,
0xb6, 0x23, 0xda, 0xc8, 0x5c, 0x2a, 0x5a, 0x04, 0xe6, 0x14, 0x5d, 0x43, 0xca, 0x76, 0x84, 0xe9,
0xb2, 0x32, 0xc2, 0x5a, 0xc1, 0x03, 0x75, 0xba, 0xfe, 0x93, 0xc0, 0xab, 0x0b, 0xce, 0xad, 0x70,
0x94, 0xfb, 0x89, 0x0b, 0x98, 0x70, 0x51, 0x69, 0x47, 0x24, 0x0f, 0x63, 0x83, 0x1c, 0xb9, 0xe4,
0xa7, 0xab, 0x45, 0xcd, 0xfc, 0xd3, 0x46, 0x50, 0x27, 0xb5, 0x22, 0x4e, 0x96, 0x22, 0x6a, 0xf7,
0x1a, 0xae, 0x5a, 0xdd, 0x2c, 0x11, 0x8a, 0x99, 0x87, 0xca, 0x09, 0x1e, 0x70, 0x26, 0x08, 0xc3,
0x82, 0xed, 0x08, 0x97, 0xf6, 0xd8, 0x81, 0x0e, 0xc3, 0x6b, 0x4b, 0x40, 0x6d, 0xe5, 0x8c, 0x76,
0xd4, 0x4e, 0xaa, 0x95, 0xfc, 0x5e, 0x0b, 0x12, 0xa5, 0x1e, 0x9f, 0x76, 0x33, 0xec, 0x6c, 0xc6,
0x24, 0xa4, 0x5f, 0xc0, 0xd4, 0xa7, 0x59, 0x21, 0xa8, 0xc1, 0xd3, 0xb0, 0xee, 0x2d, 0xe0, 0x8b,
0x6d, 0xbf, 0xc9, 0x5c, 0x51, 0x57, 0x1b, 0xe1, 0xdb, 0x6d, 0x1b, 0x34, 0x32, 0xaf, 0x7f, 0xf5,
0x00, 0xc5, 0xfe, 0x7b, 0x51, 0x38, 0x1a, 0xae, 0x61, 0x1f, 0x11, 0x66, 0x09, 0xa8, 0x15, 0x85,
0x48, 0x4e, 0xac, 0xae, 0x0d, 0x6b, 0x2d, 0x75, 0x51, 0x8b, 0x17, 0x6e, 0x4e, 0xf5, 0x1e, 0x66,
0xbc, 0x7b, 0x18, 0x0f, 0x82, 0x73, 0xde, 0x64, 0xff, 0xcf, 0xcc, 0xba, 0xef, 0x65, 0x05, 0xd0,
0x45, 0xde, 0x38, 0xde, 0x8c, 0x71, 0x64, 0x63, 0x8f, 0x98, 0x8b, 0xa3, 0x7a, 0x21, 0x77, 0x0d,
0xa9, 0xf7, 0x79, 0x27, 0xf7, 0xc9, 0xe1, 0x15, 0x75, 0xec, 0x40, 0x4a, 0xe1, 0x0e, 0x9a, 0x47,
0xb7, 0xa4, 0x30, 0x0c, 0x0a, 0x37, 0xde, 0xfe, 0x34, 0xfc, 0x92, 0xfc, 0x4c, 0x9e, 0xfd, 0x0b,
0x00, 0x00, 0xff, 0xff, 0x00, 0x92, 0x22, 0xd7, 0xb7, 0x03, 0x00, 0x00,
}

File diff suppressed because it is too large Load Diff

View File

@ -723,7 +723,7 @@ func (d *MsgClientNewLoginKeyAccepted) Deserialize(r io.Reader) error {
const (
MsgClientLogon_ObfuscationMask uint32 = 0xBAADF00D
MsgClientLogon_CurrentProtocol uint32 = 65579
MsgClientLogon_CurrentProtocol uint32 = 65580
MsgClientLogon_ProtocolVerMajorMask uint32 = 0xFFFF0000
MsgClientLogon_ProtocolVerMinorMask uint32 = 0xFFFF
MsgClientLogon_ProtocolVerMinorMinGameServers uint16 = 4
@ -744,7 +744,11 @@ const (
MsgClientLogon_ProtocolVerMinorMinForMachineAuth uint16 = 33
MsgClientLogon_ProtocolVerMinorMinForSessionIDLastAnon uint16 = 36
MsgClientLogon_ProtocolVerMinorMinForEnhancedAppList uint16 = 40
MsgClientLogon_ProtocolVerMinorMinForSteamGuardNotificationUI uint16 = 41
MsgClientLogon_ProtocolVerMinorMinForProtoBufServiceModuleCalls uint16 = 42
MsgClientLogon_ProtocolVerMinorMinForGzipMultiMessages uint16 = 43
MsgClientLogon_ProtocolVerMinorMinForNewVoiceCallAuthorize uint16 = 44
MsgClientLogon_ProtocolVerMinorMinForClientInstanceIDs uint16 = 44
)
type MsgClientLogon struct {
@ -1976,64 +1980,6 @@ func (d *MsgClientChatRoomInfo) Deserialize(r io.Reader) error {
return err
}
type MsgClientGetNumberOfCurrentPlayers struct {
GameID uint64
}
func NewMsgClientGetNumberOfCurrentPlayers() *MsgClientGetNumberOfCurrentPlayers {
return &MsgClientGetNumberOfCurrentPlayers{}
}
func (d *MsgClientGetNumberOfCurrentPlayers) GetEMsg() EMsg {
return EMsg_ClientGetNumberOfCurrentPlayers
}
func (d *MsgClientGetNumberOfCurrentPlayers) Serialize(w io.Writer) error {
var err error
err = binary.Write(w, binary.LittleEndian, d.GameID)
return err
}
func (d *MsgClientGetNumberOfCurrentPlayers) Deserialize(r io.Reader) error {
var err error
d.GameID, err = rwu.ReadUint64(r)
return err
}
type MsgClientGetNumberOfCurrentPlayersResponse struct {
Result EResult
NumPlayers uint32
}
func NewMsgClientGetNumberOfCurrentPlayersResponse() *MsgClientGetNumberOfCurrentPlayersResponse {
return &MsgClientGetNumberOfCurrentPlayersResponse{}
}
func (d *MsgClientGetNumberOfCurrentPlayersResponse) GetEMsg() EMsg {
return EMsg_ClientGetNumberOfCurrentPlayersResponse
}
func (d *MsgClientGetNumberOfCurrentPlayersResponse) Serialize(w io.Writer) error {
var err error
err = binary.Write(w, binary.LittleEndian, d.Result)
if err != nil {
return err
}
err = binary.Write(w, binary.LittleEndian, d.NumPlayers)
return err
}
func (d *MsgClientGetNumberOfCurrentPlayersResponse) Deserialize(r io.Reader) error {
var err error
t0, err := rwu.ReadInt32(r)
if err != nil {
return err
}
d.Result = EResult(t0)
d.NumPlayers, err = rwu.ReadUint32(r)
return err
}
type MsgClientSetIgnoreFriend struct {
MySteamId steamid.SteamId
SteamIdFriend steamid.SteamId
@ -2079,8 +2025,8 @@ func (d *MsgClientSetIgnoreFriend) Deserialize(r io.Reader) error {
}
type MsgClientSetIgnoreFriendResponse struct {
Unknown uint64
Result EResult
FriendId steamid.SteamId
Result EResult
}
func NewMsgClientSetIgnoreFriendResponse() *MsgClientSetIgnoreFriendResponse {
@ -2093,7 +2039,7 @@ func (d *MsgClientSetIgnoreFriendResponse) GetEMsg() EMsg {
func (d *MsgClientSetIgnoreFriendResponse) Serialize(w io.Writer) error {
var err error
err = binary.Write(w, binary.LittleEndian, d.Unknown)
err = binary.Write(w, binary.LittleEndian, d.FriendId)
if err != nil {
return err
}
@ -2103,12 +2049,13 @@ func (d *MsgClientSetIgnoreFriendResponse) Serialize(w io.Writer) error {
func (d *MsgClientSetIgnoreFriendResponse) Deserialize(r io.Reader) error {
var err error
d.Unknown, err = rwu.ReadUint64(r)
t0, err := rwu.ReadUint64(r)
if err != nil {
return err
}
t0, err := rwu.ReadInt32(r)
d.Result = EResult(t0)
d.FriendId = steamid.SteamId(t0)
t1, err := rwu.ReadInt32(r)
d.Result = EResult(t1)
return err
}
@ -2226,73 +2173,6 @@ func (d *MsgClientLogOnResponse) Deserialize(r io.Reader) error {
return err
}
type MsgClientSendGuestPass struct {
GiftId uint64
GiftType uint8
AccountId uint32
}
func NewMsgClientSendGuestPass() *MsgClientSendGuestPass {
return &MsgClientSendGuestPass{}
}
func (d *MsgClientSendGuestPass) GetEMsg() EMsg {
return EMsg_ClientSendGuestPass
}
func (d *MsgClientSendGuestPass) Serialize(w io.Writer) error {
var err error
err = binary.Write(w, binary.LittleEndian, d.GiftId)
if err != nil {
return err
}
err = binary.Write(w, binary.LittleEndian, d.GiftType)
if err != nil {
return err
}
err = binary.Write(w, binary.LittleEndian, d.AccountId)
return err
}
func (d *MsgClientSendGuestPass) Deserialize(r io.Reader) error {
var err error
d.GiftId, err = rwu.ReadUint64(r)
if err != nil {
return err
}
d.GiftType, err = rwu.ReadUint8(r)
if err != nil {
return err
}
d.AccountId, err = rwu.ReadUint32(r)
return err
}
type MsgClientSendGuestPassResponse struct {
Result EResult
}
func NewMsgClientSendGuestPassResponse() *MsgClientSendGuestPassResponse {
return &MsgClientSendGuestPassResponse{}
}
func (d *MsgClientSendGuestPassResponse) GetEMsg() EMsg {
return EMsg_ClientSendGuestPassResponse
}
func (d *MsgClientSendGuestPassResponse) Serialize(w io.Writer) error {
var err error
err = binary.Write(w, binary.LittleEndian, d.Result)
return err
}
func (d *MsgClientSendGuestPassResponse) Deserialize(r io.Reader) error {
var err error
t0, err := rwu.ReadInt32(r)
d.Result = EResult(t0)
return err
}
type MsgClientServerUnavailable struct {
JobidSent uint64
EMsgSent uint32

View File

@ -8,135 +8,116 @@ import (
)
// CMServers contains a list of worlwide servers
var CMServers = [][]string{
{ // North American Servers
// Chicago
"162.254.193.44:27018",
"162.254.193.44:27019",
"162.254.193.44:27020",
"162.254.193.44:27021",
"162.254.193.45:27017",
"162.254.193.45:27018",
"162.254.193.45:27019",
"162.254.193.45:27021",
"162.254.193.46:27017",
"162.254.193.46:27018",
"162.254.193.46:27019",
"162.254.193.46:27020",
"162.254.193.46:27021",
"162.254.193.47:27019",
"162.254.193.47:27020",
// Ashburn
"208.78.164.9:27017",
"208.78.164.9:27018",
"208.78.164.9:27019",
"208.78.164.10:27017",
"208.78.164.10:27018",
"208.78.164.10:27019",
"208.78.164.11:27017",
"208.78.164.11:27018",
"208.78.164.11:27019",
"208.78.164.12:27017",
"208.78.164.12:27018",
"208.78.164.12:27019",
"208.78.164.13:27017",
"208.78.164.13:27018",
"208.78.164.13:27019",
"208.78.164.14:27017",
"208.78.164.14:27018",
"208.78.164.14:27019",
},
{ // Europe Servers
// Luxembourg
"146.66.152.10:27017",
"146.66.152.10:27018",
"146.66.152.10:27019",
"146.66.152.10:27020",
"146.66.152.11:27017",
"146.66.152.11:27018",
"146.66.152.11:27019",
"146.66.152.11:27020",
// Poland
"155.133.242.8:27017",
"155.133.242.8:27018",
"155.133.242.8:27019",
"155.133.242.8:27020",
"155.133.242.9:27017",
"155.133.242.9:27018",
"155.133.242.9:27019",
"155.133.242.9:27020",
// Vienna
"146.66.155.8:27017",
"146.66.155.8:27018",
"146.66.155.8:27019",
"146.66.155.8:27020",
"185.25.182.10:27017",
"185.25.182.10:27018",
"185.25.182.10:27019",
"185.25.182.10:27020",
// London
"162.254.196.40:27017",
"162.254.196.40:27018",
"162.254.196.40:27019",
"162.254.196.40:27020",
"162.254.196.40:27021",
"162.254.196.41:27017",
"162.254.196.41:27018",
"162.254.196.41:27019",
"162.254.196.41:27020",
"162.254.196.41:27021",
"162.254.196.42:27017",
"162.254.196.42:27018",
"162.254.196.42:27019",
"162.254.196.42:27020",
"162.254.196.42:27021",
"162.254.196.43:27017",
"162.254.196.43:27018",
"162.254.196.43:27019",
"162.254.196.43:27020",
"162.254.196.43:27021",
// Stockholm
"185.25.180.14:27017",
"185.25.180.14:27018",
"185.25.180.14:27019",
"185.25.180.14:27020",
"185.25.180.15:27017",
"185.25.180.15:27018",
"185.25.180.15:27019",
"185.25.180.15:27020",
},
var CMServers = []string{
"155.133.248.52:27018",
"162.254.197.40:27018",
"162.254.197.180:27019",
"155.133.248.50:27019",
"162.254.197.181:27017",
"162.254.197.42:27019",
"162.254.197.180:27017",
"162.254.197.181:27018",
"162.254.197.42:27018",
"155.133.248.50:27017",
"155.133.248.52:27019",
"155.133.248.51:27019",
"155.133.248.53:27019",
"155.133.248.51:27017",
"155.133.248.53:27017",
"155.133.248.52:27017",
"155.133.248.50:27018",
"162.254.197.180:27018",
"162.254.197.40:27017",
"162.254.197.40:27019",
"162.254.197.42:27017",
"162.254.197.181:27019",
"155.133.248.53:27018",
"155.133.248.51:27018",
"146.66.152.11:27017",
"146.66.152.10:27019",
"146.66.152.10:27017",
"146.66.152.10:27018",
"146.66.152.11:27019",
"162.254.198.133:27017",
"162.254.198.133:27018",
"162.254.198.130:27019",
"162.254.198.130:27017",
"162.254.198.132:27018",
"162.254.198.130:27018",
"162.254.198.132:27017",
"162.254.198.132:27019",
"162.254.198.131:27019",
"162.254.198.131:27017",
"146.66.152.11:27018",
"162.254.198.131:27018",
"162.254.198.133:27019",
"185.25.182.77:27017",
"185.25.182.76:27018",
"185.25.182.76:27019",
"185.25.182.77:27018",
"185.25.182.76:27017",
"185.25.182.77:27019",
"162.254.196.67:27019",
"162.254.196.67:27018",
"162.254.196.83:27018",
"162.254.196.84:27018",
"162.254.196.83:27017",
"162.254.196.84:27017",
"162.254.196.68:27019",
"162.254.196.68:27017",
"162.254.196.84:27019",
"162.254.196.67:27017",
"162.254.196.83:27019",
"162.254.196.68:27018",
"146.66.155.101:27017",
"146.66.155.101:27018",
"146.66.155.100:27017",
"146.66.155.100:27018",
"146.66.155.101:27019",
"146.66.155.100:27019",
"155.133.230.50:27017",
"155.133.230.34:27018",
"155.133.230.34:27017",
"155.133.230.50:27019",
"155.133.230.34:27019",
"155.133.230.50:27018",
"162.254.192.100:27017",
"162.254.192.108:27017",
"155.133.246.68:27017",
"155.133.246.68:27018",
"155.133.246.68:27019",
"155.133.246.69:27019",
"155.133.246.69:27017",
"155.133.246.69:27018",
"162.254.192.108:27018",
"162.254.192.101:27018",
"162.254.192.101:27019",
"162.254.192.109:27018",
"162.254.192.100:27018",
"162.254.192.109:27017",
"162.254.192.109:27019",
"162.254.192.108:27019",
"162.254.192.101:27017",
"162.254.192.100:27019",
"162.254.193.46:27019",
"162.254.193.6:27018",
"162.254.193.47:27018",
"162.254.193.6:27019",
"162.254.193.7:27018",
"162.254.193.7:27017",
"162.254.193.7:27019",
"162.254.193.47:27017",
"162.254.193.47:27019",
"162.254.193.46:27018",
}
// GetRandomCM returns back a random server anywhere
// GetRandomCM returns a random server from a built-in IP list.
//
// Prefer Client.Connect(), which uses IPs from the Steam Directory,
// which is always more up-to-date.
func GetRandomCM() *netutil.PortAddr {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
servers := append(CMServers[0], CMServers[1]...)
addr := netutil.ParsePortAddr(servers[rng.Int31n(int32(len(servers)))])
if addr == nil {
panic("invalid address in CMServers slice")
}
return addr
}
// GetRandomNorthAmericaCM returns back a random server in north america
func GetRandomNorthAmericaCM() *netutil.PortAddr {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
addr := netutil.ParsePortAddr(CMServers[0][rng.Int31n(int32(len(CMServers[0])))])
if addr == nil {
panic("invalid address in CMServers slice")
}
return addr
}
// GetRandomEuropeCM returns back a random server in europe
func GetRandomEuropeCM() *netutil.PortAddr {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
addr := netutil.ParsePortAddr(CMServers[1][rng.Int31n(int32(len(CMServers[1])))])
addr := netutil.ParsePortAddr(CMServers[rng.Int31n(int32(len(CMServers)))])
if addr == nil {
panic("invalid address in CMServers slice")
}

View File

@ -3,7 +3,10 @@ package steam
import (
"bytes"
"encoding/binary"
"encoding/hex"
"io"
"sync"
"time"
. "github.com/Philipp15b/go-steam/protocol"
. "github.com/Philipp15b/go-steam/protocol/protobuf"
. "github.com/Philipp15b/go-steam/protocol/steamlang"
@ -11,9 +14,6 @@ import (
"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.
@ -21,7 +21,7 @@ type Social struct {
mutex sync.RWMutex
name string
avatar string
avatar []byte
personaState EPersonaState
Friends *socialcache.FriendsList
@ -41,7 +41,7 @@ func newSocial(client *Client) *Social {
}
// Gets the local user's avatar
func (s *Social) GetAvatar() string {
func (s *Social) GetAvatar() []byte {
s.mutex.RLock()
defer s.mutex.RUnlock()
return s.avatar
@ -156,7 +156,7 @@ func (s *Social) RequestProfileInfo(id SteamId) {
// Requests all offline messages and marks them as read
func (s *Social) RequestOfflineMessages() {
s.client.Write(NewClientMsgProtobuf(EMsg_ClientFSGetFriendMessageHistoryForOfflineMessages, &CMsgClientFSGetFriendMessageHistoryForOfflineMessages{}))
s.client.Write(NewClientMsgProtobuf(EMsg_ClientChatGetFriendMessageHistoryForOfflineMessages, &CMsgClientChatGetFriendMessageHistoryForOfflineMessages{}))
}
// Attempts to join a chat room
@ -307,7 +307,7 @@ func (s *Social) handlePersonaState(packet *Packet) {
if friend.GetPlayerName() != "" {
s.name = friend.GetPlayerName()
}
avatar := hex.EncodeToString(friend.GetAvatarHash())
avatar := friend.GetAvatarHash()
if ValidAvatar(avatar) {
s.avatar = avatar
}
@ -319,7 +319,7 @@ func (s *Social) handlePersonaState(packet *Packet) {
}
}
if (flags & EClientPersonaStateFlag_Presence) == EClientPersonaStateFlag_Presence {
avatar := hex.EncodeToString(friend.GetAvatarHash())
avatar := friend.GetAvatarHash()
if ValidAvatar(avatar) {
s.Friends.SetAvatar(id, avatar)
}
@ -338,7 +338,7 @@ func (s *Social) handlePersonaState(packet *Packet) {
}
}
if (flags & EClientPersonaStateFlag_Presence) == EClientPersonaStateFlag_Presence {
avatar := hex.EncodeToString(friend.GetAvatarHash())
avatar := friend.GetAvatarHash()
if ValidAvatar(avatar) {
s.Groups.SetAvatar(id, avatar)
}
@ -358,7 +358,7 @@ func (s *Social) handlePersonaState(packet *Packet) {
SourceSteamId: SteamId(friend.GetSteamidSource()),
GameDataBlob: friend.GetGameDataBlob(),
Name: friend.GetPlayerName(),
Avatar: hex.EncodeToString(friend.GetAvatarHash()),
Avatar: friend.GetAvatarHash(),
LastLogOff: friend.GetLastLogoff(),
LastLogOn: friend.GetLastLogon(),
ClanRank: friend.GetClanRank(),
@ -366,8 +366,6 @@ func (s *Social) handlePersonaState(packet *Packet) {
OnlineSessionInstances: friend.GetOnlineSessionInstances(),
PublishedSessionId: friend.GetPublishedInstanceId(),
PersonaSetByUser: friend.GetPersonaSetByUser(),
FacebookName: friend.GetFacebookName(),
FacebookId: friend.GetFacebookId(),
})
}
}
@ -376,10 +374,10 @@ func (s *Social) handleClanState(packet *Packet) {
body := new(CMsgClientClanState)
packet.ReadProtoMsg(body)
var name string
var avatar string
var avatar []byte
if body.GetNameInfo() != nil {
name = body.GetNameInfo().GetClanName()
avatar = hex.EncodeToString(body.GetNameInfo().GetShaAvatar())
avatar = body.GetNameInfo().GetShaAvatar()
}
var totalCount, onlineCount, chattingCount, ingameCount uint32
if body.GetUserCounts() != nil {
@ -408,18 +406,13 @@ func (s *Social) handleClanState(packet *Packet) {
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.NameInfo != nil {
info := body.NameInfo
s.Groups.SetName(clanid, info.GetClanName())
s.Groups.SetAvatar(clanid, info.GetShaAvatar())
}
if body.GetUserCounts() != nil {
s.Groups.SetMemberTotalCount(clanid, totalCount)
@ -428,8 +421,7 @@ func (s *Social) handleClanState(packet *Packet) {
s.Groups.SetMemberInGameCount(clanid, ingameCount)
}
s.client.Emit(&ClanStateEvent{
ClandId: clanid,
StateFlags: EClientPersonaStateFlag(body.GetMUnStatusFlags()),
ClanId: clanid,
AccountFlags: EAccountFlags(body.GetClanAccountFlags()),
ClanName: name,
Avatar: avatar,
@ -606,7 +598,7 @@ func (s *Social) handleProfileInfoResponse(packet *Packet) {
}
func (s *Social) handleFriendMessageHistoryResponse(packet *Packet) {
body := new(CMsgClientFSGetFriendMessageHistoryResponse)
body := new(CMsgClientChatGetFriendMessageHistoryResponse)
packet.ReadProtoMsg(body)
steamid := SteamId(body.GetSteamid())
for _, message := range body.GetMessages() {

View File

@ -1,9 +1,10 @@
package steam
import (
"time"
. "github.com/Philipp15b/go-steam/protocol/steamlang"
. "github.com/Philipp15b/go-steam/steamid"
"time"
)
type FriendsListEvent struct{}
@ -41,7 +42,7 @@ type PersonaStateEvent struct {
SourceSteamId SteamId `json:",string"`
GameDataBlob []byte
Name string
Avatar string
Avatar []byte
LastLogOff uint32
LastLogOn uint32
ClanRank uint32
@ -49,17 +50,14 @@ type PersonaStateEvent struct {
OnlineSessionInstances uint32
PublishedSessionId uint32
PersonaSetByUser bool
FacebookName string
FacebookId uint64 `json:",string"`
}
// Fired when a clan's state has been changed
type ClanStateEvent struct {
ClandId SteamId `json:",string"`
StateFlags EClientPersonaStateFlag
ClanId SteamId `json:",string"`
AccountFlags EAccountFlags
ClanName string
Avatar string
Avatar []byte
MemberTotalCount uint32
MemberOnlineCount uint32
MemberChattingCount uint32

View File

@ -2,9 +2,10 @@ package socialcache
import (
"errors"
"sync"
. "github.com/Philipp15b/go-steam/protocol/steamlang"
. "github.com/Philipp15b/go-steam/steamid"
"sync"
)
// Friends list is a thread safe map
@ -76,7 +77,7 @@ func (list *FriendsList) SetName(id SteamId, name string) {
}
}
func (list *FriendsList) SetAvatar(id SteamId, hash string) {
func (list *FriendsList) SetAvatar(id SteamId, hash []byte) {
list.mutex.Lock()
defer list.mutex.Unlock()
if val, ok := list.byId[id]; ok {
@ -136,7 +137,7 @@ func (list *FriendsList) SetGameName(id SteamId, name string) {
type Friend struct {
SteamId SteamId `json:",string"`
Name string
Avatar string
Avatar []byte
Relationship EFriendRelationship
PersonaState EPersonaState
PersonaStateFlags EPersonaStateFlag

View File

@ -2,9 +2,10 @@ package socialcache
import (
"errors"
"sync"
. "github.com/Philipp15b/go-steam/protocol/steamlang"
. "github.com/Philipp15b/go-steam/steamid"
"sync"
)
// Groups list is a thread safe map
@ -78,7 +79,7 @@ func (list *GroupsList) SetName(id SteamId, name string) {
}
}
func (list *GroupsList) SetAvatar(id SteamId, hash string) {
func (list *GroupsList) SetAvatar(id SteamId, hash []byte) {
list.mutex.Lock()
defer list.mutex.Unlock()
id = id.ChatToClan()
@ -136,7 +137,7 @@ func (list *GroupsList) SetMemberInGameCount(id SteamId, count uint32) {
type Group struct {
SteamId SteamId `json:",string"`
Name string
Avatar string
Avatar []byte
Relationship EClanRelationship
MemberTotalCount uint32
MemberOnlineCount uint32

View File

@ -1,13 +1,13 @@
language: go
go:
- 1.9
- "1.12"
install:
- go get -u golang.org/x/lint/golint
- env GO111MODULE=on go get -u golang.org/x/lint/golint
script:
- make test
- env GO111MODULE=on make test
deploy:
- provider: script

3
vendor/github.com/d5/tengo/go.mod generated vendored Normal file
View File

@ -0,0 +1,3 @@
module github.com/d5/tengo
go 1.12

View File

@ -1,53 +0,0 @@
// +build ignore
package main
import (
"bytes"
"io/ioutil"
"log"
"regexp"
"strconv"
)
var tengoModFileRE = regexp.MustCompile(`^srcmod_(\w+).tengo$`)
func main() {
modules := make(map[string]string)
// enumerate all Tengo module files
files, err := ioutil.ReadDir(".")
if err != nil {
log.Fatal(err)
}
for _, file := range files {
m := tengoModFileRE.FindStringSubmatch(file.Name())
if m != nil {
modName := m[1]
src, err := ioutil.ReadFile(file.Name())
if err != nil {
log.Fatalf("file '%s' read error: %s", file.Name(), err.Error())
}
modules[modName] = string(src)
}
}
var out bytes.Buffer
out.WriteString(`// Code generated using gensrcmods.go; DO NOT EDIT.
package stdlib
// SourceModules are source type standard library modules.
var SourceModules = map[string]string{` + "\n")
for modName, modSrc := range modules {
out.WriteString("\t\"" + modName + "\": " + strconv.Quote(modSrc) + ",\n")
}
out.WriteString("}\n")
const target = "source_modules.go"
if err := ioutil.WriteFile(target, out.Bytes(), 0644); err != nil {
log.Fatal(err)
}
}

View File

@ -1,19 +0,0 @@
language: go
sudo: false
matrix:
include:
- go: 1.7.x
- go: 1.8.x
- go: 1.9.x
- go: 1.10.x
- go: 1.11.x
- go: tip
allow_failures:
- go: tip
script:
- go get -t -v ./...
- diff -u <(echo -n) <(gofmt -d .)
- go vet $(go list ./... | grep -v /vendor/)
- go test -v -race ./...

View File

@ -1,11 +1,11 @@
# Gorilla WebSocket
[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)
[![CircleCI](https://circleci.com/gh/gorilla/websocket.svg?style=svg)](https://circleci.com/gh/gorilla/websocket)
Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
[![Build Status](https://travis-ci.org/gorilla/websocket.svg?branch=master)](https://travis-ci.org/gorilla/websocket)
[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)
### Documentation
* [API Reference](http://godoc.org/github.com/gorilla/websocket)
@ -27,7 +27,7 @@ package API is stable.
### Protocol Compliance
The Gorilla WebSocket package passes the server tests in the [Autobahn Test
Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn
Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn
subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
### Gorilla WebSocket compared with other packages
@ -40,7 +40,7 @@ subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn
</tr>
<tr>
<tr><td colspan="3"><a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> Features</td></tr>
<tr><td>Passes <a href="http://autobahn.ws/testsuite/">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr>
<tr><td>Passes <a href="https://github.com/crossbario/autobahn-testsuite">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr>
<tr><td>Receive <a href="https://tools.ietf.org/html/rfc6455#section-5.4">fragmented</a> message<td>Yes</td><td><a href="https://code.google.com/p/go/issues/detail?id=7632">No</a>, see note 1</td></tr>
<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close</a> message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=4588">No</a></td></tr>
<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">pings</a> and receive <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pongs</a></td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td>No</td></tr>

View File

@ -70,7 +70,7 @@ type Dialer struct {
// HandshakeTimeout specifies the duration for the handshake to complete.
HandshakeTimeout time.Duration
// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
// ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer
// size is zero, then a useful default size is used. The I/O buffer sizes
// do not limit the size of the messages that can be sent or received.
ReadBufferSize, WriteBufferSize int
@ -140,7 +140,7 @@ var nilDialer = *DefaultDialer
// Use the response.Header to get the selected subprotocol
// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
//
// The context will be used in the request and in the Dialer
// The context will be used in the request and in the Dialer.
//
// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
// non-nil *http.Response so that callers can handle redirects, authentication,

View File

@ -260,10 +260,12 @@ type Conn struct {
newCompressionWriter func(io.WriteCloser, int) io.WriteCloser
// Read fields
reader io.ReadCloser // the current reader returned to the application
readErr error
br *bufio.Reader
readRemaining int64 // bytes remaining in current frame.
reader io.ReadCloser // the current reader returned to the application
readErr error
br *bufio.Reader
// bytes remaining in current frame.
// set setReadRemaining to safely update this value and prevent overflow
readRemaining int64
readFinal bool // true the current message has more frames.
readLength int64 // Message size.
readLimit int64 // Maximum message size.
@ -320,6 +322,17 @@ func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int,
return c
}
// setReadRemaining tracks the number of bytes remaining on the connection. If n
// overflows, an ErrReadLimit is returned.
func (c *Conn) setReadRemaining(n int64) error {
if n < 0 {
return ErrReadLimit
}
c.readRemaining = n
return nil
}
// Subprotocol returns the negotiated protocol for the connection.
func (c *Conn) Subprotocol() string {
return c.subprotocol
@ -451,7 +464,8 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er
return err
}
func (c *Conn) prepWrite(messageType int) error {
// beginMessage prepares a connection and message writer for a new message.
func (c *Conn) beginMessage(mw *messageWriter, messageType int) error {
// Close previous writer if not already closed by the application. It's
// probably better to return an error in this situation, but we cannot
// change this without breaking existing applications.
@ -471,6 +485,10 @@ func (c *Conn) prepWrite(messageType int) error {
return err
}
mw.c = c
mw.frameType = messageType
mw.pos = maxFrameHeaderSize
if c.writeBuf == nil {
wpd, ok := c.writePool.Get().(writePoolData)
if ok {
@ -491,16 +509,11 @@ func (c *Conn) prepWrite(messageType int) error {
// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and
// PongMessage) are supported.
func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
if err := c.prepWrite(messageType); err != nil {
var mw messageWriter
if err := c.beginMessage(&mw, messageType); err != nil {
return nil, err
}
mw := &messageWriter{
c: c,
frameType: messageType,
pos: maxFrameHeaderSize,
}
c.writer = mw
c.writer = &mw
if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) {
w := c.newCompressionWriter(c.writer, c.compressionLevel)
mw.compress = true
@ -517,10 +530,16 @@ type messageWriter struct {
err error
}
func (w *messageWriter) fatal(err error) error {
func (w *messageWriter) endMessage(err error) error {
if w.err != nil {
w.err = err
w.c.writer = nil
return err
}
c := w.c
w.err = err
c.writer = nil
if c.writePool != nil {
c.writePool.Put(writePoolData{buf: c.writeBuf})
c.writeBuf = nil
}
return err
}
@ -534,7 +553,7 @@ func (w *messageWriter) flushFrame(final bool, extra []byte) error {
// Check for invalid control frames.
if isControl(w.frameType) &&
(!final || length > maxControlFramePayloadSize) {
return w.fatal(errInvalidControlFrame)
return w.endMessage(errInvalidControlFrame)
}
b0 := byte(w.frameType)
@ -579,7 +598,7 @@ func (w *messageWriter) flushFrame(final bool, extra []byte) error {
copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos])
if len(extra) > 0 {
return c.writeFatal(errors.New("websocket: internal error, extra used in client mode"))
return w.endMessage(c.writeFatal(errors.New("websocket: internal error, extra used in client mode")))
}
}
@ -600,15 +619,11 @@ func (w *messageWriter) flushFrame(final bool, extra []byte) error {
c.isWriting = false
if err != nil {
return w.fatal(err)
return w.endMessage(err)
}
if final {
c.writer = nil
if c.writePool != nil {
c.writePool.Put(writePoolData{buf: c.writeBuf})
c.writeBuf = nil
}
w.endMessage(errWriteClosed)
return nil
}
@ -706,11 +721,7 @@ func (w *messageWriter) Close() error {
if w.err != nil {
return w.err
}
if err := w.flushFrame(true, nil); err != nil {
return err
}
w.err = errWriteClosed
return nil
return w.flushFrame(true, nil)
}
// WritePreparedMessage writes prepared message into connection.
@ -742,10 +753,10 @@ func (c *Conn) WriteMessage(messageType int, data []byte) error {
if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) {
// Fast path with no allocations and single frame.
if err := c.prepWrite(messageType); err != nil {
var mw messageWriter
if err := c.beginMessage(&mw, messageType); err != nil {
return err
}
mw := messageWriter{c: c, frameType: messageType, pos: maxFrameHeaderSize}
n := copy(c.writeBuf[mw.pos:], data)
mw.pos += n
data = data[n:]
@ -792,7 +803,7 @@ func (c *Conn) advanceFrame() (int, error) {
final := p[0]&finalBit != 0
frameType := int(p[0] & 0xf)
mask := p[1]&maskBit != 0
c.readRemaining = int64(p[1] & 0x7f)
c.setReadRemaining(int64(p[1] & 0x7f))
c.readDecompress = false
if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 {
@ -826,7 +837,17 @@ func (c *Conn) advanceFrame() (int, error) {
return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType))
}
// 3. Read and parse frame length.
// 3. Read and parse frame length as per
// https://tools.ietf.org/html/rfc6455#section-5.2
//
// The length of the "Payload data", in bytes: if 0-125, that is the payload
// length.
// - If 126, the following 2 bytes interpreted as a 16-bit unsigned
// integer are the payload length.
// - If 127, the following 8 bytes interpreted as
// a 64-bit unsigned integer (the most significant bit MUST be 0) are the
// payload length. Multibyte length quantities are expressed in network byte
// order.
switch c.readRemaining {
case 126:
@ -834,13 +855,19 @@ func (c *Conn) advanceFrame() (int, error) {
if err != nil {
return noFrame, err
}
c.readRemaining = int64(binary.BigEndian.Uint16(p))
if err := c.setReadRemaining(int64(binary.BigEndian.Uint16(p))); err != nil {
return noFrame, err
}
case 127:
p, err := c.read(8)
if err != nil {
return noFrame, err
}
c.readRemaining = int64(binary.BigEndian.Uint64(p))
if err := c.setReadRemaining(int64(binary.BigEndian.Uint64(p))); err != nil {
return noFrame, err
}
}
// 4. Handle frame masking.
@ -863,6 +890,12 @@ func (c *Conn) advanceFrame() (int, error) {
if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {
c.readLength += c.readRemaining
// Don't allow readLength to overflow in the presence of a large readRemaining
// counter.
if c.readLength < 0 {
return noFrame, ErrReadLimit
}
if c.readLimit > 0 && c.readLength > c.readLimit {
c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))
return noFrame, ErrReadLimit
@ -876,7 +909,7 @@ func (c *Conn) advanceFrame() (int, error) {
var payload []byte
if c.readRemaining > 0 {
payload, err = c.read(int(c.readRemaining))
c.readRemaining = 0
c.setReadRemaining(0)
if err != nil {
return noFrame, err
}
@ -949,6 +982,7 @@ func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
c.readErr = hideTempErr(err)
break
}
if frameType == TextMessage || frameType == BinaryMessage {
c.messageReader = &messageReader{c}
c.reader = c.messageReader
@ -989,7 +1023,9 @@ func (r *messageReader) Read(b []byte) (int, error) {
if c.isServer {
c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])
}
c.readRemaining -= int64(n)
rem := c.readRemaining
rem -= int64(n)
c.setReadRemaining(rem)
if c.readRemaining > 0 && c.readErr == io.EOF {
c.readErr = errUnexpectedEOF
}
@ -1041,7 +1077,7 @@ func (c *Conn) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t)
}
// SetReadLimit sets the maximum size for a message read from the peer. If a
// SetReadLimit sets the maximum size in bytes for a message read from the peer. If a
// message exceeds the limit, the connection sends a close message to the peer
// and returns ErrReadLimit to the application.
func (c *Conn) SetReadLimit(limit int64) {

View File

@ -151,6 +151,53 @@
// checking. The application is responsible for checking the Origin header
// before calling the Upgrade function.
//
// Buffers
//
// Connections buffer network input and output to reduce the number
// of system calls when reading or writing messages.
//
// Write buffers are also used for constructing WebSocket frames. See RFC 6455,
// Section 5 for a discussion of message framing. A WebSocket frame header is
// written to the network each time a write buffer is flushed to the network.
// Decreasing the size of the write buffer can increase the amount of framing
// overhead on the connection.
//
// The buffer sizes in bytes are specified by the ReadBufferSize and
// WriteBufferSize fields in the Dialer and Upgrader. The Dialer uses a default
// size of 4096 when a buffer size field is set to zero. The Upgrader reuses
// buffers created by the HTTP server when a buffer size field is set to zero.
// The HTTP server buffers have a size of 4096 at the time of this writing.
//
// The buffer sizes do not limit the size of a message that can be read or
// written by a connection.
//
// Buffers are held for the lifetime of the connection by default. If the
// Dialer or Upgrader WriteBufferPool field is set, then a connection holds the
// write buffer only when writing a message.
//
// Applications should tune the buffer sizes to balance memory use and
// performance. Increasing the buffer size uses more memory, but can reduce the
// number of system calls to read or write the network. In the case of writing,
// increasing the buffer size can reduce the number of frame headers written to
// the network.
//
// Some guidelines for setting buffer parameters are:
//
// Limit the buffer sizes to the maximum expected message size. Buffers larger
// than the largest message do not provide any benefit.
//
// Depending on the distribution of message sizes, setting the buffer size to
// to a value less than the maximum expected message size can greatly reduce
// memory use with a small impact on performance. Here's an example: If 99% of
// the messages are smaller than 256 bytes and the maximum message size is 512
// bytes, then a buffer size of 256 bytes will result in 1.01 more system calls
// than a buffer size of 512 bytes. The memory savings is 50%.
//
// A write buffer pool is useful when the application has a modest number
// writes over a large number of connections. when buffers are pooled, a larger
// buffer size has a reduced impact on total memory use and has the benefit of
// reducing system calls and frame overhead.
//
// Compression EXPERIMENTAL
//
// Per message compression extensions (RFC 7692) are experimentally supported

3
vendor/github.com/gorilla/websocket/go.mod generated vendored Normal file
View File

@ -0,0 +1,3 @@
module github.com/gorilla/websocket
go 1.12

2
vendor/github.com/gorilla/websocket/go.sum generated vendored Normal file
View File

@ -0,0 +1,2 @@
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=

42
vendor/github.com/gorilla/websocket/join.go generated vendored Normal file
View File

@ -0,0 +1,42 @@
// Copyright 2019 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package websocket
import (
"io"
"strings"
)
// JoinMessages concatenates received messages to create a single io.Reader.
// The string term is appended to each message. The returned reader does not
// support concurrent calls to the Read method.
func JoinMessages(c *Conn, term string) io.Reader {
return &joinReader{c: c, term: term}
}
type joinReader struct {
c *Conn
term string
r io.Reader
}
func (r *joinReader) Read(p []byte) (int, error) {
if r.r == nil {
var err error
_, r.r, err = r.c.NextReader()
if err != nil {
return 0, err
}
if r.term != "" {
r.r = io.MultiReader(r.r, strings.NewReader(r.term))
}
}
n, err := r.r.Read(p)
if err == io.EOF {
err = nil
r.r = nil
}
return n, err
}

View File

@ -22,18 +22,18 @@ func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {
func init() {
proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {
return &httpProxyDialer{proxyURL: proxyURL, fowardDial: forwardDialer.Dial}, nil
return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil
})
}
type httpProxyDialer struct {
proxyURL *url.URL
fowardDial func(network, addr string) (net.Conn, error)
proxyURL *url.URL
forwardDial func(network, addr string) (net.Conn, error)
}
func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {
hostPort, _ := hostPortNoPort(hpd.proxyURL)
conn, err := hpd.fowardDial(network, hostPort)
conn, err := hpd.forwardDial(network, hostPort)
if err != nil {
return nil, err
}

View File

@ -27,7 +27,7 @@ type Upgrader struct {
// HandshakeTimeout specifies the duration for the handshake to complete.
HandshakeTimeout time.Duration
// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
// ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer
// size is zero, then buffers allocated by the HTTP server are used. The
// I/O buffer sizes do not limit the size of the messages that can be sent
// or received.
@ -153,7 +153,7 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
challengeKey := r.Header.Get("Sec-Websocket-Key")
if challengeKey == "" {
return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: `Sec-WebSocket-Key' header is missing or blank")
return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header is missing or blank")
}
subprotocol := u.selectSubprotocol(r, responseHeader)

View File

@ -31,68 +31,113 @@ func generateChallengeKey() (string, error) {
return base64.StdEncoding.EncodeToString(p), nil
}
// Octet types from RFC 2616.
var octetTypes [256]byte
const (
isTokenOctet = 1 << iota
isSpaceOctet
)
func init() {
// From RFC 2616
//
// OCTET = <any 8-bit sequence of data>
// CHAR = <any US-ASCII character (octets 0 - 127)>
// CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
// CR = <US-ASCII CR, carriage return (13)>
// LF = <US-ASCII LF, linefeed (10)>
// SP = <US-ASCII SP, space (32)>
// HT = <US-ASCII HT, horizontal-tab (9)>
// <"> = <US-ASCII double-quote mark (34)>
// CRLF = CR LF
// LWS = [CRLF] 1*( SP | HT )
// TEXT = <any OCTET except CTLs, but including LWS>
// separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
// | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
// token = 1*<any CHAR except CTLs or separators>
// qdtext = <any TEXT except <">>
for c := 0; c < 256; c++ {
var t byte
isCtl := c <= 31 || c == 127
isChar := 0 <= c && c <= 127
isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0
if strings.IndexRune(" \t\r\n", rune(c)) >= 0 {
t |= isSpaceOctet
}
if isChar && !isCtl && !isSeparator {
t |= isTokenOctet
}
octetTypes[c] = t
}
// Token octets per RFC 2616.
var isTokenOctet = [256]bool{
'!': true,
'#': true,
'$': true,
'%': true,
'&': true,
'\'': true,
'*': true,
'+': true,
'-': true,
'.': true,
'0': true,
'1': true,
'2': true,
'3': true,
'4': true,
'5': true,
'6': true,
'7': true,
'8': true,
'9': true,
'A': true,
'B': true,
'C': true,
'D': true,
'E': true,
'F': true,
'G': true,
'H': true,
'I': true,
'J': true,
'K': true,
'L': true,
'M': true,
'N': true,
'O': true,
'P': true,
'Q': true,
'R': true,
'S': true,
'T': true,
'U': true,
'W': true,
'V': true,
'X': true,
'Y': true,
'Z': true,
'^': true,
'_': true,
'`': true,
'a': true,
'b': true,
'c': true,
'd': true,
'e': true,
'f': true,
'g': true,
'h': true,
'i': true,
'j': true,
'k': true,
'l': true,
'm': true,
'n': true,
'o': true,
'p': true,
'q': true,
'r': true,
's': true,
't': true,
'u': true,
'v': true,
'w': true,
'x': true,
'y': true,
'z': true,
'|': true,
'~': true,
}
// skipSpace returns a slice of the string s with all leading RFC 2616 linear
// whitespace removed.
func skipSpace(s string) (rest string) {
i := 0
for ; i < len(s); i++ {
if octetTypes[s[i]]&isSpaceOctet == 0 {
if b := s[i]; b != ' ' && b != '\t' {
break
}
}
return s[i:]
}
// nextToken returns the leading RFC 2616 token of s and the string following
// the token.
func nextToken(s string) (token, rest string) {
i := 0
for ; i < len(s); i++ {
if octetTypes[s[i]]&isTokenOctet == 0 {
if !isTokenOctet[s[i]] {
break
}
}
return s[:i], s[i:]
}
// nextTokenOrQuoted returns the leading token or quoted string per RFC 2616
// and the string following the token or quoted string.
func nextTokenOrQuoted(s string) (value string, rest string) {
if !strings.HasPrefix(s, "\"") {
return nextToken(s)
@ -128,7 +173,8 @@ func nextTokenOrQuoted(s string) (value string, rest string) {
return "", ""
}
// equalASCIIFold returns true if s is equal to t with ASCII case folding.
// equalASCIIFold returns true if s is equal to t with ASCII case folding as
// defined in RFC 4790.
func equalASCIIFold(s, t string) bool {
for s != "" && t != "" {
sr, size := utf8.DecodeRuneInString(s)

View File

@ -1 +1,3 @@
module github.com/hashicorp/golang-lru
go 1.12

View File

@ -86,17 +86,35 @@ func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
}
// Remove removes the provided key from the cache.
func (c *Cache) Remove(key interface{}) {
func (c *Cache) Remove(key interface{}) (present bool) {
c.lock.Lock()
c.lru.Remove(key)
present = c.lru.Remove(key)
c.lock.Unlock()
return
}
// Resize changes the cache size.
func (c *Cache) Resize(size int) (evicted int) {
c.lock.Lock()
evicted = c.lru.Resize(size)
c.lock.Unlock()
return evicted
}
// RemoveOldest removes the oldest item from the cache.
func (c *Cache) RemoveOldest() {
func (c *Cache) RemoveOldest() (key interface{}, value interface{}, ok bool) {
c.lock.Lock()
c.lru.RemoveOldest()
key, value, ok = c.lru.RemoveOldest()
c.lock.Unlock()
return
}
// GetOldest returns the oldest entry
func (c *Cache) GetOldest() (key interface{}, value interface{}, ok bool) {
c.lock.Lock()
key, value, ok = c.lru.GetOldest()
c.lock.Unlock()
return
}
// Keys returns a slice of the keys in the cache, from oldest to newest.

View File

@ -73,6 +73,9 @@ func (c *LRU) Add(key, value interface{}) (evicted bool) {
func (c *LRU) Get(key interface{}) (value interface{}, ok bool) {
if ent, ok := c.items[key]; ok {
c.evictList.MoveToFront(ent)
if ent.Value.(*entry) == nil {
return nil, false
}
return ent.Value.(*entry).value, true
}
return
@ -142,6 +145,19 @@ func (c *LRU) Len() int {
return c.evictList.Len()
}
// Resize changes the cache size.
func (c *LRU) Resize(size int) (evicted int) {
diff := c.Len() - size
if diff < 0 {
diff = 0
}
for i := 0; i < diff; i++ {
c.removeOldest()
}
c.size = size
return diff
}
// removeOldest removes the oldest item from the cache.
func (c *LRU) removeOldest() {
ent := c.evictList.Back()

View File

@ -10,7 +10,7 @@ type LRUCache interface {
// updates the "recently used"-ness of the key. #value, isFound
Get(key interface{}) (value interface{}, ok bool)
// Check if a key exsists in cache without updating the recent-ness.
// Checks if a key exists in cache without updating the recent-ness.
Contains(key interface{}) (ok bool)
// Returns key's value without updating the "recently used"-ness of the key.
@ -31,6 +31,9 @@ type LRUCache interface {
// Returns the number of items in the cache.
Len() int
// Clear all cache entries
// Clears all cache entries.
Purge()
// Resizes cache, returning number evicted
Resize(int) int
}

View File

@ -33,6 +33,17 @@ type (
// Bind implements the `Binder#Bind` function.
func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
req := c.Request()
names := c.ParamNames()
values := c.ParamValues()
params := map[string][]string{}
for i, name := range names {
params[name] = []string{values[i]}
}
if err := b.bindData(i, params, "param"); err != nil {
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
}
if req.ContentLength == 0 {
if req.Method == http.MethodGet || req.Method == http.MethodDelete {
if err = b.bindData(i, c.QueryParams(), "query"); err != nil {
@ -77,9 +88,19 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
}
func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag string) error {
if ptr == nil || len(data) == 0 {
return nil
}
typ := reflect.TypeOf(ptr).Elem()
val := reflect.ValueOf(ptr).Elem()
if m, ok := ptr.(*map[string]interface{}); ok {
for k, v := range data {
(*m)[k] = v[0]
}
return nil
}
if typ.Kind() != reflect.Struct {
return errors.New("binding element must be a struct")
}

View File

@ -26,6 +26,9 @@ type (
// SetRequest sets `*http.Request`.
SetRequest(r *http.Request)
// SetResponse sets `*Response`.
SetResponse(r *Response)
// Response returns `*Response`.
Response() *Response
@ -228,6 +231,10 @@ func (c *context) Response() *Response {
return c.response
}
func (c *context) SetResponse(r *Response) {
c.response = r
}
func (c *context) IsTLS() bool {
return c.request.TLS != nil
}

View File

@ -99,9 +99,9 @@ type (
// HTTPError represents an error that occurred while handling a request.
HTTPError struct {
Code int
Message interface{}
Internal error // Stores the error returned by an external dependency
Code int `json:"-"`
Message interface{} `json:"message"`
Internal error `json:"-"` // Stores the error returned by an external dependency
}
// MiddlewareFunc defines a function to process middleware.
@ -222,11 +222,12 @@ const (
HeaderContentSecurityPolicy = "Content-Security-Policy"
HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
HeaderXCSRFToken = "X-CSRF-Token"
HeaderReferrerPolicy = "Referrer-Policy"
)
const (
// Version of Echo
Version = "4.1.5"
Version = "4.1.10"
website = "https://echo.labstack.com"
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
banner = `
@ -340,32 +341,31 @@ func (e *Echo) Routers() map[string]*Router {
// DefaultHTTPErrorHandler is the default HTTP error handler. It sends a JSON response
// with status code.
func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
var (
code = http.StatusInternalServerError
msg interface{}
)
if he, ok := err.(*HTTPError); ok {
code = he.Code
msg = he.Message
he, ok := err.(*HTTPError)
if ok {
if he.Internal != nil {
err = fmt.Errorf("%v, %v", err, he.Internal)
if herr, ok := he.Internal.(*HTTPError); ok {
he = herr
}
}
} else if e.Debug {
msg = err.Error()
} else {
msg = http.StatusText(code)
he = &HTTPError{
Code: http.StatusInternalServerError,
Message: http.StatusText(http.StatusInternalServerError),
}
}
if _, ok := msg.(string); ok {
msg = Map{"message": msg}
if e.Debug {
he.Message = err.Error()
} else if m, ok := he.Message.(string); ok {
he.Message = Map{"message": m}
}
// Send response
if !c.Response().Committed {
if c.Request().Method == http.MethodHead { // Issue #608
err = c.NoContent(code)
err = c.NoContent(he.Code)
} else {
err = c.JSON(code, msg)
err = c.JSON(he.Code, he.Message)
}
if err != nil {
e.Logger.Error(err)
@ -748,7 +748,7 @@ func NewHTTPError(code int, message ...interface{}) *HTTPError {
// Error makes it compatible with `error` interface.
func (he *HTTPError) Error() string {
return fmt.Sprintf("code=%d, message=%v", he.Code, he.Message)
return fmt.Sprintf("code=%d, message=%v, internal=%v", he.Code, he.Message, he.Internal)
}
// SetInternal sets error to HTTPError.Internal
@ -771,6 +771,7 @@ func WrapMiddleware(m func(http.Handler) http.Handler) MiddlewareFunc {
return func(c Context) (err error) {
m(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
c.SetRequest(r)
c.SetResponse(NewResponse(w, c.Echo()))
err = next(c)
})).ServeHTTP(c.Response(), c.Request())
return

View File

@ -4,12 +4,8 @@ go 1.12
require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/labstack/gommon v0.2.9
github.com/stretchr/testify v1.3.0
github.com/labstack/gommon v0.3.0
github.com/stretchr/testify v1.4.0
github.com/valyala/fasttemplate v1.0.1
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5
golang.org/x/net v0.0.0-20190607181551-461777fb6f67 // indirect
golang.org/x/sys v0.0.0-20190609082536-301114b31cce // indirect
golang.org/x/text v0.3.2 // indirect
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3 // indirect
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
)

View File

@ -1,53 +1,34 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
github.com/labstack/gommon v0.2.9 h1:heVeuAYtevIQVYkGj6A41dtfT91LrvFG220lavpWhrU=
github.com/labstack/gommon v0.2.9/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/NKavGG4=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190607181551-461777fb6f67 h1:rJJxsykSlULwd2P2+pg/rtnwN2FrWp4IuCxOSyS0V00=
golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2 h1:T5DasATyLQfmbTpfEXx/IOL9vfjzW6up+ZDkmHvIf2s=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -25,6 +25,9 @@ type (
// ErrorHandler defines a function which is executed for an invalid token.
// It may be used to define a custom JWT error.
ErrorHandler JWTErrorHandler
// ErrorHandlerWithContext is almost identical to ErrorHandler, but it's passed the current context.
ErrorHandlerWithContext JWTErrorHandlerWithContext
// Signing key to validate token. Used as fallback if SigningKeys has length 0.
// Required. This or SigningKeys.
@ -69,6 +72,9 @@ type (
// JWTErrorHandler defines a function which is executed for an invalid token.
JWTErrorHandler func(error) error
// JWTErrorHandlerWithContext is almost identical to JWTErrorHandler, but it's passed the current context.
JWTErrorHandlerWithContext func(error, echo.Context) error
jwtExtractor func(echo.Context) (string, error)
)
@ -177,6 +183,10 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if config.ErrorHandler != nil {
return config.ErrorHandler(err)
}
if config.ErrorHandlerWithContext != nil {
return config.ErrorHandlerWithContext(err, c)
}
return err
}
token := new(jwt.Token)
@ -199,6 +209,9 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if config.ErrorHandler != nil {
return config.ErrorHandler(err)
}
if config.ErrorHandlerWithContext != nil {
return config.ErrorHandlerWithContext(err, c)
}
return &echo.HTTPError{
Code: http.StatusUnauthorized,
Message: "invalid or expired jwt",

View File

@ -4,7 +4,6 @@ import (
"bytes"
"encoding/json"
"io"
"os"
"strconv"
"strings"
"sync"
@ -74,7 +73,6 @@ var (
`"status":${status},"error":"${error}","latency":${latency},"latency_human":"${latency_human}"` +
`,"bytes_in":${bytes_in},"bytes_out":${bytes_out}}` + "\n",
CustomTimeFormat: "2006-01-02 15:04:05.00000",
Output: os.Stdout,
colorer: color.New(),
}
)
@ -214,6 +212,10 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
return
}
if config.Output == nil {
_, err = c.Logger().Output().Write(buf.Bytes())
return
}
_, err = config.Output.Write(buf.Bytes())
return
}

View File

@ -66,6 +66,11 @@ type (
// maintained by Chrome (and used by Firefox and Safari): https://hstspreload.org/
// Optional. Default value false.
HSTSPreloadEnabled bool `yaml:"hsts_preload_enabled"`
// ReferrerPolicy sets the `Referrer-Policy` header providing security against
// leaking potentially sensitive request paths to third parties.
// Optional. Default value "".
ReferrerPolicy string `yaml:"referrer_policy"`
}
)
@ -131,6 +136,9 @@ func SecureWithConfig(config SecureConfig) echo.MiddlewareFunc {
res.Header().Set(echo.HeaderContentSecurityPolicy, config.ContentSecurityPolicy)
}
}
if config.ReferrerPolicy != "" {
res.Header().Set(echo.HeaderReferrerPolicy, config.ReferrerPolicy)
}
return next(c)
}
}

View File

@ -20,8 +20,8 @@ type (
pnames []string
methodHandler *methodHandler
}
kind uint8
children []*node
kind uint8
children []*node
methodHandler struct {
connect HandlerFunc
delete HandlerFunc
@ -336,10 +336,14 @@ func (r *Router) Find(method, path string, c Context) {
}
}
if l == pl {
// Continue search
search = search[l:]
} else {
if nn == nil { // Issue #1348
return // Not found
}
cn = nn
search = ns
if nk == pkind {
@ -347,8 +351,6 @@ func (r *Router) Find(method, path string, c Context) {
} else if nk == akind {
goto Any
}
// Not found
return
}
if search == "" {
@ -398,6 +400,9 @@ func (r *Router) Find(method, path string, c Context) {
if nn != nil {
cn = nn
nn = cn.parent // Next (Issue #954)
if nn != nil {
nk = nn.kind
}
search = ns
if nk == pkind {
goto Param
@ -405,8 +410,7 @@ func (r *Router) Find(method, path string, c Context) {
goto Any
}
}
// Not found
return
return // Not found
}
pvalues[len(cn.pnames)-1] = search
break

View File

@ -4,6 +4,7 @@ import (
"fmt"
"regexp"
"strconv"
"strings"
)
type (
@ -73,7 +74,7 @@ func (*Bytes) Parse(value string) (i int64, err error) {
return 0, fmt.Errorf("error parsing value=%s", value)
}
bytesString := parts[1]
multiple := parts[2]
multiple := strings.ToUpper(parts[2])
bytes, err := strconv.ParseFloat(bytesString, 64)
if err != nil {
return

View File

@ -1,3 +1,3 @@
module github.com/mattn/go-isatty
require golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
require golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a

View File

@ -1,2 +1,2 @@
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -1,12 +1,9 @@
language: go
go:
- 1.7.x
- 1.8.x
- 1.9.x
- 1.10.x
- 1.11.x
- tip
env:
- GO111MODULE=on
install: true
before_install:
- export PATH=$HOME/gopath/bin:$PATH
@ -20,6 +17,19 @@ script:
matrix:
allow_failures:
- go: tip
include:
- go: "1.7.x"
script: go test -v ./...
- go: "1.8.x"
script: go test -v ./...
- go: "1.9.x"
script: go test -v ./...
- go: "1.10.x"
script: go test -v ./...
- go: "1.11.x"
script: go test -v -mod=vendor ./...
- go: "tip"
script: go test -v -mod=vendor ./...
git:
depth: 10

View File

@ -1,3 +1,20 @@
### v0.6.0 - August 31, 2019
full differences can be viewed using `git log --oneline --decorate --color v0.5.0..v0.6.0`
thanks to everyone who has contributed since January!
#### Breaking Changes:
- Info struct has had fields removed related to deprecated functionality by slack.
- minor adjustments to some structs.
- some internal default values have changed, usually to be more inline with slack defaults or to correct inability to set a particular value. (Message Parse for example.)
##### Highlights:
- new slacktest package easy mocking for slack client. use, enjoy, please submit PRs for improvements and default behaviours! shamelessly taken from the [slack-test repo](https://github.com/lusis/slack-test) thank you lusis for letting us use it and bring it into the slack repo.
- blocks, blocks, blocks.
- RTM ManagedConnection has undergone a significant cleanup.
in particular handles backoffs gracefully, removed many deadlocks,
and Disconnect is now much more responsive.
### v0.5.0 - January 20, 2019
full differences can be viewed using `git log --oneline --decorate --color v0.4.0..v0.5.0`
- Breaking changes: various old struct fields have been removed or updated to match slack's api.

View File

@ -1,39 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
name = "github.com/gorilla/websocket"
packages = ["."]
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
version = "v1.2.0"
[[projects]]
name = "github.com/pkg/errors"
packages = ["."]
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
[[projects]]
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0"
[[projects]]
name = "github.com/stretchr/testify"
packages = ["assert"]
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
version = "v1.2.2"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "596fa546322c2a1e9708a10c9f39aca2e04792b477fab86fb2899fbaab776070"
solver-name = "gps-cdcl"
solver-version = 1

View File

@ -1,17 +0,0 @@
ignored = ["github.com/lusis/slack-test"]
[[constraint]]
name = "github.com/gorilla/websocket"
version = "1.2.0"
[[constraint]]
name = "github.com/stretchr/testify"
version = "1.2.1"
[[constraint]]
name = "github.com/pkg/errors"
version = "0.8.0"
[prune]
go-tests = true
unused-packages = true

View File

@ -35,7 +35,7 @@ func main() {
api := slack.New("YOUR_TOKEN_HERE")
// If you set debugging, it will log all requests to the console
// Useful when encountering issues
// api.SetDebug(true)
// slack.New("YOUR_TOKEN_HERE", slack.OptionDebug(true))
groups, err := api.GetGroups(false)
if err != nil {
fmt.Printf("%s\n", err)

View File

@ -2,28 +2,19 @@ package slack
import (
"context"
"errors"
"fmt"
"net/url"
"strings"
)
type adminResponse struct {
OK bool `json:"ok"`
Error string `json:"error"`
}
func adminRequest(ctx context.Context, client httpClient, method string, teamName string, values url.Values, d debug) (*adminResponse, error) {
adminResponse := &adminResponse{}
err := parseAdminResponse(ctx, client, method, teamName, values, adminResponse, d)
func (api *Client) adminRequest(ctx context.Context, method string, teamName string, values url.Values) error {
resp := &SlackResponse{}
err := parseAdminResponse(ctx, api.httpclient, method, teamName, values, resp, api)
if err != nil {
return nil, err
return err
}
if !adminResponse.OK {
return nil, errors.New(adminResponse.Error)
}
return adminResponse, nil
return resp.Err()
}
// DisableUser disabled a user account, given a user ID
@ -40,9 +31,8 @@ func (api *Client) DisableUserContext(ctx context.Context, teamName string, uid
"_attempts": {"1"},
}
_, err := adminRequest(ctx, api.httpclient, "setInactive", teamName, values, api)
if err != nil {
return fmt.Errorf("Failed to disable user with id '%s': %s", uid, err)
if err := api.adminRequest(ctx, "setInactive", teamName, values); err != nil {
return fmt.Errorf("failed to disable user with id '%s': %s", uid, err)
}
return nil
@ -67,7 +57,7 @@ func (api *Client) InviteGuestContext(ctx context.Context, teamName, channel, fi
"_attempts": {"1"},
}
_, err := adminRequest(ctx, api.httpclient, "invite", teamName, values, api)
err := api.adminRequest(ctx, "invite", teamName, values)
if err != nil {
return fmt.Errorf("Failed to invite single-channel guest: %s", err)
}
@ -94,7 +84,7 @@ func (api *Client) InviteRestrictedContext(ctx context.Context, teamName, channe
"_attempts": {"1"},
}
_, err := adminRequest(ctx, api.httpclient, "invite", teamName, values, api)
err := api.adminRequest(ctx, "invite", teamName, values)
if err != nil {
return fmt.Errorf("Failed to restricted account: %s", err)
}
@ -118,7 +108,7 @@ func (api *Client) InviteToTeamContext(ctx context.Context, teamName, firstName,
"_attempts": {"1"},
}
_, err := adminRequest(ctx, api.httpclient, "invite", teamName, values, api)
err := api.adminRequest(ctx, "invite", teamName, values)
if err != nil {
return fmt.Errorf("Failed to invite to team: %s", err)
}
@ -140,7 +130,7 @@ func (api *Client) SetRegularContext(ctx context.Context, teamName, user string)
"_attempts": {"1"},
}
_, err := adminRequest(ctx, api.httpclient, "setRegular", teamName, values, api)
err := api.adminRequest(ctx, "setRegular", teamName, values)
if err != nil {
return fmt.Errorf("Failed to change the user (%s) to a regular user: %s", user, err)
}
@ -162,7 +152,7 @@ func (api *Client) SendSSOBindingEmailContext(ctx context.Context, teamName, use
"_attempts": {"1"},
}
_, err := adminRequest(ctx, api.httpclient, "sendSSOBind", teamName, values, api)
err := api.adminRequest(ctx, "sendSSOBind", teamName, values)
if err != nil {
return fmt.Errorf("Failed to send SSO binding email for user (%s): %s", user, err)
}
@ -185,7 +175,7 @@ func (api *Client) SetUltraRestrictedContext(ctx context.Context, teamName, uid,
"_attempts": {"1"},
}
_, err := adminRequest(ctx, api.httpclient, "setUltraRestricted", teamName, values, api)
err := api.adminRequest(ctx, "setUltraRestricted", teamName, values)
if err != nil {
return fmt.Errorf("Failed to ultra-restrict account: %s", err)
}
@ -194,22 +184,23 @@ func (api *Client) SetUltraRestrictedContext(ctx context.Context, teamName, uid,
}
// SetRestricted converts a user into a restricted account
func (api *Client) SetRestricted(teamName, uid string) error {
return api.SetRestrictedContext(context.Background(), teamName, uid)
func (api *Client) SetRestricted(teamName, uid string, channelIds ...string) error {
return api.SetRestrictedContext(context.Background(), teamName, uid, channelIds...)
}
// SetRestrictedContext converts a user into a restricted account with a custom context
func (api *Client) SetRestrictedContext(ctx context.Context, teamName, uid string) error {
func (api *Client) SetRestrictedContext(ctx context.Context, teamName, uid string, channelIds ...string) error {
values := url.Values{
"user": {uid},
"token": {api.token},
"set_active": {"true"},
"_attempts": {"1"},
"channels": {strings.Join(channelIds, ",")},
}
_, err := adminRequest(ctx, api.httpclient, "setRestricted", teamName, values, api)
err := api.adminRequest(ctx, "setRestricted", teamName, values)
if err != nil {
return fmt.Errorf("Failed to restrict account: %s", err)
return fmt.Errorf("failed to restrict account: %s", err)
}
return nil

View File

@ -17,7 +17,7 @@ type AttachmentAction struct {
Name string `json:"name"` // Required.
Text string `json:"text"` // Required.
Style string `json:"style,omitempty"` // Optional. Allowed values: "default", "primary", "danger".
Type string `json:"type"` // Required. Must be set to "button" or "select".
Type actionType `json:"type"` // Required. Must be set to "button" or "select".
Value string `json:"value,omitempty"` // Optional.
DataSource string `json:"data_source,omitempty"` // Optional.
MinQueryLength int `json:"min_query_length,omitempty"` // Optional. Default value is 1.
@ -28,6 +28,11 @@ type AttachmentAction struct {
URL string `json:"url,omitempty"` // Optional.
}
// actionType returns the type of the action
func (a AttachmentAction) actionType() actionType {
return a.Type
}
// AttachmentActionOption the individual option to appear in action menu.
type AttachmentActionOption struct {
Text string `json:"text"` // Required.
@ -45,13 +50,6 @@ type AttachmentActionOptionGroup struct {
// DEPRECATED: use InteractionCallback
type AttachmentActionCallback InteractionCallback
// ActionCallback specific fields for the action callback.
type ActionCallback struct {
MessageTs string `json:"message_ts"`
AttachmentID string `json:"attachment_id"`
Actions []AttachmentAction `json:"actions"`
}
// ConfirmationField are used to ask users to confirm actions
type ConfirmationField struct {
Title string `json:"title,omitempty"` // Optional.

View File

@ -12,9 +12,9 @@ type AuthRevokeResponse struct {
}
// authRequest sends the actual request, and unmarshals the response
func authRequest(ctx context.Context, client httpClient, path string, values url.Values, d debug) (*AuthRevokeResponse, error) {
func (api *Client) authRequest(ctx context.Context, path string, values url.Values) (*AuthRevokeResponse, error) {
response := &AuthRevokeResponse{}
err := postSlackMethod(ctx, client, path, values, response, d)
err := api.postMethod(ctx, path, values, response)
if err != nil {
return nil, err
}
@ -36,5 +36,5 @@ func (api *Client) SendAuthRevokeContext(ctx context.Context, token string) (*Au
"token": {token},
}
return authRequest(ctx, api.httpclient, "auth.revoke", values, api)
return api.authRequest(ctx, "auth.revoke", values)
}

View File

@ -1,7 +1,6 @@
package slack
import (
"math"
"math/rand"
"time"
)
@ -14,41 +13,42 @@ import (
// conjunction with the time package.
type backoff struct {
attempts int
//Factor is the multiplying factor for each increment step
Factor float64
//Jitter eases contention by randomizing backoff steps
Jitter bool
//Min and Max are the minimum and maximum values of the counter
Min, Max time.Duration
// Initial value to scale out
Initial time.Duration
// Jitter value randomizes an additional delay between 0 and Jitter
Jitter time.Duration
// Max maximum values of the backoff
Max time.Duration
}
// Returns the current value of the counter and then multiplies it
// Factor
func (b *backoff) Duration() time.Duration {
//Zero-values are nonsensical, so we use
//them to apply defaults
if b.Min == 0 {
b.Min = 100 * time.Millisecond
}
func (b *backoff) Duration() (dur time.Duration) {
// Zero-values are nonsensical, so we use
// them to apply defaults
if b.Max == 0 {
b.Max = 10 * time.Second
}
if b.Factor == 0 {
b.Factor = 2
if b.Initial == 0 {
b.Initial = 100 * time.Millisecond
}
//calculate this duration
dur := float64(b.Min) * math.Pow(b.Factor, float64(b.attempts))
if b.Jitter {
dur = rand.Float64()*(dur-float64(b.Min)) + float64(b.Min)
// calculate this duration
if dur = time.Duration(1 << uint(b.attempts)); dur > 0 {
dur = dur * b.Initial
} else {
dur = b.Max
}
//cap!
if dur > float64(b.Max) {
return b.Max
if b.Jitter > 0 {
dur = dur + time.Duration(rand.Intn(int(b.Jitter)))
}
//bump attempts count
// bump attempts count
b.attempts++
//return as a time.Duration
return time.Duration(dur)
return dur
}
//Resets the current value of the counter back to Min

71
vendor/github.com/nlopes/slack/block.go generated vendored Normal file
View File

@ -0,0 +1,71 @@
package slack
// @NOTE: Blocks are in beta and subject to change.
// More Information: https://api.slack.com/block-kit
// MessageBlockType defines a named string type to define each block type
// as a constant for use within the package.
type MessageBlockType string
const (
MBTSection MessageBlockType = "section"
MBTDivider MessageBlockType = "divider"
MBTImage MessageBlockType = "image"
MBTAction MessageBlockType = "actions"
MBTContext MessageBlockType = "context"
)
// Block defines an interface all block types should implement
// to ensure consistency between blocks.
type Block interface {
BlockType() MessageBlockType
}
// Blocks is a convenience struct defined to allow dynamic unmarshalling of
// the "blocks" value in Slack's JSON response, which varies depending on block type
type Blocks struct {
BlockSet []Block `json:"blocks,omitempty"`
}
// BlockAction is the action callback sent when a block is interacted with
type BlockAction struct {
ActionID string `json:"action_id"`
BlockID string `json:"block_id"`
Type actionType `json:"type"`
Text TextBlockObject `json:"text"`
Value string `json:"value"`
ActionTs string `json:"action_ts"`
SelectedOption OptionBlockObject `json:"selected_option"`
SelectedUser string `json:"selected_user"`
SelectedChannel string `json:"selected_channel"`
SelectedConversation string `json:"selected_conversation"`
SelectedDate string `json:"selected_date"`
InitialOption OptionBlockObject `json:"initial_option"`
InitialUser string `json:"initial_user"`
InitialChannel string `json:"initial_channel"`
InitialConversation string `json:"initial_conversation"`
InitialDate string `json:"initial_date"`
}
// actionType returns the type of the action
func (b BlockAction) actionType() actionType {
return b.Type
}
// NewBlockMessage creates a new Message that contains one or more blocks to be displayed
func NewBlockMessage(blocks ...Block) Message {
return Message{
Msg: Msg{
Blocks: Blocks{
BlockSet: blocks,
},
},
}
}
// AddBlockMessage appends a block to the end of the existing list of blocks
func AddBlockMessage(message Message, newBlk Block) Message {
message.Msg.Blocks.BlockSet = append(message.Msg.Blocks.BlockSet, newBlk)
return message
}

26
vendor/github.com/nlopes/slack/block_action.go generated vendored Normal file
View File

@ -0,0 +1,26 @@
package slack
// ActionBlock defines data that is used to hold interactive elements.
//
// More Information: https://api.slack.com/reference/messaging/blocks#actions
type ActionBlock struct {
Type MessageBlockType `json:"type"`
BlockID string `json:"block_id,omitempty"`
Elements BlockElements `json:"elements"`
}
// BlockType returns the type of the block
func (s ActionBlock) BlockType() MessageBlockType {
return s.Type
}
// NewActionBlock returns a new instance of an Action Block
func NewActionBlock(blockID string, elements ...BlockElement) *ActionBlock {
return &ActionBlock{
Type: MBTAction,
BlockID: blockID,
Elements: BlockElements{
ElementSet: elements,
},
}
}

32
vendor/github.com/nlopes/slack/block_context.go generated vendored Normal file
View File

@ -0,0 +1,32 @@
package slack
// ContextBlock defines data that is used to display message context, which can
// include both images and text.
//
// More Information: https://api.slack.com/reference/messaging/blocks#actions
type ContextBlock struct {
Type MessageBlockType `json:"type"`
BlockID string `json:"block_id,omitempty"`
ContextElements ContextElements `json:"elements"`
}
// BlockType returns the type of the block
func (s ContextBlock) BlockType() MessageBlockType {
return s.Type
}
type ContextElements struct {
Elements []MixedElement
}
// NewContextBlock returns a new instance of a context block
func NewContextBlock(blockID string, mixedElements ...MixedElement) *ContextBlock {
elements := ContextElements{
Elements: mixedElements,
}
return &ContextBlock{
Type: MBTContext,
BlockID: blockID,
ContextElements: elements,
}
}

303
vendor/github.com/nlopes/slack/block_conv.go generated vendored Normal file
View File

@ -0,0 +1,303 @@
package slack
import (
"encoding/json"
"github.com/pkg/errors"
)
type sumtype struct {
TypeVal string `json:"type"`
}
// MarshalJSON implements the Marshaller interface for Blocks so that any JSON
// marshalling is delegated and proper type determination can be made before marshal
func (b Blocks) MarshalJSON() ([]byte, error) {
bytes, err := json.Marshal(b.BlockSet)
if err != nil {
return nil, err
}
return bytes, nil
}
// UnmarshalJSON implements the Unmarshaller interface for Blocks, so that any JSON
// unmarshalling is delegated and proper type determination can be made before unmarshal
func (b *Blocks) UnmarshalJSON(data []byte) error {
var raw []json.RawMessage
if string(data) == "{}" {
return nil
}
err := json.Unmarshal(data, &raw)
if err != nil {
return err
}
var blocks Blocks
for _, r := range raw {
s := sumtype{}
err := json.Unmarshal(r, &s)
if err != nil {
return err
}
var blockType string
if s.TypeVal != "" {
blockType = s.TypeVal
}
var block Block
switch blockType {
case "actions":
block = &ActionBlock{}
case "context":
block = &ContextBlock{}
case "divider":
block = &DividerBlock{}
case "image":
block = &ImageBlock{}
case "section":
block = &SectionBlock{}
default:
return errors.New("unsupported block type")
}
err = json.Unmarshal(r, block)
if err != nil {
return err
}
blocks.BlockSet = append(blocks.BlockSet, block)
}
*b = blocks
return nil
}
// MarshalJSON implements the Marshaller interface for BlockElements so that any JSON
// marshalling is delegated and proper type determination can be made before marshal
func (b *BlockElements) MarshalJSON() ([]byte, error) {
bytes, err := json.Marshal(b.ElementSet)
if err != nil {
return nil, err
}
return bytes, nil
}
// UnmarshalJSON implements the Unmarshaller interface for BlockElements, so that any JSON
// unmarshalling is delegated and proper type determination can be made before unmarshal
func (b *BlockElements) UnmarshalJSON(data []byte) error {
var raw []json.RawMessage
if string(data) == "{}" {
return nil
}
err := json.Unmarshal(data, &raw)
if err != nil {
return err
}
var blockElements BlockElements
for _, r := range raw {
s := sumtype{}
err := json.Unmarshal(r, &s)
if err != nil {
return err
}
var blockElementType string
if s.TypeVal != "" {
blockElementType = s.TypeVal
}
var blockElement BlockElement
switch blockElementType {
case "image":
blockElement = &ImageBlockElement{}
case "button":
blockElement = &ButtonBlockElement{}
case "overflow":
blockElement = &OverflowBlockElement{}
case "datepicker":
blockElement = &DatePickerBlockElement{}
case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
blockElement = &SelectBlockElement{}
default:
return errors.New("unsupported block element type")
}
err = json.Unmarshal(r, blockElement)
if err != nil {
return err
}
blockElements.ElementSet = append(blockElements.ElementSet, blockElement)
}
*b = blockElements
return nil
}
// MarshalJSON implements the Marshaller interface for Accessory so that any JSON
// marshalling is delegated and proper type determination can be made before marshal
func (a *Accessory) MarshalJSON() ([]byte, error) {
bytes, err := json.Marshal(toBlockElement(a))
if err != nil {
return nil, err
}
return bytes, nil
}
// UnmarshalJSON implements the Unmarshaller interface for Accessory, so that any JSON
// unmarshalling is delegated and proper type determination can be made before unmarshal
func (a *Accessory) UnmarshalJSON(data []byte) error {
var r json.RawMessage
if string(data) == "{\"accessory\":null}" {
return nil
}
err := json.Unmarshal(data, &r)
if err != nil {
return err
}
s := sumtype{}
err = json.Unmarshal(r, &s)
if err != nil {
return err
}
var blockElementType string
if s.TypeVal != "" {
blockElementType = s.TypeVal
}
switch blockElementType {
case "image":
element, err := unmarshalBlockElement(r, &ImageBlockElement{})
if err != nil {
return err
}
a.ImageElement = element.(*ImageBlockElement)
case "button":
element, err := unmarshalBlockElement(r, &ButtonBlockElement{})
if err != nil {
return err
}
a.ButtonElement = element.(*ButtonBlockElement)
case "overflow":
element, err := unmarshalBlockElement(r, &OverflowBlockElement{})
if err != nil {
return err
}
a.OverflowElement = element.(*OverflowBlockElement)
case "datepicker":
element, err := unmarshalBlockElement(r, &DatePickerBlockElement{})
if err != nil {
return err
}
a.DatePickerElement = element.(*DatePickerBlockElement)
case "static_select":
element, err := unmarshalBlockElement(r, &SelectBlockElement{})
if err != nil {
return err
}
a.SelectElement = element.(*SelectBlockElement)
}
return nil
}
func unmarshalBlockElement(r json.RawMessage, element BlockElement) (BlockElement, error) {
err := json.Unmarshal(r, element)
if err != nil {
return nil, err
}
return element, nil
}
func toBlockElement(element *Accessory) BlockElement {
if element.ImageElement != nil {
return element.ImageElement
}
if element.ButtonElement != nil {
return element.ButtonElement
}
if element.OverflowElement != nil {
return element.OverflowElement
}
if element.DatePickerElement != nil {
return element.DatePickerElement
}
if element.SelectElement != nil {
return element.SelectElement
}
return nil
}
// MarshalJSON implements the Marshaller interface for ContextElements so that any JSON
// marshalling is delegated and proper type determination can be made before marshal
func (e *ContextElements) MarshalJSON() ([]byte, error) {
bytes, err := json.Marshal(e.Elements)
if err != nil {
return nil, err
}
return bytes, nil
}
// UnmarshalJSON implements the Unmarshaller interface for ContextElements, so that any JSON
// unmarshalling is delegated and proper type determination can be made before unmarshal
func (e *ContextElements) UnmarshalJSON(data []byte) error {
var raw []json.RawMessage
if string(data) == "{\"elements\":null}" {
return nil
}
err := json.Unmarshal(data, &raw)
if err != nil {
return err
}
for _, r := range raw {
s := sumtype{}
err := json.Unmarshal(r, &s)
if err != nil {
return err
}
var contextElementType string
if s.TypeVal != "" {
contextElementType = s.TypeVal
}
switch contextElementType {
case PlainTextType, MarkdownType:
elem, err := unmarshalBlockObject(r, &TextBlockObject{})
if err != nil {
return err
}
e.Elements = append(e.Elements, elem.(*TextBlockObject))
case "image":
elem, err := unmarshalBlockElement(r, &ImageBlockElement{})
if err != nil {
return err
}
e.Elements = append(e.Elements, elem.(*ImageBlockElement))
default:
return errors.New("unsupported context element type")
}
}
return nil
}

22
vendor/github.com/nlopes/slack/block_divider.go generated vendored Normal file
View File

@ -0,0 +1,22 @@
package slack
// DividerBlock for displaying a divider line between blocks (similar to <hr> tag in html)
//
// More Information: https://api.slack.com/reference/messaging/blocks#divider
type DividerBlock struct {
Type MessageBlockType `json:"type"`
BlockID string `json:"block_id,omitempty"`
}
// BlockType returns the type of the block
func (s DividerBlock) BlockType() MessageBlockType {
return s.Type
}
// NewDividerBlock returns a new instance of a divider block
func NewDividerBlock() *DividerBlock {
return &DividerBlock{
Type: MBTDivider,
}
}

238
vendor/github.com/nlopes/slack/block_element.go generated vendored Normal file
View File

@ -0,0 +1,238 @@
package slack
// https://api.slack.com/reference/messaging/block-elements
const (
METImage MessageElementType = "image"
METButton MessageElementType = "button"
METOverflow MessageElementType = "overflow"
METDatepicker MessageElementType = "datepicker"
MixedElementImage MixedElementType = "mixed_image"
MixedElementText MixedElementType = "mixed_text"
OptTypeStatic string = "static_select"
OptTypeExternal string = "external_select"
OptTypeUser string = "users_select"
OptTypeConversations string = "conversations_select"
OptTypeChannels string = "channels_select"
)
type MessageElementType string
type MixedElementType string
// BlockElement defines an interface that all block element types should implement.
type BlockElement interface {
ElementType() MessageElementType
}
type MixedElement interface {
MixedElementType() MixedElementType
}
type Accessory struct {
ImageElement *ImageBlockElement
ButtonElement *ButtonBlockElement
OverflowElement *OverflowBlockElement
DatePickerElement *DatePickerBlockElement
SelectElement *SelectBlockElement
}
// NewAccessory returns a new Accessory for a given block element
func NewAccessory(element BlockElement) *Accessory {
switch element.(type) {
case *ImageBlockElement:
return &Accessory{ImageElement: element.(*ImageBlockElement)}
case *ButtonBlockElement:
return &Accessory{ButtonElement: element.(*ButtonBlockElement)}
case *OverflowBlockElement:
return &Accessory{OverflowElement: element.(*OverflowBlockElement)}
case *DatePickerBlockElement:
return &Accessory{DatePickerElement: element.(*DatePickerBlockElement)}
case *SelectBlockElement:
return &Accessory{SelectElement: element.(*SelectBlockElement)}
}
return nil
}
// BlockElements is a convenience struct defined to allow dynamic unmarshalling of
// the "elements" value in Slack's JSON response, which varies depending on BlockElement type
type BlockElements struct {
ElementSet []BlockElement `json:"elements,omitempty"`
}
// ImageBlockElement An element to insert an image - this element can be used
// in section and context blocks only. If you want a block with only an image
// in it, you're looking for the image block.
//
// More Information: https://api.slack.com/reference/messaging/block-elements#image
type ImageBlockElement struct {
Type MessageElementType `json:"type"`
ImageURL string `json:"image_url"`
AltText string `json:"alt_text"`
}
// ElementType returns the type of the Element
func (s ImageBlockElement) ElementType() MessageElementType {
return s.Type
}
func (s ImageBlockElement) MixedElementType() MixedElementType {
return MixedElementImage
}
// NewImageBlockElement returns a new instance of an image block element
func NewImageBlockElement(imageURL, altText string) *ImageBlockElement {
return &ImageBlockElement{
Type: METImage,
ImageURL: imageURL,
AltText: altText,
}
}
type Style string
const (
StyleDefault Style = "default"
StylePrimary Style = "primary"
StyleDanger Style = "danger"
)
// ButtonBlockElement defines an interactive element that inserts a button. The
// button can be a trigger for anything from opening a simple link to starting
// a complex workflow.
//
// More Information: https://api.slack.com/reference/messaging/block-elements#button
type ButtonBlockElement struct {
Type MessageElementType `json:"type,omitempty"`
Text *TextBlockObject `json:"text"`
ActionID string `json:"action_id,omitempty"`
URL string `json:"url,omitempty"`
Value string `json:"value,omitempty"`
Confirm *ConfirmationBlockObject `json:"confirm,omitempty"`
Style Style `json:"style,omitempty"`
}
// ElementType returns the type of the element
func (s ButtonBlockElement) ElementType() MessageElementType {
return s.Type
}
// add styling to button object
func (s *ButtonBlockElement) WithStyle(style Style) {
s.Style = style
}
// NewButtonBlockElement returns an instance of a new button element to be used within a block
func NewButtonBlockElement(actionID, value string, text *TextBlockObject) *ButtonBlockElement {
return &ButtonBlockElement{
Type: METButton,
ActionID: actionID,
Text: text,
Value: value,
}
}
// SelectBlockElement defines the simplest form of select menu, with a static list
// of options passed in when defining the element.
//
// More Information: https://api.slack.com/reference/messaging/block-elements#select
type SelectBlockElement struct {
Type string `json:"type,omitempty"`
Placeholder *TextBlockObject `json:"placeholder,omitempty"`
ActionID string `json:"action_id,omitempty"`
Options []*OptionBlockObject `json:"options,omitempty"`
OptionGroups []*OptionGroupBlockObject `json:"option_groups,omitempty"`
InitialOption *OptionBlockObject `json:"initial_option,omitempty"`
InitialUser string `json:"initial_user,omitempty"`
InitialConversation string `json:"initial_conversation,omitempty"`
InitialChannel string `json:"initial_channel,omitempty"`
MinQueryLength int `json:"min_query_length,omitempty"`
Confirm *ConfirmationBlockObject `json:"confirm,omitempty"`
}
// ElementType returns the type of the Element
func (s SelectBlockElement) ElementType() MessageElementType {
return MessageElementType(s.Type)
}
// NewOptionsSelectBlockElement returns a new instance of SelectBlockElement for use with
// the Options object only.
func NewOptionsSelectBlockElement(optType string, placeholder *TextBlockObject, actionID string, options ...*OptionBlockObject) *SelectBlockElement {
return &SelectBlockElement{
Type: optType,
Placeholder: placeholder,
ActionID: actionID,
Options: options,
}
}
// NewOptionsGroupSelectBlockElement returns a new instance of SelectBlockElement for use with
// the Options object only.
func NewOptionsGroupSelectBlockElement(
optType string,
placeholder *TextBlockObject,
actionID string,
optGroups ...*OptionGroupBlockObject,
) *SelectBlockElement {
return &SelectBlockElement{
Type: optType,
Placeholder: placeholder,
ActionID: actionID,
OptionGroups: optGroups,
}
}
// OverflowBlockElement defines the fields needed to use an overflow element.
// And Overflow Element is like a cross between a button and a select menu -
// when a user clicks on this overflow button, they will be presented with a
// list of options to choose from.
//
// More Information: https://api.slack.com/reference/messaging/block-elements#overflow
type OverflowBlockElement struct {
Type MessageElementType `json:"type"`
ActionID string `json:"action_id,omitempty"`
Options []*OptionBlockObject `json:"options"`
Confirm *ConfirmationBlockObject `json:"confirm,omitempty"`
}
// ElementType returns the type of the Element
func (s OverflowBlockElement) ElementType() MessageElementType {
return s.Type
}
// NewOverflowBlockElement returns an instance of a new Overflow Block Element
func NewOverflowBlockElement(actionID string, options ...*OptionBlockObject) *OverflowBlockElement {
return &OverflowBlockElement{
Type: METOverflow,
ActionID: actionID,
Options: options,
}
}
// DatePickerBlockElement defines an element which lets users easily select a
// date from a calendar style UI. Date picker elements can be used inside of
// section and actions blocks.
//
// More Information: https://api.slack.com/reference/messaging/block-elements#datepicker
type DatePickerBlockElement struct {
Type MessageElementType `json:"type"`
ActionID string `json:"action_id"`
Placeholder *TextBlockObject `json:"placeholder,omitempty"`
InitialDate string `json:"initial_date,omitempty"`
Confirm *ConfirmationBlockObject `json:"confirm,omitempty"`
}
// ElementType returns the type of the Element
func (s DatePickerBlockElement) ElementType() MessageElementType {
return s.Type
}
// NewDatePickerBlockElement returns an instance of a date picker element
func NewDatePickerBlockElement(actionID string) *DatePickerBlockElement {
return &DatePickerBlockElement{
Type: METDatepicker,
ActionID: actionID,
}
}

28
vendor/github.com/nlopes/slack/block_image.go generated vendored Normal file
View File

@ -0,0 +1,28 @@
package slack
// ImageBlock defines data required to display an image as a block element
//
// More Information: https://api.slack.com/reference/messaging/blocks#image
type ImageBlock struct {
Type MessageBlockType `json:"type"`
ImageURL string `json:"image_url"`
AltText string `json:"alt_text"`
BlockID string `json:"block_id,omitempty"`
Title *TextBlockObject `json:"title"`
}
// BlockType returns the type of the block
func (s ImageBlock) BlockType() MessageBlockType {
return s.Type
}
// NewImageBlock returns an instance of a new Image Block type
func NewImageBlock(imageURL, altText, blockID string, title *TextBlockObject) *ImageBlock {
return &ImageBlock{
Type: MBTImage,
ImageURL: imageURL,
AltText: altText,
BlockID: blockID,
Title: title,
}
}

216
vendor/github.com/nlopes/slack/block_object.go generated vendored Normal file
View File

@ -0,0 +1,216 @@
package slack
import (
"encoding/json"
)
// Block Objects are also known as Composition Objects
//
// For more information: https://api.slack.com/reference/messaging/composition-objects
// BlockObject defines an interface that all block object types should
// implement.
// @TODO: Is this interface needed?
// blockObject object types
const (
MarkdownType = "mrkdwn"
PlainTextType = "plain_text"
// The following objects don't actually have types and their corresponding
// const values are just for internal use
motConfirmation = "confirm"
motOption = "option"
motOptionGroup = "option_group"
)
type MessageObjectType string
type blockObject interface {
validateType() MessageObjectType
}
type BlockObjects struct {
TextObjects []*TextBlockObject
ConfirmationObjects []*ConfirmationBlockObject
OptionObjects []*OptionBlockObject
OptionGroupObjects []*OptionGroupBlockObject
}
// UnmarshalJSON implements the Unmarshaller interface for BlockObjects, so that any JSON
// unmarshalling is delegated and proper type determination can be made before unmarshal
func (b *BlockObjects) UnmarshalJSON(data []byte) error {
var raw []json.RawMessage
err := json.Unmarshal(data, &raw)
if err != nil {
return err
}
for _, r := range raw {
var obj map[string]interface{}
err := json.Unmarshal(r, &obj)
if err != nil {
return err
}
blockObjectType := getBlockObjectType(obj)
switch blockObjectType {
case PlainTextType, MarkdownType:
object, err := unmarshalBlockObject(r, &TextBlockObject{})
if err != nil {
return err
}
b.TextObjects = append(b.TextObjects, object.(*TextBlockObject))
case motConfirmation:
object, err := unmarshalBlockObject(r, &ConfirmationBlockObject{})
if err != nil {
return err
}
b.ConfirmationObjects = append(b.ConfirmationObjects, object.(*ConfirmationBlockObject))
case motOption:
object, err := unmarshalBlockObject(r, &OptionBlockObject{})
if err != nil {
return err
}
b.OptionObjects = append(b.OptionObjects, object.(*OptionBlockObject))
case motOptionGroup:
object, err := unmarshalBlockObject(r, &OptionGroupBlockObject{})
if err != nil {
return err
}
b.OptionGroupObjects = append(b.OptionGroupObjects, object.(*OptionGroupBlockObject))
}
}
return nil
}
// Ideally would have a better way to identify the block objects for
// type casting at time of unmarshalling, should be adapted if possible
// to accomplish in a more reliable manner.
func getBlockObjectType(obj map[string]interface{}) string {
if t, ok := obj["type"].(string); ok {
return t
}
if _, ok := obj["confirm"].(string); ok {
return "confirm"
}
if _, ok := obj["options"].(string); ok {
return "option_group"
}
if _, ok := obj["text"].(string); ok {
if _, ok := obj["value"].(string); ok {
return "option"
}
}
return ""
}
func unmarshalBlockObject(r json.RawMessage, object blockObject) (blockObject, error) {
err := json.Unmarshal(r, object)
if err != nil {
return nil, err
}
return object, nil
}
// TextBlockObject defines a text element object to be used with blocks
//
// More Information: https://api.slack.com/reference/messaging/composition-objects#text
type TextBlockObject struct {
Type string `json:"type"`
Text string `json:"text"`
Emoji bool `json:"emoji,omitempty"`
Verbatim bool `json:"verbatim,omitempty"`
}
// validateType enforces block objects for element and block parameters
func (s TextBlockObject) validateType() MessageObjectType {
return MessageObjectType(s.Type)
}
// validateType enforces block objects for element and block parameters
func (s TextBlockObject) MixedElementType() MixedElementType {
return MixedElementText
}
// NewTextBlockObject returns an instance of a new Text Block Object
func NewTextBlockObject(elementType, text string, emoji, verbatim bool) *TextBlockObject {
return &TextBlockObject{
Type: elementType,
Text: text,
Emoji: emoji,
Verbatim: verbatim,
}
}
// ConfirmationBlockObject defines a dialog that provides a confirmation step to
// any interactive element. This dialog will ask the user to confirm their action by
// offering a confirm and deny buttons.
//
// More Information: https://api.slack.com/reference/messaging/composition-objects#confirm
type ConfirmationBlockObject struct {
Title *TextBlockObject `json:"title"`
Text *TextBlockObject `json:"text"`
Confirm *TextBlockObject `json:"confirm"`
Deny *TextBlockObject `json:"deny"`
}
// validateType enforces block objects for element and block parameters
func (s ConfirmationBlockObject) validateType() MessageObjectType {
return motConfirmation
}
// NewConfirmationBlockObject returns an instance of a new Confirmation Block Object
func NewConfirmationBlockObject(title, text, confirm, deny *TextBlockObject) *ConfirmationBlockObject {
return &ConfirmationBlockObject{
Title: title,
Text: text,
Confirm: confirm,
Deny: deny,
}
}
// OptionBlockObject represents a single selectable item in a select menu
//
// More Information: https://api.slack.com/reference/messaging/composition-objects#option
type OptionBlockObject struct {
Text *TextBlockObject `json:"text"`
Value string `json:"value"`
URL string `json:"url"`
}
// NewOptionBlockObject returns an instance of a new Option Block Element
func NewOptionBlockObject(value string, text *TextBlockObject) *OptionBlockObject {
return &OptionBlockObject{
Text: text,
Value: value,
}
}
// validateType enforces block objects for element and block parameters
func (s OptionBlockObject) validateType() MessageObjectType {
return motOption
}
// OptionGroupBlockObject Provides a way to group options in a select menu.
//
// More Information: https://api.slack.com/reference/messaging/composition-objects#option-group
type OptionGroupBlockObject struct {
Label *TextBlockObject `json:"label,omitempty"`
Options []*OptionBlockObject `json:"options"`
}
// validateType enforces block objects for element and block parameters
func (s OptionGroupBlockObject) validateType() MessageObjectType {
return motOptionGroup
}
// NewOptionGroupBlockElement returns an instance of a new option group block element
func NewOptionGroupBlockElement(label *TextBlockObject, options ...*OptionBlockObject) *OptionGroupBlockObject {
return &OptionGroupBlockObject{
Label: label,
Options: options,
}
}

42
vendor/github.com/nlopes/slack/block_section.go generated vendored Normal file
View File

@ -0,0 +1,42 @@
package slack
// SectionBlock defines a new block of type section
//
// More Information: https://api.slack.com/reference/messaging/blocks#section
type SectionBlock struct {
Type MessageBlockType `json:"type"`
Text *TextBlockObject `json:"text,omitempty"`
BlockID string `json:"block_id,omitempty"`
Fields []*TextBlockObject `json:"fields,omitempty"`
Accessory *Accessory `json:"accessory,omitempty"`
}
// BlockType returns the type of the block
func (s SectionBlock) BlockType() MessageBlockType {
return s.Type
}
// SectionBlockOption allows configuration of options for a new section block
type SectionBlockOption func(*SectionBlock)
func SectionBlockOptionBlockID(blockID string) SectionBlockOption {
return func(block *SectionBlock) {
block.BlockID = blockID
}
}
// NewSectionBlock returns a new instance of a section block to be rendered
func NewSectionBlock(textObj *TextBlockObject, fields []*TextBlockObject, accessory *Accessory, options ...SectionBlockOption) *SectionBlock {
block := SectionBlock{
Type: MBTSection,
Text: textObj,
Fields: fields,
Accessory: accessory,
}
for _, option := range options {
option(&block)
}
return &block
}

View File

@ -2,7 +2,6 @@ package slack
import (
"context"
"errors"
"net/url"
)
@ -19,15 +18,17 @@ type botResponseFull struct {
SlackResponse
}
func botRequest(ctx context.Context, client httpClient, path string, values url.Values, d debug) (*botResponseFull, error) {
func (api *Client) botRequest(ctx context.Context, path string, values url.Values) (*botResponseFull, error) {
response := &botResponseFull{}
err := postSlackMethod(ctx, client, path, values, response, d)
err := api.postMethod(ctx, path, values, response)
if err != nil {
return nil, err
}
if !response.Ok {
return nil, errors.New(response.Error)
if err := response.Err(); err != nil {
return nil, err
}
return response, nil
}
@ -40,10 +41,13 @@ func (api *Client) GetBotInfo(bot string) (*Bot, error) {
func (api *Client) GetBotInfoContext(ctx context.Context, bot string) (*Bot, error) {
values := url.Values{
"token": {api.token},
"bot": {bot},
}
response, err := botRequest(ctx, api.httpclient, "bots.info", values, api)
if bot != "" {
values.Add("bot", bot)
}
response, err := api.botRequest(ctx, "bots.info", values)
if err != nil {
return nil, err
}

View File

@ -2,7 +2,6 @@ package slack
import (
"context"
"errors"
"net/url"
"strconv"
)
@ -19,23 +18,21 @@ type channelResponseFull struct {
// Channel contains information about the channel
type Channel struct {
groupConversation
GroupConversation
IsChannel bool `json:"is_channel"`
IsGeneral bool `json:"is_general"`
IsMember bool `json:"is_member"`
Locale string `json:"locale"`
}
func channelRequest(ctx context.Context, client httpClient, path string, values url.Values, d debug) (*channelResponseFull, error) {
func (api *Client) channelRequest(ctx context.Context, path string, values url.Values) (*channelResponseFull, error) {
response := &channelResponseFull{}
err := postForm(ctx, client, APIURL+path, values, response, d)
err := postForm(ctx, api.httpclient, api.endpoint+path, values, response, api)
if err != nil {
return nil, err
}
if !response.Ok {
return nil, errors.New(response.Error)
}
return response, nil
return response, response.Err()
}
type channelsConfig struct {
@ -75,7 +72,7 @@ func (api *Client) ArchiveChannelContext(ctx context.Context, channelID string)
"channel": {channelID},
}
_, err = channelRequest(ctx, api.httpclient, "channels.archive", values, api)
_, err = api.channelRequest(ctx, "channels.archive", values)
return err
}
@ -93,7 +90,7 @@ func (api *Client) UnarchiveChannelContext(ctx context.Context, channelID string
"channel": {channelID},
}
_, err = channelRequest(ctx, api.httpclient, "channels.unarchive", values, api)
_, err = api.channelRequest(ctx, "channels.unarchive", values)
return err
}
@ -111,7 +108,7 @@ func (api *Client) CreateChannelContext(ctx context.Context, channelName string)
"name": {channelName},
}
response, err := channelRequest(ctx, api.httpclient, "channels.create", values, api)
response, err := api.channelRequest(ctx, "channels.create", values)
if err != nil {
return nil, err
}
@ -156,7 +153,7 @@ func (api *Client) GetChannelHistoryContext(ctx context.Context, channelID strin
}
}
response, err := channelRequest(ctx, api.httpclient, "channels.history", values, api)
response, err := api.channelRequest(ctx, "channels.history", values)
if err != nil {
return nil, err
}
@ -178,7 +175,7 @@ func (api *Client) GetChannelInfoContext(ctx context.Context, channelID string)
"include_locale": {strconv.FormatBool(true)},
}
response, err := channelRequest(ctx, api.httpclient, "channels.info", values, api)
response, err := api.channelRequest(ctx, "channels.info", values)
if err != nil {
return nil, err
}
@ -200,7 +197,7 @@ func (api *Client) InviteUserToChannelContext(ctx context.Context, channelID, us
"user": {user},
}
response, err := channelRequest(ctx, api.httpclient, "channels.invite", values, api)
response, err := api.channelRequest(ctx, "channels.invite", values)
if err != nil {
return nil, err
}
@ -221,7 +218,7 @@ func (api *Client) JoinChannelContext(ctx context.Context, channelName string) (
"name": {channelName},
}
response, err := channelRequest(ctx, api.httpclient, "channels.join", values, api)
response, err := api.channelRequest(ctx, "channels.join", values)
if err != nil {
return nil, err
}
@ -242,7 +239,7 @@ func (api *Client) LeaveChannelContext(ctx context.Context, channelID string) (b
"channel": {channelID},
}
response, err := channelRequest(ctx, api.httpclient, "channels.leave", values, api)
response, err := api.channelRequest(ctx, "channels.leave", values)
if err != nil {
return false, err
}
@ -265,7 +262,7 @@ func (api *Client) KickUserFromChannelContext(ctx context.Context, channelID, us
"user": {user},
}
_, err = channelRequest(ctx, api.httpclient, "channels.kick", values, api)
_, err = api.channelRequest(ctx, "channels.kick", values)
return err
}
@ -283,6 +280,7 @@ func (api *Client) GetChannelsContext(ctx context.Context, excludeArchived bool,
"token": {api.token},
},
}
if excludeArchived {
options = append(options, GetChannelsOptionExcludeArchived())
}
@ -293,7 +291,7 @@ func (api *Client) GetChannelsContext(ctx context.Context, excludeArchived bool,
}
}
response, err := channelRequest(ctx, api.httpclient, "channels.list", config.values, api)
response, err := api.channelRequest(ctx, "channels.list", config.values)
if err != nil {
return nil, err
}
@ -320,7 +318,7 @@ func (api *Client) SetChannelReadMarkContext(ctx context.Context, channelID, ts
"ts": {ts},
}
_, err = channelRequest(ctx, api.httpclient, "channels.mark", values, api)
_, err = api.channelRequest(ctx, "channels.mark", values)
return err
}
@ -341,7 +339,7 @@ func (api *Client) RenameChannelContext(ctx context.Context, channelID, name str
// XXX: the created entry in this call returns a string instead of a number
// so I may have to do some workaround to solve it.
response, err := channelRequest(ctx, api.httpclient, "channels.rename", values, api)
response, err := api.channelRequest(ctx, "channels.rename", values)
if err != nil {
return nil, err
}
@ -363,7 +361,7 @@ func (api *Client) SetChannelPurposeContext(ctx context.Context, channelID, purp
"purpose": {purpose},
}
response, err := channelRequest(ctx, api.httpclient, "channels.setPurpose", values, api)
response, err := api.channelRequest(ctx, "channels.setPurpose", values)
if err != nil {
return "", err
}
@ -385,7 +383,7 @@ func (api *Client) SetChannelTopicContext(ctx context.Context, channelID, topic
"topic": {topic},
}
response, err := channelRequest(ctx, api.httpclient, "channels.setTopic", values, api)
response, err := api.channelRequest(ctx, "channels.setTopic", values)
if err != nil {
return "", err
}
@ -406,7 +404,7 @@ func (api *Client) GetChannelRepliesContext(ctx context.Context, channelID, thre
"channel": {channelID},
"thread_ts": {thread_ts},
}
response, err := channelRequest(ctx, api.httpclient, "channels.replies", values, api)
response, err := api.channelRequest(ctx, "channels.replies", values)
if err != nil {
return nil, err
}

View File

@ -3,6 +3,7 @@ package slack
import (
"context"
"encoding/json"
"net/http"
"net/url"
"github.com/nlopes/slack/slackutilsx"
@ -25,7 +26,7 @@ const (
type chatResponseFull struct {
Channel string `json:"channel"`
Timestamp string `json:"ts"` //Regualr message timestamp
Timestamp string `json:"ts"` //Regular message timestamp
MessageTimeStamp string `json:"message_ts"` //Ephemeral message timestamp
Text string `json:"text"`
SlackResponse
@ -156,17 +157,18 @@ func (api *Client) SendMessage(channel string, options ...MsgOption) (string, st
}
// SendMessageContext more flexible method for configuring messages with a custom context.
func (api *Client) SendMessageContext(ctx context.Context, channelID string, options ...MsgOption) (channel string, timestamp string, text string, err error) {
func (api *Client) SendMessageContext(ctx context.Context, channelID string, options ...MsgOption) (_channel string, _timestamp string, _text string, err error) {
var (
config sendConfig
req *http.Request
parser func(*chatResponseFull) responseParser
response chatResponseFull
)
if config, err = applyMsgOptions(api.token, channelID, options...); err != nil {
if req, parser, err = buildSender(api.endpoint, options...).BuildRequest(api.token, channelID); err != nil {
return "", "", "", err
}
if err = postForm(ctx, api.httpclient, config.endpoint, config.values, &response, api); err != nil {
if err = doPost(ctx, api.httpclient, req, parser(&response), api); err != nil {
return "", "", "", err
}
@ -176,14 +178,15 @@ func (api *Client) SendMessageContext(ctx context.Context, channelID string, opt
// UnsafeApplyMsgOptions utility function for debugging/testing chat requests.
// NOTE: USE AT YOUR OWN RISK: No issues relating to the use of this function
// will be supported by the library.
func UnsafeApplyMsgOptions(token, channel string, options ...MsgOption) (string, url.Values, error) {
config, err := applyMsgOptions(token, channel, options...)
func UnsafeApplyMsgOptions(token, channel, apiurl string, options ...MsgOption) (string, url.Values, error) {
config, err := applyMsgOptions(token, channel, apiurl, options...)
return config.endpoint, config.values, err
}
func applyMsgOptions(token, channel string, options ...MsgOption) (sendConfig, error) {
func applyMsgOptions(token, channel, apiurl string, options ...MsgOption) (sendConfig, error) {
config := sendConfig{
endpoint: APIURL + string(chatPostMessage),
apiurl: apiurl,
endpoint: apiurl + string(chatPostMessage),
values: url.Values{
"token": {token},
"channel": {channel},
@ -199,6 +202,13 @@ func applyMsgOptions(token, channel string, options ...MsgOption) (sendConfig, e
return config, nil
}
func buildSender(apiurl string, options ...MsgOption) sendConfig {
return sendConfig{
apiurl: apiurl,
options: options,
}
}
type sendMode string
const (
@ -206,22 +216,77 @@ const (
chatPostMessage sendMode = "chat.postMessage"
chatDelete sendMode = "chat.delete"
chatPostEphemeral sendMode = "chat.postEphemeral"
chatResponse sendMode = "chat.responseURL"
chatMeMessage sendMode = "chat.meMessage"
chatUnfurl sendMode = "chat.unfurl"
)
type sendConfig struct {
apiurl string
options []MsgOption
mode sendMode
endpoint string
values url.Values
attachments []Attachment
responseType string
}
func (t sendConfig) BuildRequest(token, channelID string) (req *http.Request, _ func(*chatResponseFull) responseParser, err error) {
if t, err = applyMsgOptions(token, channelID, t.apiurl, t.options...); err != nil {
return nil, nil, err
}
switch t.mode {
case chatResponse:
return responseURLSender{
endpoint: t.endpoint,
values: t.values,
attachments: t.attachments,
responseType: t.responseType,
}.BuildRequest()
default:
return formSender{endpoint: t.endpoint, values: t.values}.BuildRequest()
}
}
type formSender struct {
endpoint string
values url.Values
}
func (t formSender) BuildRequest() (*http.Request, func(*chatResponseFull) responseParser, error) {
req, err := formReq(t.endpoint, t.values)
return req, func(resp *chatResponseFull) responseParser {
return newJSONParser(resp)
}, err
}
type responseURLSender struct {
endpoint string
values url.Values
attachments []Attachment
responseType string
}
func (t responseURLSender) BuildRequest() (*http.Request, func(*chatResponseFull) responseParser, error) {
req, err := jsonReq(t.endpoint, Msg{
Text: t.values.Get("text"),
Timestamp: t.values.Get("ts"),
Attachments: t.attachments,
ResponseType: t.responseType,
})
return req, func(resp *chatResponseFull) responseParser {
return newContentTypeParser(resp)
}, err
}
// MsgOption option provided when sending a message.
type MsgOption func(*sendConfig) error
// MsgOptionPost posts a messages, this is the default.
func MsgOptionPost() MsgOption {
return func(config *sendConfig) error {
config.endpoint = APIURL + string(chatPostMessage)
config.endpoint = config.apiurl + string(chatPostMessage)
config.values.Del("ts")
return nil
}
@ -230,7 +295,7 @@ func MsgOptionPost() MsgOption {
// MsgOptionPostEphemeral - posts an ephemeral message to the provided user.
func MsgOptionPostEphemeral(userID string) MsgOption {
return func(config *sendConfig) error {
config.endpoint = APIURL + string(chatPostEphemeral)
config.endpoint = config.apiurl + string(chatPostEphemeral)
MsgOptionUser(userID)(config)
config.values.Del("ts")
@ -241,7 +306,7 @@ func MsgOptionPostEphemeral(userID string) MsgOption {
// MsgOptionMeMessage posts a "me message" type from the calling user
func MsgOptionMeMessage() MsgOption {
return func(config *sendConfig) error {
config.endpoint = APIURL + string(chatMeMessage)
config.endpoint = config.apiurl + string(chatMeMessage)
return nil
}
}
@ -249,7 +314,7 @@ func MsgOptionMeMessage() MsgOption {
// MsgOptionUpdate updates a message based on the timestamp.
func MsgOptionUpdate(timestamp string) MsgOption {
return func(config *sendConfig) error {
config.endpoint = APIURL + string(chatUpdate)
config.endpoint = config.apiurl + string(chatUpdate)
config.values.Add("ts", timestamp)
return nil
}
@ -258,7 +323,7 @@ func MsgOptionUpdate(timestamp string) MsgOption {
// MsgOptionDelete deletes a message based on the timestamp.
func MsgOptionDelete(timestamp string) MsgOption {
return func(config *sendConfig) error {
config.endpoint = APIURL + string(chatDelete)
config.endpoint = config.apiurl + string(chatDelete)
config.values.Add("ts", timestamp)
return nil
}
@ -267,7 +332,7 @@ func MsgOptionDelete(timestamp string) MsgOption {
// MsgOptionUnfurl unfurls a message based on the timestamp.
func MsgOptionUnfurl(timestamp string, unfurls map[string]Attachment) MsgOption {
return func(config *sendConfig) error {
config.endpoint = APIURL + string(chatUnfurl)
config.endpoint = config.apiurl + string(chatUnfurl)
config.values.Add("ts", timestamp)
unfurlsStr, err := json.Marshal(unfurls)
if err == nil {
@ -277,6 +342,17 @@ func MsgOptionUnfurl(timestamp string, unfurls map[string]Attachment) MsgOption
}
}
// MsgOptionResponseURL supplies a url to use as the endpoint.
func MsgOptionResponseURL(url string, rt string) MsgOption {
return func(config *sendConfig) error {
config.mode = chatResponse
config.endpoint = url
config.responseType = rt
config.values.Del("ts")
return nil
}
}
// MsgOptionAsUser whether or not to send the message as the user.
func MsgOptionAsUser(b bool) MsgOption {
return func(config *sendConfig) error {
@ -322,9 +398,31 @@ func MsgOptionAttachments(attachments ...Attachment) MsgOption {
return nil
}
attachments, err := json.Marshal(attachments)
config.attachments = attachments
// FIXME: We are setting the attachments on the message twice: above for
// the json version, and below for the html version. The marshalled bytes
// we put into config.values below don't work directly in the Msg version.
attachmentBytes, err := json.Marshal(attachments)
if err == nil {
config.values.Set("attachments", string(attachments))
config.values.Set("attachments", string(attachmentBytes))
}
return err
}
}
// MsgOptionBlocks sets blocks for the message
func MsgOptionBlocks(blocks ...Block) MsgOption {
return func(config *sendConfig) error {
if blocks == nil {
return nil
}
blocks, err := json.Marshal(blocks)
if err == nil {
config.values.Set("blocks", string(blocks))
}
return err
}
@ -395,15 +493,31 @@ func MsgOptionParse(b bool) MsgOption {
return func(c *sendConfig) error {
var v string
if b {
v = "1"
v = "full"
} else {
v = "0"
v = "none"
}
c.values.Set("parse", v)
return nil
}
}
// MsgOptionIconURL sets an icon URL
func MsgOptionIconURL(iconURL string) MsgOption {
return func(c *sendConfig) error {
c.values.Set("icon_url", iconURL)
return nil
}
}
// MsgOptionIconEmoji sets an icon emoji
func MsgOptionIconEmoji(iconEmoji string) MsgOption {
return func(c *sendConfig) error {
c.values.Set("icon_emoji", iconEmoji)
return nil
}
}
// UnsafeMsgOptionEndpoint deliver the message to the specified endpoint.
// NOTE: USE AT YOUR OWN RISK: No issues relating to the use of this Option
// will be supported by the library, it is subject to change without notice that
@ -499,7 +613,7 @@ func (api *Client) GetPermalinkContext(ctx context.Context, params *PermalinkPar
Permalink string `json:"permalink"`
SlackResponse
}{}
err := getSlackMethod(ctx, api.httpclient, "chat.getPermalink", values, &response, api)
err := api.getMethod(ctx, "chat.getPermalink", values, &response)
if err != nil {
return "", err
}

View File

@ -2,14 +2,13 @@ package slack
import (
"context"
"errors"
"net/url"
"strconv"
"strings"
)
// Conversation is the foundation for IM and BaseGroupConversation
type conversation struct {
type Conversation struct {
ID string `json:"id"`
Created JSONTime `json:"created"`
IsOpen bool `json:"is_open"`
@ -36,8 +35,8 @@ type conversation struct {
}
// GroupConversation is the foundation for Group and Channel
type groupConversation struct {
conversation
type GroupConversation struct {
Conversation
Name string `json:"name"`
Creator string `json:"creator"`
IsArchived bool `json:"is_archived"`
@ -67,10 +66,11 @@ type GetUsersInConversationParameters struct {
}
type GetConversationsForUserParameters struct {
UserID string
Cursor string
Types []string
Limit int
UserID string
Cursor string
Types []string
Limit int
ExcludeArchived bool
}
type responseMetaData struct {
@ -99,13 +99,16 @@ func (api *Client) GetUsersInConversationContext(ctx context.Context, params *Ge
ResponseMetaData responseMetaData `json:"response_metadata"`
SlackResponse
}{}
err := postSlackMethod(ctx, api.httpclient, "conversations.members", values, &response, api)
err := api.postMethod(ctx, "conversations.members", values, &response)
if err != nil {
return nil, "", err
}
if !response.Ok {
return nil, "", errors.New(response.Error)
if err := response.Err(); err != nil {
return nil, "", err
}
return response.Members, response.ResponseMetaData.NextCursor, nil
}
@ -131,12 +134,15 @@ func (api *Client) GetConversationsForUserContext(ctx context.Context, params *G
if params.Types != nil {
values.Add("types", strings.Join(params.Types, ","))
}
if params.ExcludeArchived {
values.Add("exclude_archived", "true")
}
response := struct {
Channels []Channel `json:"channels"`
ResponseMetaData responseMetaData `json:"response_metadata"`
SlackResponse
}{}
err = postSlackMethod(ctx, api.httpclient, "users.conversations", values, &response, api)
err = api.postMethod(ctx, "users.conversations", values, &response)
if err != nil {
return nil, "", err
}
@ -155,8 +161,9 @@ func (api *Client) ArchiveConversationContext(ctx context.Context, channelID str
"token": {api.token},
"channel": {channelID},
}
response := SlackResponse{}
err := postSlackMethod(ctx, api.httpclient, "conversations.archive", values, &response, api)
err := api.postMethod(ctx, "conversations.archive", values, &response)
if err != nil {
return err
}
@ -176,7 +183,7 @@ func (api *Client) UnArchiveConversationContext(ctx context.Context, channelID s
"channel": {channelID},
}
response := SlackResponse{}
err := postSlackMethod(ctx, api.httpclient, "conversations.unarchive", values, &response, api)
err := api.postMethod(ctx, "conversations.unarchive", values, &response)
if err != nil {
return err
}
@ -200,7 +207,7 @@ func (api *Client) SetTopicOfConversationContext(ctx context.Context, channelID,
SlackResponse
Channel *Channel `json:"channel"`
}{}
err := postSlackMethod(ctx, api.httpclient, "conversations.setTopic", values, &response, api)
err := api.postMethod(ctx, "conversations.setTopic", values, &response)
if err != nil {
return nil, err
}
@ -224,7 +231,8 @@ func (api *Client) SetPurposeOfConversationContext(ctx context.Context, channelI
SlackResponse
Channel *Channel `json:"channel"`
}{}
err := postSlackMethod(ctx, api.httpclient, "conversations.setPurpose", values, &response, api)
err := api.postMethod(ctx, "conversations.setPurpose", values, &response)
if err != nil {
return nil, err
}
@ -248,7 +256,8 @@ func (api *Client) RenameConversationContext(ctx context.Context, channelID, cha
SlackResponse
Channel *Channel `json:"channel"`
}{}
err := postSlackMethod(ctx, api.httpclient, "conversations.rename", values, &response, api)
err := api.postMethod(ctx, "conversations.rename", values, &response)
if err != nil {
return nil, err
}
@ -272,7 +281,8 @@ func (api *Client) InviteUsersToConversationContext(ctx context.Context, channel
SlackResponse
Channel *Channel `json:"channel"`
}{}
err := postSlackMethod(ctx, api.httpclient, "conversations.invite", values, &response, api)
err := api.postMethod(ctx, "conversations.invite", values, &response)
if err != nil {
return nil, err
}
@ -292,8 +302,9 @@ func (api *Client) KickUserFromConversationContext(ctx context.Context, channelI
"channel": {channelID},
"user": {user},
}
response := SlackResponse{}
err := postSlackMethod(ctx, api.httpclient, "conversations.kick", values, &response, api)
err := api.postMethod(ctx, "conversations.kick", values, &response)
if err != nil {
return err
}
@ -318,7 +329,7 @@ func (api *Client) CloseConversationContext(ctx context.Context, channelID strin
AlreadyClosed bool `json:"already_closed"`
}{}
err = postSlackMethod(ctx, api.httpclient, "conversations.close", values, &response, api)
err = api.postMethod(ctx, "conversations.close", values, &response)
if err != nil {
return false, false, err
}
@ -338,13 +349,12 @@ func (api *Client) CreateConversationContext(ctx context.Context, channelName st
"name": {channelName},
"is_private": {strconv.FormatBool(isPrivate)},
}
response, err := channelRequest(
ctx, api.httpclient, "conversations.create", values, api)
response, err := api.channelRequest(ctx, "conversations.create", values)
if err != nil {
return nil, err
}
return &response.Channel, response.Err()
return &response.Channel, nil
}
// GetConversationInfo retrieves information about a conversation
@ -359,8 +369,7 @@ func (api *Client) GetConversationInfoContext(ctx context.Context, channelID str
"channel": {channelID},
"include_locale": {strconv.FormatBool(includeLocale)},
}
response, err := channelRequest(
ctx, api.httpclient, "conversations.info", values, api)
response, err := api.channelRequest(ctx, "conversations.info", values)
if err != nil {
return nil, err
}
@ -380,7 +389,7 @@ func (api *Client) LeaveConversationContext(ctx context.Context, channelID strin
"channel": {channelID},
}
response, err := channelRequest(ctx, api.httpclient, "conversations.leave", values, api)
response, err := api.channelRequest(ctx, "conversations.leave", values)
if err != nil {
return false, err
}
@ -436,7 +445,7 @@ func (api *Client) GetConversationRepliesContext(ctx context.Context, params *Ge
Messages []Message `json:"messages"`
}{}
err = postSlackMethod(ctx, api.httpclient, "conversations.replies", values, &response, api)
err = api.postMethod(ctx, "conversations.replies", values, &response)
if err != nil {
return nil, false, "", err
}
@ -476,7 +485,8 @@ func (api *Client) GetConversationsContext(ctx context.Context, params *GetConve
ResponseMetaData responseMetaData `json:"response_metadata"`
SlackResponse
}{}
err = postSlackMethod(ctx, api.httpclient, "conversations.list", values, &response, api)
err = api.postMethod(ctx, "conversations.list", values, &response)
if err != nil {
return nil, "", err
}
@ -513,7 +523,8 @@ func (api *Client) OpenConversationContext(ctx context.Context, params *OpenConv
AlreadyOpen bool `json:"already_open"`
SlackResponse
}{}
err := postSlackMethod(ctx, api.httpclient, "conversations.open", values, &response, api)
err := api.postMethod(ctx, "conversations.open", values, &response)
if err != nil {
return nil, false, false, err
}
@ -537,7 +548,8 @@ func (api *Client) JoinConversationContext(ctx context.Context, channelID string
} `json:"response_metadata"`
SlackResponse
}{}
err := postSlackMethod(ctx, api.httpclient, "conversations.join", values, &response, api)
err := api.postMethod(ctx, "conversations.join", values, &response)
if err != nil {
return nil, "", nil, err
}
@ -599,7 +611,7 @@ func (api *Client) GetConversationHistoryContext(ctx context.Context, params *Ge
response := GetConversationHistoryResponse{}
err := postSlackMethod(ctx, api.httpclient, "conversations.history", values, &response, api)
err := api.postMethod(ctx, "conversations.history", values, &response)
if err != nil {
return nil, err
}

View File

@ -3,7 +3,7 @@ package slack
import (
"context"
"encoding/json"
"errors"
"strings"
)
// InputType is the type of the dialog input type
@ -25,6 +25,7 @@ type DialogInput struct {
Name string `json:"name"`
Placeholder string `json:"placeholder"`
Optional bool `json:"optional"`
Hint string `json:"hint"`
}
// DialogTrigger ...
@ -89,7 +90,7 @@ func (api *Client) OpenDialog(triggerID string, dialog Dialog) (err error) {
// EXPERIMENTAL: dialog functionality is currently experimental, api is not considered stable.
func (api *Client) OpenDialogContext(ctx context.Context, triggerID string, dialog Dialog) (err error) {
if triggerID == "" {
return errors.New("received empty parameters")
return ErrParametersMissing
}
req := DialogTrigger{
@ -103,10 +104,15 @@ func (api *Client) OpenDialogContext(ctx context.Context, triggerID string, dial
}
response := &DialogOpenResponse{}
endpoint := APIURL + "dialog.open"
endpoint := api.endpoint + "dialog.open"
if err := postJSON(ctx, api.httpclient, endpoint, api.token, encoded, response, api); err != nil {
return err
}
if len(response.DialogResponseMetadata.Messages) > 0 {
response.Ok = false
response.Error += "\n" + strings.Join(response.DialogResponseMetadata.Messages, "\n")
}
return response.Err()
}

View File

@ -21,10 +21,11 @@ type DialogInputSelect struct {
DialogInput
Value string `json:"value,omitempty"` //Optional.
DataSource SelectDataSource `json:"data_source,omitempty"` //Optional. Allowed values: "users", "channels", "conversations", "external".
SelectedOptions string `json:"selected_options,omitempty"` //Optional. Default value for "external" only
SelectedOptions []DialogSelectOption `json:"selected_options,omitempty"` //Optional. May hold at most one element, for use with "external" only.
Options []DialogSelectOption `json:"options,omitempty"` //One of options or option_groups is required.
OptionGroups []DialogOptionGroup `json:"option_groups,omitempty"` //Provide up to 100 options.
MinQueryLength int `json:"min_query_length,omitempty"` //Optional. minimum characters before query is sent.
Hint string `json:"hint,omitempty"` //Optional. Additional hint text.
}
// DialogSelectOption is an option for the user to select from the menu
@ -54,14 +55,7 @@ func NewStaticSelectDialogInput(name, label string, options []DialogSelectOption
}
// NewGroupedSelectDialogInput creates grouped options select input for Dialogs.
func NewGroupedSelectDialogInput(name, label string, groups map[string]map[string]string) *DialogInputSelect {
optionGroups := []DialogOptionGroup{}
for groupName, options := range groups {
optionGroups = append(optionGroups, DialogOptionGroup{
Label: groupName,
Options: optionsFromMap(options),
})
}
func NewGroupedSelectDialogInput(name, label string, options []DialogOptionGroup) *DialogInputSelect {
return &DialogInputSelect{
DialogInput: DialogInput{
Type: InputTypeSelect,
@ -69,34 +63,15 @@ func NewGroupedSelectDialogInput(name, label string, groups map[string]map[strin
Label: label,
},
DataSource: DialogDataSourceStatic,
OptionGroups: optionGroups,
}
OptionGroups: options}
}
func optionsFromArray(options []string) []DialogSelectOption {
selectOptions := make([]DialogSelectOption, len(options))
for idx, value := range options {
selectOptions[idx] = DialogSelectOption{
Label: value,
Value: value,
}
// NewDialogOptionGroup creates a DialogOptionGroup from several select options
func NewDialogOptionGroup(label string, options ...DialogSelectOption) DialogOptionGroup {
return DialogOptionGroup{
Label: label,
Options: options,
}
return selectOptions
}
func optionsFromMap(options map[string]string) []DialogSelectOption {
selectOptions := make([]DialogSelectOption, len(options))
idx := 0
var option DialogSelectOption
for key, value := range options {
option = DialogSelectOption{
Label: key,
Value: value,
}
selectOptions[idx] = option
idx++
}
return selectOptions
}
// NewConversationsSelect returns a `Conversations` select

View File

@ -3,6 +3,9 @@ package slack
// TextInputSubtype Accepts email, number, tel, or url. In some form factors, optimized input is provided for this subtype.
type TextInputSubtype string
// TextInputOption handle to extra inputs options.
type TextInputOption func(*TextInputElement)
const (
// InputSubtypeEmail email keyboard
InputSubtypeEmail TextInputSubtype = "email"
@ -26,8 +29,8 @@ type TextInputElement struct {
}
// NewTextInput constructor for a `text` input
func NewTextInput(name, label, text string) *TextInputElement {
return &TextInputElement{
func NewTextInput(name, label, text string, options ...TextInputOption) *TextInputElement {
t := &TextInputElement{
DialogInput: DialogInput{
Type: InputTypeText,
Name: name,
@ -35,6 +38,12 @@ func NewTextInput(name, label, text string) *TextInputElement {
},
Value: text,
}
for _, opt := range options {
opt(t)
}
return t
}
// NewTextAreaInput constructor for a `textarea` input

View File

@ -2,7 +2,6 @@ package slack
import (
"context"
"errors"
"net/url"
"strconv"
"strings"
@ -36,16 +35,14 @@ type dndTeamInfoResponse struct {
SlackResponse
}
func dndRequest(ctx context.Context, client httpClient, path string, values url.Values, d debug) (*dndResponseFull, error) {
func (api *Client) dndRequest(ctx context.Context, path string, values url.Values) (*dndResponseFull, error) {
response := &dndResponseFull{}
err := postSlackMethod(ctx, client, path, values, response, d)
err := api.postMethod(ctx, path, values, response)
if err != nil {
return nil, err
}
if !response.Ok {
return nil, errors.New(response.Error)
}
return response, nil
return response, response.Err()
}
// EndDND ends the user's scheduled Do Not Disturb session
@ -61,7 +58,7 @@ func (api *Client) EndDNDContext(ctx context.Context) error {
response := &SlackResponse{}
if err := postSlackMethod(ctx, api.httpclient, "dnd.endDnd", values, response, api); err != nil {
if err := api.postMethod(ctx, "dnd.endDnd", values, response); err != nil {
return err
}
@ -79,7 +76,7 @@ func (api *Client) EndSnoozeContext(ctx context.Context) (*DNDStatus, error) {
"token": {api.token},
}
response, err := dndRequest(ctx, api.httpclient, "dnd.endSnooze", values, api)
response, err := api.dndRequest(ctx, "dnd.endSnooze", values)
if err != nil {
return nil, err
}
@ -100,7 +97,7 @@ func (api *Client) GetDNDInfoContext(ctx context.Context, user *string) (*DNDSta
values.Set("user", *user)
}
response, err := dndRequest(ctx, api.httpclient, "dnd.info", values, api)
response, err := api.dndRequest(ctx, "dnd.info", values)
if err != nil {
return nil, err
}
@ -120,13 +117,14 @@ func (api *Client) GetDNDTeamInfoContext(ctx context.Context, users []string) (m
}
response := &dndTeamInfoResponse{}
if err := postSlackMethod(ctx, api.httpclient, "dnd.teamInfo", values, response, api); err != nil {
if err := api.postMethod(ctx, "dnd.teamInfo", values, response); err != nil {
return nil, err
}
if response.Err() != nil {
return nil, response.Err()
}
return response.Users, nil
}
@ -137,7 +135,7 @@ func (api *Client) SetSnooze(minutes int) (*DNDStatus, error) {
return api.SetSnoozeContext(context.Background(), minutes)
}
// SetSnooze adjusts the snooze duration for a user's Do Not Disturb settings with a custom context.
// SetSnoozeContext adjusts the snooze duration for a user's Do Not Disturb settings with a custom context.
// For more information see the SetSnooze docs
func (api *Client) SetSnoozeContext(ctx context.Context, minutes int) (*DNDStatus, error) {
values := url.Values{
@ -145,7 +143,7 @@ func (api *Client) SetSnoozeContext(ctx context.Context, minutes int) (*DNDStatu
"num_minutes": {strconv.Itoa(minutes)},
}
response, err := dndRequest(ctx, api.httpclient, "dnd.setSnooze", values, api)
response, err := api.dndRequest(ctx, "dnd.setSnooze", values)
if err != nil {
return nil, err
}

View File

@ -2,7 +2,6 @@ package slack
import (
"context"
"errors"
"net/url"
)
@ -23,12 +22,14 @@ func (api *Client) GetEmojiContext(ctx context.Context) (map[string]string, erro
}
response := &emojiResponseFull{}
err := postSlackMethod(ctx, api.httpclient, "emoji.list", values, response, api)
err := api.postMethod(ctx, "emoji.list", values, response)
if err != nil {
return nil, err
}
if !response.Ok {
return nil, errors.New(response.Error)
if response.Err() != nil {
return nil, response.Err()
}
return response.Emoji, nil
}

18
vendor/github.com/nlopes/slack/errors.go generated vendored Normal file
View File

@ -0,0 +1,18 @@
package slack
import "github.com/nlopes/slack/internal/errorsx"
// Errors returned by various methods.
const (
ErrAlreadyDisconnected = errorsx.String("Invalid call to Disconnect - Slack API is already disconnected")
ErrRTMDisconnected = errorsx.String("disconnect received while trying to connect")
ErrParametersMissing = errorsx.String("received empty parameters")
ErrInvalidConfiguration = errorsx.String("invalid configuration")
ErrMissingHeaders = errorsx.String("missing headers")
ErrExpiredTimestamp = errorsx.String("timestamp is too old")
)
// internal errors
const (
errPaginationComplete = errorsx.String("pagination complete")
)

View File

@ -2,7 +2,6 @@ package slack
import (
"context"
"errors"
"fmt"
"io"
"net/url"
@ -91,7 +90,8 @@ type File struct {
}
type Share struct {
Public map[string][]ShareFileInfo `json:"public"`
Public map[string][]ShareFileInfo `json:"public"`
Private map[string][]ShareFileInfo `json:"private"`
}
type ShareFileInfo struct {
@ -134,11 +134,21 @@ type GetFilesParameters struct {
Page int
}
// ListFilesParameters contains all the parameters necessary (including the optional ones) for a ListFiles() request
type ListFilesParameters struct {
Limit int
User string
Channel string
Types string
Cursor string
}
type fileResponseFull struct {
File `json:"file"`
Paging `json:"paging"`
Comments []Comment `json:"comments"`
Files []File `json:"files"`
Comments []Comment `json:"comments"`
Files []File `json:"files"`
Metadata ResponseMetadata `json:"response_metadata"`
SlackResponse
}
@ -156,9 +166,9 @@ func NewGetFilesParameters() GetFilesParameters {
}
}
func fileRequest(ctx context.Context, client httpClient, path string, values url.Values, d debug) (*fileResponseFull, error) {
func (api *Client) fileRequest(ctx context.Context, path string, values url.Values) (*fileResponseFull, error) {
response := &fileResponseFull{}
err := postForm(ctx, client, APIURL+path, values, response, d)
err := api.postMethod(ctx, path, values, response)
if err != nil {
return nil, err
}
@ -180,18 +190,57 @@ func (api *Client) GetFileInfoContext(ctx context.Context, fileID string, count,
"page": {strconv.Itoa(page)},
}
response, err := fileRequest(ctx, api.httpclient, "files.info", values, api)
response, err := api.fileRequest(ctx, "files.info", values)
if err != nil {
return nil, nil, nil, err
}
return &response.File, response.Comments, &response.Paging, nil
}
// GetFile retreives a given file from its private download URL
func (api *Client) GetFile(downloadURL string, writer io.Writer) error {
return downloadFile(api.httpclient, api.token, downloadURL, writer, api)
}
// GetFiles retrieves all files according to the parameters given
func (api *Client) GetFiles(params GetFilesParameters) ([]File, *Paging, error) {
return api.GetFilesContext(context.Background(), params)
}
// ListFiles retrieves all files according to the parameters given. Uses cursor based pagination.
func (api *Client) ListFiles(params ListFilesParameters) ([]File, *ListFilesParameters, error) {
return api.ListFilesContext(context.Background(), params)
}
// ListFilesContext retrieves all files according to the parameters given with a custom context. Uses cursor based pagination.
func (api *Client) ListFilesContext(ctx context.Context, params ListFilesParameters) ([]File, *ListFilesParameters, error) {
values := url.Values{
"token": {api.token},
}
if params.User != DEFAULT_FILES_USER {
values.Add("user", params.User)
}
if params.Channel != DEFAULT_FILES_CHANNEL {
values.Add("channel", params.Channel)
}
if params.Limit != DEFAULT_FILES_COUNT {
values.Add("limit", strconv.Itoa(params.Limit))
}
if params.Cursor != "" {
values.Add("cursor", params.Cursor)
}
response, err := api.fileRequest(ctx, "files.list", values)
if err != nil {
return nil, nil, err
}
params.Cursor = response.Metadata.Cursor
return response.Files, &params, nil
}
// GetFilesContext retrieves all files according to the parameters given with a custom context
func (api *Client) GetFilesContext(ctx context.Context, params GetFilesParameters) ([]File, *Paging, error) {
values := url.Values{
@ -219,7 +268,7 @@ func (api *Client) GetFilesContext(ctx context.Context, params GetFilesParameter
values.Add("page", strconv.Itoa(params.Page))
}
response, err := fileRequest(ctx, api.httpclient, "files.list", values, api)
response, err := api.fileRequest(ctx, "files.list", values)
if err != nil {
return nil, nil, err
}
@ -239,9 +288,6 @@ func (api *Client) UploadFileContext(ctx context.Context, params FileUploadParam
if err != nil {
return nil, err
}
if params.Filename == "" {
return nil, fmt.Errorf("files.upload: FileUploadParameters.Filename is mandatory")
}
response := &fileResponseFull{}
values := url.Values{
"token": {api.token},
@ -266,12 +312,16 @@ func (api *Client) UploadFileContext(ctx context.Context, params FileUploadParam
}
if params.Content != "" {
values.Add("content", params.Content)
err = postForm(ctx, api.httpclient, APIURL+"files.upload", values, response, api)
err = api.postMethod(ctx, "files.upload", values, response)
} else if params.File != "" {
err = postLocalWithMultipartResponse(ctx, api.httpclient, "files.upload", params.File, "file", values, response, api)
err = postLocalWithMultipartResponse(ctx, api.httpclient, api.endpoint+"files.upload", params.File, "file", values, response, api)
} else if params.Reader != nil {
err = postWithMultipartResponse(ctx, api.httpclient, "files.upload", params.Filename, "file", values, params.Reader, response, api)
if params.Filename == "" {
return nil, fmt.Errorf("files.upload: FileUploadParameters.Filename is mandatory when using FileUploadParameters.Reader")
}
err = postWithMultipartResponse(ctx, api.httpclient, api.endpoint+"files.upload", params.Filename, "file", values, params.Reader, response, api)
}
if err != nil {
return nil, err
}
@ -287,7 +337,7 @@ func (api *Client) DeleteFileComment(commentID, fileID string) error {
// DeleteFileCommentContext deletes a file's comment with a custom context
func (api *Client) DeleteFileCommentContext(ctx context.Context, fileID, commentID string) (err error) {
if fileID == "" || commentID == "" {
return errors.New("received empty parameters")
return ErrParametersMissing
}
values := url.Values{
@ -295,7 +345,7 @@ func (api *Client) DeleteFileCommentContext(ctx context.Context, fileID, comment
"file": {fileID},
"id": {commentID},
}
_, err = fileRequest(ctx, api.httpclient, "files.comments.delete", values, api)
_, err = api.fileRequest(ctx, "files.comments.delete", values)
return err
}
@ -311,7 +361,7 @@ func (api *Client) DeleteFileContext(ctx context.Context, fileID string) (err er
"file": {fileID},
}
_, err = fileRequest(ctx, api.httpclient, "files.delete", values, api)
_, err = api.fileRequest(ctx, "files.delete", values)
return err
}
@ -327,7 +377,7 @@ func (api *Client) RevokeFilePublicURLContext(ctx context.Context, fileID string
"file": {fileID},
}
response, err := fileRequest(ctx, api.httpclient, "files.revokePublicURL", values, api)
response, err := api.fileRequest(ctx, "files.revokePublicURL", values)
if err != nil {
return nil, err
}
@ -346,7 +396,7 @@ func (api *Client) ShareFilePublicURLContext(ctx context.Context, fileID string)
"file": {fileID},
}
response, err := fileRequest(ctx, api.httpclient, "files.sharedPublicURL", values, api)
response, err := api.fileRequest(ctx, "files.sharedPublicURL", values)
if err != nil {
return nil, nil, nil, err
}

9
vendor/github.com/nlopes/slack/go.mod generated vendored Normal file
View File

@ -0,0 +1,9 @@
module github.com/nlopes/slack
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gorilla/websocket v1.2.0
github.com/pkg/errors v0.8.0
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.2.2
)

22
vendor/github.com/nlopes/slack/go.sum generated vendored Normal file
View File

@ -0,0 +1,22 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/nlopes/slack v0.1.0/go.mod h1:jVI4BBK3lSktibKahxBF74txcK2vyvkza1z/+rRnVAM=
github.com/nlopes/slack v0.5.0 h1:NbIae8Kd0NpqaEI3iUrsuS0KbcEDhzhc939jLW5fNm0=
github.com/nlopes/slack v0.5.0/go.mod h1:jVI4BBK3lSktibKahxBF74txcK2vyvkza1z/+rRnVAM=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/victorcoder/slack-test v0.0.0-20190131110821-6f9a569c10af h1:JFxr+No3ZWgCtxnnTWCybnB/z0Iy3qLmdj3u2NV5o48=
github.com/victorcoder/slack-test v0.0.0-20190131110821-6f9a569c10af/go.mod h1:dStM4ShMus8J3hiq66ExbbzGLkwyZ+RQJePwFhWCCvQ=
github.com/victorcoder/slack-test v0.0.0-20190131113129-a43b3bb77f43 h1:wtFekkaAAQibpy3iE4Hhx2Gi9pZAbITOSfVP7GXk5eM=
github.com/victorcoder/slack-test v0.0.0-20190131113129-a43b3bb77f43/go.mod h1:dStM4ShMus8J3hiq66ExbbzGLkwyZ+RQJePwFhWCCvQ=
golang.org/x/net v0.0.0-20180108090419-434ec0c7fe37 h1:BkNcmLtAVeWe9h5k0jt24CQgaG5vb4x/doFbAiEC/Ho=
golang.org/x/net v0.0.0-20180108090419-434ec0c7fe37/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

View File

@ -8,7 +8,7 @@ import (
// Group contains all the information for a group
type Group struct {
groupConversation
GroupConversation
IsGroup bool `json:"is_group"`
}
@ -27,9 +27,9 @@ type groupResponseFull struct {
SlackResponse
}
func groupRequest(ctx context.Context, client httpClient, path string, values url.Values, d debug) (*groupResponseFull, error) {
func (api *Client) groupRequest(ctx context.Context, path string, values url.Values) (*groupResponseFull, error) {
response := &groupResponseFull{}
err := postForm(ctx, client, APIURL+path, values, response, d)
err := api.postMethod(ctx, path, values, response)
if err != nil {
return nil, err
}
@ -49,7 +49,7 @@ func (api *Client) ArchiveGroupContext(ctx context.Context, group string) error
"channel": {group},
}
_, err := groupRequest(ctx, api.httpclient, "groups.archive", values, api)
_, err := api.groupRequest(ctx, "groups.archive", values)
return err
}
@ -65,7 +65,7 @@ func (api *Client) UnarchiveGroupContext(ctx context.Context, group string) erro
"channel": {group},
}
_, err := groupRequest(ctx, api.httpclient, "groups.unarchive", values, api)
_, err := api.groupRequest(ctx, "groups.unarchive", values)
return err
}
@ -81,7 +81,7 @@ func (api *Client) CreateGroupContext(ctx context.Context, group string) (*Group
"name": {group},
}
response, err := groupRequest(ctx, api.httpclient, "groups.create", values, api)
response, err := api.groupRequest(ctx, "groups.create", values)
if err != nil {
return nil, err
}
@ -106,7 +106,7 @@ func (api *Client) CreateChildGroupContext(ctx context.Context, group string) (*
"channel": {group},
}
response, err := groupRequest(ctx, api.httpclient, "groups.createChild", values, api)
response, err := api.groupRequest(ctx, "groups.createChild", values)
if err != nil {
return nil, err
}
@ -148,7 +148,7 @@ func (api *Client) GetGroupHistoryContext(ctx context.Context, group string, par
}
}
response, err := groupRequest(ctx, api.httpclient, "groups.history", values, api)
response, err := api.groupRequest(ctx, "groups.history", values)
if err != nil {
return nil, err
}
@ -168,7 +168,7 @@ func (api *Client) InviteUserToGroupContext(ctx context.Context, group, user str
"user": {user},
}
response, err := groupRequest(ctx, api.httpclient, "groups.invite", values, api)
response, err := api.groupRequest(ctx, "groups.invite", values)
if err != nil {
return nil, false, err
}
@ -187,7 +187,7 @@ func (api *Client) LeaveGroupContext(ctx context.Context, group string) (err err
"channel": {group},
}
_, err = groupRequest(ctx, api.httpclient, "groups.leave", values, api)
_, err = api.groupRequest(ctx, "groups.leave", values)
return err
}
@ -204,7 +204,7 @@ func (api *Client) KickUserFromGroupContext(ctx context.Context, group, user str
"user": {user},
}
_, err = groupRequest(ctx, api.httpclient, "groups.kick", values, api)
_, err = api.groupRequest(ctx, "groups.kick", values)
return err
}
@ -222,7 +222,7 @@ func (api *Client) GetGroupsContext(ctx context.Context, excludeArchived bool) (
values.Add("exclude_archived", "1")
}
response, err := groupRequest(ctx, api.httpclient, "groups.list", values, api)
response, err := api.groupRequest(ctx, "groups.list", values)
if err != nil {
return nil, err
}
@ -242,7 +242,7 @@ func (api *Client) GetGroupInfoContext(ctx context.Context, group string) (*Grou
"include_locale": {strconv.FormatBool(true)},
}
response, err := groupRequest(ctx, api.httpclient, "groups.info", values, api)
response, err := api.groupRequest(ctx, "groups.info", values)
if err != nil {
return nil, err
}
@ -267,7 +267,7 @@ func (api *Client) SetGroupReadMarkContext(ctx context.Context, group, ts string
"ts": {ts},
}
_, err = groupRequest(ctx, api.httpclient, "groups.mark", values, api)
_, err = api.groupRequest(ctx, "groups.mark", values)
return err
}
@ -283,7 +283,7 @@ func (api *Client) OpenGroupContext(ctx context.Context, group string) (bool, bo
"channel": {group},
}
response, err := groupRequest(ctx, api.httpclient, "groups.open", values, api)
response, err := api.groupRequest(ctx, "groups.open", values)
if err != nil {
return false, false, err
}
@ -307,7 +307,7 @@ func (api *Client) RenameGroupContext(ctx context.Context, group, name string) (
// XXX: the created entry in this call returns a string instead of a number
// so I may have to do some workaround to solve it.
response, err := groupRequest(ctx, api.httpclient, "groups.rename", values, api)
response, err := api.groupRequest(ctx, "groups.rename", values)
if err != nil {
return nil, err
}
@ -327,7 +327,7 @@ func (api *Client) SetGroupPurposeContext(ctx context.Context, group, purpose st
"purpose": {purpose},
}
response, err := groupRequest(ctx, api.httpclient, "groups.setPurpose", values, api)
response, err := api.groupRequest(ctx, "groups.setPurpose", values)
if err != nil {
return "", err
}
@ -347,7 +347,7 @@ func (api *Client) SetGroupTopicContext(ctx context.Context, group, topic string
"topic": {topic},
}
response, err := groupRequest(ctx, api.httpclient, "groups.setTopic", values, api)
response, err := api.groupRequest(ctx, "groups.setTopic", values)
if err != nil {
return "", err
}

20
vendor/github.com/nlopes/slack/im.go generated vendored
View File

@ -22,15 +22,13 @@ type imResponseFull struct {
// IM contains information related to the Direct Message channel
type IM struct {
conversation
IsIM bool `json:"is_im"`
User string `json:"user"`
IsUserDeleted bool `json:"is_user_deleted"`
Conversation
IsUserDeleted bool `json:"is_user_deleted"`
}
func imRequest(ctx context.Context, client httpClient, path string, values url.Values, d debug) (*imResponseFull, error) {
func (api *Client) imRequest(ctx context.Context, path string, values url.Values) (*imResponseFull, error) {
response := &imResponseFull{}
err := postSlackMethod(ctx, client, path, values, response, d)
err := api.postMethod(ctx, path, values, response)
if err != nil {
return nil, err
}
@ -50,7 +48,7 @@ func (api *Client) CloseIMChannelContext(ctx context.Context, channel string) (b
"channel": {channel},
}
response, err := imRequest(ctx, api.httpclient, "im.close", values, api)
response, err := api.imRequest(ctx, "im.close", values)
if err != nil {
return false, false, err
}
@ -71,7 +69,7 @@ func (api *Client) OpenIMChannelContext(ctx context.Context, user string) (bool,
"user": {user},
}
response, err := imRequest(ctx, api.httpclient, "im.open", values, api)
response, err := api.imRequest(ctx, "im.open", values)
if err != nil {
return false, false, "", err
}
@ -91,7 +89,7 @@ func (api *Client) MarkIMChannelContext(ctx context.Context, channel, ts string)
"ts": {ts},
}
_, err := imRequest(ctx, api.httpclient, "im.mark", values, api)
_, err := api.imRequest(ctx, "im.mark", values)
return err
}
@ -130,7 +128,7 @@ func (api *Client) GetIMHistoryContext(ctx context.Context, channel string, para
}
}
response, err := imRequest(ctx, api.httpclient, "im.history", values, api)
response, err := api.imRequest(ctx, "im.history", values)
if err != nil {
return nil, err
}
@ -148,7 +146,7 @@ func (api *Client) GetIMChannelsContext(ctx context.Context) ([]IM, error) {
"token": {api.token},
}
response, err := imRequest(ctx, api.httpclient, "im.list", values, api)
response, err := api.imRequest(ctx, "im.list", values)
if err != nil {
return nil, err
}

View File

@ -156,17 +156,12 @@ type Icons struct {
Image72 string `json:"image_72,omitempty"`
}
// Info contains various details about Users, Channels, Bots and the authenticated user.
// Info contains various details about the authenticated user and team.
// It is returned by StartRTM or included in the "ConnectedEvent" RTM event.
type Info struct {
URL string `json:"url,omitempty"`
User *UserDetails `json:"self,omitempty"`
Team *Team `json:"team,omitempty"`
Users []User `json:"users,omitempty"`
Channels []Channel `json:"channels,omitempty"`
Groups []Group `json:"groups,omitempty"`
Bots []Bot `json:"bots,omitempty"`
IMs []IM `json:"ims,omitempty"`
URL string `json:"url,omitempty"`
User *UserDetails `json:"self,omitempty"`
Team *Team `json:"team,omitempty"`
}
type infoResponseFull struct {
@ -174,52 +169,27 @@ type infoResponseFull struct {
SlackResponse
}
// GetBotByID returns a bot given a bot id
// GetBotByID is deprecated and returns nil
func (info Info) GetBotByID(botID string) *Bot {
for _, bot := range info.Bots {
if bot.ID == botID {
return &bot
}
}
return nil
}
// GetUserByID returns a user given a user id
// GetUserByID is deprecated and returns nil
func (info Info) GetUserByID(userID string) *User {
for _, user := range info.Users {
if user.ID == userID {
return &user
}
}
return nil
}
// GetChannelByID returns a channel given a channel id
// GetChannelByID is deprecated and returns nil
func (info Info) GetChannelByID(channelID string) *Channel {
for _, channel := range info.Channels {
if channel.ID == channelID {
return &channel
}
}
return nil
}
// GetGroupByID returns a group given a group id
// GetGroupByID is deprecated and returns nil
func (info Info) GetGroupByID(groupID string) *Group {
for _, group := range info.Groups {
if group.ID == groupID {
return &group
}
}
return nil
}
// GetIMByID returns an IM given an IM id
// GetIMByID is deprecated and returns nil
func (info Info) GetIMByID(imID string) *IM {
for _, im := range info.IMs {
if im.ID == imID {
return &im
}
}
return nil
}

View File

@ -1,8 +1,20 @@
package slack
import (
"encoding/json"
)
// InteractionType type of interactions
type InteractionType string
// ActionType type represents the type of action (attachment, block, etc.)
type actionType string
// action is an interface that should be implemented by all callback action types
type action interface {
actionType() actionType
}
// Types of interactions that can be received.
const (
InteractionTypeDialogCancellation = InteractionType("dialog_cancellation")
@ -10,6 +22,7 @@ const (
InteractionTypeDialogSuggestion = InteractionType("dialog_suggestion")
InteractionTypeInteractionMessage = InteractionType("interactive_message")
InteractionTypeMessageAction = InteractionType("message_action")
InteractionTypeBlockActions = InteractionType("block_actions")
)
// InteractionCallback is sent from slack when a user interactions with a button or dialog.
@ -27,6 +40,59 @@ type InteractionCallback struct {
Message Message `json:"message"`
Name string `json:"name"`
Value string `json:"value"`
ActionCallback
MessageTs string `json:"message_ts"`
AttachmentID string `json:"attachment_id"`
ActionCallback ActionCallbacks `json:"actions"`
DialogSubmissionCallback
}
// ActionCallback is a convenience struct defined to allow dynamic unmarshalling of
// the "actions" value in Slack's JSON response, which varies depending on block type
type ActionCallbacks struct {
AttachmentActions []*AttachmentAction
BlockActions []*BlockAction
}
// UnmarshalJSON implements the Marshaller interface in order to delegate
// marshalling and allow for proper type assertion when decoding the response
func (a *ActionCallbacks) UnmarshalJSON(data []byte) error {
var raw []json.RawMessage
err := json.Unmarshal(data, &raw)
if err != nil {
return err
}
for _, r := range raw {
var obj map[string]interface{}
err := json.Unmarshal(r, &obj)
if err != nil {
return err
}
if _, ok := obj["block_id"].(string); ok {
action, err := unmarshalAction(r, &BlockAction{})
if err != nil {
return err
}
a.BlockActions = append(a.BlockActions, action.(*BlockAction))
return nil
}
action, err := unmarshalAction(r, &AttachmentAction{})
if err != nil {
return err
}
a.AttachmentActions = append(a.AttachmentActions, action.(*AttachmentAction))
}
return nil
}
func unmarshalAction(r json.RawMessage, callbackAction action) (action, error) {
err := json.Unmarshal(r, callbackAction)
if err != nil {
return nil, err
}
return callbackAction, nil
}

View File

@ -0,0 +1,8 @@
package errorsx
// String representing an error, useful for declaring string constants as errors.
type String string
func (t String) Error() string {
return string(t)
}

18
vendor/github.com/nlopes/slack/internal/timex/timex.go generated vendored Normal file
View File

@ -0,0 +1,18 @@
package timex
import "time"
// Max returns the maximum duration
func Max(values ...time.Duration) time.Duration {
var (
max time.Duration
)
for _, v := range values {
if v > max {
max = v
}
}
return max
}

View File

@ -16,6 +16,7 @@ type OutgoingMessage struct {
type Message struct {
Msg
SubMessage *Msg `json:"message,omitempty"`
PreviousMessage *Msg `json:"previous_message,omitempty"`
}
// Msg contains information about a slack message
@ -92,8 +93,18 @@ type Msg struct {
ResponseType string `json:"response_type,omitempty"`
ReplaceOriginal bool `json:"replace_original"`
DeleteOriginal bool `json:"delete_original"`
// Block type Message
Blocks Blocks `json:"blocks,omitempty"`
}
const (
// ResponseTypeInChannel in channel response for slash commands.
ResponseTypeInChannel = "in_channel"
// ResponseTypeEphemeral ephemeral respone for slash commands.
ResponseTypeEphemeral = "ephemeral"
)
// Icon is used for bot messages
type Icon struct {
IconURL string `json:"icon_url,omitempty"`

View File

@ -8,6 +8,7 @@ import (
"fmt"
"io"
"io/ioutil"
"mime"
"mime/multipart"
"net/http"
"net/http/httputil"
@ -48,34 +49,98 @@ type statusCodeError struct {
}
func (t statusCodeError) Error() string {
// TODO: this is a bad error string, should clean it up with a breaking changes
// merger.
return fmt.Sprintf("Slack server error: %s.", t.Status)
return fmt.Sprintf("slack server error: %s", t.Status)
}
func (t statusCodeError) HTTPStatusCode() int {
return t.Code
}
func (t statusCodeError) Retryable() bool {
if t.Code >= 500 || t.Code == http.StatusTooManyRequests {
return true
}
return false
}
// RateLimitedError represents the rate limit respond from slack
type RateLimitedError struct {
RetryAfter time.Duration
}
func (e *RateLimitedError) Error() string {
return fmt.Sprintf("Slack rate limit exceeded, retry after %s", e.RetryAfter)
return fmt.Sprintf("slack rate limit exceeded, retry after %s", e.RetryAfter)
}
func (e *RateLimitedError) Retryable() bool {
return true
}
func fileUploadReq(ctx context.Context, path string, values url.Values, r io.Reader) (*http.Request, error) {
req, err := http.NewRequest("POST", path, r)
req = req.WithContext(ctx)
if err != nil {
return nil, err
}
req = req.WithContext(ctx)
req.URL.RawQuery = (values).Encode()
return req, nil
}
func downloadFile(client httpClient, token string, downloadURL string, writer io.Writer, d debug) error {
if downloadURL == "" {
return fmt.Errorf("received empty download URL")
}
req, err := http.NewRequest("GET", downloadURL, &bytes.Buffer{})
if err != nil {
return err
}
var bearer = "Bearer " + token
req.Header.Add("Authorization", bearer)
req.WithContext(context.Background())
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
err = checkStatusCode(resp, d)
if err != nil {
return err
}
_, err = io.Copy(writer, resp.Body)
return err
}
func formReq(endpoint string, values url.Values) (req *http.Request, err error) {
if req, err = http.NewRequest("POST", endpoint, strings.NewReader(values.Encode())); err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return req, nil
}
func jsonReq(endpoint string, body interface{}) (req *http.Request, err error) {
buffer := bytes.NewBuffer([]byte{})
if err = json.NewEncoder(buffer).Encode(body); err != nil {
return nil, err
}
if req, err = http.NewRequest("POST", endpoint, buffer); err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
return req, nil
}
func parseResponseBody(body io.ReadCloser, intf interface{}, d debug) error {
response, err := ioutil.ReadAll(body)
if err != nil {
@ -89,7 +154,7 @@ func parseResponseBody(body io.ReadCloser, intf interface{}, d debug) error {
return json.Unmarshal(response, intf)
}
func postLocalWithMultipartResponse(ctx context.Context, client httpClient, path, fpath, fieldname string, values url.Values, intf interface{}, d debug) error {
func postLocalWithMultipartResponse(ctx context.Context, client httpClient, method, fpath, fieldname string, values url.Values, intf interface{}, d debug) error {
fullpath, err := filepath.Abs(fpath)
if err != nil {
return err
@ -99,7 +164,8 @@ func postLocalWithMultipartResponse(ctx context.Context, client httpClient, path
return err
}
defer file.Close()
return postWithMultipartResponse(ctx, client, path, filepath.Base(fpath), fieldname, values, file, intf, d)
return postWithMultipartResponse(ctx, client, method, filepath.Base(fpath), fieldname, values, file, intf, d)
}
func postWithMultipartResponse(ctx context.Context, client httpClient, path, name, fieldname string, values url.Values, r io.Reader, intf interface{}, d debug) error {
@ -123,7 +189,7 @@ func postWithMultipartResponse(ctx context.Context, client httpClient, path, nam
return
}
}()
req, err := fileUploadReq(ctx, APIURL+path, values, pipeReader)
req, err := fileUploadReq(ctx, path, values, pipeReader)
if err != nil {
return err
}
@ -136,28 +202,20 @@ func postWithMultipartResponse(ctx context.Context, client httpClient, path, nam
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusTooManyRequests {
retry, err := strconv.ParseInt(resp.Header.Get("Retry-After"), 10, 64)
if err != nil {
return err
}
return &RateLimitedError{time.Duration(retry) * time.Second}
err = checkStatusCode(resp, d)
if err != nil {
return err
}
// Slack seems to send an HTML body along with 5xx error codes. Don't parse it.
if resp.StatusCode != http.StatusOK {
logResponse(resp, d)
return statusCodeError{Code: resp.StatusCode, Status: resp.Status}
}
select {
case err = <-errc:
return err
default:
return parseResponseBody(resp.Body, intf, d)
return newJSONParser(intf)(resp)
}
}
func doPost(ctx context.Context, client httpClient, req *http.Request, intf interface{}, d debug) error {
func doPost(ctx context.Context, client httpClient, req *http.Request, parser responseParser, d debug) error {
req = req.WithContext(ctx)
resp, err := client.Do(req)
if err != nil {
@ -165,21 +223,12 @@ func doPost(ctx context.Context, client httpClient, req *http.Request, intf inte
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusTooManyRequests {
retry, err := strconv.ParseInt(resp.Header.Get("Retry-After"), 10, 64)
if err != nil {
return err
}
return &RateLimitedError{time.Duration(retry) * time.Second}
err = checkStatusCode(resp, d)
if err != nil {
return err
}
// Slack seems to send an HTML body along with 5xx error codes. Don't parse it.
if resp.StatusCode != http.StatusOK {
logResponse(resp, d)
return statusCodeError{Code: resp.StatusCode, Status: resp.Status}
}
return parseResponseBody(resp.Body, intf, d)
return parser(resp)
}
// post JSON.
@ -191,7 +240,8 @@ func postJSON(ctx context.Context, client httpClient, endpoint, token string, js
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
return doPost(ctx, client, req, intf, d)
return doPost(ctx, client, req, newJSONParser(intf), d)
}
// post a url encoded form.
@ -202,17 +252,7 @@ func postForm(ctx context.Context, client httpClient, endpoint string, values ur
return err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return doPost(ctx, client, req, intf, d)
}
// post to a slack web method.
func postSlackMethod(ctx context.Context, client httpClient, path string, values url.Values, intf interface{}, d debug) error {
return postForm(ctx, client, APIURL+path, values, intf, d)
}
// get a slack web method.
func getSlackMethod(ctx context.Context, client httpClient, path string, values url.Values, intf interface{}, d debug) error {
return getResource(ctx, client, APIURL+path, values, intf, d)
return doPost(ctx, client, req, newJSONParser(intf), d)
}
func getResource(ctx context.Context, client httpClient, endpoint string, values url.Values, intf interface{}, d debug) error {
@ -223,7 +263,7 @@ func getResource(ctx context.Context, client httpClient, endpoint string, values
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.URL.RawQuery = values.Encode()
return doPost(ctx, client, req, intf, d)
return doPost(ctx, client, req, newJSONParser(intf), d)
}
func parseAdminResponse(ctx context.Context, client httpClient, method string, teamName string, values url.Values, intf interface{}, d debug) error {
@ -251,12 +291,6 @@ func okJSONHandler(rw http.ResponseWriter, r *http.Request) {
rw.Write(response)
}
type errorString string
func (t errorString) Error() string {
return string(t)
}
// timerReset safely reset a timer, see time.Timer.Reset for details.
func timerReset(t *time.Timer, d time.Duration) {
if !t.Stop() {
@ -264,3 +298,63 @@ func timerReset(t *time.Timer, d time.Duration) {
}
t.Reset(d)
}
func checkStatusCode(resp *http.Response, d debug) error {
if resp.StatusCode == http.StatusTooManyRequests {
retry, err := strconv.ParseInt(resp.Header.Get("Retry-After"), 10, 64)
if err != nil {
return err
}
return &RateLimitedError{time.Duration(retry) * time.Second}
}
// Slack seems to send an HTML body along with 5xx error codes. Don't parse it.
if resp.StatusCode != http.StatusOK {
logResponse(resp, d)
return statusCodeError{Code: resp.StatusCode, Status: resp.Status}
}
return nil
}
type responseParser func(*http.Response) error
func newJSONParser(dst interface{}) responseParser {
return func(resp *http.Response) error {
return json.NewDecoder(resp.Body).Decode(dst)
}
}
func newTextParser(dst interface{}) responseParser {
return func(resp *http.Response) error {
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
if !bytes.Equal(b, []byte("ok")) {
return errors.New(string(b))
}
return nil
}
}
func newContentTypeParser(dst interface{}) responseParser {
return func(req *http.Response) (err error) {
var (
ctype string
)
if ctype, _, err = mime.ParseMediaType(req.Header.Get("Content-Type")); err != nil {
return err
}
switch ctype {
case "application/json":
return newJSONParser(dst)(req)
default:
return newTextParser(dst)(req)
}
}
}

View File

@ -57,7 +57,7 @@ func GetOAuthResponseContext(ctx context.Context, client httpClient, clientID, c
"redirect_uri": {redirectURI},
}
response := &OAuthResponse{}
if err = postSlackMethod(ctx, client, "oauth.access", values, response, discard{}); err != nil {
if err = postForm(ctx, client, APIURL+"oauth.access", values, response, discard{}); err != nil {
return nil, err
}
return response, response.Err()

View File

@ -34,7 +34,7 @@ func (api *Client) AddPinContext(ctx context.Context, channel string, item ItemR
}
response := &SlackResponse{}
if err := postSlackMethod(ctx, api.httpclient, "pins.add", values, response, api); err != nil {
if err := api.postMethod(ctx, "pins.add", values, response); err != nil {
return err
}
@ -63,7 +63,7 @@ func (api *Client) RemovePinContext(ctx context.Context, channel string, item It
}
response := &SlackResponse{}
if err := postSlackMethod(ctx, api.httpclient, "pins.remove", values, response, api); err != nil {
if err := api.postMethod(ctx, "pins.remove", values, response); err != nil {
return err
}
@ -83,7 +83,7 @@ func (api *Client) ListPinsContext(ctx context.Context, channel string) ([]Item,
}
response := &listPinsResponseFull{}
err := postSlackMethod(ctx, api.httpclient, "pins.list", values, response, api)
err := api.postMethod(ctx, "pins.list", values, response)
if err != nil {
return nil, nil, err
}

View File

@ -2,7 +2,6 @@ package slack
import (
"context"
"errors"
"net/url"
"strconv"
)
@ -155,7 +154,7 @@ func (api *Client) AddReactionContext(ctx context.Context, name string, item Ite
}
response := &SlackResponse{}
if err := postSlackMethod(ctx, api.httpclient, "reactions.add", values, response, api); err != nil {
if err := api.postMethod(ctx, "reactions.add", values, response); err != nil {
return err
}
@ -189,7 +188,7 @@ func (api *Client) RemoveReactionContext(ctx context.Context, name string, item
}
response := &SlackResponse{}
if err := postSlackMethod(ctx, api.httpclient, "reactions.remove", values, response, api); err != nil {
if err := api.postMethod(ctx, "reactions.remove", values, response); err != nil {
return err
}
@ -223,12 +222,14 @@ func (api *Client) GetReactionsContext(ctx context.Context, item ItemRef, params
}
response := &getReactionsResponseFull{}
if err := postSlackMethod(ctx, api.httpclient, "reactions.get", values, response, api); err != nil {
if err := api.postMethod(ctx, "reactions.get", values, response); err != nil {
return nil, err
}
if !response.Ok {
return nil, errors.New(response.Error)
if err := response.Err(); err != nil {
return nil, err
}
return response.extractReactions(), nil
}
@ -256,12 +257,14 @@ func (api *Client) ListReactionsContext(ctx context.Context, params ListReaction
}
response := &listReactionsResponseFull{}
err := postSlackMethod(ctx, api.httpclient, "reactions.list", values, response, api)
err := api.postMethod(ctx, "reactions.list", values, response)
if err != nil {
return nil, nil, err
}
if !response.Ok {
return nil, nil, errors.New(response.Error)
if err := response.Err(); err != nil {
return nil, nil, err
}
return response.extractReactedItems(), &response.Paging, nil
}

View File

@ -23,7 +23,7 @@ type reminderResp struct {
func (api *Client) doReminder(ctx context.Context, path string, values url.Values) (*Reminder, error) {
response := &reminderResp{}
if err := postSlackMethod(ctx, api.httpclient, path, values, response, api); err != nil {
if err := api.postMethod(ctx, path, values, response); err != nil {
return nil, err
}
return &response.Reminder, response.Err()
@ -68,7 +68,7 @@ func (api *Client) DeleteReminder(id string) error {
"reminder": {id},
}
response := &SlackResponse{}
if err := postSlackMethod(context.Background(), api.httpclient, "reminders.delete", values, response, api); err != nil {
if err := api.postMethod(context.Background(), "reminders.delete", values, response); err != nil {
return err
}
return response.Err()

View File

@ -38,7 +38,7 @@ func (api *Client) StartRTM() (info *Info, websocketURL string, err error) {
// To have a fully managed Websocket connection, use `NewRTM`, and call `ManageConnection()` on it.
func (api *Client) StartRTMContext(ctx context.Context) (info *Info, websocketURL string, err error) {
response := &infoResponseFull{}
err = postSlackMethod(ctx, api.httpclient, "rtm.start", url.Values{"token": {api.token}}, response, api)
err = api.postMethod(ctx, "rtm.start", url.Values{"token": {api.token}}, response)
if err != nil {
return nil, "", err
}
@ -63,7 +63,7 @@ func (api *Client) ConnectRTM() (info *Info, websocketURL string, err error) {
// To have a fully managed Websocket connection, use `NewRTM`, and call `ManageConnection()` on it.
func (api *Client) ConnectRTMContext(ctx context.Context) (info *Info, websocketURL string, err error) {
response := &infoResponseFull{}
err = postSlackMethod(ctx, api.httpclient, "rtm.connect", url.Values{"token": {api.token}}, response, api)
err = api.postMethod(ctx, "rtm.connect", url.Values{"token": {api.token}}, response)
if err != nil {
api.Debugf("Failed to connect to RTM: %s", err)
return nil, "", err
@ -112,14 +112,13 @@ func RTMOptionConnParams(connParams url.Values) RTMOption {
func (api *Client) NewRTM(options ...RTMOption) *RTM {
result := &RTM{
Client: *api,
wasIntentional: true,
isConnected: false,
IncomingEvents: make(chan RTMEvent, 50),
outgoingMessages: make(chan OutgoingMessage, 20),
pingInterval: defaultPingInterval,
pingDeadman: time.NewTimer(deadmanDuration(defaultPingInterval)),
killChannel: make(chan bool),
disconnected: make(chan struct{}, 1),
disconnected: make(chan struct{}),
disconnectedm: &sync.Once{},
forcePing: make(chan bool),
rawEvents: make(chan json.RawMessage),
idGen: NewSafeID(1),

View File

@ -41,6 +41,7 @@ type SearchMessage struct {
User string `json:"user"`
Username string `json:"username"`
Timestamp string `json:"ts"`
Blocks Blocks `json:"blocks,omitempty"`
Text string `json:"text"`
Permalink string `json:"permalink"`
Attachments []Attachment `json:"attachments"`
@ -103,7 +104,7 @@ func (api *Client) _search(ctx context.Context, path, query string, params Searc
}
response = &searchResponseFull{}
err := postSlackMethod(ctx, api.httpclient, path, values, response, api)
err := api.postMethod(ctx, path, values, response)
if err != nil {
return nil, err
}

View File

@ -4,7 +4,6 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"hash"
"net/http"
@ -34,7 +33,7 @@ func unsafeSignatureVerifier(header http.Header, secret string) (_ SecretsVerifi
stimestamp := header.Get(hTimestamp)
if signature == "" || stimestamp == "" {
return SecretsVerifier{}, errors.New("missing headers")
return SecretsVerifier{}, ErrMissingHeaders
}
if bsignature, err = hex.DecodeString(strings.TrimPrefix(signature, "v0=")); err != nil {
@ -70,7 +69,7 @@ func NewSecretsVerifier(header http.Header, secret string) (sv SecretsVerifier,
diff := absDuration(time.Since(time.Unix(timestamp, 0)))
if diff > 5*time.Minute {
return SecretsVerifier{}, fmt.Errorf("timestamp is too old")
return SecretsVerifier{}, ErrExpiredTimestamp
}
return sv, err
@ -88,7 +87,7 @@ func (v SecretsVerifier) Ensure() error {
return nil
}
return fmt.Errorf("Expected signing signature: %s, but computed: %s", v.signature, computed)
return fmt.Errorf("Expected signing signature: %s, but computed: %s", hex.EncodeToString(v.signature), hex.EncodeToString(computed))
}
func abs64(n int64) int64 {

View File

@ -9,11 +9,12 @@ import (
"os"
)
// APIURL added as a var so that we can change this for testing purposes
var APIURL = "https://slack.com/api/"
// WEBAPIURLFormat ...
const WEBAPIURLFormat = "https://%s.slack.com/api/users.admin.%s?t=%d"
const (
// APIURL of the slack api.
APIURL = "https://slack.com/api/"
// WEBAPIURLFormat ...
WEBAPIURLFormat = "https://%s.slack.com/api/users.admin.%s?t=%d"
)
// httpClient defines the minimal interface needed for an http.Client to be implemented.
type httpClient interface {
@ -40,6 +41,8 @@ type AuthTestResponse struct {
User string `json:"user"`
TeamID string `json:"team_id"`
UserID string `json:"user_id"`
// EnterpriseID is only returned when an enterprise id present
EnterpriseID string `json:"enterprise_id,omitempty"`
}
type authTestResponseFull struct {
@ -48,8 +51,11 @@ type authTestResponseFull struct {
}
// Client for the slack api.
type ParamOption func(*url.Values)
type Client struct {
token string
endpoint string
debug bool
log ilogger
httpclient httpClient
@ -79,10 +85,16 @@ func OptionLog(l logger) func(*Client) {
}
}
// OptionAPIURL set the url for the client. only useful for testing.
func OptionAPIURL(u string) func(*Client) {
return func(c *Client) { c.endpoint = u }
}
// New builds a slack client from the provided token and options.
func New(token string, options ...Option) *Client {
s := &Client{
token: token,
endpoint: APIURL,
httpclient: &http.Client{},
log: log.New(os.Stderr, "nlopes/slack", log.LstdFlags|log.Lshortfile),
}
@ -103,7 +115,7 @@ func (api *Client) AuthTest() (response *AuthTestResponse, error error) {
func (api *Client) AuthTestContext(ctx context.Context) (response *AuthTestResponse, err error) {
api.Debugf("Challenging auth...")
responseFull := &authTestResponseFull{}
err = postSlackMethod(ctx, api.httpclient, "auth.test", url.Values{"token": {api.token}}, responseFull, api)
err = api.postMethod(ctx, "auth.test", url.Values{"token": {api.token}}, responseFull)
if err != nil {
return nil, err
}
@ -129,3 +141,13 @@ func (api *Client) Debugln(v ...interface{}) {
func (api *Client) Debug() bool {
return api.debug
}
// post to a slack web method.
func (api *Client) postMethod(ctx context.Context, path string, values url.Values, intf interface{}) error {
return postForm(ctx, api.httpclient, api.endpoint+path, values, intf, api)
}
// get a slack web method.
func (api *Client) getMethod(ctx context.Context, path string, values url.Values, intf interface{}) error {
return getResource(ctx, api.httpclient, api.endpoint+path, values, intf, api)
}

Some files were not shown because too many files have changed in this diff Show More