Use fork for ovrstat until updated
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Tyler 2020-01-23 21:52:09 -05:00
parent 3ca4448a7e
commit c0bd927903
4 changed files with 273 additions and 1 deletions

2
go.mod
View File

@ -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
View File

@ -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=

View File

@ -17,7 +17,7 @@ import (
)
const (
Version = "2.3.1"
Version = "2.3.2"
OpAdd = "add"
OpRemove = "remove"

268
pro/main.go Normal file
View File

@ -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
}