/*
* Copyright (C) 2006 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.IO;
using System.Text;
using System.Threading;
using System.Diagnostics;
using DCSharp.Backend.Connections;
using DCSharp.Backend.Managers;
using DCSharp.Backend.Objects;
using DCSharp.Hashing;
using DCSharp.Logging;
using DCSharp.Security.Cryptography;
using DCSharp.Settings;
using NmdcDCSharp.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 sealed class Runtime
{
public static event EventHandler<RuntimeErrorEventArgs> Error;
public static event EventHandler<ConnectionEventArgs> ConnectionCreated;
private static Logger log = LogManager.GetLogger("Runtime");
private static FavoriteManager favoriteManager;
private static HashStore hashStore;
private static Nmdc.UdpProtocol udpProtocol;
private static string settingsFile;
private static string favoritesFile;
private static string queueFile;
static Runtime()
{
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
applicationData = Path.Combine(appData, "dcsharp");
settingsFile = GetDataFile("Settings.xml");
favoritesFile = GetDataFile("Favorites.xml");
queueFile = GetDataFile("Queue.xml");
if (!Directory.Exists(applicationData))
{
Directory.CreateDirectory(applicationData);
}
}
#region Properties
public static string ApplicationData
{
get { return applicationData; }
}
private static string applicationData;
public static IConnectionSettings ConnectionSettings
{
get { return settings.ConnectionSettings; }
}
public static IRuntimeSettings Settings
{
get { return settings; }
}
private static RuntimeSettings settings;
public static Listener Listener
{
get { return listener; }
}
private static Listener listener;
public static ProtocolHelper ProtocolHelper
{
get { return protocolHelper; }
set { protocolHelper = value; }
}
private static ProtocolHelper protocolHelper;
// Managers
public static HubManager HubManager
{
get { return hubManager; }
}
private static HubManager hubManager;
public static ConnectionManager ConnectionManager
{
get { return connectionManager; }
}
private static ConnectionManager connectionManager;
public static SearchManager SearchManager
{
get { return searchManager; }
}
private static SearchManager searchManager;
public static ShareManager ShareManager
{
get { return shareManager; }
}
private static ShareManager shareManager;
// Favorite Managers
public static IFavoriteHubManager FavoriteHubManager
{
get { return favoriteManager; }
}
public static IFavoriteUserManager FavoriteUserManager
{
get { return favoriteManager; }
}
// Transfer Managers
public static DownloadManager DownloadManager
{
get { return downloadManager; }
}
private static DownloadManager downloadManager;
public static UploadManager UploadManager
{
get { return uploadManager; }
}
private static UploadManager uploadManager;
#endregion
#region Methods
public static void Init()
{
// Settings
settings = RuntimeSettings.Load(settingsFile);
// Set the default encoding
try
{
DCSharp.Backend.Protocols.Nmdc.Protocol.DefaultEncoding =
Encoding.GetEncoding(settings.ProtocolCodePage);
}
catch
{
}
// Hashing
string indexFile = GetDataFile("HashIndex.xml");
string dataFile = GetDataFile("HashData.dat");
hashStore = new HashStore(Tiger.Create(), indexFile, dataFile);
try
{
hashStore.Load();
}
catch (FileNotFoundException)
{
}
catch (Exception e)
{
log.Error("Error loading hash store", e);
}
// Managers
hubManager = new HubManager();
connectionManager = new ConnectionManager(hubManager);
listener = new Listener(hubManager);
searchManager = new SearchManager(hubManager);
shareManager = new ShareManager(hashStore, applicationData);
favoriteManager = FavoriteManager.Load(favoritesFile);
downloadManager = new DownloadManager(connectionManager, listener);
uploadManager = new UploadManager(connectionManager);
// Load the downloads
downloadManager.Load(queueFile);
// Other
protocolHelper = new ProtocolHelper(hubManager, connectionManager,
downloadManager, uploadManager, searchManager, shareManager,
settings, ConnectionSettings);
udpProtocol = new Nmdc.UdpProtocol(protocolHelper, protocolHelper);
ThreadPool.QueueUserWorkItem(new WaitCallback(InitializeNonCritical),
null);
StartServers();
}
public static void Shutdown()
{
StopServers();
UdpServer.CloseSockets();
lock (hashStore)
{
hashStore.Save();
}
SaveSettings();
}
#region Server
public static bool StartServers()
{
StopServers();
if (ConnectionSettings.SupportsIncoming)
{
try
{
TcpServer.StartListening(ConnectionSettings.Port,
protocolHelper.HandleIncomingConnection);
UdpServer.StartListening(ConnectionSettings.Port, udpProtocol);
}
catch(System.Net.Sockets.SocketException e)
{
OnError(RuntimeError.ServerStart, e);
return false;
}
}
return true;
}
public static void StopServers()
{
TcpServer.StopListening();
UdpServer.StopListening();
}
#endregion
#region ConnectToHub
public static void ConnectToFavoriteHubs()
{
lock (favoriteManager)
{
foreach (FavoriteHubInfo hub in favoriteManager.Hubs)
{
if (hub.AutoConnect)
{
ConnectToHub(hub);
}
}
}
}
public static HubConnection ConnectToHub(FavoriteHubInfo favoriteHub)
{
if (favoriteHub == null)
{
throw new ArgumentNullException("favoriteHub");
}
HubConnection hub = hubManager.GetHub(favoriteHub.Hostname);
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 ConnectToHub(favoriteHub.Hostname, user, favoriteHub.Password);
}
public static HubConnection ConnectToHub(string hostname)
{
return ConnectToHub(hostname, settings.LocalIdentity, null);
}
public static HubConnection ConnectToHub(string hostname,
LocalIdentity user, string password)
{
if (hostname == null)
{
throw new ArgumentNullException("hostname");
}
if (user == null)
{
throw new ArgumentNullException("user");
}
HubConnection hub = hubManager.GetHub(hostname);
if (hub != null)
{
return hub;
}
Nmdc.HubProtocol protocol = new Nmdc.HubProtocol(protocolHelper);
hub = new HubConnection(hostname, user, protocol);
protocol.Connection = hub;
hub.Password = password;
hub.StateChanged += OnHubStateChanged;
OnConnectionCreated(hub);
hub.Connect();
return hub;
}
private static void OnHubStateChanged(object obj, EventArgs args)
{
HubConnection hub = (HubConnection)obj;
if (hub.State == ConnectionState.Connected)
{
hubManager.Add(hub);
}
else if (hub.State == ConnectionState.Disconnected)
{
hubManager.Remove(hub);
}
}
#endregion
public static string GetDataFile(string filename)
{
return Path.Combine(ApplicationData, filename);
}
private static void InitializeNonCritical(object state)
{
// Load the shared directories
foreach (ShareInfo shared in settings.SharedDirectories)
{
try
{
shareManager.AddDirectory(shared.Path, shared.VirtualName);
}
catch
{
}
}
string ip = ConnectionSettings.Address;
if (ip == null || ip.Length == 0)
{
// Get the local IP address. This takes a few seconds.
ConnectionSettings.Address = DCSharp.Extras.Util.GetLocalIPAddress();
}
}
private static void SaveSettings()
{
downloadManager.Save(queueFile);
favoriteManager.Save(favoritesFile);
lock (shareManager.SyncRoot)
{
settings.SharedDirectories = new List<ShareInfo>(shareManager);
}
settings.Save(settingsFile);
}
private static void OnConnectionCreated(HubConnection hub)
{
if (ConnectionCreated != null)
{
ConnectionCreated(null, new ConnectionEventArgs(hub));
}
}
private static void OnError(RuntimeError error, Exception e)
{
log.Error(error.ToString(), e);
if (Error != null)
{
Error(null, new RuntimeErrorEventArgs(error));
}
}
#endregion
}
}
|