This commit is contained in:
Artemy
2025-06-27 21:50:23 +07:00
parent 05298c004c
commit 26dc4ccc1f
6 changed files with 302 additions and 155 deletions
+172 -145
View File
@@ -1,187 +1,214 @@
using Microsoft.AspNetCore.SignalR.Client;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using Govor.Contracts.Requests;
/*====================================
*Горелые Петушки Чат
*Личные сообщения| Егор
*====================================
* [15:59] Вы добавили (Егор) в друзья
*
* [16:30] Егор >> Привет!
* [16:31] Ты >> Че как?
*
* [16:30] Егор >> Привет, Питухам!
* [16:31] Anon >> Че как?
* Я норм << [16:32]
*------------------------------------
* >> "Привет, Егор!"
* >> "Пойдем завтра гулять?!"
*/
class Program
namespace Govor.ConsoleClient
{
private static HttpClient _httpClient = new HttpClient();
private static HubConnection _hubConnection;
private static string _jwtToken;
private static Guid _userId;
private static Guid _toUserId;
static async Task Main(string[] args)
class Program
{
Console.WriteLine("Welcome to the Chat Client!");
Console.WriteLine("Enter your username:");
string username = Console.ReadLine();
Console.WriteLine("Enter your password:");
string password = Console.ReadLine();
static string? AuthToken = null;
static HttpClientService HttpService = new("https://localhost:7155"); // поменяй URL на свой
private static FriendsClient friendsClient;
static Dictionary<string, List<string>> ChatHistory = new();
static string CurrentChatUser = null;
// Аутентификация и получение JWT
bool authenticated = await AuthenticateAsync(username, password);
if (!authenticated)
static async Task Main()
{
Console.WriteLine("Authentication failed. Exiting...");
return;
LoginWindow();
while (true)
{
Console.Write(CurrentChatUser == null ? "/> " : ">> ");
var input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input)) continue;
if (input.StartsWith("/"))
HandleCommand(input);
else if (CurrentChatUser != null)
SendMessage(input);
else
Console.WriteLine("[Система] Введите команду, например /friends");
}
}
Console.Clear();
// Извлечение UserId из JWT
_userId = ExtractUserIdFromJwt(_jwtToken);
Console.WriteLine($"Authenticated successfully! Your UserId: {_userId}");
// Настройка SignalR
await SetupSignalRAsync();
// Обработка команд
Console.WriteLine("Enter command /chat {username} to send a chat message");
Console.WriteLine("Enter commands in format: /send {message}, in chat {username}");
Console.WriteLine("Type 'exit' to quit.");
while (true)
static async void HandleCommand(string input)
{
string input = Console.ReadLine();
if (input.ToLower() == "exit")
break;
var args = input.Split(' ', 2);
var command = args[0].ToLower();
var argument = args.Length > 1 ? args[1] : null;
await ProcessCommandAsync(input);
switch (command)
{
case "/login":
Console.Write("username: ");
var loginUsername = Console.ReadLine();
Console.Write("password: ");
var loginPassword = Console.ReadLine();
try
{
AuthToken = await HttpService.LoginAsync(loginUsername, loginPassword);
HttpClient sharedClient = new();
sharedClient.BaseAddress = new Uri("https://localhost:7155");
sharedClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthToken);
friendsClient = new FriendsClient(sharedClient);
Console.WriteLine("[Успех] Вход выполнен. Токен сохранен.");
}
catch (Exception ex)
{
Console.WriteLine($"[Ошибка] {ex.Message}");
}
break;
case "/reg":
Console.Write("username: ");
var regUsername = Console.ReadLine();
Console.Write("password: ");
var regPassword = Console.ReadLine();
Console.Write("invitation: ");
var inviteCode = Console.ReadLine();
try
{
AuthToken = await HttpService.RegisterAsync(regUsername, regPassword, inviteCode);
HttpClient sharedClient = new();
sharedClient.BaseAddress = new Uri("https://localhost:7155");
sharedClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthToken);
friendsClient = new FriendsClient(sharedClient);
Console.WriteLine("[Успех] Регистрация завершена. Токен сохранен.");
}
catch (Exception ex)
{
Console.WriteLine($"[Ошибка] {ex.Message}");
}
break;
case "/search":
Console.Write("Введите имя друга: ");
var q = Console.ReadLine();
var foundUsers = await friendsClient.SearchAsync(q);
foreach (var user in foundUsers)
{
Console.WriteLine($"{user.Username} [{user.Id}]");
}
break;
case "/exit":
Console.WriteLine("[Система] Выход...");
Environment.Exit(0);
break;
case "/friends":
var friends = await friendsClient.GetFriendsAsync();
foreach (var f in friends)
{
Console.WriteLine($"{f.Username} | был онлайн: {f.WasOnline}");
}
break;
case "/friend":
Console.Write("Введите ID пользователя, которому хотите отправить запрос: ");
var targetId = Guid.Parse(Console.ReadLine());
await friendsClient.SendFriendRequestAsync(targetId);
Console.WriteLine("Запрос отправлен");
break;
case "/accept":
Console.Write("Введите ID пользователя, чью заявку принимаете: ");
var acceptId = Guid.Parse(Console.ReadLine());
await friendsClient.AcceptFriendRequestAsync(acceptId);
Console.WriteLine("Принято");
break;
case "/incoming":
var requests = await friendsClient.GetIncomingRequestsAsync();
foreach (var r in requests)
{
Console.WriteLine($"Запрос от: {r.RequesterId} (добавьте через /accept {r.RequesterId})");
}
break;
case "/chat":
if (string.IsNullOrEmpty(argument))
{
Console.WriteLine("[Ошибка] Укажите имя друга");
break;
}
CurrentChatUser = argument;
ShowChat(argument);
break;
case "/back":
CurrentChatUser = null;
break;
default:
Console.WriteLine("[Ошибка] Неизвестная команда");
break;
}
}
// Отключение SignalR
await _hubConnection.StopAsync();
}
private static async Task<bool> AuthenticateAsync(string username, string password)
{
try
static void ShowChat(string user)
{
RegistrationRequest loginData = new RegistrationRequest()
{
Name = username,
Password = password
};
Console.Clear();
Console.WriteLine($"/*====================================");
Console.WriteLine($" * Личные сообщения | {user}");
Console.WriteLine($" *====================================");
var response = await _httpClient.PostAsJsonAsync(
"https://localhost:7155/api/Auth/login",
loginData);
if (!response.IsSuccessStatusCode)
if (!ChatHistory.ContainsKey(user))
{
Console.WriteLine($"Login failed: {response.StatusCode}");
return false;
ChatHistory[user] = new List<string>
{
$"[15:59] Вы добавили ({user}) в друзья",
$"[16:30] {user} >> Привет!",
$"[16:31] Ты >> Че как?"
};
}
var json = await response.Content.ReadAsStringAsync();
var tokenResponse = JsonSerializer.Deserialize<LoginResponse>(json, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
foreach (var msg in ChatHistory[user])
Console.WriteLine(" * " + msg);
_jwtToken = tokenResponse.token;
return true;
}
catch (Exception ex)
{
Console.WriteLine($"Authentication error: {ex.Message}");
return false;
}
}
private static Guid ExtractUserIdFromJwt(string jwtToken)
{
try
{
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(jwtToken);
var userIdClaim = token.Claims.FirstOrDefault(c => c.Type == "sub" || c.Type == "userID")?.Value;
return Guid.TryParse(userIdClaim, out Guid userId) ? userId : Guid.Empty;
}
catch (Exception ex)
{
Console.WriteLine($"Error extracting UserId: {ex.Message}");
return Guid.Empty;
}
}
private static async Task SetupSignalRAsync()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl("https://localhost:7155/api/chats", options =>
{
options.AccessTokenProvider = () => Task.FromResult(_jwtToken);
})
.WithAutomaticReconnect()
.Build();
_hubConnection.On<string, Guid>("Receive", (message, senderId) =>
{
Console.WriteLine($"[{DateTime.Now}] From {senderId}: {message}");
});
try
{
await _hubConnection.StartAsync();
Console.WriteLine("Connected to SignalR hub.");
}
catch (Exception ex)
{
Console.WriteLine($"SignalR connection error: {ex.Message}");
}
}
private static async Task ProcessCommandAsync(string input)
{
if (string.IsNullOrWhiteSpace(input))
return;
var parts = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 3 || parts[0].ToLower() != "/send")
{
Console.WriteLine("Invalid command. Use: /send {toUserId} {message}");
return;
Console.WriteLine(" *------------------------------------");
}
if (!Guid.TryParse(parts[1], out Guid toUserId))
static void SendMessage(string message)
{
Console.WriteLine("Invalid toUserId format. Must be a valid Guid.");
return;
if (string.IsNullOrWhiteSpace(message)) return;
ChatHistory[CurrentChatUser].Add($"Ты >> {message}");
Console.WriteLine($">> {message}");
}
string message = string.Join(" ", parts[2..]);
if (string.IsNullOrWhiteSpace(message))
static void LoginWindow()
{
Console.WriteLine("Message cannot be empty.");
return;
}
try
{
await _hubConnection.InvokeAsync("Send", message, toUserId);
Console.WriteLine($"Message sent to {toUserId}");
}
catch (Exception ex)
{
Console.WriteLine($"Error sending message: {ex.Message}");
Console.WriteLine($"/*====================================");
Console.WriteLine($" * Добро пожаловать в Govor!");
Console.WriteLine($" *====================================");
Console.WriteLine(" * /reg - создать аккаунт ");
Console.WriteLine(" * /login - войти");
}
}
}
public class LoginResponse
{
public string token { get; set; }