Merge branch 'ConnectionController'

This commit is contained in:
Felix Hartmann (PEA3-Fe-FI)
2021-09-24 09:15:02 +02:00
21 changed files with 991 additions and 152 deletions

View File

@@ -1,29 +1,42 @@
using System;
using System.Diagnostics;
using System.Text.Json;
using Windows.UI.Xaml;
namespace PolyChat.Models
{
public class ChatMessage
{
public readonly string Sender;
public readonly DateTime Timestamp = new DateTime(1970, 01, 01);
public readonly string Content;
public readonly string Ip;
public readonly bool Foreign;
public string Origin;
public string Type;
public string Content;
public DateTime TimeStamp;
public HorizontalAlignment Align;
private bool Foreign;
public ChatMessage(string Content = "", bool Foreign = true, string Sender= "Unknown", string Ip = "127.0.0.1")
/// <summary>
/// Create Message
/// </summary>
/// <param name="origin">Origin IP</param>
/// <param name="type">Message Type, usually "message"</param>
/// <param name="content">Message Content, usually plain text</param>
/// <param name="timeStamp">Parsed DateTime</param>
public ChatMessage(string origin, string type, string content, DateTime timeStamp, bool foreign)
{
this.Sender = Sender;
this.Timestamp = DateTime.Now;
this.Content = Content;
this.Foreign = Foreign;
this.Ip = Ip;
Origin = origin;
TimeStamp = timeStamp;
Type = type;
Content = content;
Align = foreign ? HorizontalAlignment.Right : HorizontalAlignment.Left;
Foreign = foreign;
Debug.WriteLine("Created Loaded Message: " + ToString());
}
override
public string ToString()
{
string prefix = Foreign ? "Other" : "Me";
return $"{prefix}: {Content}({Sender})";
return $"{Type} from {prefix}: {Content}({Origin})";
}
}
}

View File

