wpf sucks
This commit is contained in:
@@ -6,4 +6,8 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AsyncAwaitBestPractices" Version="4.3.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -11,6 +11,7 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SharedClientServer", "..\Sh
|
|||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||||
|
..\SharedClientServer\SharedClientServer.projitems*{67a9bf1a-d317-47ca-9f07-c3480d1360ff}*SharedItemsImports = 5
|
||||||
..\SharedClientServer\SharedClientServer.projitems*{6d26f969-9cb1-414f-ac3e-7253d449ac5a}*SharedItemsImports = 13
|
..\SharedClientServer\SharedClientServer.projitems*{6d26f969-9cb1-414f-ac3e-7253d449ac5a}*SharedItemsImports = 13
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|||||||
3
Server/FodyWeavers.xml
Normal file
3
Server/FodyWeavers.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||||
|
<PropertyChanged />
|
||||||
|
</Weavers>
|
||||||
74
Server/FodyWeavers.xsd
Normal file
74
Server/FodyWeavers.xsd
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||||
|
<xs:element name="Weavers">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="PropertyChanged" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="InjectOnPropertyNameChanged" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if the On_PropertyName_Changed feature is enabled.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="TriggerDependentProperties" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if the Dependent properties feature is enabled.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="EnableIsChangedProperty" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if the IsChanged property feature is enabled.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="EventInvokerNames" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="CheckForEquality" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="CheckForEqualityUsingBaseEquals" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if equality checks should use the Equals method resolved from the base class.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="UseStaticEqualsFromBase" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if equality checks should use the static Equals method resolved from the base class.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="SuppressWarnings" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to turn off build warnings from this weaver.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="SuppressOnPropertyNameChangedWarning" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to turn off build warnings about mismatched On_PropertyName_Changed methods.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
14
Server/Models/Information.cs
Normal file
14
Server/Models/Information.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
using SharedClientServer;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Server.Models
|
||||||
|
{
|
||||||
|
class Information : ObservableObject
|
||||||
|
{
|
||||||
|
public bool CanStartServer { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
99
Server/Models/ServerClient.cs
Normal file
99
Server/Models/ServerClient.cs
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
using SharedClientServer;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Server.Models
|
||||||
|
{
|
||||||
|
class ServerClient : ObservableObject
|
||||||
|
{
|
||||||
|
public string Username { get; set; }
|
||||||
|
private TcpClient tcpClient;
|
||||||
|
private NetworkStream stream;
|
||||||
|
private byte[] buffer = new byte[1024];
|
||||||
|
private byte[] totalBuffer = new byte[1024];
|
||||||
|
private int totalBufferReceived = 0;
|
||||||
|
|
||||||
|
public ServerClient(TcpClient client)
|
||||||
|
{
|
||||||
|
tcpClient = client;
|
||||||
|
stream = tcpClient.GetStream();
|
||||||
|
stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnRead), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// callback method that gets called when the stream has finished reading a message from the stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ar">the async result status</param>
|
||||||
|
private void OnRead(IAsyncResult ar)
|
||||||
|
{
|
||||||
|
int bytesReceived = this.stream.EndRead(ar);
|
||||||
|
|
||||||
|
if (totalBufferReceived + bytesReceived > 1024)
|
||||||
|
{
|
||||||
|
throw new OutOfMemoryException("buffer is too small!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the received bytes into the buffer
|
||||||
|
Array.Copy(buffer, 0, totalBuffer, totalBufferReceived, bytesReceived);
|
||||||
|
// add the bytes we received to the total amount
|
||||||
|
totalBufferReceived += bytesReceived;
|
||||||
|
|
||||||
|
// calculate the expected length of the message
|
||||||
|
int expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0);
|
||||||
|
|
||||||
|
while (totalBufferReceived >= expectedMessageLength)
|
||||||
|
{
|
||||||
|
// we have received the full packet
|
||||||
|
byte[] message = new byte[expectedMessageLength];
|
||||||
|
// copy the total buffer contents into the message array so we can pass it to the handleIncomingMessage method
|
||||||
|
Array.Copy(totalBuffer, 0, message, 0, expectedMessageLength);
|
||||||
|
HandleIncomingMessage(message);
|
||||||
|
|
||||||
|
// move the contents of the totalbuffer to the start of the array
|
||||||
|
Array.Copy(totalBuffer, expectedMessageLength, totalBuffer, 0, (totalBufferReceived - expectedMessageLength));
|
||||||
|
|
||||||
|
totalBufferReceived -= expectedMessageLength;
|
||||||
|
expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0);
|
||||||
|
if (expectedMessageLength == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// start reading for a new message
|
||||||
|
stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnRead), null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method to handle incoming message data
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">the incoming message</param>
|
||||||
|
private void HandleIncomingMessage(byte[] message)
|
||||||
|
{
|
||||||
|
//TODO implement ways to handle the message
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// sends a message to the tcp client
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">message to send</param>
|
||||||
|
public void sendMessage(byte[] message)
|
||||||
|
{
|
||||||
|
stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// callback method that gets called when the stream has finished writing the message
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ar">the async result status</param>
|
||||||
|
private void OnWrite(IAsyncResult ar)
|
||||||
|
{
|
||||||
|
stream.EndWrite(ar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
Server/Models/ServerCommunication.cs
Normal file
41
Server/Models/ServerCommunication.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
using SharedClientServer;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Server.Models
|
||||||
|
{
|
||||||
|
class ServerCommunication : ObservableObject
|
||||||
|
{
|
||||||
|
private TcpListener listener;
|
||||||
|
private List<ServerClient> serverClients;
|
||||||
|
public bool Started = false;
|
||||||
|
|
||||||
|
public ServerCommunication(TcpListener listener)
|
||||||
|
{
|
||||||
|
this.listener = listener;
|
||||||
|
serverClients = new List<ServerClient>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
listener.Start();
|
||||||
|
Debug.WriteLine($"================================================\nStarted Accepting clients at {DateTime.Now}\n================================================");
|
||||||
|
Started = true;
|
||||||
|
listener.BeginAcceptTcpClient(new AsyncCallback(OnClientConnected), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnClientConnected(IAsyncResult ar)
|
||||||
|
{
|
||||||
|
TcpClient tcpClient = listener.EndAcceptTcpClient(ar);
|
||||||
|
Console.WriteLine($"Got connection from {tcpClient.Client.RemoteEndPoint}");
|
||||||
|
ServerClient sc = new ServerClient(tcpClient);
|
||||||
|
|
||||||
|
serverClients.Add(new ServerClient(tcpClient));
|
||||||
|
listener.BeginAcceptTcpClient(new AsyncCallback(OnClientConnected), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,4 +6,12 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="..\SharedClientServer\SharedClientServer.projitems" Label="Shared" />
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AsyncAwaitBestPractices" Version="4.3.0" />
|
||||||
|
<PackageReference Include="MvvmLightLibs" Version="5.4.1.1" />
|
||||||
|
<PackageReference Include="PropertyChanged.Fody" Version="3.2.9" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
45
Server/ViewModels/MainViewModel.cs
Normal file
45
Server/ViewModels/MainViewModel.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using GalaSoft.MvvmLight.Command;
|
||||||
|
using Server.Models;
|
||||||
|
using SharedClientServer;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace Server.ViewModels
|
||||||
|
{
|
||||||
|
class MainViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
private ServerCommunication serverCommunication;
|
||||||
|
public ICommand ServerStartCommand { get; set; }
|
||||||
|
public Information InformationModel { get; set; }
|
||||||
|
|
||||||
|
public MainViewModel()
|
||||||
|
{
|
||||||
|
Debug.WriteLine("init mainviewmodel");
|
||||||
|
InformationModel = new Information();
|
||||||
|
InformationModel.CanStartServer = true;
|
||||||
|
this.ServerStartCommand = new RelayCommand(() =>
|
||||||
|
{
|
||||||
|
Debug.WriteLine("connect button clicked");
|
||||||
|
if (serverCommunication == null)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("making new server communication");
|
||||||
|
serverCommunication = new ServerCommunication(new TcpListener(IPAddress.Any,5555));
|
||||||
|
}
|
||||||
|
if (!serverCommunication.Started)
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.WriteLine("can start server " + InformationModel.CanStartServer);
|
||||||
|
serverCommunication.Start();
|
||||||
|
|
||||||
|
InformationModel.CanStartServer = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -7,9 +7,7 @@
|
|||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="MainWindow" Height="450" Width="800">
|
Title="MainWindow" Height="450" Width="800">
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextBox HorizontalAlignment="center" Margin="0,0,0,0" Text="{Binding ipAddress, Mode=OneWay}" TextWrapping="Wrap" VerticalAlignment="Center" Width="120"/>
|
<Button Content="Start Server" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Command="{Binding ServerStartCommand}" IsEnabled="{Binding MainViewModel.InformationModel.CanStartServer}"/>
|
||||||
<Label Content="IP address:" HorizontalAlignment="Center" Margin="0,176,0,0" VerticalAlignment="Top" Width="120"/>
|
<Label Content="{Binding MainViewModel.InformationModel.CanStartServer}" HorizontalAlignment="Left" Margin="97,7,0,0" VerticalAlignment="Top"/>
|
||||||
<Button Content="Connect" HorizontalAlignment="Left" Margin="465,0,0,0" VerticalAlignment="Center" Click="ConnectServer"/>
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using System;
|
using Server.ViewModels;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -20,15 +22,13 @@ namespace Server
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class MainWindow : Window
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
private string ipAddress = "test";
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
// use mainviewmodel for the bindings of our methods
|
||||||
|
DataContext = new MainViewModel();
|
||||||
private void ConnectServer(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
SharedClientServer/ObservableObject.cs
Normal file
12
SharedClientServer/ObservableObject.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SharedClientServer
|
||||||
|
{
|
||||||
|
public abstract class ObservableObject : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,5 +10,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)ClientServerUtil.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)ClientServerUtil.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)ObservableObject.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user