Use fork for ovrstat until updated
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
3ca4448a7e
commit
c0bd927903
2
go.mod
2
go.mod
|
@ -2,6 +2,8 @@ module git.meow.tf/ow-api/ow-api
|
|||
|
||||
go 1.12
|
||||
|
||||
replace s32x.com/ovrstat => github.com/seilem/ovrstat v0.0.0-20200123200456-7b7e24d39506
|
||||
|
||||
require (
|
||||
github.com/PuerkitoBio/goquery v1.5.1-0.20190109230704-3dcf72e6c17f
|
||||
github.com/andybalholm/cascadia v1.1.0 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -46,6 +46,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/seilem/ovrstat v0.0.0-20200123200456-7b7e24d39506 h1:xAdnQYUFimq8Uiz4Io7QlnNGV+4BtagWGC+DDxVG3Fo=
|
||||
github.com/seilem/ovrstat v0.0.0-20200123200456-7b7e24d39506/go.mod h1:UzsLSEoY8B4FByz4e+5GGKebJio+H+axo3RxLr7d7Mw=
|
||||
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/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
|
|
2
main.go
2
main.go
|
@ -17,7 +17,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
Version = "2.3.1"
|
||||
Version = "2.3.2"
|
||||
|
||||
OpAdd = "add"
|
||||
OpRemove = "remove"
|
||||
|
|
|
@ -0,0 +1,268 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/miekg/dns"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"s32x.com/ovrstat/ovrstat"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cloudfrontUrl, err := lookupCloudfrontURL()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to find url:", err)
|
||||
}
|
||||
|
||||
log.Println("URL:", cloudfrontUrl)
|
||||
|
||||
ips, err := lookupIpv6Dns(cloudfrontUrl)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to find ips:", err)
|
||||
}
|
||||
|
||||
log.Println("IPs:", ips)
|
||||
|
||||
localIps, err := checkIpv6Local()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to get local ips")
|
||||
}
|
||||
|
||||
log.Println("Local IPs:", localIps)
|
||||
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
localAddr, err := net.ResolveIPAddr("ip", "")
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// You also need to do this to make it work and not give you a
|
||||
// "mismatched local address type ip"
|
||||
// This will make the ResolveIPAddr a TCPAddr without needing to
|
||||
// say what SRC port number to use.
|
||||
localTCPAddr := net.TCPAddr{
|
||||
IP: localAddr.IP,
|
||||
}
|
||||
|
||||
defaultDialer := &net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}
|
||||
|
||||
dialer := &net.Dialer{
|
||||
LocalAddr: &localTCPAddr,
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
oldNetwork := network
|
||||
oldAddr := addr
|
||||
|
||||
if addr == "playoverwatch.com:443" {
|
||||
network = "tcp6"
|
||||
addr = "[" + ips[r.Intn(len(ips))] + "]:443"
|
||||
}
|
||||
|
||||
log.Println("Dial using", addr)
|
||||
|
||||
c, err := dialer.DialContext(ctx, network, addr)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Fallback")
|
||||
c, err = defaultDialer.DialContext(ctx, oldNetwork, oldAddr)
|
||||
}
|
||||
|
||||
return c, err
|
||||
},
|
||||
TLSClientConfig: &tls.Config{
|
||||
ServerName: "playoverwatch.com",
|
||||
},
|
||||
}
|
||||
|
||||
http.DefaultClient = &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
stats, err := ovrstat.PCStats("cats-11481")
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln("Error retrieving:", err)
|
||||
}
|
||||
|
||||
log.Println(stats.Name+" is level", stats.Level)
|
||||
}
|
||||
|
||||
func lookupCloudfrontURL() (string, error) {
|
||||
res, err := http.Get("https://playoverwatch.com/en-us/")
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(res.Body)
|
||||
|
||||
links := doc.Find("link").Map(func(i int, s *goquery.Selection) string {
|
||||
v, exists := s.Attr("href")
|
||||
|
||||
if !exists {
|
||||
return ""
|
||||
}
|
||||
|
||||
return v
|
||||
})
|
||||
|
||||
for _, link := range links {
|
||||
u, err := url.Parse(link)
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasSuffix(u.Host, "cloudfront.net") {
|
||||
return u.Host, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("no cloudfront url")
|
||||
}
|
||||
|
||||
func lookupIpv6Dns(host string) ([]string, error) {
|
||||
c := &dns.Client{
|
||||
Net: "udp",
|
||||
}
|
||||
|
||||
msg := new(dns.Msg)
|
||||
msg.Id = dns.Id()
|
||||
msg.RecursionDesired = true
|
||||
msg.Question = make([]dns.Question, 1)
|
||||
msg.Question[0] = dns.Question{Name: dns.Fqdn(host), Qtype: dns.TypeAAAA, Qclass: dns.ClassINET}
|
||||
|
||||
in, _, err := c.Exchange(msg, "8.8.8.8:53")
|
||||
|
||||
result := make([]string, 0)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in != nil && in.Rcode != dns.RcodeSuccess {
|
||||
return result, errors.New(dns.RcodeToString[in.Rcode])
|
||||
}
|
||||
|
||||
for _, record := range in.Answer {
|
||||
if t, ok := record.(*dns.AAAA); ok {
|
||||
result = append(result, t.AAAA.String())
|
||||
}
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func checkIpv6Local() ([]string, error) {
|
||||
ifaces, err := net.Interfaces()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := make([]string, 0)
|
||||
|
||||
for _, i := range ifaces {
|
||||
addrs, err := i.Addrs()
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
}
|
||||
|
||||
log.Println("Check", ip.String())
|
||||
|
||||
if ip == nil || ip.To4() == nil || isPrivateIP(ip) {
|
||||
continue
|
||||
}
|
||||
|
||||
log.Println("Checking", ip.String())
|
||||
|
||||
if ipnet, ok := addr.(*net.IPNet); ok {
|
||||
for ip := ipnet.IP.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
|
||||
ret = append(ret, ip.String())
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
ret = append(ret, ip.String())
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func inc(ip net.IP) {
|
||||
for j := len(ip) - 1; j >= 0; j-- {
|
||||
ip[j]++
|
||||
if ip[j] > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var privateIPBlocks []*net.IPNet
|
||||
|
||||
func init() {
|
||||
for _, cidr := range []string{
|
||||
"127.0.0.0/8", // IPv4 loopback
|
||||
"10.0.0.0/8", // RFC1918
|
||||
"172.16.0.0/12", // RFC1918
|
||||
"192.168.0.0/16", // RFC1918
|
||||
"169.254.0.0/16", // RFC3927 link-local
|
||||
"::1/128", // IPv6 loopback
|
||||
"fe80::/10", // IPv6 link-local
|
||||
"fc00::/7", // IPv6 unique local addr
|
||||
} {
|
||||
_, block, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("parse error on %q: %v", cidr, err))
|
||||
}
|
||||
privateIPBlocks = append(privateIPBlocks, block)
|
||||
}
|
||||
}
|
||||
|
||||
func isPrivateIP(ip net.IP) bool {
|
||||
if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, block := range privateIPBlocks {
|
||||
if block.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
Loading…
Reference in New Issue