diff --git a/DX86/DX86.cs b/DX86/DX86.cs index e1bf356..83c476e 100644 --- a/DX86/DX86.cs +++ b/DX86/DX86.cs @@ -130,6 +130,23 @@ namespace DX86 while ((numBytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0) { string receivedMessage = Encoding.UTF8.GetString(buffer, 0, numBytesRead); + // remove last \n and \r from receivedMessage (if its on last position) + if (receivedMessage.EndsWith("\n")) + { + receivedMessage = receivedMessage.Substring(0, receivedMessage.Length - 1); + } + if (receivedMessage.EndsWith("\r")) + { + receivedMessage = receivedMessage.Substring(0, receivedMessage.Length - 1); + } + if (receivedMessage.EndsWith("\n")) + { + receivedMessage = receivedMessage.Substring(0, receivedMessage.Length - 1); + } + if (receivedMessage.EndsWith("\r")) + { + receivedMessage = receivedMessage.Substring(0, receivedMessage.Length - 1); + } MessageReceived?.Invoke(client, receivedMessage); //ms.Log($"[DX86] Message from client: {receivedMessage}"); BroadcastMessage(receivedMessage, client); diff --git a/Library/Worker.cs b/Library/Employee.cs similarity index 56% rename from Library/Worker.cs rename to Library/Employee.cs index c58516a..d639ba8 100644 --- a/Library/Worker.cs +++ b/Library/Employee.cs @@ -1,6 +1,6 @@ namespace Library; -public class Worker +public class Employee { } \ No newline at end of file diff --git a/Library/WorkerState.cs b/Library/EmployeeState.cs similarity index 68% rename from Library/WorkerState.cs rename to Library/EmployeeState.cs index 21c7f3b..713c40b 100644 --- a/Library/WorkerState.cs +++ b/Library/EmployeeState.cs @@ -1,6 +1,6 @@ namespace Library; -public enum WorkerState +public enum EmployeeState { WORKING, BREAK, diff --git a/Library/Server.cs b/Library/Server.cs index a18349b..9baa4ad 100644 --- a/Library/Server.cs +++ b/Library/Server.cs @@ -1,6 +1,195 @@ -namespace Library; +using System.Net.Sockets; +using System.Text; +using System.Text.Json; +using System.Collections.Concurrent; + +namespace Library; public class Server { + private TcpClient client; + private NetworkStream stream; + private StreamReader reader; + private StreamWriter writer; + private Action onMessageReceived; + private ConcurrentDictionary> pendingRequests = new(); + + public Server(string ip, int port) + { + ConnectAsync(ip, port).Wait(); + } + + private async Task ConnectAsync(string serverIp, int serverPort) + { + client = new TcpClient(); + await client.ConnectAsync(serverIp, serverPort); + stream = client.GetStream(); + reader = new StreamReader(stream, Encoding.UTF8); + writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true }; + + Console.WriteLine("Connected to the server."); + _ = ReceiveMessagesAsync(); // Start receiving messages in the background + } + + private async Task ReceiveMessagesAsync() + { + try + { + while (client.Connected) + { + string message = await reader.ReadLineAsync(); + if (message != null) + { + // Parse the JSON response + var response = JsonSerializer.Deserialize(message); + if (response != null && pendingRequests.TryRemove(response.Id, out var tcs)) + { + tcs.SetResult(response.Response); // Complete the task with the response + } + else + { + onMessageReceived?.Invoke(message); // Handle other messages + } + } + } + } + catch (Exception ex) + { + Console.WriteLine("Error receiving data: " + ex.Message); + } + } + + private async Task ExecuteCommandAsync(string command) + { + var requestId = Guid.NewGuid().ToString(); // Generate a unique ID for the request + var tcs = new TaskCompletionSource(); + pendingRequests[requestId] = tcs; + + // Create the JSON request + var request = new JsonRequest + { + Id = requestId, + Command = command + }; + + string jsonString = JsonSerializer.Serialize(request); + + // Send the command with the request ID + await SendMessageAsync(jsonString); + + // Await the response + return await tcs.Task; + } + + private async Task SendMessageAsync(string message) + { + if (client.Connected) + { + await writer.WriteLineAsync(message); + } + } + + private class JsonRequest + { + public string Id { get; set; } + public string Command { get; set; } + } + + private class JsonResponse + { + public string Id { get; set; } + public string Response { get; set; } + } + + public Task GetEmployee(int? id = null, string code = null) + { + if (id == null && code == null) + { + throw new ArgumentException("Either id or code must be provided."); + } + + if (id != null && code != null) + { + throw new ArgumentException("Only one of id or code should be provided."); + } + + Employee? employee = null; + string commandResult; + + // Implement logic to get a worker by ID or code + if (id != null) + commandResult = ExecuteCommandAsync(".get worker byid " + id).Result; + else + commandResult = ExecuteCommandAsync(".get worker bycode " + id).Result; + + // Deserialize the command result to an Employee object + try + { + employee = JsonSerializer.Deserialize(commandResult); + return Task.FromResult(employee); + } + catch (JsonException) + { + Console.WriteLine("Failed to deserialize the command result."); + } + + return Task.FromException(new Exception("Failed to get worker.")); + } + + public Task Login(string username, string password) + { + // Implement login logic + var commandResult = ExecuteCommandAsync(".login " + username + " " + password).Result; + if (commandResult == "success") + { + return Task.FromResult("Success"); + } + return Task.FromException(new Exception("Failed to login.")); + } + + public Task Logout() + { + // Implement logout logic + var commandResult = ExecuteCommandAsync(".logout").Result; + if (commandResult == "success") + { + return Task.FromResult("Success"); + } + return Task.FromException(new Exception("Failed to logout.")); + } + + public Task clockIn(Employee employee) + { + var commandResult = ExecuteCommandAsync(".clockin ").Result; + if (commandResult == "success") + { + return Task.FromResult("Success"); + } + return Task.FromException(new Exception("Failed to clock in.")); + } + public Task clockOut(Employee employee) + { + var commandResult = ExecuteCommandAsync(".clockout ").Result; + if (commandResult == "success") + { + return Task.FromResult("Success"); + } + else + { + return Task.FromException(new Exception("Failed to clock out.")); + } + } + public Task clockBreak(Employee employee) + { + var commandResult = ExecuteCommandAsync(".clockbreak").Result; + if (commandResult == "success") + { + return Task.FromResult("Success"); + } + else + { + return Task.FromException(new Exception("Failed to clock break.")); + } + } } \ No newline at end of file diff --git a/Server/BackendServer.cs b/Server/BackendServer.cs index 1930583..91b44f5 100644 --- a/Server/BackendServer.cs +++ b/Server/BackendServer.cs @@ -5,11 +5,11 @@ namespace Server; public class BackendServer : DX86.TcpServer { - CommandManager _CommandManager; + CommandManager commandManager; public BackendServer(string address, int port, MessageSender ms) : base(address, port, ms) { ms.Log("[BACKENDSERVER] Setting up server."); - _CommandManager = new CommandManager(); + commandManager = new CommandManager(); ms.Log("[BACKENDSERVER] Server Setup Complete."); } @@ -49,6 +49,6 @@ public class BackendServer : DX86.TcpServer string command = args[0].Substring(1); // Remove the leading dot string[] commandArgs = args.Skip(1).ToArray(); // Get the arguments after the command - + commandManager.ExecuteCommand(executor:command, args:commandArgs, client:client, clientSocket:this); } } \ No newline at end of file diff --git a/Server/CommandManager.cs b/Server/CommandManager.cs index 82c2be8..d61fa28 100644 --- a/Server/CommandManager.cs +++ b/Server/CommandManager.cs @@ -1,4 +1,6 @@ -using System.Reflection; +using System.Net.Sockets; +using System.Reflection; +using DX86; using Server.Commands; namespace Server; @@ -30,11 +32,11 @@ public class CommandManager } } - public void ExecuteCommand(string executor, params string[] args) + public void ExecuteCommand(string executor, TcpClient? client = null, TcpServer? clientSocket = null, params string[] args) { if (_commands.TryGetValue(executor, out var command)) { - command.Exec(args); + command.Exec(args:args, client:client, clientSocket:clientSocket); } else { diff --git a/Server/Commands/HelpCommand.cs b/Server/Commands/HelpCommand.cs new file mode 100644 index 0000000..822cac7 --- /dev/null +++ b/Server/Commands/HelpCommand.cs @@ -0,0 +1,24 @@ +using System.Net.Sockets; +using DX86; + +namespace Server.Commands; + +public class HelpCommand : ICommand +{ + public string Executor { get; } + public HelpCommand() + { + Executor = "help"; + } + public void Exec(string[] args, TcpClient? client = null, TcpServer? clientSocket = null) + { + clientSocket.SendMessageAsync(client, "" + + "Available commands:\n" + + "1. help - Show this help message\n" + + "2. exit - Exit the server\n" + + "3. user - User management\n" + + "4. settings - Server settings\n" + + "5. start - Start the server\n" + + "6. stop - Stop the server\n"); + } +} \ No newline at end of file diff --git a/Server/Program.cs b/Server/Program.cs index eadb753..8f2482f 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -1,4 +1,5 @@ -using DX86.Modules; +using DX86; +using DX86.Modules; using Library; namespace Server; @@ -10,6 +11,7 @@ class Program public static InputBox inputBox; public static ItemSelector itemSelector; public static MySQL mySql; + private static List servers; static void Main(string[] args) { @@ -19,16 +21,28 @@ class Program messageBox = new MessageBox(messageSender); inputBox = new InputBox(messageSender); itemSelector = new ItemSelector(messageSender); + servers = new List(); // Connect to the database //mySql = new MySQL("username", "password", "localhost", "database", messageSender); // Start the server - - messageBox.ShowAsync("Server started", ["LOL","Laurenz Stinkt xd"]); - string name = inputBox.ShowAsync("Test", ["type your name "]); + ServerLoop(); - messageBox.ShowAsync("Welcome", ["Hello " + name]); - + } + + private static void ServerLoop() + { + bool running = true; + string[] menuItems; + string selectedItem; + servers.Add(new BackendServer("0.0.0.0", 3767, messageSender)); + // Main server loop + while (running) + { + menuItems = [ "Benutzerverwaltung", "Einstellungen", "Beenden" ]; + itemSelector.SetTitle("Hauptmenü"); + //selectedItem = itemSelector.SelectItemFromList(menuItems); + } } } \ No newline at end of file