This repository has been archived by the owner on Mar 1, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Minizbot2012
committed
Jul 2, 2020
0 parents
commit 5e15844
Showing
9 changed files
with
560 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
auth_config.json | ||
twitch_code.txt | ||
.cav_token.txt | ||
.idea | ||
test/twitch_code.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2018 Modmuss50 | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# CAV2 | ||
|
||
Curse Api Version 2 - in go | ||
Fork-mirror from [Modmuss50/cav2](https://github.com/modmuss50/CAV2) | ||
Extended and cleaned by me (Mini) | ||
Use the [Twitch OAuth Generator](https://twitchapps.com/tmi/) to get your oauth token |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
package cav2 | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"strconv" | ||
) | ||
|
||
const ( | ||
//APIEndpoint URL of API | ||
APIEndpoint = "https://addons-ecs.forgesvc.net/api/v2/" | ||
) | ||
|
||
var ( | ||
//EMPTY Empty req data | ||
EMPTY []byte | ||
) | ||
|
||
//GetAddon gets Addon with addonID | ||
func GetAddon(addonID string) (*Addon, error) { | ||
response, err := GetHTTPResponse("GET", getAPI()+"addon/"+addonID, EMPTY) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var addonResponse *Addon | ||
err = json.NewDecoder(response.Body).Decode(&addonResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return addonResponse, nil | ||
} | ||
|
||
//GetAddons Gets addons with []AddonID | ||
func GetAddons(addons []int) ([]*Addon, error) { | ||
jsonPayload, _ := json.Marshal(addons) | ||
response, err := GetHTTPResponse("POST", getAPI()+"addon", jsonPayload) | ||
if err != nil { | ||
return nil, err | ||
} | ||
var addonResponse []*Addon | ||
err = json.NewDecoder(response.Body).Decode(&addonResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return addonResponse, nil | ||
} | ||
|
||
//GetAddonFile Gets an addons file with AddonID and fileId | ||
func GetAddonFile(addon int, fileID int) (*File, error) { | ||
response, err := GetHTTPResponse("GET", getAPI()+"addon/"+strconv.Itoa(addon)+"/file/"+strconv.Itoa(fileID), EMPTY) | ||
if err != nil { | ||
return nil, err | ||
} | ||
var addonResponse *File | ||
err = json.NewDecoder(response.Body).Decode(&addonResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return addonResponse, nil | ||
} | ||
|
||
//GetAddonFiles Gets files for addonID | ||
func GetAddonFiles(addonID string) ([]*File, error) { | ||
response, err := GetHTTPResponse("GET", getAPI()+"addon/"+addonID+"/files", EMPTY) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var addonResponse []*File | ||
err = json.NewDecoder(response.Body).Decode(&addonResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return addonResponse, nil | ||
} | ||
|
||
//GetHashMatches Gets addon Fingerprints | ||
func GetHashMatches(addons []int) (*FingerprintList, error) { | ||
jsonPayload, _ := json.Marshal(addons) | ||
response, err := GetHTTPResponse("POST", APIEndpoint+"fingerprint", jsonPayload) | ||
if err != nil { | ||
return nil, err | ||
} | ||
var addonResponse *FingerprintList | ||
err = json.NewDecoder(response.Body).Decode(&addonResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return addonResponse, nil | ||
} | ||
|
||
//GetAddonDatabaseTimestamp Gets last update of addon DB | ||
func GetAddonDatabaseTimestamp() (string, error) { | ||
response, err := GetHTTPResponse("GET", getAPI()+"addon/timestamp", EMPTY) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
bodyBytes, _ := ioutil.ReadAll(response.Body) | ||
bodyString := string(bodyBytes) | ||
|
||
return bodyString, nil | ||
} | ||
|
||
//Search searches for addons with query | ||
func Search(query string) ([]*Addon, error) { | ||
//TODO expand this to allow more things to be searched for | ||
//"api/addon/search?gameId={0}§ionId={1}&categoryId={2}&gameVersion={3}&index={4}&pageSize={5}&searchFilter={6}&sort={7}&sortDescending={8}" | ||
seachPayload := "?gameId=432§ionId=-1&categoryId=-1&index=0&pageSize=1000&sort=TotalDownloads&sortDescending=true&searchFilter=" + query | ||
response, err := GetHTTPResponse("GET", getAPI()+"addon/search"+seachPayload, EMPTY) | ||
if err != nil { | ||
return nil, err | ||
} | ||
var addonResponse []*Addon | ||
err = json.NewDecoder(response.Body).Decode(&addonResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return addonResponse, nil | ||
} | ||
|
||
//GetAllAddons Uses the search to find as many addons as possible, not perfect but should get most of them. | ||
//This is a very expensive call, takes a while and uses a lot of api requests | ||
func GetAllAddons() ([]*Addon, error) { | ||
allAddons := make([]*Addon, 0) | ||
|
||
lastFind := 1000 | ||
index := 0 | ||
for lastFind == 1000 { | ||
if index > 100 { | ||
fmt.Println("Breaking out index too big") | ||
break | ||
} | ||
seachPayload := "?gameId=432§ionId=6&categoryId=0&index=" + strconv.Itoa(len(allAddons)) + "&searchFilter=&pageSize=1000&sort=5" | ||
response, err := GetHTTPResponse("GET", APIEndpoint+"addon/search"+seachPayload, EMPTY) | ||
if err != nil { | ||
fmt.Println(err.Error()) | ||
return nil, err | ||
} | ||
var addonResponse []*Addon | ||
err = json.NewDecoder(response.Body).Decode(&addonResponse) | ||
if err != nil { | ||
fmt.Println(err.Error()) | ||
return nil, err | ||
} | ||
|
||
lastFind = len(addonResponse) | ||
index++ | ||
allAddons = append(allAddons, addonResponse...) | ||
} | ||
|
||
return allAddons, nil | ||
} | ||
|
||
func getAPI() string { | ||
return APIEndpoint | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package cav2 | ||
|
||
var ( | ||
//OAuthToken - Twitch oauth's token | ||
OAuthToken string | ||
//WriteSession - Unknown | ||
WriteSession = false | ||
) | ||
|
||
const ( | ||
twitchCodeFile = "twitch_code.txt" | ||
) | ||
|
||
//SetOAuth Takes in a twitch oauth code generated with OAuth.html | ||
func SetOAuth(token string) { | ||
OAuthToken = token | ||
} | ||
|
||
//ReadTokenFromDisk Reads the auth token from a file | ||
func ReadTokenFromDisk() { | ||
code := readStringFromFile(twitchCodeFile) | ||
SetOAuth(code) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package cav2 | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"io/ioutil" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
//GetHTTPResponse gets response from URL (Wraps GetAuthenicatedResponse) | ||
func GetHTTPResponse(method, url string, b []byte) (*http.Response, error) { | ||
return GetAuthenticatedReponse(method, OAuthToken, url, b) | ||
} | ||
|
||
//GetAuthenticatedReponse wraps an http client with an authenication token | ||
func GetAuthenticatedReponse(method, token, url string, b []byte) (*http.Response, error) { | ||
client := &http.Client{} | ||
|
||
req, err := http.NewRequest(method, url, bytes.NewReader(b)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(token) > 0 && strings.HasPrefix(url, APIEndpoint) { | ||
req.Header.Add("AuthenticationToken", token) | ||
} | ||
req.Header.Add("Content-Type", "application/json") | ||
|
||
resp, err := client.Do(req) | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return resp, errors.New(resp.Status) | ||
} | ||
|
||
return resp, err | ||
} | ||
|
||
//DoHTTPRequest does a basic http request | ||
func DoHTTPRequest(url string) (*http.Response, error) { | ||
client := &http.Client{} | ||
req, err := http.NewRequest("GET", url, bytes.NewReader(EMPTY)) | ||
resp, err := client.Do(req) | ||
if resp.StatusCode != http.StatusOK { | ||
return resp, errors.New(resp.Status) | ||
} | ||
return resp, err | ||
} | ||
|
||
//ResponseToBytes Converts an http.Response to bytes | ||
func ResponseToBytes(response *http.Response) []byte { | ||
bodyBytes, _ := ioutil.ReadAll(response.Body) | ||
return bodyBytes | ||
} | ||
|
||
//ResponseToString Converts an http.Response to a string | ||
func ResponseToString(response *http.Response) string { | ||
bodyBytes, _ := ioutil.ReadAll(response.Body) | ||
bodyString := string(bodyBytes) | ||
return bodyString | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package cav2 | ||
|
||
import ( | ||
"io/ioutil" | ||
|
||
"github.com/aviddiviner/go-murmur" | ||
) | ||
|
||
//GetByteArrayHash Computes a murmur2 byte array hash | ||
func GetByteArrayHash(bytes []byte) int { | ||
return int(murmur.MurmurHash2(computeNormalizedArray(bytes), 1)) | ||
} | ||
|
||
//GetFileHash Computes a murmur2 hash of a file | ||
func GetFileHash(file string) (int, error) { | ||
bytes, err := ioutil.ReadFile(file) | ||
if err != nil { | ||
return 0, err | ||
} | ||
result := GetByteArrayHash(bytes) | ||
return result, nil | ||
} | ||
|
||
func computeNormalizedArray(bytes []byte) []byte { | ||
var newArray []byte | ||
for _, byte := range bytes { | ||
if !isWhitespaceCharacter(byte) { | ||
newArray = append(newArray, byte) | ||
} | ||
} | ||
return newArray | ||
} | ||
|
||
func isWhitespaceCharacter(b byte) bool { | ||
return b == 9 || b == 10 || b == 13 || b == 32 | ||
} |
Oops, something went wrong.