-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathProgram.cs
More file actions
120 lines (99 loc) · 4.96 KB
/
Program.cs
File metadata and controls
120 lines (99 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// This file is part of TorrentCore.
// https://torrentcore.org
// Copyright (c) Samuel Fisher.
//
// Licensed under the GNU Lesser General Public License, version 3. See the
// LICENSE file in the project root for full license information.
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TorrentCore;
using TorrentCore.Application.BitTorrent;
using TorrentCore.Data;
using TorrentCore.Engine;
using TorrentCore.Tracker;
using TorrentCore.Transport;
namespace CustomTransportProtocol
{
class Program
{
static async Task Main(string[] args)
{
var transportDir = Path.Combine(Environment.CurrentDirectory, "transport");
var seederDir = Path.Combine(Environment.CurrentDirectory, "seeder");
var downloaderDir = Path.Combine(Environment.CurrentDirectory, "downloader");
// Clear old data
if (Directory.Exists(transportDir))
Directory.Delete(transportDir, true);
if (Directory.Exists(seederDir))
Directory.Delete(seederDir, true);
if (Directory.Exists(downloaderDir))
Directory.Delete(downloaderDir, true);
// Create directories
Directory.CreateDirectory(transportDir);
Directory.CreateDirectory(Path.Combine(transportDir, "announce"));
Directory.CreateDirectory(seederDir);
Directory.CreateDirectory(downloaderDir);
File.Copy(Path.Combine(Environment.CurrentDirectory, "TorrentContent.txt"), Path.Combine(seederDir, "TorrentContent.txt"), true);
// Share a main loop between both peers to make this easier to follow as an example
var mainLoop = new MainLoop();
var metainfo = new MetainfoBuilder("CustomTransportProtocol")
.AddFile("TorrentContent.txt", File.ReadAllBytes("TorrentContent.txt"))
.WithTracker(new Uri("http://example.com/announce")) // Tracker URI is not used in this example
.Build();
var cancelSeeder = new CancellationTokenSource();
var seeder = RunSeederAsync(mainLoop, transportDir, seederDir, metainfo, cancelSeeder.Token);
// Run downloader and awit until finished downloading
await RunDownloaderAsync(mainLoop, transportDir, downloaderDir, metainfo);
// Stop seeding
cancelSeeder.Cancel();
mainLoop.Stop();
Console.WriteLine("Finished...");
Console.ReadKey();
}
static async Task RunSeederAsync(IMainLoop mainLoop, string transportDir, string contentDir, Metainfo metainfo, CancellationToken ct)
{
var client = new TorrentClientBuilder()
.UsePeerId(new PeerId(Encoding.ASCII.GetBytes("SEEDER".PadRight(20, 'X'))))
.ConfigureServices(services =>
{
services.AddLogging(loggingBuilder => loggingBuilder.AddConsole().SetMinimumLevel(LogLevel.Debug));
services.AddSingleton(mainLoop);
services.AddSingleton<ITransportProtocol>(s => new FileTransportProtocol(new DirectoryInfo(transportDir), s.GetRequiredService<PeerId>()));
services.AddSingleton<ITrackerClientFactory>(s => new SingletonTracker(new FileTracker(transportDir, s.GetRequiredService<PeerId>())));
})
.AddBitTorrentApplicationProtocol()
.AddDefaultPipeline()
.Build();
var torrent = client.Add(metainfo, contentDir);
torrent.Start();
await Task.Run(() => ct.WaitHandle.WaitOne());
torrent.Stop();
client.Dispose();
}
static async Task RunDownloaderAsync(IMainLoop mainLoop, string transportDir, string contentDir, Metainfo metainfo)
{
var client = new TorrentClientBuilder()
.UsePeerId(new PeerId(Encoding.ASCII.GetBytes("DOWNLOADER".PadRight(20, 'X'))))
.ConfigureServices(services =>
{
services.AddLogging(loggingBuilder => loggingBuilder.AddConsole().SetMinimumLevel(LogLevel.Debug));
services.AddSingleton(mainLoop);
services.AddSingleton<ITransportProtocol>(s => new FileTransportProtocol(new DirectoryInfo(transportDir), s.GetRequiredService<PeerId>()));
services.AddSingleton<ITrackerClientFactory>(s => new SingletonTracker(new FileTracker(transportDir, s.GetRequiredService<PeerId>())));
})
.AddBitTorrentApplicationProtocol()
.AddDefaultPipeline()
.Build();
var torrent = client.Add(metainfo, contentDir);
torrent.Start();
await torrent.WaitForDownloadCompletionAsync();
torrent.Stop();
client.Dispose();
}
}
}