diff --git a/BrazChat.sln b/BrazChat.sln
new file mode 100644
index 0000000..d34e957
--- /dev/null
+++ b/BrazChat.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.2.32616.157
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BrazChatServer", "BrazChat\BrazChatServer.csproj", "{4C021E19-57F4-490E-ADE7-13064329DE7D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BrazChatClient", "BrazChatClient\BrazChatClient.csproj", "{B21A1847-29C5-4AD2-BE79-ADBA5FA89578}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4C021E19-57F4-490E-ADE7-13064329DE7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4C021E19-57F4-490E-ADE7-13064329DE7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4C021E19-57F4-490E-ADE7-13064329DE7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4C021E19-57F4-490E-ADE7-13064329DE7D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B21A1847-29C5-4AD2-BE79-ADBA5FA89578}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B21A1847-29C5-4AD2-BE79-ADBA5FA89578}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B21A1847-29C5-4AD2-BE79-ADBA5FA89578}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B21A1847-29C5-4AD2-BE79-ADBA5FA89578}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {0FB81DD0-9A62-4AEA-A1B1-B165821EB7BA}
+ EndGlobalSection
+EndGlobal
diff --git a/BrazChat/BrazChat.proto b/BrazChat/BrazChat.proto
new file mode 100644
index 0000000..38c941e
--- /dev/null
+++ b/BrazChat/BrazChat.proto
@@ -0,0 +1,73 @@
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+option java_package = "io.grpc.examples.brazchat";
+option java_outer_classname = "BrazChatProto";
+option objc_class_prefix = "BCH";
+
+package brazchat;
+
+
+service Messaging {
+ rpc Greeting (GreetingRequest) returns (GreetingReply) {} //Just a handshake to test connection
+ rpc GetMessages (GetMessagesRequest) returns (GetMessagesReply) {}
+ rpc GetMessageLogs (GetMessageLogsRequest) returns (GetMessageLogsReply) {}
+ rpc SendMessage (SendMessageRequest) returns (SendMessageReply) {}
+ rpc WelcomeMessage (WelcomeMessageRequest) returns (WelcomeMessageReply) {}
+}
+
+message GreetingRequest{
+}
+
+message GreetingReply{
+}
+
+message GetMessagesRequest {
+ string clientUsername = 1;
+}
+
+
+message GetMessagesReply {
+ string confirmation = 1;
+ string messages = 2;
+}
+
+message GetMessageLogsRequest{
+
+}
+
+message GetMessageLogsReply{
+ string log = 1;
+}
+
+message SendMessageRequest {
+ string clientUsername = 1;
+ string message = 2;
+ string color = 3;
+}
+
+message SendMessageReply{
+ string confirmation = 1;
+}
+
+message WelcomeMessageRequest{ //Feels redundant to have this here lol.
+}
+
+message WelcomeMessageReply{
+ string WelcomeLogo = 1;
+ string MOTD = 2;
+}
\ No newline at end of file
diff --git a/BrazChat/BrazChatServer.csproj b/BrazChat/BrazChatServer.csproj
new file mode 100644
index 0000000..a149ec2
--- /dev/null
+++ b/BrazChat/BrazChatServer.csproj
@@ -0,0 +1,29 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+ Always
+
+
+
+
diff --git a/BrazChat/Program.cs b/BrazChat/Program.cs
new file mode 100644
index 0000000..34e97ea
--- /dev/null
+++ b/BrazChat/Program.cs
@@ -0,0 +1,103 @@
+using System;
+using System.IO;
+using Grpc;
+using Grpc.Core;
+using Brazchat;
+using Google.Protobuf;
+using Newtonsoft.Json;
+
+namespace BrazChatServer
+{
+ class MessagingImpl : Messaging.MessagingBase
+ {
+
+ public override Task SendMessage(SendMessageRequest request, ServerCallContext context)
+ {
+ string username = request.ClientUsername;
+ if(request.ClientUsername == null)
+ {
+ username = "Guest";
+ }
+ Console.WriteLine($"Message received: '{request.Message}' from {username}");
+ Utilities.LogNewMessage(request.Message, username);
+ return Task.FromResult(new SendMessageReply { Confirmation = "Successfully sent message to target!" });
+ }
+ public override Task GetMessageLogs(GetMessageLogsRequest request, ServerCallContext context)
+ {
+ return Task.FromResult(new GetMessageLogsReply { Log = File.ReadAllText(@$"{Program.brazChatPath}\log\ChatLog.txt")});
+ }
+ public override Task GetMessages(GetMessagesRequest request, ServerCallContext context)
+ {
+ List text = File.ReadLines(@$"{Program.brazChatPath}\log\ChatLog.txt").Reverse().Take(20).Reverse().ToList();
+ string messages = string.Join("\n", text);
+ return Task.FromResult(new GetMessagesReply { Confirmation = "Successful!", Messages = messages});
+ }
+ public override Task WelcomeMessage(WelcomeMessageRequest request, ServerCallContext context)
+ {
+ return Task.FromResult(new WelcomeMessageReply {WelcomeLogo = Figgle.FiggleFonts.Banner3D.Render("BrazChat") , MOTD = File.ReadAllText(@$"{Program.brazChatPath}\config\MOTD.txt") }); //Make this read the logo from a file in the future.
+ }
+ public override Task Greeting(GreetingRequest request, ServerCallContext context)
+ {
+ return Task.FromResult(new GreetingReply { });
+ }
+
+ }
+ class Program
+ {
+ public static string brazChatPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
+ const int Port = 50051;
+ public static void Main(string[] args)
+ {
+ CheckNecessaryFiles();
+ List configItems = new List();
+ using (StreamReader r = new StreamReader(@$"{Program.brazChatPath}\config\config.json"))
+ {
+ string json = r.ReadToEnd();
+ configItems = JsonConvert.DeserializeObject>(json);
+ }
+ Server server = new Server
+ {
+ Services = { Messaging.BindService(new MessagingImpl()) },
+ Ports = { new ServerPort(configItems[0].Host, configItems[0].Port, ServerCredentials.Insecure)}
+ };
+ server.Start();
+ Console.WriteLine("Server running. Press any key to stop server.");
+ Console.ReadKey();
+ }
+ public static void CheckNecessaryFiles()
+ {
+ if (File.Exists(@$"{Program.brazChatPath}\config\MOTD.txt") == false)
+ {
+ Directory.CreateDirectory($@"{Program.brazChatPath}\config");
+ File.WriteAllText(@$"{Program.brazChatPath}\config\MOTD.txt", "Default MOTD");
+ }
+ if (File.Exists(@$"{Program.brazChatPath}\config\config.json") == false)
+ {
+ Console.WriteLine("No config file found! Exiting.");
+ Environment.Exit(2);
+ }
+ if (File.Exists(@$"{Program.brazChatPath}\log\ChatLog.txt") == false)
+ {
+ Directory.CreateDirectory($@"{Program.brazChatPath}\log");
+ File.WriteAllText(@$"{Program.brazChatPath}\log\ChatLog.txt", "Say something!\n");
+ }
+ }
+ }
+ class Utilities
+ {
+ public static void LogNewMessage(string message, string username)
+ {
+ string path = @$"{Program.brazChatPath}\log\ChatLog.txt";
+
+ File.AppendAllText(path, $"{username}: {message}\n");
+ }
+ }
+
+ public class Config
+ {
+ public string Host;
+ public int Port;
+ }
+}
+
+
diff --git a/BrazChat/config/MOTD.txt b/BrazChat/config/MOTD.txt
new file mode 100644
index 0000000..a847678
--- /dev/null
+++ b/BrazChat/config/MOTD.txt
@@ -0,0 +1,2 @@
+This is a test motd!
+New linerino!!
\ No newline at end of file
diff --git a/BrazChat/config/config.json b/BrazChat/config/config.json
new file mode 100644
index 0000000..ebebdf2
--- /dev/null
+++ b/BrazChat/config/config.json
@@ -0,0 +1,6 @@
+[
+ {
+ "host": "localhost",
+ "port": 50051
+ }
+]
\ No newline at end of file
diff --git a/BrazChatClient/BrazChat.proto b/BrazChatClient/BrazChat.proto
new file mode 100644
index 0000000..38c941e
--- /dev/null
+++ b/BrazChatClient/BrazChat.proto
@@ -0,0 +1,73 @@
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+option java_package = "io.grpc.examples.brazchat";
+option java_outer_classname = "BrazChatProto";
+option objc_class_prefix = "BCH";
+
+package brazchat;
+
+
+service Messaging {
+ rpc Greeting (GreetingRequest) returns (GreetingReply) {} //Just a handshake to test connection
+ rpc GetMessages (GetMessagesRequest) returns (GetMessagesReply) {}
+ rpc GetMessageLogs (GetMessageLogsRequest) returns (GetMessageLogsReply) {}
+ rpc SendMessage (SendMessageRequest) returns (SendMessageReply) {}
+ rpc WelcomeMessage (WelcomeMessageRequest) returns (WelcomeMessageReply) {}
+}
+
+message GreetingRequest{
+}
+
+message GreetingReply{
+}
+
+message GetMessagesRequest {
+ string clientUsername = 1;
+}
+
+
+message GetMessagesReply {
+ string confirmation = 1;
+ string messages = 2;
+}
+
+message GetMessageLogsRequest{
+
+}
+
+message GetMessageLogsReply{
+ string log = 1;
+}
+
+message SendMessageRequest {
+ string clientUsername = 1;
+ string message = 2;
+ string color = 3;
+}
+
+message SendMessageReply{
+ string confirmation = 1;
+}
+
+message WelcomeMessageRequest{ //Feels redundant to have this here lol.
+}
+
+message WelcomeMessageReply{
+ string WelcomeLogo = 1;
+ string MOTD = 2;
+}
\ No newline at end of file
diff --git a/BrazChatClient/BrazChatClient.csproj b/BrazChatClient/BrazChatClient.csproj
new file mode 100644
index 0000000..12dee1a
--- /dev/null
+++ b/BrazChatClient/BrazChatClient.csproj
@@ -0,0 +1,22 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
diff --git a/BrazChatClient/Program.cs b/BrazChatClient/Program.cs
new file mode 100644
index 0000000..4f3d88e
--- /dev/null
+++ b/BrazChatClient/Program.cs
@@ -0,0 +1,213 @@
+using Brazchat;
+using Grpc.Core;
+
+namespace BrazChatClient
+{
+ class Program
+ {
+ public static string username = "";
+ public static string host = "";
+ public static void Main(string[] args)
+ {
+ StartScreen();
+ }
+
+ public static void StartScreen()
+ {
+ Console.Clear();
+ Console.WriteLine("Please enter a hostname (ip:port)");
+ host = Console.ReadLine();
+ Console.WriteLine(host);
+ try
+ {
+ Channel channel = new Channel(host, ChannelCredentials.Insecure);
+
+ var client = new Messaging.MessagingClient(channel);
+
+ var reply = client.Greeting(new GreetingRequest { });
+
+ channel.ShutdownAsync().Wait();
+ WelcomeScreen();
+ }
+ catch (RpcException)
+ {
+ Console.WriteLine("Invalid host! Press any key to try again.");
+ Console.ReadKey();
+ Console.Clear();
+ StartScreen();
+ }
+ }
+ public static void WelcomeScreen()
+ {
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.Clear();
+ string[] WelcomeMessage = GetWelcomeMessage();
+ Console.WriteLine(WelcomeMessage[0]);
+ Console.WriteLine(WelcomeMessage[1]);
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("Type in a username please!");
+ username = Console.ReadLine();
+ Console.WriteLine("Press any key to start sending messages!");
+ Console.ReadKey();
+ ChatScreen();
+ }
+ public static void ChatScreen()
+ {
+ Console.Clear();
+ while (!Console.KeyAvailable)
+ {
+ Console.CursorVisible = false;
+ CustomClear();
+ Console.SetCursorPosition(0, 0);
+ var Messages = GetMessages();
+ if (Messages.Confirmation == "Nope!")
+ {
+ ConnectionFailureScreen();
+ }
+ else
+ {
+ Console.WriteLine($"{Messages.Messages}\n");
+ //Console.WriteLine("----------------------");
+ Console.WriteLine("T - Type message \nL - View logs");
+ Thread.Sleep(100);
+ }
+ }
+ ConsoleKey input = Console.ReadKey(true).Key;
+ switch (input)
+ {
+ case ConsoleKey.T:
+ TypeScreen();
+ break;
+ case ConsoleKey.L:
+ ChatLogScreen();
+ break;
+ default:
+ ChatScreen();
+ break;
+ }
+ }
+
+ public static void TypeScreen()
+ {
+ Console.Clear();
+ var Messages = GetMessages();
+ if (Messages.Confirmation == "Nope!")
+ {
+ ConnectionFailureScreen();
+ }
+ else
+ {
+ Console.WriteLine(Messages.Messages);
+ Console.WriteLine("Type your message!");
+ string? message = Console.ReadLine();
+ SendMessage(message);
+ ChatScreen();
+ }
+ }
+
+ public static void ChatLogScreen()
+ {
+ Console.Clear();
+ var Messages = GetMessages();
+ if(GetMessages().Confirmation == "Nope!")
+ {
+ Console.WriteLine("Connection to server lost! Press any key to return to connection menu!");
+ ConnectionFailureScreen();
+ }else{
+ Console.WriteLine("--------------------------");
+ Console.WriteLine(GetMessageLogs().Log);
+ Console.WriteLine("--------------------------");
+ Console.ReadKey();
+ Console.Clear();
+ ChatScreen();
+ }
+ }
+
+ public static void ConnectionFailureScreen()
+ {
+ Console.Clear();
+ Console.WriteLine("Connection to server lost! Press any key to return to connection menu!");
+ Console.ReadKey();
+ StartScreen();
+ }
+ public static string[] GetWelcomeMessage()
+ {
+ try
+ {
+ Channel channel = new Channel(host, ChannelCredentials.Insecure);
+
+ var client = new Messaging.MessagingClient(channel);
+
+ var reply = client.WelcomeMessage(new WelcomeMessageRequest { });
+
+ string[] WelcomeMessage = { reply.WelcomeLogo, reply.MOTD };
+
+ channel.ShutdownAsync().Wait();
+ return WelcomeMessage;
+ }
+ catch (RpcException)
+ {
+ string[] Fallback = { "Brazchat", "ERRORNOCONNECTION" }; //0 = Logo, 1 = MOTD
+ return Fallback;
+ }
+ }
+ public static void SendMessage(string? message)
+ {
+ try
+ {
+ Channel channel = new Channel(host, ChannelCredentials.Insecure);
+
+ var client = new Messaging.MessagingClient(channel);
+
+ var reply = client.SendMessage(new SendMessageRequest { ClientUsername = username, Message = message, Color = "Red" });
+ Console.WriteLine("Message sent. Result:" + reply.Confirmation);
+
+ channel.ShutdownAsync().Wait();
+ }
+ catch (Grpc.Core.RpcException)
+ {
+ ConnectionFailureScreen();
+ }
+ }
+
+ public static GetMessagesReply GetMessages()
+ {
+ try
+ {
+ Channel channel = new Channel(host, ChannelCredentials.Insecure);
+
+ var client = new Messaging.MessagingClient(channel);
+ String clientUsername = "Brazman";
+
+ var reply = client.GetMessages(new GetMessagesRequest { ClientUsername = clientUsername });
+ channel.ShutdownAsync().Wait();
+ return reply;
+ }
+ catch (Grpc.Core.RpcException)
+ {
+ //lord forgive me
+ var Fallback = new GetMessagesReply { Confirmation = "Nope!", Messages = "No connection! Retrying!\n" };
+ return Fallback;
+ }
+ }
+ public static GetMessageLogsReply GetMessageLogs()
+ {
+ Channel channel = new Channel(host, ChannelCredentials.Insecure);
+
+ var client = new Messaging.MessagingClient(channel);
+
+ var reply = client.GetMessageLogs(new GetMessageLogsRequest { });
+ channel.ShutdownAsync().Wait();
+ return reply;
+ }
+
+ public static void CustomClear()
+ {
+ Console.SetCursorPosition(0, 0);
+ for (int y = 0; y < Console.WindowHeight; y++)
+ Console.Write(new String(' ', Console.WindowWidth));
+ Console.SetCursorPosition(0, 0);
+ }
+
+ }
+}
\ No newline at end of file