mirror of
https://github.com/SinTan1729/privtracker.git
synced 2024-12-26 23:38:37 -06:00
110 lines
2.6 KiB
Go
110 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/jackpal/bencode-go"
|
|
)
|
|
|
|
func main() {
|
|
r := gin.Default()
|
|
r.GET("/:room/announce", announce)
|
|
r.GET("/:room/scrape", scrape)
|
|
go Cleanup()
|
|
r.Run()
|
|
}
|
|
|
|
type AnnounceRequest struct {
|
|
InfoHash string `form:"info_hash"`
|
|
PeerID string `form:"peer_id"`
|
|
IP string `form:"ip"`
|
|
Port uint16 `form:"port"`
|
|
Uploaded uint `form:"uploaded"`
|
|
Downloaded uint `form:"downloaded"`
|
|
Left uint `form:"left"`
|
|
Numwant uint `form:"numwant"`
|
|
Key string `form:"key"`
|
|
Compact bool `form:"compact"`
|
|
SupportCrypto bool `form:"supportcrypto"`
|
|
Event string `form:"event"`
|
|
}
|
|
|
|
func (req *AnnounceRequest) IsSeeding() bool {
|
|
return req.Left == 0
|
|
}
|
|
|
|
type AnnounceResponse struct {
|
|
Interval int `bencode:"interval"`
|
|
Complete int `bencode:"complete"`
|
|
Incomplete int `bencode:"incomplete"`
|
|
Peers []byte `bencode:"peers"`
|
|
PeersIPv6 []byte `bencode:"peers_ipv6"`
|
|
}
|
|
|
|
func announce(c *gin.Context) {
|
|
req := new(AnnounceRequest)
|
|
c.BindQuery(req)
|
|
// if req.IP == "" {
|
|
req.IP = c.ClientIP() // not sure if ip from request should be honored
|
|
// }
|
|
if req.Numwant == 0 {
|
|
req.Numwant = 30
|
|
}
|
|
switch req.Event {
|
|
case "stopped":
|
|
DeletePeer(c.Param("room"), req.InfoHash, req.IP, req.Port)
|
|
case "completed":
|
|
GraduateLeecher(c.Param("room"), req.InfoHash, req.IP, req.Port)
|
|
default:
|
|
PutPeer(c.Param("room"), req.InfoHash, req.IP, req.Port, req.IsSeeding())
|
|
}
|
|
peersIPv4, peersIPv6, numSeeders, numLeechers := GetPeers(c.Param("room"), req.InfoHash, req.IP, req.Port, req.IsSeeding(), req.Numwant)
|
|
interval := 120
|
|
if numSeeders == 0 {
|
|
interval /= 2
|
|
} else if numLeechers == 0 {
|
|
interval *= 2
|
|
}
|
|
resp := AnnounceResponse{
|
|
Interval: interval,
|
|
Complete: numSeeders,
|
|
Incomplete: numLeechers,
|
|
Peers: peersIPv4,
|
|
PeersIPv6: peersIPv6,
|
|
}
|
|
if err := bencode.Marshal(c.Writer, resp); err != nil {
|
|
c.Error(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
type ScrapeRequest struct {
|
|
InfoHash string `form:"info_hash"`
|
|
}
|
|
|
|
type ScrapeResponse struct {
|
|
Files map[string]Stat `bencode:"files"`
|
|
}
|
|
|
|
type Stat struct {
|
|
Complete int `bencode:"complete"`
|
|
Incomplete int `bencode:"incomplete"`
|
|
// Downloaded uint `bencode:"downloaded"`
|
|
}
|
|
|
|
func scrape(c *gin.Context) {
|
|
req := new(ScrapeRequest)
|
|
c.BindQuery(req)
|
|
numSeeders, numLeechers := GetStats(c.Param("room"), req.InfoHash)
|
|
resp := ScrapeResponse{
|
|
Files: map[string]Stat{
|
|
req.InfoHash: {
|
|
Complete: numSeeders,
|
|
Incomplete: numLeechers,
|
|
},
|
|
},
|
|
}
|
|
if err := bencode.Marshal(c.Writer, resp); err != nil {
|
|
c.Error(err)
|
|
return
|
|
}
|
|
}
|