/*
* Copyright (C) 2006-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.Collections.Generic;
using System.Text;
using DCSharp.Backend.Connections;
using DCSharp.Backend.Managers;
using DCSharp.Backend.Objects;
using DCSharp.Hashing;
using DCSharp.Logging;
using DCSharp.Settings;
using Nmdc = DCSharp.Backend.Protocols.Nmdc;
namespace DCSharp
{
public enum RuntimeError
{
ServerStart
}
public class RuntimeErrorEventArgs : EventArgs
{
public RuntimeErrorEventArgs(RuntimeError error)
{
this.error = error;
}
public RuntimeError Error
{
get { return error; }
}
private RuntimeError error;
}
///
///
///
public class Runtime
{
public event EventHandler Error;
private static Logger log = LogManager.GetLogger("Runtime");
private IRuntimeSettings settings;
private IConnectionSettings connectionSettings;
private HubManager hubManager;
private ConnectionManager connectionManager;
private SearchManager searchManager;
private ShareManager shareManager;
private DownloadManager downloadManager;
private UploadManager uploadManager;
private ProtocolHelper protocolHelper;
private Nmdc.UdpProtocol udpProtocol;
#region Constructors
public Runtime(IRuntimeSettings settings, IConnectionSettings connectionSettings,
HashStore hashStore, string dataDir, IEnumerable shared)
{
if (settings == null)
{
throw new ArgumentNullException("settings");
}
if (connectionSettings == null)
{
throw new ArgumentNullException("connectionSettings");
}
this.settings = settings;
this.connectionSettings = connectionSettings;
protocolHelper = new ProtocolHelper(this);
// Managers
hubManager = new HubManager(protocolHelper, settings);
connectionManager = new ConnectionManager(hubManager, protocolHelper,
settings);
searchManager = new SearchManager(hubManager);
shareManager = new ShareManager(settings, hashStore, dataDir, shared);
uploadManager = new UploadManager(settings, connectionManager,
shareManager);
downloadManager = new DownloadManager(settings, connectionManager,
hashStore);
// Other
udpProtocol = new Nmdc.UdpProtocol(protocolHelper, protocolHelper);
}
#endregion
#region Properties
///
/// The general settings.
///
public IRuntimeSettings Settings
{
get { return settings; }
}
///
/// The connection settings.
///
public IConnectionSettings ConnectionSettings
{
get { return connectionSettings; }
}
///
///
///
public HubManager HubManager
{
get { return hubManager; }
}
///
///
///
public ConnectionManager ConnectionManager
{
get { return connectionManager; }
}
///
///
///
public SearchManager SearchManager
{
get { return searchManager; }
}
///
///
///
public ShareManager ShareManager
{
get { return shareManager; }
}
///
///
///
public DownloadManager DownloadManager
{
get { return downloadManager; }
}
///
///
///
public UploadManager UploadManager
{
get { return uploadManager; }
}
#endregion
#region Methods
///
/// Shuts down all the managers and stops listening.
///
public void Shutdown()
{
downloadManager.Dispose();
shareManager.SaveFileList();
StopServers();
UdpServer.CloseSockets();
}
#region Server
///
/// Starts listening for incoming connections and search results.
///
/// Nothing is done if listening has been disabled in the settings.
/// True if no errors occured; otherwise, false.
public bool StartServers()
{
StopServers();
if (ConnectionSettings.SupportsIncoming)
{
try
{
TcpServer.StartListening(ConnectionSettings.Port,
connectionManager.HandleIncomingConnection);
UdpServer.StartListening(ConnectionSettings.Port, udpProtocol);
}
catch(System.Net.Sockets.SocketException e)
{
OnError(RuntimeError.ServerStart, e);
return false;
}
}
return true;
}
///
/// Stops listening.
///
public void StopServers()
{
TcpServer.StopListening();
UdpServer.StopListening();
}
#endregion
///
/// Connects to a hub.
///
/// The hub to connect to.
/// The existing or a new connection to the hub.
public HubConnection ConnectToHub(FavoriteHubInfo favoriteHub)
{
// TODO: Move to HubManager/FavoriteHubManager?
if (favoriteHub == null)
{
throw new ArgumentNullException("favoriteHub");
}
Uri uri = StringUtil.CreateUri(favoriteHub.Hostname);
HubConnection hub = hubManager.GetHub(uri);
if (hub != null)
{
return hub;
}
// Create the user for this hub
LocalIdentity user = settings.LocalIdentity;
if (!String.IsNullOrEmpty(favoriteHub.Nick) ||
!String.IsNullOrEmpty(favoriteHub.UserDescription))
{
user = (LocalIdentity)settings.LocalIdentity.Clone();
if (!String.IsNullOrEmpty(favoriteHub.Nick))
{
user.Nick = favoriteHub.Nick;
}
if (!String.IsNullOrEmpty(favoriteHub.UserDescription))
{
user.Description = favoriteHub.UserDescription;
}
}
return hubManager.ConnectTo(uri, user, favoriteHub.Password,
StringUtil.TryGetEncoding(favoriteHub.Encoding));
}
protected virtual void OnError(RuntimeError error, Exception e)
{
log.Error(error.ToString(), e);
if (Error != null)
{
Error(null, new RuntimeErrorEventArgs(error));
}
}
#endregion
}
}