From df5e276eb3f4dee6252003dae1517a53c2854085 Mon Sep 17 00:00:00 2001 From: fabjuuuh Date: Mon, 12 Oct 2020 12:50:38 +0200 Subject: [PATCH 01/15] Vastgelopen --- DoctorApp/App.xaml | 18 ++ DoctorApp/App.xaml.cs | 17 ++ DoctorApp/AssemblyInfo.cs | 10 + DoctorApp/DoctorApp.csproj | 22 ++ DoctorApp/Models/Info.cs | 16 ++ DoctorApp/Utils/Client.cs | 251 ++++++++++++++++++++ DoctorApp/Utils/DataParser.cs | 206 ++++++++++++++++ DoctorApp/Utils/ObservableObject.cs | 12 + DoctorApp/ViewModels/ClientInfoViewModel.cs | 10 + DoctorApp/ViewModels/LoginViewModel.cs | 44 ++++ DoctorApp/ViewModels/MainViewModel.cs | 17 ++ DoctorApp/ViewModels/MainWindowViewModel.cs | 25 ++ DoctorApp/Views/ClientInfoView.xaml | 14 ++ DoctorApp/Views/ClientInfoView.xaml.cs | 26 ++ DoctorApp/Views/LoginView.xaml | 23 ++ DoctorApp/Views/LoginView.xaml.cs | 26 ++ DoctorApp/Views/MainView.xaml | 14 ++ DoctorApp/Views/MainView.xaml.cs | 26 ++ DoctorApp/Views/MainWindow.xaml | 13 + DoctorApp/Views/MainWindow.xaml.cs | 32 +++ ProftaakRH/ProftaakRH.sln | 7 + 21 files changed, 829 insertions(+) create mode 100644 DoctorApp/App.xaml create mode 100644 DoctorApp/App.xaml.cs create mode 100644 DoctorApp/AssemblyInfo.cs create mode 100644 DoctorApp/DoctorApp.csproj create mode 100644 DoctorApp/Models/Info.cs create mode 100644 DoctorApp/Utils/Client.cs create mode 100644 DoctorApp/Utils/DataParser.cs create mode 100644 DoctorApp/Utils/ObservableObject.cs create mode 100644 DoctorApp/ViewModels/ClientInfoViewModel.cs create mode 100644 DoctorApp/ViewModels/LoginViewModel.cs create mode 100644 DoctorApp/ViewModels/MainViewModel.cs create mode 100644 DoctorApp/ViewModels/MainWindowViewModel.cs create mode 100644 DoctorApp/Views/ClientInfoView.xaml create mode 100644 DoctorApp/Views/ClientInfoView.xaml.cs create mode 100644 DoctorApp/Views/LoginView.xaml create mode 100644 DoctorApp/Views/LoginView.xaml.cs create mode 100644 DoctorApp/Views/MainView.xaml create mode 100644 DoctorApp/Views/MainView.xaml.cs create mode 100644 DoctorApp/Views/MainWindow.xaml create mode 100644 DoctorApp/Views/MainWindow.xaml.cs diff --git a/DoctorApp/App.xaml b/DoctorApp/App.xaml new file mode 100644 index 0000000..3c1bb2a --- /dev/null +++ b/DoctorApp/App.xaml @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/DoctorApp/App.xaml.cs b/DoctorApp/App.xaml.cs new file mode 100644 index 0000000..018bc45 --- /dev/null +++ b/DoctorApp/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace DoctorApp +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/DoctorApp/AssemblyInfo.cs b/DoctorApp/AssemblyInfo.cs new file mode 100644 index 0000000..8b5504e --- /dev/null +++ b/DoctorApp/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/DoctorApp/DoctorApp.csproj b/DoctorApp/DoctorApp.csproj new file mode 100644 index 0000000..516e849 --- /dev/null +++ b/DoctorApp/DoctorApp.csproj @@ -0,0 +1,22 @@ + + + + WinExe + netcoreapp3.1 + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DoctorApp/Models/Info.cs b/DoctorApp/Models/Info.cs new file mode 100644 index 0000000..4c195ca --- /dev/null +++ b/DoctorApp/Models/Info.cs @@ -0,0 +1,16 @@ +using DoctorApp.Utils; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DoctorApp.Models +{ + class Info : ObservableObject + { + public bool ConnectedToServer { get; set; } + public bool ConnectedToVREngine { get; set; } + public bool DoctorConnected { get; set; } + + public bool CanConnectToVR { get; set; } + } +} diff --git a/DoctorApp/Utils/Client.cs b/DoctorApp/Utils/Client.cs new file mode 100644 index 0000000..a3b6273 --- /dev/null +++ b/DoctorApp/Utils/Client.cs @@ -0,0 +1,251 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using DoctorApp.ViewModels; +using ProftaakRH; + +namespace DoctorApp.Utils +{ + public delegate void EngineCallback(); + public class Client : IDataReceiver + { + private TcpClient client; + private NetworkStream stream; + private byte[] buffer = new byte[1024]; + private bool connected; + private byte[] totalBuffer = new byte[1024]; + private int totalBufferReceived = 0; + private bool sessionRunning = false; + private IHandler handler = null; + private LoginViewModel LoginViewModel; + + + public Client() : this("localhost", 5555) + { + + } + + public Client(string adress, int port) + { + this.client = new TcpClient(); + this.connected = false; + client.BeginConnect(adress, port, new AsyncCallback(OnConnect), null); + } + + /// + /// callback method for when the TCP client is connected + /// + /// the result of the async read + private void OnConnect(IAsyncResult ar) + { + this.client.EndConnect(ar); + Console.WriteLine("TCP client Verbonden!"); + + this.stream = this.client.GetStream(); + + this.stream.BeginRead(this.buffer, 0, this.buffer.Length, new AsyncCallback(OnRead), null); + } + + /// + /// callback method for when there is a message read + /// + /// the result of the async read + private void OnRead(IAsyncResult ar) + { + int receivedBytes = this.stream.EndRead(ar); + + if (totalBufferReceived + receivedBytes > 1024) + { + throw new OutOfMemoryException("buffer too small"); + } + Array.Copy(buffer, 0, totalBuffer, totalBufferReceived, receivedBytes); + totalBufferReceived += receivedBytes; + + int expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); + while (totalBufferReceived >= expectedMessageLength) + { + //volledig packet binnen + byte[] messageBytes = new byte[expectedMessageLength]; + Array.Copy(totalBuffer, 0, messageBytes, 0, expectedMessageLength); + + + byte[] payloadbytes = new byte[BitConverter.ToInt32(messageBytes, 0) - 5]; + + Array.Copy(messageBytes, 5, payloadbytes, 0, payloadbytes.Length); + + string identifier; + bool isJson = DataParser.getJsonIdentifier(messageBytes, out identifier); + if (isJson) + { + switch (identifier) + { + case DataParser.LOGIN_RESPONSE: + string responseStatus = DataParser.getResponseStatus(payloadbytes); + if (responseStatus == "OK") + { + Debug.WriteLine("Username and password correct!"); + this.LoginViewModel.setLoginStatus(true); + this.connected = true; + + } + else + { + this.LoginViewModel.setLoginStatus(false); + Debug.WriteLine($"login failed \"{responseStatus}\""); + } + break; + case DataParser.START_SESSION: + Console.WriteLine("Session started!"); + this.sessionRunning = true; + sendMessage(DataParser.getStartSessionJson()); + break; + case DataParser.STOP_SESSION: + Console.WriteLine("Stop session identifier"); + this.sessionRunning = false; + sendMessage(DataParser.getStopSessionJson()); + break; + case DataParser.SET_RESISTANCE: + Console.WriteLine("Set resistance identifier"); + if (this.handler == null) + { + Console.WriteLine("handler is null"); + sendMessage(DataParser.getSetResistanceResponseJson(false)); + } + else + { + this.handler.setResistance(DataParser.getResistanceFromJson(payloadbytes)); + sendMessage(DataParser.getSetResistanceResponseJson(true)); + } + break; + default: + Console.WriteLine($"Received json with identifier {identifier}:\n{Encoding.ASCII.GetString(payloadbytes)}"); + break; + } + } + else if (DataParser.isRawData(messageBytes)) + { + Console.WriteLine($"Received data: {BitConverter.ToString(payloadbytes)}"); + } + + totalBufferReceived -= expectedMessageLength; + expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); + } + + this.stream.BeginRead(this.buffer, 0, this.buffer.Length, new AsyncCallback(OnRead), null); + + } + + /// + /// starts sending a message to the server + /// + /// the message to send + private void sendMessage(byte[] message) + { + stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null); + } + + /// + /// callback method for when a message is fully written to the server + /// + /// the async result representing the asynchronous call + private void OnWrite(IAsyncResult ar) + { + this.stream.EndWrite(ar); + } + + #region interface + //maybe move this to other place + /// + /// bpm method for receiving the BPM value from the bluetooth bike or the simulation + /// + /// the message + public void BPM(byte[] bytes) + { + if (!sessionRunning) + { + return; + } + if (bytes == null) + { + throw new ArgumentNullException("no bytes"); + } + byte[] message = DataParser.GetRawDataMessage(bytes); + + + this.stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null); + } + + /// + /// method for receiving the bike message from the bluetooth bike or the simulation + /// + /// the message + public void Bike(byte[] bytes) + { + + if (!sessionRunning) + { + return; + } + if (bytes == null) + { + throw new ArgumentNullException("no bytes"); + } + byte[] message = DataParser.GetRawDataMessage(bytes); + + /* switch (bytes[0]) + { + + case 0x10: + + if (canSendToEngine) engineConnection.BikeSpeed = (bytes[4] | (bytes[5] << 8)) * 0.01f; + break; + case 0x19: + if (canSendToEngine) engineConnection.BikePower = (bytes[5]) | (bytes[6] & 0b00001111) << 8; + break; + }*/ + + + this.stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null); + } + + #endregion + + /// + /// wether or not the client stream is connected + /// + /// true if it's connected, false if not + public bool IsConnected() + { + return this.connected; + } + /// + /// tries to log in to the server by asking for a username and password + /// + public void tryLogin(string username, string password) + { + string hashUser = Hashing.Hasher.HashString(username); + string hashPassword = Hashing.Hasher.HashString(password); + + byte[] message = DataParser.getJsonMessage(DataParser.GetLoginJson(hashUser, hashPassword)); + + + this.stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null); + } + + /// + /// sets the handler for the client, so either the bike simulator or the bluetooth bike handler + /// + /// + public void SetHandler(IHandler handler) + { + this.handler = handler; + } + + internal void SetLoginViewModel(LoginViewModel loginViewModel) + { + this.LoginViewModel = loginViewModel; + } + } +} diff --git a/DoctorApp/Utils/DataParser.cs b/DoctorApp/Utils/DataParser.cs new file mode 100644 index 0000000..0e06fe8 --- /dev/null +++ b/DoctorApp/Utils/DataParser.cs @@ -0,0 +1,206 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System; +using System.Globalization; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Text; + +namespace DoctorApp.Utils +{ + public class DataParser + { + public const string LOGIN = "LOGIN"; + public const string LOGIN_RESPONSE = "LOGIN RESPONSE"; + public const string START_SESSION = "START SESSION"; + public const string STOP_SESSION = "STOP SESSION"; + public const string SET_RESISTANCE = "SET RESISTANCE"; + /// + /// makes the json object with LOGIN identifier and username and password + /// + /// username + /// password + /// json object to ASCII to bytes + public static byte[] GetLoginJson(string mUsername, string mPassword) + { + dynamic json = new + { + identifier = LOGIN, + data = new + { + username = mUsername, + password = mPassword, + } + }; + + return Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(json)); + } + + public static bool GetUsernamePassword(byte[] jsonbytes, out string username, out string password) + { + dynamic json = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(jsonbytes)); + try + { + username = json.data.username; + password = json.data.password; + return true; + } + catch + { + username = null; + password = null; + return false; + } + } + + private static byte[] getJsonMessage(string mIdentifier, dynamic data) + { + dynamic json = new + { + identifier = mIdentifier, + data + }; + return getMessage(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(json)), 0x01); + } + + private static byte[] getJsonMessage(string mIdentifier) + { + dynamic json = new + { + identifier = mIdentifier, + }; + return getMessage(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(json)), 0x01); + } + + public static byte[] getLoginResponse(string mStatus) + { + return getJsonMessage(LOGIN_RESPONSE, new { status = mStatus }); + } + + public static string getResponseStatus(byte[] json) + { + return ((dynamic)JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json))).data.status; + } + + /// + /// get the identifier from json + /// + /// json in ASCII + /// gets the identifier + /// if it sucseeded + public static bool getJsonIdentifier(byte[] bytes, out string identifier) + { + if (bytes.Length <= 5) + { + throw new ArgumentException("bytes to short"); + } + byte messageId = bytes[4]; + + if (messageId == 0x01) + { + dynamic json = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(bytes.Skip(5).ToArray())); + identifier = json.identifier; + return true; + } + else + { + identifier = ""; + return false; + } + } + + /// + /// checks if the de message is raw data according to the protocol + /// + /// message + /// if message contains raw data + public static bool isRawData(byte[] bytes) + { + if (bytes.Length <= 5) + { + throw new ArgumentException("bytes to short"); + } + return bytes[4] == 0x02; + } + + /// + /// constructs a message with the payload, messageId and clientId + /// + /// + /// + /// + /// the message ready for sending + private static byte[] getMessage(byte[] payload, byte messageId) + { + byte[] res = new byte[payload.Length + 5]; + + Array.Copy(BitConverter.GetBytes(payload.Length + 5), 0, res, 0, 4); + res[4] = messageId; + Array.Copy(payload, 0, res, 5, payload.Length); + + return res; + } + + /// + /// constructs a message with the payload and clientId and assumes the payload is raw data + /// + /// + /// + /// the message ready for sending + public static byte[] GetRawDataMessage(byte[] payload) + { + return getMessage(payload, 0x02); + } + + /// + /// constructs a message with the payload and clientId and assumes the payload is json + /// + /// + /// + /// the message ready for sending + public static byte[] getJsonMessage(byte[] payload) + { + return getMessage(payload, 0x01); + } + + public static byte[] getStartSessionJson() + { + return getJsonMessage(START_SESSION); + } + + public static byte[] getStopSessionJson() + { + return getJsonMessage(STOP_SESSION); + } + + public static byte[] getSetResistanceJson(float mResistance) + { + dynamic data = new + { + resistance = mResistance + }; + return getJsonMessage(SET_RESISTANCE, data); + } + + public static byte[] getSetResistanceResponseJson(bool mWorked) + { + dynamic data = new + { + worked = mWorked + }; + return getJsonMessage(SET_RESISTANCE, data); + } + + public static float getResistanceFromJson(byte[] json) + { + return ((dynamic)JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json))).data.resistance; + } + + public static bool getResistanceFromResponseJson(byte[] json) + { + return ((dynamic)JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json))).data.worked; + } + + + } +} diff --git a/DoctorApp/Utils/ObservableObject.cs b/DoctorApp/Utils/ObservableObject.cs new file mode 100644 index 0000000..9b35f60 --- /dev/null +++ b/DoctorApp/Utils/ObservableObject.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; + +namespace DoctorApp.Utils +{ + public abstract class ObservableObject : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + } +} diff --git a/DoctorApp/ViewModels/ClientInfoViewModel.cs b/DoctorApp/ViewModels/ClientInfoViewModel.cs new file mode 100644 index 0000000..987c76c --- /dev/null +++ b/DoctorApp/ViewModels/ClientInfoViewModel.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DoctorApp.ViewModels +{ + class ClientInfoViewModel + { + } +} diff --git a/DoctorApp/ViewModels/LoginViewModel.cs b/DoctorApp/ViewModels/LoginViewModel.cs new file mode 100644 index 0000000..791aa02 --- /dev/null +++ b/DoctorApp/ViewModels/LoginViewModel.cs @@ -0,0 +1,44 @@ + +using DoctorApp.Utils; +using GalaSoft.MvvmLight.Command; +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Controls; +using System.Windows.Input; + +namespace DoctorApp.ViewModels +{ + class LoginViewModel : ObservableObject + { + public string Username { get; set; } + public ICommand LoginCommand { get; set; } + + public bool LoginStatus { get; set; } + + public bool InvertedLoginStatus { get; set; } + + private MainWindowViewModel mainWindowViewModel; + public LoginViewModel(MainWindowViewModel mainWindowViewModel) + { + this.mainWindowViewModel = mainWindowViewModel; + LoginCommand = new RelayCommand((parameter) => + { + //TODO send username and password to server + this.mainWindowViewModel.client.tryLogin(Username, ((PasswordBox)parameter).Password); + }); + } + + + + internal void setLoginStatus(bool status) + { + this.mainWindowViewModel.InfoModel.ConnectedToServer = status; + this.InvertedLoginStatus = !status; + if (status) + { + this.mainWindowViewModel.SelectedViewModel = new MainViewModel(mainWindowViewModel); + } + } + } +} diff --git a/DoctorApp/ViewModels/MainViewModel.cs b/DoctorApp/ViewModels/MainViewModel.cs new file mode 100644 index 0000000..04d0637 --- /dev/null +++ b/DoctorApp/ViewModels/MainViewModel.cs @@ -0,0 +1,17 @@ +using DoctorApp.Utils; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DoctorApp.ViewModels +{ + class MainViewModel : ObservableObject + { + public MainWindowViewModel MainWindowViewModel { get; set; } + + public MainViewModel(MainWindowViewModel mainWindowViewModel) + { + MainWindowViewModel = mainWindowViewModel; + } + } +} diff --git a/DoctorApp/ViewModels/MainWindowViewModel.cs b/DoctorApp/ViewModels/MainWindowViewModel.cs new file mode 100644 index 0000000..c269da7 --- /dev/null +++ b/DoctorApp/ViewModels/MainWindowViewModel.cs @@ -0,0 +1,25 @@ +using DoctorApp.Models; +using DoctorApp.Utils; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DoctorApp.ViewModels +{ + class MainWindowViewModel + { + public Info InfoModel { get; set; } + + public ObservableObject SelectedViewModel { get; set; } + public Client client { get; } + + public MainWindowViewModel(Client client) + { + this.InfoModel = new Info(); + this.client = client; + LoginViewModel loginViewModel = new LoginViewModel(this); + SelectedViewModel = loginViewModel; + this.client.SetLoginViewModel(loginViewModel); + } + } +} diff --git a/DoctorApp/Views/ClientInfoView.xaml b/DoctorApp/Views/ClientInfoView.xaml new file mode 100644 index 0000000..c67fbae --- /dev/null +++ b/DoctorApp/Views/ClientInfoView.xaml @@ -0,0 +1,14 @@ + + + + + + diff --git a/DoctorApp/Views/ClientInfoView.xaml.cs b/DoctorApp/Views/ClientInfoView.xaml.cs new file mode 100644 index 0000000..8480c28 --- /dev/null +++ b/DoctorApp/Views/ClientInfoView.xaml.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace DoctorApp.Views +{ + /// + /// Interaction logic for ClientInfoView.xaml + /// + public partial class ClientInfoView : Page + { + public ClientInfoView() + { + InitializeComponent(); + } + } +} diff --git a/DoctorApp/Views/LoginView.xaml b/DoctorApp/Views/LoginView.xaml new file mode 100644 index 0000000..8d0ff26 --- /dev/null +++ b/DoctorApp/Views/LoginView.xaml @@ -0,0 +1,23 @@ + + + + + From 568896c28db73c7892c35de422b8d1ba006edf6d Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 14 Oct 2020 12:21:53 +0200 Subject: [PATCH 05/15] fully added the vr engine stuff to the client app --- ClientApp/Utils/EngineConnection.cs | 82 ++++++++++++++++++++++++++++- RH-Engine/JSONParser.cs | 15 ++++++ RH-Engine/Program.cs | 4 +- 3 files changed, 98 insertions(+), 3 deletions(-) diff --git a/ClientApp/Utils/EngineConnection.cs b/ClientApp/Utils/EngineConnection.cs index bc7781f..80b1822 100644 --- a/ClientApp/Utils/EngineConnection.cs +++ b/ClientApp/Utils/EngineConnection.cs @@ -3,6 +3,9 @@ using System.Collections.Generic; using System.Text; using RH_Engine; using System.Net.Sockets; +using Newtonsoft.Json.Linq; +using System.Diagnostics; +using LibNoise.Primitive; namespace ClientApp.Utils { @@ -37,6 +40,8 @@ namespace ClientApp.Utils private static string panelId = string.Empty; private static string bikeId = string.Empty; private static string headId = string.Empty; + private static string groundPlaneId = string.Empty; + private static string terrainId = string.Empty; public float BikeSpeed { get; set; } public float BikePower { get; set; } @@ -191,8 +196,11 @@ namespace ClientApp.Utils string headId = JSONParser.GetIdSceneInfoChild(message, "Head"); string handLeftId = JSONParser.GetIdSceneInfoChild(message, "LeftHand"); string handRightId = JSONParser.GetIdSceneInfoChild(message, "RightHand"); + groundPlaneId = JSONParser.GetIdSceneInfoChild(message, "GroundPlane"); + Write("--- Ground plane id is " + groundPlaneId); }); // add the route and set the route id + CreateTerrain(); SendMessageAndOnResponse(mainCommand.RouteCommand("routeID"), "routeID", (message) => routeId = JSONParser.GetResponseUuid(message)); } @@ -217,8 +225,45 @@ namespace ClientApp.Utils while (cameraId == string.Empty) { } SetFollowSpeed(5.0f); + WriteTextMessage(mainCommand.RoadCommand(routeId, "road")); + WriteTextMessage(mainCommand.ShowRoute("showRouteFalse", false)); }); }); + setEnvironment(); + + + } + + private void setEnvironment() + { + Write("Setting environment"); + WriteTextMessage(mainCommand.DeleteNode(groundPlaneId, "none")); + + PlaceHouses(mainCommand); + + WriteTextMessage(mainCommand.SkyboxCommand(DateTime.Now.Hour)); + } + + private void PlaceHouses(Command mainCommand) + { + PlaceHouse(mainCommand, 2, new float[] { 10f, 1f, 30f }, 1); + PlaceHouse(mainCommand, 1, new float[] { 42f, 1f, 22f }, new float[] { 0f, 90f, 0f }, 2); + PlaceHouse(mainCommand, 11, new float[] { -20f, 1f, 0f }, new float[] { 0f, -35f, 0f }, 3); + PlaceHouse(mainCommand, 7, new float[] { -15f, 1f, 50f }, new float[] { 0f, -50f, 0f }, 4); + PlaceHouse(mainCommand, 24, new float[] { 40f, 1f, 40f }, new float[] { 0f, 75f, 0f }, 5); + PlaceHouse(mainCommand, 22, new float[] { 34f, 1f, -20f }, 6); + PlaceHouse(mainCommand, 14, new float[] { 0f, 1f, -20f }, new float[] { 0f, 210f, 0f }, 7); + } + + private void PlaceHouse(Command mainCommand, int numberHousemodel, float[] position, int serialNumber) + { + PlaceHouse(mainCommand, numberHousemodel, position, new float[] { 0f, 0f, 0f }, serialNumber); + } + + private void PlaceHouse(Command mainCommand, int numberHousemodel, float[] position, float[] rotation, int serialNumber) + { + string folderHouses = @"data\NetworkEngine\models\houses\set1\"; + SendMessageAndOnResponse(mainCommand.AddModel("House1", "housePlacement" + serialNumber, folderHouses + "house" + numberHousemodel + ".obj", position, 4, rotation), "housePlacement" + serialNumber, (message) => Console.WriteLine(message)); } public void UpdateInfoPanel() @@ -264,6 +309,41 @@ namespace ClientApp.Utils WriteTextMessage(mainCommand.RouteFollow(routeId, cameraId, speed)); } + public void CreateTerrain() + { + float x = 0f; + float[] height = new float[256 * 256]; + ImprovedPerlin improvedPerlin = new ImprovedPerlin(0, LibNoise.NoiseQuality.Best); + for (int i = 0; i < 256 * 256; i++) + { + height[i] = improvedPerlin.GetValue(x / 10, x / 10, x * 100) / 3.5f + 1; + + if (height[i] > 1.1f) + { + height[i] = height[i] * 0.8f; + } + else if (height[i] < 0.9f) + { + height[i] = height[i] * 1.2f; + } + x += 0.001f; + } + + SendMessageAndOnResponse(mainCommand.TerrainAdd(new int[] { 256, 256 }, height, "terrain"), "terrain", + (message) => + { + + SendMessageAndOnResponse(mainCommand.renderTerrain("renderTerrain"), "renderTerrain", + (message) => + { + terrainId = JSONParser.GetTerrainID(message); + string addLayerMsg = mainCommand.AddLayer(terrainId, "addLayer"); + SendMessageAndOnResponse(addLayerMsg, "addLayer", (message) => Console.WriteLine("")); + + }); + }); + } + #endregion #region message send/receive @@ -315,7 +395,7 @@ namespace ClientApp.Utils } public void Write(string msg) { - Console.WriteLine("[ENGINECONNECT] " + msg); + Debug.WriteLine("[ENGINECONNECT] " + msg); } } diff --git a/RH-Engine/JSONParser.cs b/RH-Engine/JSONParser.cs index 19bf695..30d750a 100644 --- a/RH-Engine/JSONParser.cs +++ b/RH-Engine/JSONParser.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; namespace RH_Engine @@ -122,5 +123,19 @@ namespace RH_Engine } return null; } + + public static string GetChildUuid(string name, JArray children) + { + foreach (dynamic child in children) + { + if (child.name == name) + { + return child.uuid; + } + } + Console.WriteLine("Could not find id of " + name); + return null; + } + } } \ No newline at end of file diff --git a/RH-Engine/Program.cs b/RH-Engine/Program.cs index 4df6e5e..5eba099 100644 --- a/RH-Engine/Program.cs +++ b/RH-Engine/Program.cs @@ -19,9 +19,9 @@ namespace RH_Engine //new PC("DESKTOP-M2CIH87", "Fabian"), //new PC("T470S", "Shinichi"), //new PC("DESKTOP-DHS478C", "semme"), - //new PC("HP-ZBOOK-SEM", "Sem"), + new PC("HP-ZBOOK-SEM", "Sem"), //new PC("DESKTOP-TV73FKO", "Wouter"), - new PC("DESKTOP-SINMKT1", "Ralf van Aert"), + //new PC("DESKTOP-SINMKT1", "Ralf van Aert"), //new PC("NA", "Bart") }; From c9c0cf35a095cc20819126ce6d01a427de1f7001 Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 14 Oct 2020 13:05:55 +0200 Subject: [PATCH 06/15] removed maincommand from placehouse sig --- ClientApp/Utils/EngineConnection.cs | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/ClientApp/Utils/EngineConnection.cs b/ClientApp/Utils/EngineConnection.cs index 80b1822..ea699a3 100644 --- a/ClientApp/Utils/EngineConnection.cs +++ b/ClientApp/Utils/EngineConnection.cs @@ -239,28 +239,28 @@ namespace ClientApp.Utils Write("Setting environment"); WriteTextMessage(mainCommand.DeleteNode(groundPlaneId, "none")); - PlaceHouses(mainCommand); + PlaceHouses(); WriteTextMessage(mainCommand.SkyboxCommand(DateTime.Now.Hour)); } - private void PlaceHouses(Command mainCommand) + private void PlaceHouses() { - PlaceHouse(mainCommand, 2, new float[] { 10f, 1f, 30f }, 1); - PlaceHouse(mainCommand, 1, new float[] { 42f, 1f, 22f }, new float[] { 0f, 90f, 0f }, 2); - PlaceHouse(mainCommand, 11, new float[] { -20f, 1f, 0f }, new float[] { 0f, -35f, 0f }, 3); - PlaceHouse(mainCommand, 7, new float[] { -15f, 1f, 50f }, new float[] { 0f, -50f, 0f }, 4); - PlaceHouse(mainCommand, 24, new float[] { 40f, 1f, 40f }, new float[] { 0f, 75f, 0f }, 5); - PlaceHouse(mainCommand, 22, new float[] { 34f, 1f, -20f }, 6); - PlaceHouse(mainCommand, 14, new float[] { 0f, 1f, -20f }, new float[] { 0f, 210f, 0f }, 7); + PlaceHouse(2, new float[] { 10f, 1f, 30f }, 1); + PlaceHouse(1, new float[] { 42f, 1f, 22f }, new float[] { 0f, 90f, 0f }, 2); + PlaceHouse(11, new float[] { -20f, 1f, 0f }, new float[] { 0f, -35f, 0f }, 3); + PlaceHouse(7, new float[] { -15f, 1f, 50f }, new float[] { 0f, -50f, 0f }, 4); + PlaceHouse(24, new float[] { 40f, 1f, 40f }, new float[] { 0f, 75f, 0f }, 5); + PlaceHouse(22, new float[] { 34f, 1f, -20f }, 6); + PlaceHouse(14, new float[] { 0f, 1f, -20f }, new float[] { 0f, 210f, 0f }, 7); } - private void PlaceHouse(Command mainCommand, int numberHousemodel, float[] position, int serialNumber) + private void PlaceHouse(int numberHousemodel, float[] position, int serialNumber) { - PlaceHouse(mainCommand, numberHousemodel, position, new float[] { 0f, 0f, 0f }, serialNumber); + PlaceHouse(numberHousemodel, position, new float[] { 0f, 0f, 0f }, serialNumber); } - private void PlaceHouse(Command mainCommand, int numberHousemodel, float[] position, float[] rotation, int serialNumber) + private void PlaceHouse(int numberHousemodel, float[] position, float[] rotation, int serialNumber) { string folderHouses = @"data\NetworkEngine\models\houses\set1\"; SendMessageAndOnResponse(mainCommand.AddModel("House1", "housePlacement" + serialNumber, folderHouses + "house" + numberHousemodel + ".obj", position, 4, rotation), "housePlacement" + serialNumber, (message) => Console.WriteLine(message)); @@ -316,16 +316,16 @@ namespace ClientApp.Utils ImprovedPerlin improvedPerlin = new ImprovedPerlin(0, LibNoise.NoiseQuality.Best); for (int i = 0; i < 256 * 256; i++) { - height[i] = improvedPerlin.GetValue(x / 10, x / 10, x * 100) / 3.5f + 1; + height[i] = improvedPerlin.GetValue(x /10, x / 10, x * 100) / 3.5f + 1; - if (height[i] > 1.1f) - { - height[i] = height[i] * 0.8f; - } - else if (height[i] < 0.9f) - { - height[i] = height[i] * 1.2f; - } + //if (height[i] > 1.1f) + //{ + // height[i] = height[i] * 0.8f; + //} + //else if (height[i] < 0.9f) + //{ + // height[i] = height[i] * 1.2f; + //} x += 0.001f; } From 25176dbaeba97fce95bad8fd9ebc5b8d8c23831b Mon Sep 17 00:00:00 2001 From: fabjuuuh Date: Wed, 14 Oct 2020 13:05:56 +0200 Subject: [PATCH 07/15] Connections shit --- DoctorApp/App.xaml | 7 +- DoctorApp/Utils/Client.cs | 18 +++++ DoctorApp/Utils/DataParser.cs | 25 +++++++ DoctorApp/ViewModels/ClientInfoViewModel.cs | 3 + DoctorApp/ViewModels/LoginViewModel.cs | 4 +- DoctorApp/ViewModels/MainViewModel.cs | 25 +++++++ DoctorApp/Views/ClientInfoView.xaml | 80 +++++++++++++++++---- DoctorApp/Views/ClientInfoView.xaml.cs | 2 +- DoctorApp/Views/MainView.xaml | 16 ++++- DoctorApp/Views/MainWindow.xaml | 9 +-- Server/Client.cs | 8 +-- Server/Communication.cs | 22 ++++-- Server/Server.csproj | 1 + 13 files changed, 186 insertions(+), 34 deletions(-) diff --git a/DoctorApp/App.xaml b/DoctorApp/App.xaml index 5159278..1fcbd5c 100644 --- a/DoctorApp/App.xaml +++ b/DoctorApp/App.xaml @@ -14,6 +14,9 @@ - - + + + + + diff --git a/DoctorApp/Utils/Client.cs b/DoctorApp/Utils/Client.cs index a3b6273..9ce05b7 100644 --- a/DoctorApp/Utils/Client.cs +++ b/DoctorApp/Utils/Client.cs @@ -20,6 +20,8 @@ namespace DoctorApp.Utils private bool sessionRunning = false; private IHandler handler = null; private LoginViewModel LoginViewModel; + private MainViewModel MainViewModel; + private ClientInfoViewModel ClientInfoViewModel; public Client() : this("localhost", 5555) @@ -119,6 +121,12 @@ namespace DoctorApp.Utils sendMessage(DataParser.getSetResistanceResponseJson(true)); } break; + case DataParser.NEW_CONNECTION: + this.MainViewModel.NewConnectedUser(DataParser.getUsernameFromResponseJson(payloadbytes)); + break; + case DataParser.DISCONNECT: + this.MainViewModel.NewConnectedUser(DataParser.getUsernameFromResponseJson(payloadbytes)); + break; default: Console.WriteLine($"Received json with identifier {identifier}:\n{Encoding.ASCII.GetString(payloadbytes)}"); break; @@ -247,5 +255,15 @@ namespace DoctorApp.Utils { this.LoginViewModel = loginViewModel; } + + internal void SetMainViewModel(MainViewModel mainViewModel) + { + this.MainViewModel = mainViewModel; + } + + internal void SetClientInfoViewModel(ClientInfoViewModel clientInfoViewModel) + { + this.ClientInfoViewModel = clientInfoViewModel; + } } } diff --git a/DoctorApp/Utils/DataParser.cs b/DoctorApp/Utils/DataParser.cs index 0e06fe8..ca7ca90 100644 --- a/DoctorApp/Utils/DataParser.cs +++ b/DoctorApp/Utils/DataParser.cs @@ -15,6 +15,8 @@ namespace DoctorApp.Utils public const string START_SESSION = "START SESSION"; public const string STOP_SESSION = "STOP SESSION"; public const string SET_RESISTANCE = "SET RESISTANCE"; + public const string NEW_CONNECTION = "NEW CONNECTION"; + public const string DISCONNECT = "DISCONNECT"; /// /// makes the json object with LOGIN identifier and username and password /// @@ -191,6 +193,24 @@ namespace DoctorApp.Utils return getJsonMessage(SET_RESISTANCE, data); } + public static byte[] getNewConnectionJson(string user) + { + dynamic data = new + { + username = user + }; + return getJsonMessage(NEW_CONNECTION, data); + } + + public static byte[] getDisconnectJson(string user) + { + dynamic data = new + { + username = user + }; + return getJsonMessage(DISCONNECT, data); + } + public static float getResistanceFromJson(byte[] json) { return ((dynamic)JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json))).data.resistance; @@ -201,6 +221,11 @@ namespace DoctorApp.Utils return ((dynamic)JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json))).data.worked; } + public static string getUsernameFromResponseJson(byte[] json) + { + return ((dynamic)JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json))).data.username; + } + } } diff --git a/DoctorApp/ViewModels/ClientInfoViewModel.cs b/DoctorApp/ViewModels/ClientInfoViewModel.cs index 987c76c..54d2df0 100644 --- a/DoctorApp/ViewModels/ClientInfoViewModel.cs +++ b/DoctorApp/ViewModels/ClientInfoViewModel.cs @@ -4,7 +4,10 @@ using System.Text; namespace DoctorApp.ViewModels { + class ClientInfoViewModel { + public string Username { get; set; } + public string TabName { get; set; } } } diff --git a/DoctorApp/ViewModels/LoginViewModel.cs b/DoctorApp/ViewModels/LoginViewModel.cs index 791aa02..a8e26ae 100644 --- a/DoctorApp/ViewModels/LoginViewModel.cs +++ b/DoctorApp/ViewModels/LoginViewModel.cs @@ -37,7 +37,9 @@ namespace DoctorApp.ViewModels this.InvertedLoginStatus = !status; if (status) { - this.mainWindowViewModel.SelectedViewModel = new MainViewModel(mainWindowViewModel); + MainViewModel mainViewModel = new MainViewModel(mainWindowViewModel); + this.mainWindowViewModel.client.SetMainViewModel(mainViewModel); + this.mainWindowViewModel.SelectedViewModel = mainViewModel; } } } diff --git a/DoctorApp/ViewModels/MainViewModel.cs b/DoctorApp/ViewModels/MainViewModel.cs index fe7feba..27c8e69 100644 --- a/DoctorApp/ViewModels/MainViewModel.cs +++ b/DoctorApp/ViewModels/MainViewModel.cs @@ -1,12 +1,17 @@ using DoctorApp.Utils; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; using System.Text; +using System.Windows.Controls; namespace DoctorApp.ViewModels { class MainViewModel : ObservableObject { + public ObservableCollection Tabs { get; set; } + public int Selected { get; set; } public MainWindowViewModel MainWindowViewModel { get; set; } Client client; @@ -15,6 +20,26 @@ namespace DoctorApp.ViewModels { this.MainWindowViewModel = mainWindowViewModel; client = this.MainWindowViewModel.client; + Tabs= new ObservableCollection(); + } + + public void NewConnectedUser(string username) + { + App.Current.Dispatcher.Invoke((Action)delegate + { + Tabs.Add(new ClientInfoViewModel + { + Username = username, + TabName = username + }); + }); + } + + public void DisconnectedUser(string username) + { + } } + + } diff --git a/DoctorApp/Views/ClientInfoView.xaml b/DoctorApp/Views/ClientInfoView.xaml index c67fbae..29eda51 100644 --- a/DoctorApp/Views/ClientInfoView.xaml +++ b/DoctorApp/Views/ClientInfoView.xaml @@ -1,14 +1,68 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +