mirror of
https://github.com/ap-pauloafonso/ratio-spoof.git
synced 2026-01-11 20:10:22 +00:00
estimatedTime to tracker.go
This commit is contained in:
parent
8a630643bb
commit
4fd2969d82
6 changed files with 52 additions and 69 deletions
|
|
@ -1,8 +1,8 @@
|
|||
package bencode
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
|
@ -99,13 +99,13 @@ func TestMapParse(T *testing.T) {
|
|||
|
||||
func TestDecode(T *testing.T) {
|
||||
|
||||
files, err := ioutil.ReadDir("./torrent_files_test")
|
||||
files, err := os.ReadDir("./torrent_files_test")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for _, f := range files {
|
||||
T.Run(f.Name(), func(t *testing.T) {
|
||||
data, _ := ioutil.ReadFile("./torrent_files_test/" + f.Name())
|
||||
data, _ := os.ReadFile("./torrent_files_test/" + f.Name())
|
||||
result, _ := Decode(data)
|
||||
t.Log(result["info"].(map[string]interface{})["name"])
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package emulation
|
|||
import (
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
|
||||
"github.com/ap-pauloafonso/ratio-spoof/internal/generator"
|
||||
)
|
||||
|
|
@ -83,7 +83,7 @@ func extractClient(code string) (*ClientInfo, error) {
|
|||
}
|
||||
defer f.Close()
|
||||
|
||||
bytes, err := ioutil.ReadAll(f)
|
||||
bytes, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package generator
|
|||
|
||||
import "testing"
|
||||
|
||||
func TestNextAmountReport(t *testing.T) {
|
||||
func TestDefaultRounding(t *testing.T) {
|
||||
r, _ := NewDefaultRoudingGenerator()
|
||||
|
||||
d, u, l := r.Round(656497856, 46479878, 7879879, 1024)
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func PrintState(state *ratiospoof.RatioSpoof) {
|
|||
}
|
||||
lastDequeItem := state.AnnounceHistory.At(state.AnnounceHistory.Len() - 1).(ratiospoof.AnnounceEntry)
|
||||
|
||||
remaining := time.Until(state.EstimatedTimeToAnnounce)
|
||||
remaining := time.Until(state.Tracker.EstimatedTimeToAnnounce)
|
||||
fmt.Printf("#%v downloaded: %v(%.2f%%) | left: %v | uploaded: %v | next announce in: %v %v\n", lastDequeItem.Count,
|
||||
humanReadableSize(float64(lastDequeItem.Downloaded)),
|
||||
lastDequeItem.PercentDownloaded,
|
||||
|
|
|
|||
|
|
@ -3,13 +3,11 @@ package ratiospoof
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
|
|
@ -25,21 +23,18 @@ const (
|
|||
)
|
||||
|
||||
type RatioSpoof struct {
|
||||
mutex *sync.Mutex
|
||||
TorrentInfo *bencode.TorrentInfo
|
||||
Input *input.InputParsed
|
||||
Tracker *tracker.HttpTracker
|
||||
BitTorrentClient *emulation.Emulation
|
||||
AnnounceInterval int
|
||||
EstimatedTimeToAnnounce time.Time
|
||||
EstimatedTimeToAnnounceUpdateCh chan int
|
||||
NumWant int
|
||||
Seeders int
|
||||
Leechers int
|
||||
AnnounceCount int
|
||||
Status string
|
||||
AnnounceHistory announceHistory
|
||||
StopPrintCH chan interface{}
|
||||
TorrentInfo *bencode.TorrentInfo
|
||||
Input *input.InputParsed
|
||||
Tracker *tracker.HttpTracker
|
||||
BitTorrentClient *emulation.Emulation
|
||||
AnnounceInterval int
|
||||
NumWant int
|
||||
Seeders int
|
||||
Leechers int
|
||||
AnnounceCount int
|
||||
Status string
|
||||
AnnounceHistory announceHistory
|
||||
StopPrintCH chan interface{}
|
||||
}
|
||||
|
||||
type AnnounceEntry struct {
|
||||
|
|
@ -55,9 +50,8 @@ type announceHistory struct {
|
|||
}
|
||||
|
||||
func NewRatioSpoofState(input input.InputArgs) (*RatioSpoof, error) {
|
||||
EstimatedTimeToAnnounceUpdateCh := make(chan int)
|
||||
stopPrintCh := make(chan interface{})
|
||||
dat, err := ioutil.ReadFile(input.TorrentPath)
|
||||
dat, err := os.ReadFile(input.TorrentPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -83,15 +77,13 @@ func NewRatioSpoofState(input input.InputArgs) (*RatioSpoof, error) {
|
|||
}
|
||||
|
||||
return &RatioSpoof{
|
||||
BitTorrentClient: client,
|
||||
TorrentInfo: torrentInfo,
|
||||
Tracker: httpTracker,
|
||||
Input: inputParsed,
|
||||
NumWant: 200,
|
||||
Status: "started",
|
||||
mutex: &sync.Mutex{},
|
||||
StopPrintCH: stopPrintCh,
|
||||
EstimatedTimeToAnnounceUpdateCh: EstimatedTimeToAnnounceUpdateCh,
|
||||
BitTorrentClient: client,
|
||||
TorrentInfo: torrentInfo,
|
||||
Tracker: httpTracker,
|
||||
Input: inputParsed,
|
||||
NumWant: 200,
|
||||
Status: "started",
|
||||
StopPrintCH: stopPrintCh,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +109,6 @@ func (R *RatioSpoof) Run() {
|
|||
|
||||
signal.Notify(sigCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||||
R.firstAnnounce()
|
||||
go R.updateEstimatedTimeToAnnounceListener()
|
||||
go func() {
|
||||
for {
|
||||
R.generateNextAnnounce()
|
||||
|
|
@ -134,28 +125,6 @@ func (R *RatioSpoof) firstAnnounce() {
|
|||
R.fireAnnounce(false)
|
||||
}
|
||||
|
||||
func (R *RatioSpoof) updateInterval(interval int) {
|
||||
if interval > 0 {
|
||||
R.AnnounceInterval = interval
|
||||
} else {
|
||||
R.AnnounceInterval = 1800
|
||||
}
|
||||
R.updateEstimatedTimeToAnnounce(R.AnnounceInterval)
|
||||
}
|
||||
|
||||
func (R *RatioSpoof) updateEstimatedTimeToAnnounce(interval int) {
|
||||
R.mutex.Lock()
|
||||
defer R.mutex.Unlock()
|
||||
R.EstimatedTimeToAnnounce = time.Now().Add(time.Duration(interval) * time.Second)
|
||||
}
|
||||
|
||||
func (R *RatioSpoof) updateEstimatedTimeToAnnounceListener() {
|
||||
for {
|
||||
interval := <-R.EstimatedTimeToAnnounceUpdateCh
|
||||
R.updateEstimatedTimeToAnnounce(interval)
|
||||
}
|
||||
}
|
||||
|
||||
func (R *RatioSpoof) updateSeedersAndLeechers(resp tracker.TrackerResponse) {
|
||||
R.Seeders = resp.Seeders
|
||||
R.Leechers = resp.Leechers
|
||||
|
|
@ -176,14 +145,14 @@ func (R *RatioSpoof) fireAnnounce(retry bool) error {
|
|||
"{event}", R.Status,
|
||||
"{numwant}", fmt.Sprint(R.NumWant))
|
||||
query := replacer.Replace(R.BitTorrentClient.Query)
|
||||
trackerResp, err := R.Tracker.Announce(query, R.BitTorrentClient.Headers, retry, R.EstimatedTimeToAnnounceUpdateCh)
|
||||
trackerResp, err := R.Tracker.Announce(query, R.BitTorrentClient.Headers, retry)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to reach the tracker:\n%s ", err.Error())
|
||||
}
|
||||
|
||||
if trackerResp != nil {
|
||||
R.updateSeedersAndLeechers(*trackerResp)
|
||||
R.updateInterval(trackerResp.Interval)
|
||||
R.AnnounceInterval = trackerResp.Interval
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"bytes"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -13,10 +13,11 @@ import (
|
|||
)
|
||||
|
||||
type HttpTracker struct {
|
||||
Urls []string
|
||||
RetryAttempt int
|
||||
LastAnounceRequest string
|
||||
LastTackerResponse string
|
||||
Urls []string
|
||||
RetryAttempt int
|
||||
LastAnounceRequest string
|
||||
LastTackerResponse string
|
||||
EstimatedTimeToAnnounce time.Time
|
||||
}
|
||||
|
||||
type TrackerResponse struct {
|
||||
|
|
@ -46,7 +47,18 @@ func (T *HttpTracker) SwapFirst(currentIdx int) {
|
|||
T.Urls[currentIdx] = aux
|
||||
}
|
||||
|
||||
func (T *HttpTracker) Announce(query string, headers map[string]string, retry bool, estimatedTimeToAnnounceUpdateCh chan<- int) (*TrackerResponse, error) {
|
||||
func (T *HttpTracker) updateEstimatedTimeToAnnounce(interval int) {
|
||||
T.EstimatedTimeToAnnounce = time.Now().Add(time.Duration(interval) * time.Second)
|
||||
}
|
||||
func (T *HttpTracker) HandleSuccessfulResponse(resp *TrackerResponse) {
|
||||
if resp.Interval <= 0 {
|
||||
resp.Interval = 1800
|
||||
}
|
||||
|
||||
T.updateEstimatedTimeToAnnounce(resp.Interval)
|
||||
}
|
||||
|
||||
func (T *HttpTracker) Announce(query string, headers map[string]string, retry bool) (*TrackerResponse, error) {
|
||||
defer func() {
|
||||
T.RetryAttempt = 0
|
||||
}()
|
||||
|
|
@ -55,7 +67,7 @@ func (T *HttpTracker) Announce(query string, headers map[string]string, retry bo
|
|||
for {
|
||||
trackerResp, err := T.tryMakeRequest(query, headers)
|
||||
if err != nil {
|
||||
estimatedTimeToAnnounceUpdateCh <- retryDelay
|
||||
T.updateEstimatedTimeToAnnounce(retryDelay)
|
||||
T.RetryAttempt++
|
||||
time.Sleep(time.Duration(retryDelay) * time.Second)
|
||||
retryDelay *= 2
|
||||
|
|
@ -64,6 +76,7 @@ func (T *HttpTracker) Announce(query string, headers map[string]string, retry bo
|
|||
}
|
||||
continue
|
||||
}
|
||||
T.HandleSuccessfulResponse(trackerResp)
|
||||
return trackerResp, nil
|
||||
}
|
||||
|
||||
|
|
@ -72,6 +85,7 @@ func (T *HttpTracker) Announce(query string, headers map[string]string, retry bo
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
T.HandleSuccessfulResponse(resp)
|
||||
return resp, nil
|
||||
}
|
||||
}
|
||||
|
|
@ -87,14 +101,14 @@ func (t *HttpTracker) tryMakeRequest(query string, headers map[string]string) (*
|
|||
resp, err := http.DefaultClient.Do(req)
|
||||
if err == nil {
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
bytesR, _ := ioutil.ReadAll(resp.Body)
|
||||
bytesR, _ := io.ReadAll(resp.Body)
|
||||
if len(bytesR) == 0 {
|
||||
continue
|
||||
}
|
||||
mimeType := http.DetectContentType(bytesR)
|
||||
if mimeType == "application/x-gzip" {
|
||||
gzipReader, _ := gzip.NewReader(bytes.NewReader(bytesR))
|
||||
bytesR, _ = ioutil.ReadAll(gzipReader)
|
||||
bytesR, _ = io.ReadAll(gzipReader)
|
||||
gzipReader.Close()
|
||||
}
|
||||
t.LastTackerResponse = string(bytesR)
|
||||
|
|
|
|||
Loading…
Reference in a new issue