mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
186 lines
4.0 KiB
Go
186 lines
4.0 KiB
Go
package torr
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
"server/settings"
|
|
"server/torr/storage"
|
|
"server/torr/storage/memcache"
|
|
"server/torr/storage/state"
|
|
"server/utils"
|
|
|
|
"github.com/anacrolix/torrent"
|
|
"github.com/anacrolix/torrent/iplist"
|
|
"github.com/anacrolix/torrent/metainfo"
|
|
)
|
|
|
|
type BTServer struct {
|
|
config *torrent.ClientConfig
|
|
client *torrent.Client
|
|
|
|
storage storage.Storage
|
|
|
|
torrents map[metainfo.Hash]*Torrent
|
|
|
|
mu sync.Mutex
|
|
wmu sync.Mutex
|
|
|
|
watching bool
|
|
}
|
|
|
|
func NewBTS() *BTServer {
|
|
bts := new(BTServer)
|
|
bts.torrents = make(map[metainfo.Hash]*Torrent)
|
|
return bts
|
|
}
|
|
|
|
func (bt *BTServer) Connect() error {
|
|
bt.mu.Lock()
|
|
defer bt.mu.Unlock()
|
|
var err error
|
|
bt.configure()
|
|
bt.client, err = torrent.NewClient(bt.config)
|
|
bt.torrents = make(map[metainfo.Hash]*Torrent)
|
|
return err
|
|
}
|
|
|
|
func (bt *BTServer) Disconnect() {
|
|
bt.mu.Lock()
|
|
defer bt.mu.Unlock()
|
|
if bt.client != nil {
|
|
bt.client.Close()
|
|
bt.client = nil
|
|
utils.FreeOSMemGC()
|
|
}
|
|
}
|
|
|
|
func (bt *BTServer) Reconnect() error {
|
|
bt.Disconnect()
|
|
return bt.Connect()
|
|
}
|
|
|
|
func (bt *BTServer) configure() {
|
|
bt.storage = memcache.NewStorage(settings.Get().CacheSize)
|
|
|
|
blocklist, _ := iplist.MMapPackedFile(filepath.Join(settings.Path, "blocklist"))
|
|
|
|
userAgent := "uTorrent/3.4.9"
|
|
peerID := "-UT3490-"
|
|
|
|
bt.config = torrent.NewDefaultClientConfig()
|
|
|
|
bt.config.DisableIPv6 = true
|
|
bt.config.DisableTCP = settings.Get().DisableTCP
|
|
bt.config.DisableUTP = settings.Get().DisableUTP
|
|
bt.config.NoDefaultPortForwarding = settings.Get().DisableUPNP
|
|
bt.config.NoDHT = settings.Get().DisableDHT
|
|
bt.config.NoUpload = settings.Get().DisableUpload
|
|
bt.config.EncryptionPolicy = torrent.EncryptionPolicy{
|
|
DisableEncryption: settings.Get().Encryption == 1,
|
|
ForceEncryption: settings.Get().Encryption == 2,
|
|
}
|
|
bt.config.IPBlocklist = blocklist
|
|
bt.config.DefaultStorage = bt.storage
|
|
bt.config.Bep20 = peerID
|
|
bt.config.PeerID = utils.PeerIDRandom(peerID)
|
|
bt.config.HTTPUserAgent = userAgent
|
|
bt.config.EstablishedConnsPerTorrent = settings.Get().ConnectionsLimit
|
|
|
|
bt.config.TorrentPeersHighWater = 3000
|
|
bt.config.HalfOpenConnsPerTorrent = 50
|
|
|
|
if settings.Get().DownloadRateLimit > 0 {
|
|
bt.config.DownloadRateLimiter = utils.Limit(settings.Get().DownloadRateLimit * 1024)
|
|
}
|
|
if settings.Get().UploadRateLimit > 0 {
|
|
bt.config.UploadRateLimiter = utils.Limit(settings.Get().UploadRateLimit * 1024)
|
|
}
|
|
if settings.Get().ListenPort > 0 {
|
|
bt.config.ListenPort = settings.Get().ListenPort
|
|
}
|
|
|
|
//bt.config.Debug = true
|
|
|
|
fmt.Println("Configure client:", settings.Get())
|
|
}
|
|
|
|
func (bt *BTServer) AddTorrent(magnet metainfo.Magnet, onAdd func(*Torrent)) (*Torrent, error) {
|
|
torr, err := NewTorrent(magnet, bt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if onAdd != nil {
|
|
go func() {
|
|
if torr.GotInfo() {
|
|
onAdd(torr)
|
|
}
|
|
}()
|
|
} else {
|
|
go torr.GotInfo()
|
|
}
|
|
|
|
return torr, nil
|
|
}
|
|
|
|
func (bt *BTServer) List() []*Torrent {
|
|
bt.mu.Lock()
|
|
defer bt.mu.Unlock()
|
|
list := make([]*Torrent, 0)
|
|
for _, t := range bt.torrents {
|
|
list = append(list, t)
|
|
}
|
|
return list
|
|
}
|
|
|
|
func (bt *BTServer) GetTorrent(hash metainfo.Hash) *Torrent {
|
|
bt.mu.Lock()
|
|
defer bt.mu.Unlock()
|
|
|
|
if t, ok := bt.torrents[hash]; ok {
|
|
return t
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (bt *BTServer) RemoveTorrent(hash torrent.InfoHash) {
|
|
if torr, ok := bt.torrents[hash]; ok {
|
|
torr.Close()
|
|
}
|
|
}
|
|
|
|
func (bt *BTServer) BTState() *BTState {
|
|
bt.mu.Lock()
|
|
defer bt.mu.Unlock()
|
|
|
|
btState := new(BTState)
|
|
btState.LocalPort = bt.client.LocalPort()
|
|
btState.PeerID = fmt.Sprintf("%x", bt.client.PeerID())
|
|
btState.BannedIPs = len(bt.client.BadPeerIPs())
|
|
for _, dht := range bt.client.DhtServers() {
|
|
btState.DHTs = append(btState.DHTs, dht)
|
|
}
|
|
for _, t := range bt.torrents {
|
|
btState.Torrents = append(btState.Torrents, t)
|
|
}
|
|
return btState
|
|
}
|
|
|
|
func (bt *BTServer) CacheState(hash metainfo.Hash) *state.CacheState {
|
|
st := bt.GetTorrent(hash)
|
|
if st == nil {
|
|
return nil
|
|
}
|
|
|
|
cacheState := bt.storage.GetStats(hash)
|
|
return cacheState
|
|
}
|
|
|
|
func (bt *BTServer) WriteState(w io.Writer) {
|
|
bt.client.WriteStatus(w)
|
|
}
|