Push failed torrent code as backup before I remove it

This commit is contained in:
2026-01-07 11:03:33 -06:00
parent 8b6801e608
commit 1d5ba40ef0
36 changed files with 2192 additions and 7 deletions

View File

@@ -0,0 +1,70 @@
#pragma once
#include "../Serialization/Bencode.hpp"
#include "TorrentStream.hpp"
namespace Tesses::Framework::BitTorrent
{
constexpr int DEFAULT_PIECE_LENGTH = 524288;
class TorrentFileInfo {
Serialization::Bencode::BeDictionary info;
public:
TorrentFileInfo();
TorrentFileInfo(const Serialization::Bencode::BeDictionary& tkn);
int64_t piece_length=DEFAULT_PIECE_LENGTH;
Serialization::Bencode::BeString pieces;
int64_t isPrivate=0;
Serialization::Bencode::BeString name;
std::variant<int64_t, std::vector<TorrentFileEntry>> fileListOrLength;
int64_t GetTorrentFileSize();
/// @brief Generate the info
/// @return the dictionary containing the info
Serialization::Bencode::BeDictionary& GenerateInfoDictionary();
/// @brief Get the info hash for info (if you are filling out the fields, you need to call GenerateInfoDictionary first)
/// @return the 20 byte info hash
Serialization::Bencode::BeString GetInfoHash();
/// @brief Get the info (does not regenerate info from the fields)
/// @return the dictionary containing the info
Serialization::Bencode::BeDictionary& GetInfoDictionary();
/// @brief Used to load a dictionary in, will overwrite all the fields
/// @param dict the dictionary to load
void Load(const Serialization::Bencode::BeDictionary& dict);
/// @brief Gets a read write based on this info object
/// @param vfs the vfs object
/// @param path file or directory inside vfs
/// @return The read write at object
std::shared_ptr<ReadWriteAt> GetStreamFromFilesystem(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, const Tesses::Framework::Filesystem::VFSPath& path);
/// @brief Create info from file/directory
/// @param vfs the vfs object
/// @param path file or directory inside vfs
/// @param isPrivate whether you use private trackers
/// @param pieceLength length of pieces
void CreateFromFilesystem(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, const Tesses::Framework::Filesystem::VFSPath& path, bool isPrivate=false, int64_t pieceLength=DEFAULT_PIECE_LENGTH);
};
class TorrentFile {
public:
TorrentFile();
TorrentFile(const Serialization::Bencode::BeDictionary& tkn);
Serialization::Bencode::BeString announce;
std::vector<Serialization::Bencode::BeString> announce_list;
std::vector<Serialization::Bencode::BeString> url_list;
Serialization::Bencode::BeString comment;
Serialization::Bencode::BeString created_by;
int64_t creation_date=0;
TorrentFileInfo info;
Serialization::Bencode::BeDictionary ToDictionary();
void Print(std::shared_ptr<TextStreams::TextWriter> writer);
static void CreateTorrent(std::shared_ptr<Tesses::Framework::Streams::Stream> torrent_file_stream,const std::vector<Serialization::Bencode::BeString>& trackers,const std::vector<Serialization::Bencode::BeString>& webseeds, std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, const Tesses::Framework::Filesystem::VFSPath& path, bool isPrivate=false, int64_t pieceLength=DEFAULT_PIECE_LENGTH, Serialization::Bencode::BeString comment="", Serialization::Bencode::BeString created_by = "TessesFrameworkTorrent");
};
}

View File