@@ -1,5 +1,8 @@
using SocketIOSharp.Server.Client;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace PolyChat.Models
{
@@ -7,20 +10,20 @@ namespace PolyChat.Models
{
public string Name;
public string Code;
public ObservableCollection<Message> Messages;
public ObservableCollection<ChatMessage> Messages;
private SocketIOSocket socketIOSocket;
public ChatPartner(string name, string code, ObservableCollection<Message> messages = null)
public ChatPartner(string name, string code, ObservableCollection<ChatMessage> messages = null)
{
Name = name;
Code = code;
if (messages == null) Messages = new ObservableCollection<Message>();
if (messages == null) Messages = new ObservableCollection<ChatMessage>();
else Messages = messages;
}
public SocketIOSocket SocketIOSocket { get => socketIOSocket; set => socketIOSocket = value; }
public void AddMessage(Message message)
public void AddMessage(ChatMessage message)
{
Messages.Add(message);
}

View File

@@ -0,0 +1,101 @@
using System;
using System.Diagnostics;
using EngineIOSharp.Common.Enum;
using Newtonsoft.Json.Linq;
using SocketIOSharp.Client;
using SocketIOSharp.Common;
using SocketIOSharp.Server.Client;
using PolyChat.Models;
namespace PolyChat.Models
{
public class Connection
{
private SocketIOClient Client;
private SocketIOSocket Socket;
private bool Connected = false;
private readonly string IP;
private Action<string, bool, bool> DeleteConnection;
public Connection(string ip, ushort port, Action<JToken[]> onMessage, Action<string, bool, bool> onClose)
{
Debug.WriteLine("! CONNECTING TO SERVER !");
IP = ip;
DeleteConnection = onClose;
// establish connection
Client = new SocketIOClient(new SocketIOClientOption(EngineIOScheme.http, ip, port));
Client.Connect();
// setup event listeners
Client.On(SocketIOEvent.CONNECTION, OnConnect);
Client.On(SocketIOEvent.DISCONNECT, OnDisconnect);
Client.On(SocketIOEvent.ERROR, (JToken[] Data) => OnError(Data));
Client.On("message", (Action<JToken[]>) onMessage);
}
public Connection(SocketIOSocket socket, Action<JToken[]> onMessage, Action<string, bool, bool> onClose)
{
Socket = socket;
DeleteConnection = onClose;
Socket.On(SocketIOEvent.DISCONNECT, OnDisconnect);
Socket.On(SocketIOEvent.ERROR, (JToken[] Data) => OnError(Data));
Socket.On("message", (Action<JToken[]>) onMessage);
//we are connected if we got here, inital packet was already received
Connected = true;
}
public void SendMessage(string message)
{
Debug.WriteLine("--- Sending message ---");
Debug.WriteLine($"Connected {Connected}");
Debug.WriteLine($"Client {Client}");
Debug.WriteLine($"Socket {Socket}");
if (Socket != null) Socket.Emit("message", message);
else if (Client != null) Client.Emit("message", message);
}
// Event Methods
private void OnConnect()
{
Debug.WriteLine("--- Sending initial packet to server ---");
Client.Emit("initial", Controller.getIP());
Debug.WriteLine("--- Connection successfull ---");
Connected = true;
}
private void OnDisconnect()
{
Debug.WriteLine("--- Disconnected! ---");
Debug.WriteLine($"--- Deleting Connection with IP: {IP}---");
DeleteConnection(IP, IsConnected(),false);
Connected = false;
}
private void OnError(JToken[] data)
{
Debug.WriteLine("--- Error: ---");
if (data != null && data.Length > 0 && data[0] != null)
Debug.WriteLine(data[0]);
else
Debug.WriteLine("Unkown Error");
Debug.WriteLine("---");
Close();
}
// Getters
public void Close()
{
if (Client != null) Client.Close();
if (Socket != null) Socket.Close();
}
public bool IsConnected()
{
return Connected;
}
public string getIP()
{
return IP;
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PolyChat.Models
{
public class DialogButton
{
public string Text;
public Action Action;
public DialogButton(string text, Action action)
{
Text = text;
Action = action;
}
}
}

View File

@@ -0,0 +1,258 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;
using System.Diagnostics;
using System.Threading;
using Newtonsoft.Json.Linq;
namespace PolyChat.Models
{
class FileManager
{
// Controller
private readonly Controller controller;
//===============================================================================================================================================
//Constructor
//===============================================================================================================================================
public FileManager(Controller controller)
{
this.controller = controller;
}
//===============================================================================================================================================
// editing save files
//===============================================================================================================================================
/// <summary>
/// deletes chatlog of one speciffic user
/// </summary>
/// <param name="ip"></param>
public void deleteChat(String ip)
{
if (Directory.Exists("U:\\PolyChat\\Saves"))
{
Debug.WriteLine("--Path exists.--");
//go through all files and send ip and json array to ui
String[] filepaths = Directory.GetFiles("U:\\PolyChat\\Saves");
if (filepaths.Length > 0)
{
foreach (String path in filepaths)
{
if (Path.GetFileName(path).Equals(ip+".txt"))
{
File.Delete(path);
return;
}
}
}
}
}
/// <summary>
/// loads one chatlog probably when someone tries to connect
/// </summary>
/// <param name="ip"></param>
public void loadChat(String ip)
{
//load dir and create if non existant
if (Directory.Exists("U:\\PolyChat\\Saves"))
{
Debug.WriteLine("--Path exists.--");
if (File.Exists($"U:\\PolyChat\\Saves\\{ip}.txt"))
{
String jsonArr = decrypt(File.ReadAllText($"U:\\PolyChat\\Saves\\{ip}.txt"));
controller.SendIncomingMessageUI(ip, jsonArr);
}
}
}
/// <summary>
/// sends chatlogs as json array to uiController with corrosponding ip
///
/// in ui when chat is clicked connection gets established
/// </summary>
/// <param name="ip"></param>
public void loadChats()
{
//load dir and create if non existant
if (Directory.Exists("U:\\PolyChat\\Saves"))
{
Debug.WriteLine("--Path exists.--");
}
else
{
Directory.CreateDirectory("U:\\PolyChat\\Saves");
Debug.WriteLine("--Path Created--.");
}
//go through all files and send ip and json array to ui
String[] filepaths = Directory.GetFiles("U:\\PolyChat\\Saves");
if (filepaths.Length > 0)
{
Debug.WriteLine("---Loading Saves");
foreach (String path in filepaths)
{
Debug.WriteLine($"--{path}");
String jsonArr = decrypt(File.ReadAllText(path));
String ip = Path.GetFileName(path);
ip = ip.Substring(0, ip.Length - 4);
Debug.WriteLine($"-{ip}");
Debug.WriteLine(jsonArr);
controller.SendIncomingMessageUI(ip, jsonArr);
}
}
}
/// <summary>
/// Saves incoming chat message to U:\PolyChat\Saves\ip.txt
/// </summary>
/// <param name="ip"></param>
/// <param name="json"></param>
public void saveChats(string ip, string json, DateTime timeStamp)
{
new Thread(() =>
{
//breaking if namechange
JObject obj = JObject.Parse(json);
if (!obj["type"].ToString().Equals("username"))
{
//adding timestamp
obj.Add(new JProperty("timestamp", timeStamp));
json = obj.ToString();
if (File.Exists($"U:\\PolyChat\\Saves\\{ip}.txt"))
{
Debug.WriteLine("--File allready exists--");
//check for integraty of file
string output = decrypt(File.ReadAllText($"U:\\PolyChat\\Saves\\{ip}.txt"));
Debug.WriteLine($"---{output}---");
if (output.Substring(0, 1).Equals("[") && output.Substring(output.Length - 1, 1).Equals("]"))
{
//structure intact
//save new chat
Debug.WriteLine("--adding new chatmessage--");
output = output.Substring(0, output.Length - 1) + ", " + json + " ]"; //rip appart and put file back together
File.Delete($"U:\\PolyChat\\Saves\\{ip}.txt");
File.WriteAllText($"U:\\PolyChat\\Saves\\{ip}.txt", encrypt(output)); //encrypt and save to textfile
}
else
{
//structure not intact
//redo file
Debug.WriteLine("--Structure not intact--");
Debug.WriteLine("--redoing file--");
File.Delete($"U:\\PolyChat\\Saves\\{ip}.txt");
File.WriteAllText($"U:\\PolyChat\\Saves\\{ip}.txt", encrypt($"[ {json} ]")); //encrypt and write to file
}
}
else
{
//setup file
Debug.WriteLine("--Creating new File--");
File.WriteAllText($"U:\\PolyChat\\Saves\\{ip}.txt", encrypt($"[ {json} ]"));
}
}
}).Start();
}
//===============================================================================================================================================
// Encryption
//===============================================================================================================================================
/// <summary>
/// generates keypair [public, privte] (100% secure, trust me)
/// </summary>
/// <returns></returns>
private String[] genKeys()
{
return new String[] {"12345678", "12345678" };
}
/// <summary>
/// does exactly what it says. XD
///
/// encrypts given string and returns unreadable string
/// </summary>
/// <param name="toEncrypt"></param>
/// <returns></returns>
private String encrypt(String toEncrypt)
{
try
{
string textToEncrypt = toEncrypt;
string ToReturn = "";
string publickey = genKeys()[0];
string secretkey = genKeys()[1];
byte[] secretkeyByte = { };
secretkeyByte = System.Text.Encoding.UTF8.GetBytes(secretkey);
byte[] publickeybyte = { };
publickeybyte = System.Text.Encoding.UTF8.GetBytes(publickey);
MemoryStream ms = null;
CryptoStream cs = null;
byte[] inputbyteArray = System.Text.Encoding.UTF8.GetBytes(textToEncrypt);
using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
{
ms = new MemoryStream();
cs = new CryptoStream(ms, des.CreateEncryptor(publickeybyte, secretkeyByte), CryptoStreamMode.Write);
cs.Write(inputbyteArray, 0, inputbyteArray.Length);
cs.FlushFinalBlock();
ToReturn = Convert.ToBase64String(ms.ToArray());
}
return ToReturn;
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex.InnerException);
}
}
/// <summary>
/// does exactly what it says. XD
///
/// takes in unreadable string and returns infirmation
/// </summary>
/// <param name="toEncrypt"></param>
/// <returns></returns>
private String decrypt(String toDecrypt)
{
try
{
string textToDecrypt = toDecrypt;
string ToReturn = "";
string publickey = genKeys()[0];
string privatekey = genKeys()[1];
byte[] privatekeyByte = { };
privatekeyByte = System.Text.Encoding.UTF8.GetBytes(privatekey);
byte[] publickeybyte = { };
publickeybyte = System.Text.Encoding.UTF8.GetBytes(publickey);
MemoryStream ms = null;
CryptoStream cs = null;
byte[] inputbyteArray = new byte[textToDecrypt.Replace(" ", "+").Length];
inputbyteArray = Convert.FromBase64String(textToDecrypt.Replace(" ", "+"));
using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
{
ms = new MemoryStream();
cs = new CryptoStream(ms, des.CreateDecryptor(publickeybyte, privatekeyByte), CryptoStreamMode.Write);
cs.Write(inputbyteArray, 0, inputbyteArray.Length);
cs.FlushFinalBlock();
Encoding encoding = Encoding.UTF8;
ToReturn = encoding.GetString(ms.ToArray());
}
return ToReturn;
}
catch (Exception ae)
{
throw new Exception(ae.Message, ae.InnerException);
}
}
}
}

View File

@@ -1,29 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace PolyChat.Models
{
/// <summary>
/// dumy class for json converter
/// </summary>
public class MSG
{
public String sender = "unknown";
public DateTime timestamp = new DateTime(2000, 01, 01);
public String msg = "empty";
public IPAddress ip = new IPAddress(new byte[] { 49,48,46,49,46,50,49,49,46,50,54 });
public MSG(IPAddress ip, String msg, DateTime timestamp)
{
this.sender = sender;
this.ip = ip;
this.timestamp = timestamp;
this.msg = msg;
}
}
}

View File

@@ -1,10 +0,0 @@
namespace PolyChat.Models
{
enum SendCode
{
Message,
Command,
NameChange,
Initial
}
}