feat: add server scanning

This commit is contained in:
Anna 2020-11-06 15:19:42 -05:00
parent 9379b6f84f
commit eaeee89264
12 changed files with 127 additions and 30 deletions

View File

@ -18,7 +18,8 @@
<TabControl>
<TabItem Header="Servers">
<cc:SavedServers ItemsSource="{Binding Config.Servers}"
ItemDoubleClick="SavedServers_ItemDoubleClick" />
ItemDoubleClick="SavedServers_ItemDoubleClick"
ControlsVisibility="Visible" />
</TabItem>
<TabItem Header="Window">
<Grid Margin="8">
@ -74,4 +75,4 @@
</Grid>
</TabItem>
</TabControl>
</Window>
</Window>

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using XIVChatCommon;
@ -87,6 +88,27 @@ namespace XIVChat_Desktop {
this.Host = host;
this.Port = port;
}
protected bool Equals(SavedServer other) {
return this.Name == other.Name && this.Host == other.Host && this.Port == other.Port;
}
public override bool Equals(object? obj) {
if (ReferenceEquals(null, obj)) {
return false;
}
if (ReferenceEquals(this, obj)) {
return true;
}
return obj.GetType() == this.GetType() && this.Equals((SavedServer)obj);
}
[SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")]
public override int GetHashCode() {
return HashCode.Combine(this.Name, this.Host, this.Port);
}
}
[JsonObject]

View File

@ -23,7 +23,8 @@
<cc:SavedServers x:Name="Servers"
ItemsSource="{Binding App.Config.Servers}"
ItemDoubleClick="Servers_ItemDoubleClick" />
ItemDoubleClick="Servers_ItemDoubleClick"
ControlsVisibility="Visible" />
<WrapPanel Grid.Row="1"
Grid.ColumnSpan="2"
@ -40,4 +41,4 @@
</Button>
</WrapPanel>
</Grid>
</Window>
</Window>

View File

