Korero – Rev 1
?pathlinks?
using System;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Korero.Chat;
using Korero.Communication;
using Korero.Database;
using Korero.Economy;
using Korero.Friendship;
using Korero.Heartbeat;
using Korero.Inventory;
using Korero.Land;
using Korero.Notifications;
using Korero.Properties;
using Korero.Teleport;
using Korero.Utilities;
using NetSparkleUpdater.Enums;
using NetSparkleUpdater.Interfaces;
using NetSparkleUpdater.SignatureVerifiers;
using NetSparkleUpdater;
using NetSparkleUpdater.UI.WinForms;
using Serilog;
using System.Reflection;
namespace Korero
{
public partial class MainForm : Form
{
#region Public Enums, Properties and Fields
public ChatForm ChatForm { get; set; }
public MessageDatabase MessageDatabase { get; set; }
public MqttCommunication MqttCommunication { get; set; }
#endregion
#region Private Delegates, Events, Enums, Properties, Indexers and Fields
private readonly Task _autoAwayTask;
private readonly CancellationTokenSource _cancellationTokenSource;
private readonly Task _mqttCommunicationTask;
private readonly NotificationManager _notificationManager;
private AboutForm _aboutForm;
private EconomyForm _economyForm;
private FriendshipForm _friendsForm;
private HeartbeatForm _heartbeatForm;
private InventoryForm _inventoryForm;
private LandForm _mapForm;
private SettingsForm _settingsForm;
private TeleportForm _teleportForm;
private readonly SparkleUpdater _sparkle;
#endregion
#region Constructors, Destructors and Finalizers
public MainForm(Mutex mutex)
{
InitializeComponent();
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(Path.Combine(Constants.UserApplicationDirectory, "Logs", $"{Constants.AssemblyName}.log"),
rollingInterval: RollingInterval.Day)
.CreateLogger();
// Upgrade settings if required.
if (!ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).HasFile)
{
if (Settings.Default.UpdateRequired)
{
Settings.Default.Upgrade();
Settings.Default.Reload();
Settings.Default.UpdateRequired = false;
Settings.Default.Save();
mutex.ReleaseMutex();
Process.Start(Application.ExecutablePath);
Environment.Exit(0);
}
}
// Bind to settings changed event.
Settings.Default.SettingsLoaded += Default_SettingsLoaded;
Settings.Default.SettingsSaving += Default_SettingsSaving;
Settings.Default.PropertyChanged += Default_PropertyChanged;
_cancellationTokenSource = new CancellationTokenSource();
_notificationManager = new NotificationManager(TaskScheduler.FromCurrentSynchronizationContext());
MqttCommunication = new MqttCommunication();
MqttCommunication.NotificationReceived += MqttCommunication_NotificationReceived;
MqttCommunication.Connected += MqttCommunication_Connected;
MqttCommunication.Disconnected += MqttCommunication_Disconnected;
MessageDatabase = new MessageDatabase();
_mqttCommunicationTask = MqttCommunication.Start();
_autoAwayTask = AutoAway(_cancellationTokenSource.Token);
// Start application update.
var manifestModuleName = Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName;
var icon = Icon.ExtractAssociatedIcon(manifestModuleName);
_sparkle = new SparkleUpdater("https://korero.grimore.org/update/appcast.xml",
new Ed25519Checker(SecurityMode.Strict, "LonrgxVjSF0GnY4hzwlRJnLkaxnDn2ikdmOifILzLJY="))
{
UIFactory = new UIFactory(icon),
RelaunchAfterUpdate = true,
SecurityProtocolType = SecurityProtocolType.Tls12
};
_sparkle.StartLoop(true, true);
}
#endregion
#region Event Handlers
private void MqttCommunication_Disconnected(object sender, MqttDisconnectedEventArgs e)
{
_notificationManager.ShowNotification("Korero: Connection", "Disconnected from the MQTT broker.",
Settings.Default.ToasterTimeout);
}
private void MqttCommunication_Connected(object sender, MqttConnectedEventArgs e)
{
_notificationManager.ShowNotification("Korero: Connection",
"Connection to the MQTT broker succeeded.",
Settings.Default.ToasterTimeout);
}
private async void MqttCommunication_NotificationReceived(object sender, MqttNotificationEventArgs e)
{
// Add message to database.
switch (e.Notification["notification"])
{
case "group":
var databaseGroupMessage = new DatabaseMessageGroup(e.Notification["firstname"],
e.Notification["lastname"], e.Notification["message"], e.Notification["group"], DateTime.Now);
await MessageDatabase.SaveGroupMessage(databaseGroupMessage);
await MessageDatabase.MarkConversationSeen($"{databaseGroupMessage.Group}", false);
_notificationManager.ShowNotification("Korero: Group Message",
$"{e.Notification["firstname"]} {e.Notification["lastname"]} says {e.Notification["message"]}",
Resources.comm,
Settings.Default.ToasterTimeout, ShowChatForm);
break;
case "message":
var databaseMessage = new DatabaseMessage(e.Notification["firstname"], e.Notification["lastname"],
e.Notification["message"], DateTime.Now);
await MessageDatabase.SaveMessage(databaseMessage);
await MessageDatabase.MarkConversationSeen(
$"{databaseMessage.FirstName} {databaseMessage.LastName}", false);
_notificationManager.ShowNotification("Korero: Instant Message",
$"{e.Notification["firstname"]} {e.Notification["lastname"]} says {e.Notification["message"]}",
Resources.comm,
Settings.Default.ToasterTimeout, ShowChatForm);
break;
}
switch (e.Notification["notification"])
{
case "balance":
_notificationManager.ShowNotification("Korero: Balance Update",
$"The current balance has changed and is now: {e.Notification["balance"]}", Resources.money,
Settings.Default.ToasterTimeout);
break;
}
}
private static void Default_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Settings.Default.Save();
}
private static void Default_SettingsSaving(object sender, CancelEventArgs e)
{
}
private static void Default_SettingsLoaded(object sender, SettingsLoadedEventArgs e)
{
}
private void QuitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
Environment.Exit(0);
}
private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_aboutForm != null)
{
return;
}
_aboutForm = new AboutForm();
_aboutForm.Closing += AboutForm_Closing;
_aboutForm.Show();
}
private void AboutForm_Closing(object sender, CancelEventArgs e)
{
if (_aboutForm == null)
{
return;
}
_aboutForm.Closing -= AboutForm_Closing;
_aboutForm.Dispose();
_aboutForm = null;
}
private void SettingsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_settingsForm != null)
{
return;
}
_settingsForm = new SettingsForm(MqttCommunication);
_settingsForm.Closing += SettingsForm_Closing;
_settingsForm.Show();
}
private void SettingsForm_Closing(object sender, CancelEventArgs e)
{
if (_settingsForm == null)
{
return;
}
_settingsForm.Closing -= SettingsForm_Closing;
_settingsForm.Dispose();
_settingsForm = null;
}
private void ChatForm_Closing(object sender, CancelEventArgs e)
{
if (ChatForm == null)
{
return;
}
ChatForm.Closing -= ChatForm_Closing;
ChatForm.Dispose();
ChatForm = null;
}
private void ChatToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowChatForm();
}
private void MapToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_mapForm != null)
{
return;
}
_mapForm = new LandForm(this, MqttCommunication);
_mapForm.Closing += MapForm_Closing;
_mapForm.Show();
}
private void MapForm_Closing(object sender, CancelEventArgs e)
{
if (_mapForm == null)
{
return;
}
_mapForm.Closing -= MapForm_Closing;
_mapForm.Dispose();
_mapForm = null;
}
private void TeleportToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_teleportForm != null)
{
return;
}
_teleportForm = new TeleportForm(this, MqttCommunication);
_teleportForm.Closing += TeleportForm_Closing;
_teleportForm.Show();
}
private void TeleportForm_Closing(object sender, CancelEventArgs e)
{
if (_teleportForm == null)
{
return;
}
_teleportForm.Closing -= TeleportForm_Closing;
_teleportForm.Dispose();
_teleportForm = null;
}
private void FriendsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_friendsForm != null)
{
return;
}
_friendsForm = new FriendshipForm(this, MqttCommunication);
_friendsForm.Closing += FriendsForm_Closing;
_friendsForm.Show();
}
private void FriendsForm_Closing(object sender, CancelEventArgs e)
{
if (_friendsForm == null)
{
return;
}
_friendsForm.Closing -= FriendsForm_Closing;
_friendsForm.Dispose();
_friendsForm = null;
}
private void EconomyToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_economyForm != null)
{
return;
}
_economyForm = new EconomyForm(this, MqttCommunication);
_economyForm.Closing += EconomyForm_Closing;
_economyForm.Show();
}
private void EconomyForm_Closing(object sender, CancelEventArgs e)
{
if (_economyForm == null)
{
return;
}
_economyForm.Closing -= EconomyForm_Closing;
_economyForm.Dispose();
_economyForm = null;
}
private void InventoryToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_inventoryForm != null)
{
return;
}
_inventoryForm = new InventoryForm(this, MqttCommunication);
_inventoryForm.Closing += InventoryForm_Closing;
_inventoryForm.Show();
}
private void InventoryForm_Closing(object sender, CancelEventArgs e)
{
if (_inventoryForm == null)
{
return;
}
_inventoryForm.Closing -= InventoryForm_Closing;
_inventoryForm.Dispose();
_inventoryForm = null;
}
private async void UpdateToolStripMenuItem_Click(object sender, EventArgs e)
{
// Manually check for updates, this will not show a ui
var result = await _sparkle.CheckForUpdatesQuietly();
var updates = result.Updates;
if (result.Status == UpdateStatus.UpdateAvailable)
{
// if update(s) are found, then we have to trigger the UI to show it gracefully
_sparkle.ShowUpdateNeededUI();
return;
}
MessageBox.Show("No updates available at this time.", "Korero", MessageBoxButtons.OK,
MessageBoxIcon.Asterisk,
MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly, false);
}
private void HeartbeatToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_heartbeatForm != null)
{
return;
}
_heartbeatForm = new HeartbeatForm(this, MqttCommunication);
_heartbeatForm.Closing += HeartbeatForm_Closing;
_heartbeatForm.Show();
}
private void HeartbeatForm_Closing(object sender, CancelEventArgs e)
{
if (_heartbeatForm == null)
{
return;
}
_heartbeatForm.Closing -= HeartbeatForm_Closing;
_heartbeatForm.Dispose();
_heartbeatForm = null;
}
#endregion
#region Public Methods
public async Task AutoAway(CancellationToken cancellationToken)
{
try
{
do
{
await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken);
if (!Settings.Default.AutoAwayEnabled)
{
continue;
}
if (Miscellaneous.GetIdleTime() < TimeSpan.FromMinutes((int) Settings.Default.AutoAwayMinutes))
{
continue;
}
Settings.Default.CurrentStatus = Resources.Away;
} while (cancellationToken.IsCancellationRequested);
}
catch (Exception ex) when (ex is ObjectDisposedException || ex is OperationCanceledException)
{
}
catch (Exception ex)
{
Log.Warning(ex, "Error while setting auto-away.");
}
}
#endregion
#region Private Methods
private void ShowChatForm()
{
if (ChatForm != null)
{
return;
}
ChatForm = new ChatForm(this, MqttCommunication);
ChatForm.Closing += ChatForm_Closing;
ChatForm.Show();
}
#endregion
}
}
Generated by GNU Enscript 1.6.5.90.