mirror of
https://github.com/i1v/googleplay
synced 2024-09-21 12:19:26 +00:00
149 lines
3.1 KiB
Go
149 lines
3.1 KiB
Go
package googleplay
|
|
|
|
import (
|
|
"2a.pages.dev/rosso/protobuf"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
)
|
|
|
|
type File struct {
|
|
Package_Name string
|
|
Version_Code uint64
|
|
}
|
|
|
|
func (f File) APK(id string) string {
|
|
b := []byte(f.Package_Name)
|
|
b = append(b, '-')
|
|
if id != "" {
|
|
b = append(b, id...)
|
|
b = append(b, '-')
|
|
}
|
|
b = strconv.AppendUint(b, f.Version_Code, 10)
|
|
b = append(b, ".apk"...)
|
|
return string(b)
|
|
}
|
|
|
|
func (f File) OBB(file_type uint64) string {
|
|
var b []byte
|
|
if file_type >= 1 {
|
|
b = append(b, "patch"...)
|
|
} else {
|
|
b = append(b, "main"...)
|
|
}
|
|
b = append(b, '.')
|
|
b = strconv.AppendUint(b, f.Version_Code, 10)
|
|
b = append(b, '.')
|
|
b = append(b, f.Package_Name...)
|
|
b = append(b, ".obb"...)
|
|
return string(b)
|
|
}
|
|
|
|
func (h Header) Delivery(app string, ver uint64) (*Delivery, error) {
|
|
req, err := http.NewRequest(
|
|
"GET", "https://play-fe.googleapis.com/fdfe/delivery", nil,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
h.Set_Agent(req.Header)
|
|
h.Set_Auth(req.Header) // needed for single APK
|
|
h.Set_Device(req.Header)
|
|
req.URL.RawQuery = url.Values{
|
|
"doc": {app},
|
|
"vc": {strconv.FormatUint(ver, 10)},
|
|
}.Encode()
|
|
res, err := Client.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer res.Body.Close()
|
|
body, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// ResponseWrapper
|
|
response_wrapper, err := protobuf.Unmarshal(body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// .payload.deliveryResponse
|
|
delivery_response := response_wrapper.Get(1).Get(21)
|
|
// .status
|
|
status, err := delivery_response.Get_Varint(1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
switch status {
|
|
case 2:
|
|
return nil, errors.New("geo-blocking")
|
|
case 3:
|
|
return nil, errors.New("purchase required")
|
|
case 5:
|
|
return nil, errors.New("invalid version")
|
|
}
|
|
var del Delivery
|
|
// .appDeliveryData
|
|
del.Message = delivery_response.Get(2)
|
|
return &del, nil
|
|
}
|
|
|
|
// .downloadUrl
|
|
func (d Delivery) Download_URL() (string, error) {
|
|
return d.Get_String(3)
|
|
}
|
|
|
|
func (d Delivery) Split_Data() []Split_Data {
|
|
var splits []Split_Data
|
|
// .splitDeliveryData
|
|
for _, split := range d.Get_Messages(15) {
|
|
splits = append(splits, Split_Data{split})
|
|
}
|
|
return splits
|
|
}
|
|
|
|
// AndroidAppDeliveryData
|
|
type Delivery struct {
|
|
protobuf.Message
|
|
}
|
|
|
|
func (d Delivery) Additional_File() []App_File_Metadata {
|
|
var files []App_File_Metadata
|
|
// .additionalFile
|
|
for _, file := range d.Get_Messages(4) {
|
|
files = append(files, App_File_Metadata{file})
|
|
}
|
|
return files
|
|
}
|
|
|
|
// SplitDeliveryData
|
|
type Split_Data struct {
|
|
protobuf.Message
|
|
}
|
|
|
|
// .id
|
|
func (s Split_Data) ID() (string, error) {
|
|
return s.Get_String(1)
|
|
}
|
|
|
|
// .downloadUrl
|
|
func (s Split_Data) Download_URL() (string, error) {
|
|
return s.Get_String(5)
|
|
}
|
|
|
|
// AppFileMetadata
|
|
type App_File_Metadata struct {
|
|
protobuf.Message
|
|
}
|
|
|
|
// .fileType
|
|
func (a App_File_Metadata) File_Type() (uint64, error) {
|
|
return a.Get_Varint(1)
|
|
}
|
|
|
|
// .downloadUrl
|
|
func (a App_File_Metadata) Download_URL() (string, error) {
|
|
return a.Get_String(4)
|
|
}
|