diff --git a/Chat/Chat.sln b/Chat/Chat.sln
index b8af116..bc8ef70 100644
--- a/Chat/Chat.sln
+++ b/Chat/Chat.sln
@@ -3,11 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{44FE944D-8D60-4A9C-B739-32F53A033880}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{44FE944D-8D60-4A9C-B739-32F53A033880}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{0BF351F8-CA96-446D-83DE-00CAE7B4CC5D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "Core\Core.csproj", "{0BF351F8-CA96-446D-83DE-00CAE7B4CC5D}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestConsoleClient", "TestConsoleClient\TestConsoleClient.csproj", "{E8D23703-2D2E-43C2-9B77-16EA04CD7331}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestConsoleClient", "TestConsoleClient\TestConsoleClient.csproj", "{E8D23703-2D2E-43C2-9B77-16EA04CD7331}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{9AF35D95-2021-41EE-ADD4-9B02123A7809}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -27,6 +29,10 @@ Global
{E8D23703-2D2E-43C2-9B77-16EA04CD7331}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8D23703-2D2E-43C2-9B77-16EA04CD7331}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E8D23703-2D2E-43C2-9B77-16EA04CD7331}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9AF35D95-2021-41EE-ADD4-9B02123A7809}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9AF35D95-2021-41EE-ADD4-9B02123A7809}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9AF35D95-2021-41EE-ADD4-9B02123A7809}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9AF35D95-2021-41EE-ADD4-9B02123A7809}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Chat/Client/ChatRoomForm.Designer.cs b/Chat/Client/ChatRoomForm.Designer.cs
new file mode 100644
index 0000000..91e75fd
--- /dev/null
+++ b/Chat/Client/ChatRoomForm.Designer.cs
@@ -0,0 +1,99 @@
+namespace Client
+{
+ partial class ChatRoomForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.lbxMsg = new System.Windows.Forms.ListBox();
+ this.tbxMsg = new System.Windows.Forms.TextBox();
+ this.btmSend = new System.Windows.Forms.Button();
+ this.lbxUser = new System.Windows.Forms.ListBox();
+ this.SuspendLayout();
+ //
+ // lbxMsg
+ //
+ this.lbxMsg.FormattingEnabled = true;
+ this.lbxMsg.ItemHeight = 15;
+ this.lbxMsg.Location = new System.Drawing.Point(12, 12);
+ this.lbxMsg.Name = "lbxMsg";
+ this.lbxMsg.Size = new System.Drawing.Size(380, 349);
+ this.lbxMsg.TabIndex = 0;
+ //
+ // tbxMsg
+ //
+ this.tbxMsg.Location = new System.Drawing.Point(12, 368);
+ this.tbxMsg.Name = "tbxMsg";
+ this.tbxMsg.Size = new System.Drawing.Size(318, 23);
+ this.tbxMsg.TabIndex = 1;
+ //
+ // btmSend
+ //
+ this.btmSend.Location = new System.Drawing.Point(336, 368);
+ this.btmSend.Name = "btmSend";
+ this.btmSend.Size = new System.Drawing.Size(56, 23);
+ this.btmSend.TabIndex = 2;
+ this.btmSend.Text = "send";
+ this.btmSend.UseVisualStyleBackColor = true;
+ this.btmSend.Click += new System.EventHandler(this.btmSend_Click);
+ //
+ // lbxUser
+ //
+ this.lbxUser.FormattingEnabled = true;
+ this.lbxUser.ItemHeight = 15;
+ this.lbxUser.Location = new System.Drawing.Point(398, 12);
+ this.lbxUser.Name = "lbxUser";
+ this.lbxUser.Size = new System.Drawing.Size(102, 379);
+ this.lbxUser.TabIndex = 0;
+ //
+ // ChatRoomForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(512, 404);
+ this.Controls.Add(this.btmSend);
+ this.Controls.Add(this.tbxMsg);
+ this.Controls.Add(this.lbxUser);
+ this.Controls.Add(this.lbxMsg);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "ChatRoomForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "CharRoomForm";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private ListBox lbxMsg;
+ private TextBox tbxMsg;
+ private Button btmSend;
+ private ListBox lbxUser;
+ }
+}
\ No newline at end of file
diff --git a/Chat/Client/ChatRoomForm.cs b/Chat/Client/ChatRoomForm.cs
new file mode 100644
index 0000000..9074dd8
--- /dev/null
+++ b/Chat/Client/ChatRoomForm.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Client
+{
+ public partial class ChatRoomForm : Form
+ {
+ public ChatRoomForm()
+ {
+ InitializeComponent();
+ }
+
+ private void btmSend_Click(object sender, EventArgs e)
+ {
+ if (string.IsNullOrEmpty(tbxMsg.Text))
+ return;
+
+ lbxMsg.Items.Add(tbxMsg.Text);
+ tbxMsg.Text = null;
+
+ ScrollMsgToEnd();
+ }
+
+ private void ScrollMsgToEnd()
+ {
+ lbxMsg.SelectedIndex = lbxMsg.Items.Count - 1;
+ lbxMsg.SelectedIndex = -1;
+ }
+ }
+}
diff --git a/Chat/Client/ChatRoomForm.resx b/Chat/Client/ChatRoomForm.resx
new file mode 100644
index 0000000..f298a7b
--- /dev/null
+++ b/Chat/Client/ChatRoomForm.resx
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Chat/Client/Client.csproj b/Chat/Client/Client.csproj
new file mode 100644
index 0000000..b57c89e
--- /dev/null
+++ b/Chat/Client/Client.csproj
@@ -0,0 +1,11 @@
+
+
+
+ WinExe
+ net6.0-windows
+ enable
+ true
+ enable
+
+
+
\ No newline at end of file
diff --git a/Chat/Client/LoginForm.Designer.cs b/Chat/Client/LoginForm.Designer.cs
new file mode 100644
index 0000000..5ce983a
--- /dev/null
+++ b/Chat/Client/LoginForm.Designer.cs
@@ -0,0 +1,105 @@
+namespace Client
+{
+ partial class LoginForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.label1 = new System.Windows.Forms.Label();
+ this.tbxId = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.tbxNickname = new System.Windows.Forms.TextBox();
+ this.btnLogin = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(12, 16);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(19, 15);
+ this.label1.TabIndex = 0;
+ this.label1.Text = "ID";
+ //
+ // tbxId
+ //
+ this.tbxId.Location = new System.Drawing.Point(79, 12);
+ this.tbxId.Name = "tbxId";
+ this.tbxId.Size = new System.Drawing.Size(181, 23);
+ this.tbxId.TabIndex = 1;
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(12, 45);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(61, 15);
+ this.label2.TabIndex = 0;
+ this.label2.Text = "Nickname";
+ //
+ // tbxNickname
+ //
+ this.tbxNickname.Location = new System.Drawing.Point(79, 41);
+ this.tbxNickname.Name = "tbxNickname";
+ this.tbxNickname.Size = new System.Drawing.Size(181, 23);
+ this.tbxNickname.TabIndex = 1;
+ //
+ // btnLogin
+ //
+ this.btnLogin.Location = new System.Drawing.Point(12, 86);
+ this.btnLogin.Name = "btnLogin";
+ this.btnLogin.Size = new System.Drawing.Size(248, 23);
+ this.btnLogin.TabIndex = 2;
+ this.btnLogin.Text = "Login";
+ this.btnLogin.UseVisualStyleBackColor = true;
+ this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
+ //
+ // LoginForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(275, 121);
+ this.Controls.Add(this.btnLogin);
+ this.Controls.Add(this.tbxNickname);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.tbxId);
+ this.Controls.Add(this.label1);
+ this.Name = "LoginForm";
+ this.Text = "Login";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private Label label1;
+ private TextBox tbxId;
+ private Label label2;
+ private TextBox tbxNickname;
+ private Button btnLogin;
+ }
+}
\ No newline at end of file
diff --git a/Chat/Client/LoginForm.cs b/Chat/Client/LoginForm.cs
new file mode 100644
index 0000000..490666b
--- /dev/null
+++ b/Chat/Client/LoginForm.cs
@@ -0,0 +1,25 @@
+namespace Client
+{
+ public partial class LoginForm : Form
+ {
+ public LoginForm()
+ {
+ InitializeComponent();
+ }
+
+ private void btnLogin_Click(object sender, EventArgs e)
+ {
+ if (string.IsNullOrEmpty(tbxId.Text) || string.IsNullOrEmpty(tbxNickname.Text))
+ {
+ MessageBox.Show("Please input ID and Nickname.");
+ return;
+ }
+
+ Singleton.Instance.Id = tbxId.Text;
+ Singleton.Instance.Nickname = tbxNickname.Text;
+
+ RoomListForm roomListForm = new RoomListForm();
+ roomListForm.ShowDialog();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Chat/Client/LoginForm.resx b/Chat/Client/LoginForm.resx
new file mode 100644
index 0000000..f298a7b
--- /dev/null
+++ b/Chat/Client/LoginForm.resx
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Chat/Client/Program.cs b/Chat/Client/Program.cs
new file mode 100644
index 0000000..be85999
--- /dev/null
+++ b/Chat/Client/Program.cs
@@ -0,0 +1,17 @@
+namespace Client
+{
+ internal static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ // To customize application configuration such as set high DPI settings or default font,
+ // see https://aka.ms/applicationconfiguration.
+ ApplicationConfiguration.Initialize();
+ Application.Run(new LoginForm());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Chat/Client/RoomListForm.Designer.cs b/Chat/Client/RoomListForm.Designer.cs
new file mode 100644
index 0000000..e61e0a3
--- /dev/null
+++ b/Chat/Client/RoomListForm.Designer.cs
@@ -0,0 +1,125 @@
+namespace Client
+{
+ partial class RoomListForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.lbxRoom = new System.Windows.Forms.ListBox();
+ this.btnEnter = new System.Windows.Forms.Button();
+ this.tbxRoomName = new System.Windows.Forms.TextBox();
+ this.btnCreate = new System.Windows.Forms.Button();
+ this.label1 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.SuspendLayout();
+ //
+ // lbxRoom
+ //
+ this.lbxRoom.FormattingEnabled = true;
+ this.lbxRoom.ItemHeight = 15;
+ this.lbxRoom.Location = new System.Drawing.Point(12, 27);
+ this.lbxRoom.Name = "lbxRoom";
+ this.lbxRoom.Size = new System.Drawing.Size(180, 214);
+ this.lbxRoom.TabIndex = 0;
+ //
+ // btnEnter
+ //
+ this.btnEnter.Location = new System.Drawing.Point(12, 247);
+ this.btnEnter.Name = "btnEnter";
+ this.btnEnter.Size = new System.Drawing.Size(180, 23);
+ this.btnEnter.TabIndex = 1;
+ this.btnEnter.Text = "Enter";
+ this.btnEnter.UseVisualStyleBackColor = true;
+ this.btnEnter.Click += new System.EventHandler(this.btnEnter_Click);
+ //
+ // tbxRoomName
+ //
+ this.tbxRoomName.Location = new System.Drawing.Point(12, 310);
+ this.tbxRoomName.Name = "tbxRoomName";
+ this.tbxRoomName.Size = new System.Drawing.Size(180, 23);
+ this.tbxRoomName.TabIndex = 2;
+ //
+ // btnCreate
+ //
+ this.btnCreate.Location = new System.Drawing.Point(12, 339);
+ this.btnCreate.Name = "btnCreate";
+ this.btnCreate.Size = new System.Drawing.Size(180, 23);
+ this.btnCreate.TabIndex = 3;
+ this.btnCreate.Text = "Create";
+ this.btnCreate.UseVisualStyleBackColor = true;
+ this.btnCreate.Click += new System.EventHandler(this.btnCreate_Click);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(12, 9);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(59, 15);
+ this.label1.TabIndex = 4;
+ this.label1.Text = "Enterance";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(12, 292);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(52, 15);
+ this.label2.TabIndex = 5;
+ this.label2.Text = "Creation";
+ //
+ // RoomListForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(204, 375);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.btnCreate);
+ this.Controls.Add(this.tbxRoomName);
+ this.Controls.Add(this.btnEnter);
+ this.Controls.Add(this.lbxRoom);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "RoomListForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Room list";
+ this.Activated += new System.EventHandler(this.RoomListForm_Activated);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private ListBox lbxRoom;
+ private Button btnEnter;
+ private TextBox tbxRoomName;
+ private Button btnCreate;
+ private Label label1;
+ private Label label2;
+ }
+}
\ No newline at end of file
diff --git a/Chat/Client/RoomListForm.cs b/Chat/Client/RoomListForm.cs
new file mode 100644
index 0000000..02cd168
--- /dev/null
+++ b/Chat/Client/RoomListForm.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Client
+{
+ public partial class RoomListForm : Form
+ {
+ public RoomListForm()
+ {
+ InitializeComponent();
+ }
+
+ private void btnEnter_Click(object sender, EventArgs e)
+ {
+ if (lbxRoom.SelectedItem == null)
+ {
+ MessageBox.Show("Please select a room.");
+ return;
+ }
+
+ ChatRoomForm chatRoomForm = new ChatRoomForm();
+ chatRoomForm.Text = lbxRoom.SelectedItem.ToString();
+ chatRoomForm.ShowDialog();
+ }
+
+ private void btnCreate_Click(object sender, EventArgs e)
+ {
+ string roomName = tbxRoomName.Text;
+ if (string.IsNullOrEmpty(roomName))
+ {
+ MessageBox.Show("Please input a room name.");
+ return;
+ }
+
+ ChatRoomForm chatRoomForm = new ChatRoomForm();
+ chatRoomForm.Text = roomName;
+ chatRoomForm.ShowDialog();
+ }
+
+ private void RoomListForm_Activated(object sender, EventArgs e)
+ {
+ lbxRoom.Items.Clear();
+ }
+ }
+}
diff --git a/Chat/Client/RoomListForm.resx b/Chat/Client/RoomListForm.resx
new file mode 100644
index 0000000..f298a7b
--- /dev/null
+++ b/Chat/Client/RoomListForm.resx
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Chat/Client/Singleton.cs b/Chat/Client/Singleton.cs
new file mode 100644
index 0000000..29d12b6
--- /dev/null
+++ b/Chat/Client/Singleton.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Client
+{
+ internal class Singleton
+ {
+ public static Singleton Instance { get; set; } = new Singleton();
+
+ public string Id { get; set; } = "";
+ public string Nickname { get; set; } = "";
+ }
+}