@@ -0,0 +1,95 @@
#pragma once
#include "TorrentFile.hpp"
#include <queue>
#include "../Threading/Thread.hpp"
#include "../Random.hpp"
namespace Tesses::Framework::BitTorrent
{
class ActiveTorrent;
class TorrentBitField {
std::vector<uint8_t> bits;
size_t no_bits=0;
public:
TorrentBitField();
TorrentBitField(size_t bits);
bool get(size_t index);
void set(size_t index, bool val);
void zero();
size_t size();
void resize(size_t len);
std::vector<uint8_t>& data();
bool allone();
};
struct CancelRequest {
uint32_t piece;
uint32_t begin;
uint32_t length;
};
class TorrentPeer {
public:
bool isChokingMe;
bool isChoked;
bool intrested;
std::shared_ptr<Tesses::Framework::Streams::NetworkStream> stream;
std::vector<CancelRequest> cancel_requests;
std::vector<uint8_t> messages;
TorrentBitField has;
std::vector<std::optional<TorrentBitField>> blocksRequested;
std::string ip;
uint16_t port;
};
class ActiveTorrent {
public:
Random rng;
ActiveTorrent(TorrentFile file, std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,Tesses::Framework::Filesystem::VFSPath directory, std::string peer_id);
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
std::map<std::string,uint64_t> udp_connection_ids;
int64_t downloaded;
int64_t uploaded;
int64_t getLeft();
void addPeer(std::string ip, uint16_t port);
Tesses::Framework::Serialization::Bencode::BeString info_hash;
std::string peer_id;
time_t lastTime;
bool mustAnnounce();
void udpAnounce(Tesses::Framework::Http::Uri uri);
void httpAnounce(std::string url);
Tesses::Framework::Threading::Mutex mtx;
std::vector<std::optional<TorrentBitField>> blocksAquired;
TorrentBitField has;
TorrentFile file;
int64_t torrentSize; //to make it more efficient
Tesses::Framework::Filesystem::VFSPath directory;
std::vector<std::shared_ptr<TorrentPeer>> connections;
std::shared_ptr<ReadWriteAt> torrent_disk;
size_t pieceSize(size_t piece);
std::array<uint8_t,1024> buffer;
void process();
bool processMessages(std::shared_ptr<TorrentPeer> peer);
};
class TorrentManager
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath defaultDirectory;
std::vector<std::shared_ptr<ActiveTorrent>> downloading;
std::vector<std::shared_ptr<ActiveTorrent>> seeding;
std::queue<std::pair<TorrentFile,Tesses::Framework::Filesystem::VFSPath>> torrentQueue;
int torrentCount;
std::atomic<bool> running=false;
public:
TorrentManager(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath defaultDirectory, int torrentCount);
void AddTorrent(TorrentFile file);
void AddTorrent(TorrentFile file, Tesses::Framework::Filesystem::VFSPath directory);
void Start();
void Stop();
~TorrentManager();
};
std::string GeneratePeerId();
}

View File

@@ -0,0 +1,46 @@
#pragma once
#include "TessesFramework/Http/HttpClient.hpp"
#include "TessesFramework/Streams/NetworkStream.hpp"
namespace Tesses::Framework::BitTorrent
{
class TorrentFileEntry {
public:
TorrentFileEntry();
TorrentFileEntry(Tesses::Framework::Filesystem::VFSPath path, int64_t length);
Tesses::Framework::Filesystem::VFSPath path;
int64_t length=0;
};
class ReadWriteAt {
public:
virtual bool ReadBlockAt(uint64_t offset, uint8_t* data, size_t len)=0;
virtual void WriteBlockAt(uint64_t offset, const uint8_t* data, size_t len)=0;
virtual ~ReadWriteAt();
};
class TorrentFileStream : public ReadWriteAt
{
Tesses::Framework::Threading::Mutex mtx;
public:
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path;
uint64_t length;
TorrentFileStream(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path, uint64_t length);
bool ReadBlockAt(uint64_t offset, uint8_t* data, size_t len);
void WriteBlockAt(uint64_t offset, const uint8_t* data, size_t len);
};
class TorrentDirectoryStream : public ReadWriteAt
{
std::vector<Tesses::Framework::Threading::Mutex> mtxs;
public:
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path;
std::vector<TorrentFileEntry> entries;
TorrentDirectoryStream(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path,std::vector<TorrentFileEntry> entries);
bool ReadBlockAt(uint64_t offset, uint8_t* data, size_t len);
void WriteBlockAt(uint64_t offset, const uint8_t* data, size_t len);
};
}

View File

@@ -9,6 +9,7 @@
#include <vector>
#include <functional>
#include "Threading/Mutex.hpp"
#include <optional>
namespace Tesses::Framework
{
@@ -88,8 +89,10 @@ namespace Tesses::Framework
};
extern EventList<uint64_t> OnItteraton;
std::optional<std::string> TF_GetCommandName();
void TF_Init();
void TF_InitWithConsole();
void TF_AllowPortable(std::string argv0);
void TF_ConnectToSelf(uint16_t port);
void TF_InitEventLoop();
void TF_RunEventLoop();
@@ -101,6 +104,7 @@ namespace Tesses::Framework
void TF_SetConsoleEventsEnabled(bool flag);
void TF_InitConsole();
void TF_Invoke(std::function<void()> cb);
std::string TF_FileSize(uint64_t bytes, bool usesBin=true);
#if defined(TESSESFRAMEWORK_LOGTOFILE)
void TF_Log(std::string dataToLog);

View File

@@ -39,6 +39,9 @@ namespace Tesses::Framework::Filesystem
void Chmod(VFSPath path, uint32_t mode);
void Lock(VFSPath path);
void Unlock(VFSPath path);
};
extern std::shared_ptr<LocalFilesystem> LocalFS;
}

View File

@@ -57,5 +57,7 @@ namespace Tesses::Framework::Filesystem
void Chmod(VFSPath path, uint32_t mode);
void Lock(VFSPath path);
void Unlock(VFSPath path);
};
}

View File

