Author: alanmc Date: 2008-01-20 05:16:49 -0500 (Sun, 20 Jan 2008) New Revision: 93343
Added: trunk/bitsharp/src/MonoTorrent/Client/Tracker/AnnounceParameters.cs Modified: trunk/bitsharp/src/MonoTorrent/Client/Managers/TrackerManager.cs trunk/bitsharp/src/MonoTorrent/Client/Tracker/HTTPTracker.cs trunk/bitsharp/src/MonoTorrent/Client/Tracker/Tracker.cs trunk/bitsharp/src/MonoTorrent/Client/Tracker/TrackerConnectionId.cs trunk/bitsharp/src/MonoTorrent/Makefile Log: Refactored the Tracker base class again. Simplified usage Modified: trunk/bitsharp/src/MonoTorrent/Client/Managers/TrackerManager.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/Client/Managers/TrackerManager.cs 2008-01-20 10:14:38 UTC (rev 93342) +++ trunk/bitsharp/src/MonoTorrent/Client/Managers/TrackerManager.cs 2008-01-20 10:16:49 UTC (rev 93343) @@ -62,7 +62,7 @@ /// <summary> /// The infohash for the torrent /// </summary> - private string infoHash; + private byte[] infoHash; /// <summary> @@ -106,7 +106,8 @@ public TrackerManager(TorrentManager manager) { this.manager = manager; - this.infoHash = HttpUtility.UrlEncode(manager.Torrent.InfoHash); + this.infoHash = new byte[20]; + Buffer.BlockCopy(manager.Torrent.infoHash, 0, infoHash, 0, 20); // Check if this tracker supports scraping this.trackerTiers = new TrackerTier[manager.Torrent.AnnounceUrls.Count]; @@ -117,6 +118,7 @@ { foreach (Tracker tracker in tier) { + tracker.Tier = tier; tracker.AnnounceComplete += new EventHandler<AnnounceResponseEventArgs>(OnAnnounceComplete); tracker.ScrapeComplete += new EventHandler<ScrapeResponseEventArgs>(OnScrapeComplete); } @@ -142,27 +144,28 @@ /// <param name="clientEvent">The Event (if any) that represents this update</param> internal WaitHandle Announce(TorrentEvent clientEvent) { - return Announce(this.trackerTiers[0], this.trackerTiers[0].Trackers[0], clientEvent, true); + return Announce(this.trackerTiers[0].Trackers[0], clientEvent, true); } public WaitHandle Announce(TrackerTier tier, Tracker tracker) { - return Announce(tier, tracker, TorrentEvent.None, false); + return Announce(tracker, TorrentEvent.None, false); } - private WaitHandle Announce(TrackerTier tier, Tracker tracker, TorrentEvent clientEvent, bool trySubsequent) + private WaitHandle Announce(Tracker tracker, TorrentEvent clientEvent, bool trySubsequent) { - TrackerConnectionID id = new TrackerConnectionID(tier, tracker, trySubsequent, clientEvent, null); + TrackerConnectionID id = new TrackerConnectionID(tracker, trySubsequent, clientEvent, null); this.updateSucceeded = true; this.lastUpdated = DateTime.Now; bool supportsEncryption = ClientEngine.SupportsEncryption && manager.Engine.Settings.MinEncryptionLevel != EncryptionType.None; - WaitHandle handle = tracker.Announce(this.manager.Monitor.DataBytesDownloaded, + AnnounceParameters p = new AnnounceParameters(this.manager.Monitor.DataBytesDownloaded, this.manager.Monitor.DataBytesUploaded, (long)((1 - this.manager.Bitfield.PercentComplete / 100.0) * this.manager.Torrent.Size), clientEvent, this.infoHash, id, supportsEncryption, manager.Engine.PeerId, null, manager.Engine.Settings.ListenPort); + WaitHandle handle = tracker.Announce(p); return handle; } @@ -212,7 +215,7 @@ if (e.Successful) { // FIXME: Figure out why manually firing the event throws an exception here - try {Toolbox.Switch<Tracker>(e.TrackerId.TrackerTier.Trackers, 0, e.TrackerId.TrackerTier.IndexOf(e.Tracker));}catch{} + try {Toolbox.Switch<Tracker>(e.TrackerId.Tracker.Tier.Trackers, 0, e.TrackerId.Tracker.Tier.IndexOf(e.Tracker));}catch{} manager.AddPeers(e.Peers); } else @@ -220,11 +223,14 @@ if (!e.TrackerId.TrySubsequent) return; - GetNextTracker(e.TrackerId.Tracker, out e.TrackerId.TrackerTier, out e.TrackerId.Tracker); - if (e.TrackerId.TrackerTier == null || e.TrackerId.Tracker == null) + TrackerTier tier = e.Tracker.Tier; + Tracker tracker = e.Tracker; + + GetNextTracker(e.TrackerId.Tracker, out tier, out tracker); + if (tier == null || tracker == null) return; - Announce(e.TrackerId.TrackerTier, e.TrackerId.Tracker, e.TrackerId.TorrentEvent, true); + Announce(tracker, e.TrackerId.TorrentEvent, true); } } @@ -235,7 +241,7 @@ /// <returns></returns> public WaitHandle Scrape() { - return Scrape(this.trackerTiers[0], this.trackerTiers[0].Trackers[0], true); + return Scrape(this.trackerTiers[0].Trackers[0], true); } /// <summary> @@ -243,17 +249,17 @@ /// </summary> /// <param name="requestSingle">True if you want scrape information for just the torrent in the TorrentManager. False if you want everything on the tracker</param> /// <returns></returns> - public WaitHandle Scrape(TrackerTier tier, Tracker tracker) + public WaitHandle Scrape(Tracker tracker) { - return Scrape(tier, tracker, false); + return Scrape(tracker, false); } - private WaitHandle Scrape(TrackerTier tier, Tracker tracker, bool trySubsequent) + private WaitHandle Scrape(Tracker tracker, bool trySubsequent) { if (!tracker.CanScrape) throw new TorrentException("This tracker does not support scraping"); - TrackerConnectionID id = new TrackerConnectionID(tier, tracker, trySubsequent, TorrentEvent.None, null); + TrackerConnectionID id = new TrackerConnectionID(tracker, trySubsequent, TorrentEvent.None, null); WaitHandle handle = tracker.Scrape(this.infoHash, id); return handle; Added: trunk/bitsharp/src/MonoTorrent/Client/Tracker/AnnounceParameters.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/Client/Tracker/AnnounceParameters.cs 2008-01-20 10:14:38 UTC (rev 93342) +++ trunk/bitsharp/src/MonoTorrent/Client/Tracker/AnnounceParameters.cs 2008-01-20 10:16:49 UTC (rev 93343) @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MonoTorrent.Common; + +namespace MonoTorrent.Client +{ + public class AnnounceParameters + { + private long bytesDownloaded; + private long bytesLeft; + private long bytesUploaded; + private TorrentEvent clientEvent; + private TrackerConnectionID id; + private byte[] infohash; + private string ipaddress; + private string peerId; + private int port; + private bool requireEncryption; + + /// <summary> + /// The number of bytes downloaded this session + /// </summary> + public long BytesDownloaded + { + get { return bytesDownloaded; } + set { bytesDownloaded = value; } + } + + /// <summary> + /// The number of bytes left to download + /// </summary> + public long BytesLeft + { + get { return bytesLeft; } + set { bytesLeft = value; } + } + + /// <summary> + /// The number of bytes uploaded this session + /// </summary> + public long BytesUploaded + { + get { return bytesUploaded; } + set { bytesUploaded = value; } + } + + /// <summary> + /// The event that caused this announce (if any) + /// </summary> + public TorrentEvent ClientEvent + { + get { return clientEvent; } + set { clientEvent = value; } + } + + /// <summary> + /// FIXME: Maybe this should be private.... + /// </summary> + internal TrackerConnectionID Id + { + get { return id; } + set { id = value; } + } + + /// <summary> + /// The infohash for the torrent which caused this announce + /// </summary> + public byte[] Infohash + { + get { return infohash; } + set { infohash = value; } + } + + /// <summary> + /// The publicly advertised IP address for this computer + /// </summary> + public string Ipaddress + { + get { return ipaddress; } + set { ipaddress = value; } + } + + /// <summary> + /// FIXME: Maybe this should be private?... + /// </summary> + public string PeerId + { + get { return peerId; } + set { peerId = value; } + } + + /// <summary> + /// The public port number that the engine is listening at for connections + /// </summary> + public int Port + { + get { return port; } + set { port = value; } + } + + /// <summary> + /// True if encrypted connections are required + /// </summary> + public bool RequireEncryption + { + get { return requireEncryption; } + set { requireEncryption = value; } + } + + + public AnnounceParameters() + { + + } + + public AnnounceParameters(long bytesDownloaded, long bytesUploaded, long bytesLeft, + TorrentEvent clientEvent, byte[] infohash, TrackerConnectionID id, + bool requireEncryption, string peerId, string ipaddress, int port) + { + this.bytesDownloaded = bytesDownloaded; + this.bytesUploaded = bytesUploaded; + this.bytesLeft = bytesLeft; + this.clientEvent = clientEvent; + this.infohash = infohash; + this.id = id; + this.requireEncryption = requireEncryption; + this.peerId = peerId; + this.ipaddress = ipaddress; + this.port = port; + } + + + } +} \ No newline at end of file Property changes on: trunk/bitsharp/src/MonoTorrent/Client/Tracker/AnnounceParameters.cs ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/bitsharp/src/MonoTorrent/Client/Tracker/HTTPTracker.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/Client/Tracker/HTTPTracker.cs 2008-01-20 10:14:38 UTC (rev 93342) +++ trunk/bitsharp/src/MonoTorrent/Client/Tracker/HTTPTracker.cs 2008-01-20 10:16:49 UTC (rev 93343) @@ -36,6 +36,7 @@ using System.Text.RegularExpressions; using System.Text; using System.Collections.Generic; +using System.Web; namespace MonoTorrent.Client { @@ -67,7 +68,7 @@ } } - public override WaitHandle Scrape(string infohash, TrackerConnectionID id) + public override WaitHandle Scrape(byte[] infohash, TrackerConnectionID id) { HttpWebRequest request; string url = scrapeUrl; @@ -87,25 +88,20 @@ return request.BeginGetResponse(ScrapeReceived, id).AsyncWaitHandle; } - public override WaitHandle Announce(long bytesDownloaded, long bytesUploaded, long bytesLeft, - TorrentEvent clientEvent, string infohash, TrackerConnectionID id, - bool requireEncryption, string peerId, string ipaddress, int port) + public override WaitHandle Announce(AnnounceParameters parameters) { - string announceString = CreateAnnounceString(bytesDownloaded, bytesUploaded, bytesLeft, - clientEvent, infohash, id, requireEncryption, peerId, ipaddress, port); + string announceString = CreateAnnounceString(parameters); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(announceString); request.Proxy = new WebProxy(); // If i don't do this, i can't run the webrequest. It's wierd. - id.Request = request; + parameters.Id.Request = request; UpdateState(TrackerState.Announcing); - return request.BeginGetResponse(AnnounceReceived, id).AsyncWaitHandle; + return request.BeginGetResponse(AnnounceReceived, parameters.Id).AsyncWaitHandle; } - protected string CreateAnnounceString(long bytesDownloaded, long bytesUploaded, long bytesLeft, - TorrentEvent clientEvent, string infohash, TrackerConnectionID id, - bool requireEncryption, string peerId, string ipaddress, int port) + protected string CreateAnnounceString(AnnounceParameters parameters) { StringBuilder sb = new StringBuilder(256); @@ -115,43 +111,43 @@ sb.Append(this.announceUrl); sb.Append((this.announceUrl.IndexOf('?') == -1) ? '?' : '&'); sb.Append("info_hash="); - sb.Append(infohash); + sb.Append(HttpUtility.UrlEncode(parameters.Infohash)); sb.Append("&peer_id="); - sb.Append(peerId); + sb.Append(parameters.PeerId); sb.Append("&port="); - sb.Append(port); + sb.Append(parameters.Port); if (ClientEngine.SupportsEncryption) sb.Append("&supportcrypto=1"); - if (requireEncryption) + if (parameters.RequireEncryption && ClientEngine.SupportsEncryption) sb.Append("&requirecrypto=1"); sb.Append("&uploaded="); - sb.Append(bytesUploaded); + sb.Append(parameters.BytesUploaded); sb.Append("&downloaded="); - sb.Append(bytesDownloaded); + sb.Append(parameters.BytesDownloaded); sb.Append("&left="); - sb.Append(bytesLeft); + sb.Append(parameters.BytesLeft); sb.Append("&compact=1"); // Always use compact response sb.Append("&numwant="); sb.Append(100); sb.Append("&key="); // The 'key' protocol, used as a kind of 'password'. Must be the same between announces sb.Append(Key); - if (ipaddress != null) + if (parameters.Ipaddress != null) { sb.Append("&ip="); - sb.Append(ipaddress); + sb.Append(parameters.Ipaddress); } // If we have not successfully sent the started event to this tier, override the passed in started event // Otherwise append the event if it is not "none" - if (!id.TrackerTier.SentStartedEvent) + if (!parameters.Id.Tracker.Tier.SentStartedEvent) { sb.Append("&event=started"); - id.TrackerTier.SendingStartedEvent = true; + parameters.Id.Tracker.Tier.SendingStartedEvent = true; } - else if (clientEvent != TorrentEvent.None) + else if (parameters.ClientEvent != TorrentEvent.None) { sb.Append("&event="); - sb.Append(clientEvent.ToString().ToLower()); + sb.Append(parameters.ClientEvent.ToString().ToLower()); } if (!string.IsNullOrEmpty(TrackerId)) @@ -170,7 +166,7 @@ /// </summary> /// <param name="result"></param> /// <returns></returns> - public override BEncodedDictionary DecodeResponse(IAsyncResult result) + private BEncodedDictionary DecodeResponse(IAsyncResult result) { int bytesRead = 0; int totalRead = 0; @@ -233,7 +229,7 @@ private void AnnounceReceived(IAsyncResult result) { TrackerConnectionID id = (TrackerConnectionID)result.AsyncState; - BEncodedDictionary dict = id.Tracker.DecodeResponse(result); + BEncodedDictionary dict = DecodeResponse(result); AnnounceResponseEventArgs args = new AnnounceResponseEventArgs(id); @@ -245,14 +241,14 @@ } else { - if (id.TrackerTier.SendingStartedEvent) - id.TrackerTier.SentStartedEvent = true; + if (id.Tracker.Tier.SendingStartedEvent) + id.Tracker.Tier.SentStartedEvent = true; HandleAnnounce(dict, args); UpdateState(TrackerState.AnnounceSuccessful); } - id.TrackerTier.SendingStartedEvent = false; + id.Tracker.Tier.SendingStartedEvent = false; args.Successful = UpdateSucceeded; RaiseAnnounceComplete(args); } @@ -324,7 +320,7 @@ { BEncodedDictionary d; TrackerConnectionID id = (TrackerConnectionID)result.AsyncState; - BEncodedDictionary dict = id.Tracker.DecodeResponse(result); + BEncodedDictionary dict = DecodeResponse(result); bool successful = !dict.ContainsKey("custom error"); ScrapeResponseEventArgs args = new ScrapeResponseEventArgs(this, successful); Modified: trunk/bitsharp/src/MonoTorrent/Client/Tracker/Tracker.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/Client/Tracker/Tracker.cs 2008-01-20 10:14:38 UTC (rev 93342) +++ trunk/bitsharp/src/MonoTorrent/Client/Tracker/Tracker.cs 2008-01-20 10:16:49 UTC (rev 93343) @@ -65,6 +65,7 @@ private DateTime lastUpdated; private int minUpdateInterval; private TrackerState state; + private TrackerTier tier; private string trackerId; private int updateInterval; private bool updateSucceeded; @@ -159,9 +160,13 @@ public TrackerState State { get { return this.state; } - internal set { this.state = value; } } + internal TrackerTier Tier + { + get { return tier; } + set { tier = value; } + } /// <summary> /// The ID for the current tracker @@ -227,14 +232,12 @@ #region Methods - public abstract BEncodedDictionary DecodeResponse(IAsyncResult result); + public abstract WaitHandle Announce(AnnounceParameters parameters); - public abstract WaitHandle Scrape(string infohash, TrackerConnectionID id); + public abstract WaitHandle Scrape(byte[] infohash, TrackerConnectionID id); - public abstract WaitHandle Announce(long bytesDownloaded, long bytesUploaded, long bytesLeft, - TorrentEvent clientEvent, string infohash, TrackerConnectionID id, - bool requireEncryption, string peerId, string ipaddress, int port); + /// <summary> /// Wrapper method to call the OnStateChanged event correctly /// </summary> @@ -242,12 +245,12 @@ /// <param name="newState"></param> protected void UpdateState(TrackerState newState) { - if (State == newState) + if (state == newState) return; // FIXME: Don't send null! TrackerStateChangedEventArgs e = new TrackerStateChangedEventArgs(null, this, State, newState); - State = newState; + state = newState; RaiseStateChanged(e); } Modified: trunk/bitsharp/src/MonoTorrent/Client/Tracker/TrackerConnectionId.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/Client/Tracker/TrackerConnectionId.cs 2008-01-20 10:14:38 UTC (rev 93342) +++ trunk/bitsharp/src/MonoTorrent/Client/Tracker/TrackerConnectionId.cs 2008-01-20 10:16:49 UTC (rev 93343) @@ -53,9 +53,7 @@ public Tracker Tracker; - public TrackerTier TrackerTier; - internal bool TrySubsequent; @@ -65,9 +63,8 @@ /// </summary> /// <param name="request">Object containing information about the Async Request</param> /// <param name="manager">The TorrentManager associated with the TrackerConnection</param> - public TrackerConnectionID(TrackerTier tier, Tracker tracker, bool trySubsequent, TorrentEvent torrentEvent, object request) + public TrackerConnectionID(Tracker tracker, bool trySubsequent, TorrentEvent torrentEvent, object request) { - this.TrackerTier = tier; this.Tracker = tracker; this.TrySubsequent = trySubsequent; this.TorrentEvent = torrentEvent; Modified: trunk/bitsharp/src/MonoTorrent/Makefile =================================================================== --- trunk/bitsharp/src/MonoTorrent/Makefile 2008-01-20 10:14:38 UTC (rev 93342) +++ trunk/bitsharp/src/MonoTorrent/Makefile 2008-01-20 10:16:49 UTC (rev 93343) @@ -139,6 +139,7 @@ Client/Settings/TorrentSettings.cs \ \ \ + Client/Tracker/AnnounceParameters.cs \ Client/Tracker/HTTPTracker.cs \ Client/Tracker/TrackerConnectionId.cs \ Client/Tracker/Tracker.cs \ _______________________________________________ Mono-patches maillist - Mono-patches@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-patches