/*
* Copyright (C) 2007 Eskil Bylund
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Net;
using System.Net.Sockets;
using DCSharp.Backend.Connections;
using DCSharp.Backend.Managers;
using DCSharp.Backend.Objects;
using DCSharp.Backend.Protocols;
using DCSharp.Settings;
using NmdcDCSharp.Backend.Protocols.Nmdc;
namespace DCSharp{
public class ProtocolHelper : IHubProtocolHelper, IUserProtocolHelper
{
private HubManager hubManager;
private ConnectionManager connectionManager;
private DownloadManager downloadManager;
private UploadManager uploadManager;
private SearchManager searchManager;
private ShareManager shareManager;
private IRuntimeSettings settings;
public ProtocolHelper(HubManager hubManager, ConnectionManager connectionManager,
DownloadManager downloadManager, UploadManager uploadManager,
SearchManager searchManager, ShareManager shareManager,
IRuntimeSettings settings, IConnectionSettings connectionSettings)
{
// TODO: Check arguments for null.
this.hubManager = hubManager;
this.connectionManager = connectionManager;
this.downloadManager = downloadManager;
this.uploadManager = uploadManager;
this.searchManager = searchManager;
this.shareManager = shareManager;
this.settings = settings;
this.connectionSettings = connectionSettings;
}
public void HandleIncomingConnection(Socket socket)
{
Nmdc.UserProtocol protocol = new Nmdc.UserProtocol(this);
UserConnection connection = CreateUserConnection(socket, protocol);
protocol.Connection = connection;
connection.Connect();
}
#region IHubProtocolHelper
public IConnectionSettings ConnectionSettings
{
get { return connectionSettings; }
}
private IConnectionSettings connectionSettings;
public int Slots
{
get { return settings.Slots; }
}
public int FreeSlots
{
get
{
int slots = settings.Slots - uploadManager.ActiveUploads;
return slots >= 0 ? slots : 0;
}
}
public long ShareTotal
{
get { return shareManager.Total; }
}
public IUserProtocolHelper UserProtocolHelper
{
get { return this; }
}
public UserConnection CreateUserConnection(Socket socket,
IUserProtocol protocol)
{
return Setup(new UserConnection(socket, settings.LocalIdentity,
protocol));
}
public UserConnection CreateUserConnection(IPEndPoint endPoint,
IUserProtocol protocol)
{
return Setup(new UserConnection(endPoint, settings.LocalIdentity,
protocol));
}
public void RedirectTo(string hostname)
{
Runtime.ConnectToHub(hostname);
}
public bool CanSearch(string identifier)
{
// TODO: Handle search floods.
return true;
}
public void Search(SearchInfo searchInfo, int? maxResults)
{
shareManager.Search(searchInfo, maxResults);
}
private UserConnection Setup(UserConnection connection)
{
connection.RemoteIdentityChanged += OnRemoteIdentityChanged;
connection.StateChanged += OnStateChanged;
return connection;
}
private void OnRemoteIdentityChanged(object obj, EventArgs args)
{
UserConnection connection = (UserConnection)obj;
connectionManager.Remove(connection);
if (connection.RemoteIdentity != null)
{
connectionManager.Add(connection);
}
}
private void OnStateChanged(object obj, EventArgs args)
{
UserConnection connection = (UserConnection)obj;
if (connection.State == ConnectionState.Disconnected)
{
connectionManager.Remove(connection);
}
}
#endregion
#region IUserProtocolHelper
public IShareManager ShareManager
{
get { return shareManager; }
}
public TransferDirection GetTransferDirection(User user)
{
return downloadManager.HasDownload(user) ? TransferDirection.Down :
TransferDirection.Up;
}
public bool CanUpload(UserConnection connection, UploadFileInfo upload)
{
return uploadManager.CanUpload(connection, upload);
}
#endregion
#region ISearchResultHandler
public void HandleSearchResult(SearchResult result)
{
searchManager.AddResult(result);
}
#endregion
#region ILegacyUserIdentifier
public bool IdentifyUser(string nick, out HubConnection hub,
out Identity identity)
{
return IdentifyUser(nick, null, null, out hub, out identity);
}
public bool IdentifyUser(string nick, string hubName, string hubAddress,
out HubConnection hub, out Identity identity)
{
hub = null;
identity = null;
if (hubAddress != null)
{
hub = hubManager.GetHub(hubAddress);
}
if (hub == null && hubName != null)
{
hub = hubManager.Find(delegate(HubConnection h)
{
return h.Name == hubName;
});
}
if (hub == null && nick != null &&
GetUserAndHubFromNick(nick, out identity, out hub))
{
return true;
}
else if (hub != null)
{
identity = hub.Users.Find(delegate(Identity i)
{
return i.Nick == nick;
});
}
return hub != null && identity != null;
}
private bool GetUserAndHubFromNick(string nick, out Identity identity,
out HubConnection hub)
{
identity = null;
hub = null;
lock (hubManager.SyncRoot)
{
foreach (HubConnection nextHub in hubManager)
{
hub = nextHub;
identity = nextHub.Users.Find(delegate(Identity i)
{
return i.Nick == nick;
});
if (identity != null && downloadManager.HasDownload(identity.User))
{
return true;
}
}
}
return hub != null && identity != null;
}
#endregion
}
}
|