@@ -41,5 +41,7 @@ namespace Tesses::Framework::Filesystem
void Chmod(VFSPath path, uint32_t mode);
void Lock(VFSPath path);
void Unlock(VFSPath path);
};
}

View File

@@ -46,6 +46,9 @@ namespace Tesses::Framework::Filesystem
void Chmod(VFSPath path, uint32_t mode);
void Close();
void Lock(VFSPath path);
void Unlock(VFSPath path);
~TempFS();
};
}

View File

@@ -153,6 +153,9 @@ namespace Tesses::Framework::Filesystem
virtual void Chmod(VFSPath path, uint32_t mode);
virtual void Lock(VFSPath path);
virtual void Unlock(VFSPath path);
virtual ~VFS();
virtual void Close();

View File

@@ -3,4 +3,8 @@
#undef DeleteFile
#undef MoveFile
#undef MoveDirectory
/*
Just in case
*/
#undef Lock
#undef Unlock

View File

@@ -145,6 +145,10 @@ struct CaseInsensitiveLess {
public:
static char NibbleToHex(uint8_t nibble);
static uint8_t HexToNibble(char c);
static std::string BytesToHex(const std::vector<uint8_t>& data);
static void BytesToHex(std::string& text,const std::vector<uint8_t>& data);
static std::vector<uint8_t> HexToBytes(const std::string& text);
static void HexToBytes(std::vector<uint8_t>& data,const std::string& text);
static std::string MimeType(std::filesystem::path p);
static bool Invalid(char c);
static std::string Sanitise(std::string text);

View File

@@ -0,0 +1,15 @@
#pragma once
#include "Common.hpp"
namespace Tesses::Framework {
class Random {
uint64_t num;
public:
Random();
Random(uint64_t seed);
uint64_t Next();
uint32_t Next(uint32_t max);
int32_t Next(int32_t min,int32_t max);
uint8_t NextByte();
};
}

View File

@@ -0,0 +1,59 @@
#pragma once
#include <cstdint>
#include <vector>
#include <variant>
#include <string>
#include "../Streams/Stream.hpp"
#include "../TextStreams/TextWriter.hpp"
#include "Json.hpp"
namespace Tesses::Framework::Serialization::Bencode {
class BeArray;
class BeDictionary;
class BeString;
using BeUndefined = std::monostate;
using BeToken = std::variant<BeUndefined,BeArray,BeDictionary,BeString,int64_t>;
class BeArray {
public:
std::vector<BeToken> tokens;
};
class BeDictionary {
public:
std::vector<std::pair<BeString,BeToken>> tokens;
BeToken GetValue(BeString key) const;
void SetValue(BeString key, BeToken value);
};
class BeString {
public:
BeString();
BeString(const std::string& text);
BeString(const char* text);
BeString(const std::vector<uint8_t>& data);
std::vector<uint8_t> data;
operator std::string() const;
};
bool operator==(const BeString& lStr, const BeString& rStr);
bool operator==(const BeString& lStr, const std::string& rStr);
bool operator==(const std::string& lStr, const BeString& rStr);
bool operator==(const BeString& lStr, const char* rStr);
bool operator==(const char* lStr, const BeString& rStr);
bool operator!=(const BeString& lStr, const BeString& rStr);
bool operator!=(const BeString& lStr, const std::string& rStr);
bool operator!=(const std::string& lStr, const BeString& rStr);
bool operator!=(const BeString& lStr, const char* rStr);
bool operator!=(const char* lStr, const BeString& rStr);
class Bencode {
public:
static void Save(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,const BeToken& value);
static BeToken Load(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
//This cannot be converted back to torrent, this may (probably will) be out of order
static Json::JToken ToJson(const BeToken& tkn);
//This may (probably will) be out of order
static void Print(std::shared_ptr<Tesses::Framework::TextStreams::TextWriter> writer, BeToken tkn);
};
}

View File

@@ -9,9 +9,7 @@ namespace Tesses::Framework::Serialization::Json
{
class JArray;
class JObject;
class JUndefined {
public:
};
using JUndefined = std::monostate;
using JToken = std::variant<JUndefined,std::nullptr_t,bool,int64_t,double,std::string, JArray, JObject>;

View File

@@ -34,6 +34,7 @@ namespace Tesses::Framework::Streams
bool success;
bool endOfStream;
public:
bool DataAvailable(int timeout=0);
bool EndOfStream();
bool CanRead();
bool CanWrite();

View File

@@ -39,7 +39,10 @@
#include "HiddenField.hpp"
#include "Serialization/Json.hpp"
#include "Serialization/SQLite.hpp"
#include "Serialization/Bencode.hpp"
#include "Platform/Environment.hpp"
#include "Platform/Process.hpp"
#include "Serialization/BitConverter.hpp"
#include "Args.hpp"
#include "Args.hpp"
#include "BitTorrent/TorrentManager.hpp"
#include "Random.hpp"