@ -62,7 +62,7 @@ namespace XIVChat_Desktop {
if (!this.app.Config.TrustedKeys.Any(trusted => trusted.Key.SequenceEqual(handshake.RemotePublicKey))) {
var trustChannel = Channel.CreateBounded<bool>(1);
this.Dispatch(() => {
this.app.Dispatch(() => {
new TrustDialog(this.app.Window, trustChannel.Writer, handshake.RemotePublicKey).Show();
});
@ -77,13 +77,13 @@ namespace XIVChat_Desktop {
var currentHost = $"{this.host}:{this.port}";
var sameHost = this.app.LastHost == currentHost;
if (!sameHost) {
this.Dispatch(() => {
this.app.Dispatch(() => {
this.app.Window.ClearAllMessages();
this.app.LastHost = currentHost;
});
}
this.Dispatch(() => {
this.app.Dispatch(() => {
this.app.Window.AddSystemMessage("Connected");
});
@ -122,7 +122,7 @@ namespace XIVChat_Desktop {
var result = await Task.WhenAny(inc, cancel);
if (result == inc) {
if (inc.Exception != null) {
this.Dispatch(() => {
this.app.Dispatch(() => {
this.app.Window.AddSystemMessage("Error reading incoming message.");
// ReSharper disable once LocalizableElement
Console.WriteLine($"Error reading incoming message: {inc.Exception.Message}");
@ -166,7 +166,7 @@ namespace XIVChat_Desktop {
try {
await SecretMessage.SendSecretMessage(stream, handshake.Keys.tx, message, this.cancel.Token);
} catch (Exception ex) {
this.Dispatch(() => {
this.app.Dispatch(() => {
this.app.Window.AddSystemMessage("Error sending message.");
// ReSharper disable once LocalizableElement
Console.WriteLine($"Error sending message: {ex.Message}");
@ -180,7 +180,7 @@ namespace XIVChat_Desktop {
// and we need to send this message
await SecretMessage.SendSecretMessage(stream, handshake.Keys.tx, ClientShutdown.Instance);
} catch (Exception ex) {
this.Dispatch(() => {
this.app.Dispatch(() => {
this.app.Window.AddSystemMessage("Error sending message.");
// ReSharper disable once LocalizableElement
Console.WriteLine($"Error sending message: {ex.Message}");
@ -196,7 +196,7 @@ namespace XIVChat_Desktop {
this.SetPlayerData(null);
// at this point, we are disconnected, so log it
this.Dispatch(() => {
this.app.Dispatch(() => {
this.app.Window.AddSystemMessage("Disconnected");
});
@ -221,7 +221,7 @@ namespace XIVChat_Desktop {
case ServerOperation.Message:
var message = ServerMessage.Decode(payload);
this.Dispatch(() => {
this.app.Dispatch(() => {
this.app.Window.AddMessage(message);
});
break;
@ -240,7 +240,7 @@ namespace XIVChat_Desktop {
this.CurrentChannel = channel.name;
this.Dispatch(() => {
this.app.Dispatch(() => {
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.CurrentChannel)));
});
break;
@ -253,7 +253,7 @@ namespace XIVChat_Desktop {
foreach (var msg in backlog.messages.ToList().Chunks(100)) {
msg.Reverse();
var array = msg.ToArray();
this.Dispatch(DispatcherPriority.Background, () => {
this.app.Dispatch(DispatcherPriority.Background, () => {
this.app.Window.AddReversedChunk(array, seq);
});
}
@ -271,11 +271,10 @@ namespace XIVChat_Desktop {
private void SetPlayerData(PlayerData? playerData) {
var visibility = playerData == null ? Visibility.Collapsed : Visibility.Visible;
this.Dispatch(() => {
this.app.Dispatch(() => {
var window = this.app.Window;
window.LoggedInAs.Content = playerData?.name;
window.LoggedInAs.Visibility = visibility;
window.LoggedInAs.Content = playerData?.name ?? "Not logged in";
window.LoggedInAsSeparator.Visibility = visibility;
@ -288,13 +287,5 @@ namespace XIVChat_Desktop {
window.Location.Visibility = visibility;
});
}
private void Dispatch(Action action) {
this.Dispatch(DispatcherPriority.Normal, action);
}
private void Dispatch(DispatcherPriority priority, Action action) {
this.app.Dispatcher.BeginInvoke(priority, action);
}
}
}

View File

@ -31,7 +31,9 @@
</ListView>
<WrapPanel Grid.Column="1"
Orientation="Vertical"
Margin="8,0,0,0">
Margin="8,0,0,0"
DataContext="{Binding ElementName=SavedServersControl}"
Visibility="{Binding ControlsVisibility}">
<Button HorizontalAlignment="Stretch"
Margin="0,0,0,4"
Click="AddServer_Click">
@ -48,4 +50,4 @@
</Button>
</WrapPanel>
</Grid>
</UserControl>
</UserControl>

View File

@ -15,6 +15,11 @@ namespace XIVChat_Desktop.Controls {
set { this.SetValue(ItemsSourceProperty, value); }
}
public Visibility ControlsVisibility {
get { return (Visibility)this.GetValue(ControlsVisibilityProperty); }
set { this.SetValue(ControlsVisibilityProperty, value); }
}
public SavedServer? SelectedServer {
get {
var item = this.Servers.SelectedItem;
@ -26,8 +31,13 @@ namespace XIVChat_Desktop.Controls {
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
"ItemsSource",
typeof(IEnumerable<SavedServer>),
typeof(SavedServers),
new PropertyMetadata(null)
typeof(SavedServers)
);
public static readonly DependencyProperty ControlsVisibilityProperty = DependencyProperty.Register(
"ControlsVisibility",
typeof(Visibility),
typeof(SavedServers)
);
public SavedServers() {

View File

@ -27,6 +27,8 @@
<MenuItem Header="Disconnect"
Click="Disconnect_Click"
IsEnabled="{Binding App.Connected, UpdateSourceTrigger=PropertyChanged}" />
<MenuItem Header="Scan"
Click="Scan_Click" />
<Separator />
<MenuItem Header="Configuration"
Click="Configuration_Click" />

View File

@ -158,5 +158,9 @@ namespace XIVChat_Desktop {
private void ManageTabs_Click(object sender, RoutedEventArgs e) {
new ManageTabs(this).Show();
}
private void Scan_Click(object sender, RoutedEventArgs e) {
new ServerScan(this).Show();
}
}
}

View File

@ -20,6 +20,15 @@ namespace XIVChat_Desktop {
this.DataContext = this;
}
public ManageServer(Window owner, SavedServer server, bool isNewServer) {
this.Owner = owner;
this.Server = server;
this.isNewServer = isNewServer;
this.InitializeComponent();
this.DataContext = this;
}
private void Save_Click(object sender, RoutedEventArgs e) {
// FIXME: this shouldn't be using data bindings because it should only take effect after clicking save
var serverName = this.ServerName.Text;

View File

@ -0,0 +1,44 @@
<Window x:Class="XIVChat_Desktop.ServerScan"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:XIVChat_Desktop"
xmlns:cc="clr-namespace:XIVChat_Desktop.Controls"
mc:Ignorable="d"
xmlns:ui="http://schemas.modernwpf.com/2019"
ui:WindowHelper.UseModernWindowStyle="True"
Title="Server scan"
Closing="ServerScan_OnClosing"
ContentRendered="ServerScan_OnContentRendered"
MinWidth="400"
MinHeight="250"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterOwner"
ResizeMode="CanResizeWithGrip"
ShowInTaskbar="False"
d:DataContext="{d:DesignInstance local:ServerScan}">
<Grid Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<cc:SavedServers Grid.RowSpan="2"
x:Name="SavedServers"
ItemsSource="{Binding Servers}"
ItemDoubleClick="SavedServers_OnItemDoubleClick"
ControlsVisibility="Collapsed" />
<Button Grid.Row="0"
Grid.Column="1"
Click="Add_Click">
Add
</Button>
</Grid>
</Window>

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Windows.Threading;
namespace XIVChat_Desktop {
public static class Util {
@ -8,5 +9,13 @@ namespace XIVChat_Desktop {
yield return locations.GetRange(i, Math.Min(nSize, locations.Count - i));
}
}
public static void Dispatch(this DispatcherObject dispatcherObj, Action action) {
dispatcherObj.Dispatcher.BeginInvoke(action);
}
public static void Dispatch(this DispatcherObject dispatcherObj, DispatcherPriority priority, Action action) {
dispatcherObj.Dispatcher.BeginInvoke(priority, action);
}
}
}

View File

@ -60,7 +60,9 @@ namespace XIVChatPlugin {
await Task.Delay(10_000);
const int multicastPort = 17444;
using var udp = new UdpClient(new IPEndPoint(IPAddress.Any, multicastPort));
using var udp = new UdpClient();
udp.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udp.Client.Bind(new IPEndPoint(IPAddress.Any, multicastPort));
var multicastAddr = IPAddress.Parse("224.0.0.147");
udp.JoinMulticastGroup(multicastAddr);