Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
a95d012d69 | |||
d1d3af2ec9 | |||
4e61a1d7b9 | |||
446745d4df | |||
00df7505a7 | |||
b17d391406 | |||
2092d2c6d3 | |||
fd743dcb42 | |||
9214460927 | |||
1b30636937 | |||
72d9b99c4c |
@ -7,10 +7,11 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Meziantou.Framework.Win32.CredentialManager" Version="1.7.6" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.16" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.16" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.5" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.9" />
|
||||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.10.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.14.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -15,6 +15,8 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
private RestClient _client;
|
private RestClient _client;
|
||||||
private LoggingService _loggingService;
|
private LoggingService _loggingService;
|
||||||
|
|
||||||
|
private CredentialService _credService = new();
|
||||||
|
|
||||||
internal string? sessionToken;
|
internal string? sessionToken;
|
||||||
internal string apiUri;
|
internal string apiUri;
|
||||||
|
|
||||||
@ -235,9 +237,9 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ServiceResponse<User>> LoginAsync(UserLoginDto userLoginDto)
|
public async Task<ServiceResponse<string>> LoginAsync(UserLoginDto userLoginDto)
|
||||||
{
|
{
|
||||||
var serviceResponse = new ServiceResponse<User>();
|
var serviceResponse = new ServiceResponse<string>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -257,13 +259,11 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
{
|
{
|
||||||
SessionToken = response.Data!;
|
SessionToken = response.Data!;
|
||||||
|
|
||||||
await File.WriteAllTextAsync("./session.token", response.Message);
|
|
||||||
|
|
||||||
var user = await SetCurrentUser();
|
var user = await SetCurrentUser();
|
||||||
|
|
||||||
serviceResponse.Success = true;
|
serviceResponse.Success = true;
|
||||||
if (response.Message != null) serviceResponse.Message = response.Message;
|
if (response.Message != null) serviceResponse.Message = response.Message;
|
||||||
serviceResponse.Data = user;
|
serviceResponse.Data = response.Message;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -413,21 +413,23 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
public async Task<ServiceResponse<string>> RefreshSessionIfInvalid()
|
public async Task<ServiceResponse<string>> RefreshSessionIfInvalid()
|
||||||
{
|
{
|
||||||
var tokenHandler = new JwtSecurityTokenHandler();
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
var refToken = await File.ReadAllTextAsync("./session.token");
|
var refToken = _credService.GetAccessToken(); // fuck CA1416, if this is being ran on linux it should just crash (theoretically)
|
||||||
|
|
||||||
|
if (refToken == null)
|
||||||
|
{
|
||||||
|
// treat as session expired
|
||||||
|
return new ServiceResponse<string> { Success = false, Message = "Refresh Token Not Found. Session Expired." };
|
||||||
|
}
|
||||||
|
|
||||||
JwtSecurityToken token = tokenHandler.ReadJwtToken(SessionToken);
|
JwtSecurityToken token = tokenHandler.ReadJwtToken(SessionToken);
|
||||||
|
|
||||||
if(DateTime.Compare(DateTime.UtcNow, token.ValidTo) > 0)
|
if(DateTime.Compare(DateTime.UtcNow, token.ValidTo) > 0)
|
||||||
{
|
{
|
||||||
if (!File.Exists("./session.token")) { return new ServiceResponse<string> { Success = false, Message = "Session File Not Found. Session Expired." }; }
|
|
||||||
|
|
||||||
var result = await RefreshLogin(refToken);
|
var result = await RefreshLogin(refToken);
|
||||||
|
|
||||||
if (result == null || result.Success == false)
|
if (result == null || result.Success == false)
|
||||||
{
|
{
|
||||||
File.Delete("./session.token");
|
return new ServiceResponse<string> { Success = false, Message = "Session Expired." }; // logging in again should overwrite old token
|
||||||
|
|
||||||
return new ServiceResponse<string> { Success = false, Message = "Session Expired." };
|
|
||||||
} else return new ServiceResponse<string> { Success = true, Data = refToken };
|
} else return new ServiceResponse<string> { Success = true, Data = refToken };
|
||||||
} else return new ServiceResponse<string> { Success = true, Data = refToken };
|
} else return new ServiceResponse<string> { Success = true, Data = refToken };
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
public Task<ServiceResponse<List<UserInformationDto>>> GetOnlineUsersAsync();
|
public Task<ServiceResponse<List<UserInformationDto>>> GetOnlineUsersAsync();
|
||||||
public Task<ServiceResponse<List<UserInformationDto>>> GetAllUsersAsync();
|
public Task<ServiceResponse<List<UserInformationDto>>> GetAllUsersAsync();
|
||||||
public Task<ServiceResponse<User>> DeleteUserById(string id);
|
public Task<ServiceResponse<User>> DeleteUserById(string id);
|
||||||
public Task<ServiceResponse<User>> LoginAsync(UserLoginDto userLoginDto);
|
public Task<ServiceResponse<string>> LoginAsync(UserLoginDto userLoginDto);
|
||||||
public Task<ServiceResponse<bool>> ResendVerificationEmail(string email);
|
public Task<ServiceResponse<bool>> ResendVerificationEmail(string email);
|
||||||
public Task<ServiceResponse<bool>> SendPasswordResetEmail(string email);
|
public Task<ServiceResponse<bool>> SendPasswordResetEmail(string email);
|
||||||
public Task<ServiceResponse<bool>> ResetPassword(UserPasswordResetDto request);
|
public Task<ServiceResponse<bool>> ResetPassword(UserPasswordResetDto request);
|
||||||
|
26
QtCNETAPI/Services/CredentialService.cs
Normal file
26
QtCNETAPI/Services/CredentialService.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Meziantou.Framework.Win32;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Services
|
||||||
|
{
|
||||||
|
public class CredentialService()
|
||||||
|
{
|
||||||
|
public void SaveAccessToken(string username, string accessToken)
|
||||||
|
{
|
||||||
|
string applicationName = "QtC.NET";
|
||||||
|
if (System.Diagnostics.Debugger.IsAttached) applicationName = "QtC.NET.Development";
|
||||||
|
|
||||||
|
CredentialManager.WriteCredential(applicationName, username, accessToken, $"Access Token For User {username} On QtC.NET", CredentialPersistence.LocalMachine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? GetAccessToken()
|
||||||
|
{
|
||||||
|
string applicationName = "QtC.NET";
|
||||||
|
if (System.Diagnostics.Debugger.IsAttached) applicationName = "QtC.NET.Development";
|
||||||
|
|
||||||
|
var credential = CredentialManager.ReadCredential(applicationName);
|
||||||
|
if (credential == null) return null;
|
||||||
|
|
||||||
|
return credential.Password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -36,9 +36,6 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
|
|
||||||
public async Task StartAsync()
|
public async Task StartAsync()
|
||||||
{
|
{
|
||||||
// just to be safe (it doesn't load the server since it shouldn't request a new one unless its actually expired)
|
|
||||||
await _apiService.RefreshSessionIfInvalid();
|
|
||||||
|
|
||||||
// build connection
|
// build connection
|
||||||
var gwConBuilder = new HubConnectionBuilder()
|
var gwConBuilder = new HubConnectionBuilder()
|
||||||
.WithAutomaticReconnect()
|
.WithAutomaticReconnect()
|
||||||
@ -51,8 +48,14 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
})
|
})
|
||||||
.WithUrl(gwBaseUri, options =>
|
.WithUrl(gwBaseUri, options =>
|
||||||
{
|
{
|
||||||
options.AccessTokenProvider = () => Task.FromResult(_apiService.SessionToken);
|
options.AccessTokenProvider = async () =>
|
||||||
});
|
{
|
||||||
|
// this should hopefully refresh the session every time the gateway connection is used to prevent connection aborts
|
||||||
|
await _apiService.RefreshSessionIfInvalid();
|
||||||
|
return _apiService.SessionToken;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.WithStatefulReconnect();
|
||||||
HubConnection = gwConBuilder.Build();
|
HubConnection = gwConBuilder.Build();
|
||||||
|
|
||||||
// register events
|
// register events
|
||||||
@ -119,8 +122,6 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
|
|
||||||
public async Task JoinLobbyAsync()
|
public async Task JoinLobbyAsync()
|
||||||
{
|
{
|
||||||
await _apiService.RefreshSessionIfInvalid();
|
|
||||||
|
|
||||||
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
||||||
|
|
||||||
await HubConnection.SendAsync("JoinLobby", _apiService.CurrentUser);
|
await HubConnection.SendAsync("JoinLobby", _apiService.CurrentUser);
|
||||||
@ -130,8 +131,6 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
|
|
||||||
public async Task JoinRoomAsync(Room room)
|
public async Task JoinRoomAsync(Room room)
|
||||||
{
|
{
|
||||||
await _apiService.RefreshSessionIfInvalid();
|
|
||||||
|
|
||||||
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
||||||
|
|
||||||
if (InLobby == true)
|
if (InLobby == true)
|
||||||
@ -150,8 +149,6 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
|
|
||||||
public async Task LeaveRoomAsync()
|
public async Task LeaveRoomAsync()
|
||||||
{
|
{
|
||||||
await _apiService.RefreshSessionIfInvalid();
|
|
||||||
|
|
||||||
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
||||||
|
|
||||||
if (InLobby)
|
if (InLobby)
|
||||||
@ -168,8 +165,6 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
|
|
||||||
public async Task PostMessageAsync(Message message)
|
public async Task PostMessageAsync(Message message)
|
||||||
{
|
{
|
||||||
await _apiService.RefreshSessionIfInvalid();
|
|
||||||
|
|
||||||
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
||||||
|
|
||||||
await HubConnection.SendAsync("SendMessage", _apiService.CurrentUser, message, InLobby, CurrentRoom);
|
await HubConnection.SendAsync("SendMessage", _apiService.CurrentUser, message, InLobby, CurrentRoom);
|
||||||
@ -186,8 +181,6 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
|
|
||||||
public async Task UpdateStatus(int status)
|
public async Task UpdateStatus(int status)
|
||||||
{
|
{
|
||||||
await _apiService.RefreshSessionIfInvalid();
|
|
||||||
|
|
||||||
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
||||||
|
|
||||||
await HubConnection.SendAsync("UpdateStatus", _apiService.CurrentUser, status);
|
await HubConnection.SendAsync("UpdateStatus", _apiService.CurrentUser, status);
|
||||||
|
4
qtc-net-client-2/Forms/Login.Designer.cs
generated
4
qtc-net-client-2/Forms/Login.Designer.cs
generated
@ -1,6 +1,6 @@
|
|||||||
namespace qtc_net_client_2.Forms
|
namespace qtc_net_client_2.Forms
|
||||||
{
|
{
|
||||||
partial class llblForgotPassword
|
partial class Login
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required designer variable.
|
/// Required designer variable.
|
||||||
@ -28,7 +28,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(llblForgotPassword));
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Login));
|
||||||
pbLoginBanner = new PictureBox();
|
pbLoginBanner = new PictureBox();
|
||||||
tbEmail = new TextBox();
|
tbEmail = new TextBox();
|
||||||
lblEmail = new Label();
|
lblEmail = new Label();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using QtCNETAPI.Services.ApiService;
|
using QtCNETAPI.Services.ApiService;
|
||||||
|
using QtCNETAPI.Services;
|
||||||
using QtCNETAPI.Dtos.User;
|
using QtCNETAPI.Dtos.User;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -9,13 +10,15 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using qtc_net_client_2.Services;
|
||||||
|
|
||||||
namespace qtc_net_client_2.Forms
|
namespace qtc_net_client_2.Forms
|
||||||
{
|
{
|
||||||
public partial class llblForgotPassword : Form
|
public partial class Login : Form
|
||||||
{
|
{
|
||||||
private IApiService _apiService;
|
private IApiService _apiService;
|
||||||
public llblForgotPassword(IApiService apiService)
|
private CredentialService _credService = new();
|
||||||
|
public Login(IApiService apiService)
|
||||||
{
|
{
|
||||||
_apiService = apiService;
|
_apiService = apiService;
|
||||||
|
|
||||||
@ -24,14 +27,14 @@ namespace qtc_net_client_2.Forms
|
|||||||
|
|
||||||
private async void frmLogin_Load(object sender, EventArgs e)
|
private async void frmLogin_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (File.Exists("./session.token"))
|
string? accessToken = _credService.GetAccessToken();
|
||||||
|
|
||||||
|
if (accessToken != null)
|
||||||
{
|
{
|
||||||
ToggleControls(false, false);
|
ToggleControls(false, false);
|
||||||
|
|
||||||
// try logging in with the token in the file
|
// try logging in with the token in cred storage
|
||||||
string token = File.ReadAllText("./session.token");
|
var result = await _apiService.RefreshLogin(accessToken);
|
||||||
|
|
||||||
var result = await _apiService.RefreshLogin(token);
|
|
||||||
if (result.Success)
|
if (result.Success)
|
||||||
{
|
{
|
||||||
DialogResult = DialogResult.OK;
|
DialogResult = DialogResult.OK;
|
||||||
@ -55,8 +58,9 @@ namespace qtc_net_client_2.Forms
|
|||||||
RememberMe = cbRememberMe.Checked
|
RememberMe = cbRememberMe.Checked
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.Success)
|
if (result.Success && result.Data != null)
|
||||||
{
|
{
|
||||||
|
_credService.SaveAccessToken(_apiService.CurrentUser.Username, result.Data);
|
||||||
DialogResult = DialogResult.OK;
|
DialogResult = DialogResult.OK;
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ namespace qtc_net_client_2
|
|||||||
if (_apiService.CurrentUser == null)
|
if (_apiService.CurrentUser == null)
|
||||||
{
|
{
|
||||||
// not logged in, load the login form
|
// not logged in, load the login form
|
||||||
llblForgotPassword frmLogin = new llblForgotPassword(_apiService);
|
Login frmLogin = new Login(_apiService);
|
||||||
var result = frmLogin.ShowDialog();
|
var result = frmLogin.ShowDialog();
|
||||||
|
|
||||||
if (result == DialogResult.OK)
|
if (result == DialogResult.OK)
|
||||||
@ -60,7 +60,7 @@ namespace qtc_net_client_2
|
|||||||
private async void llblSignIn_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
private async void llblSignIn_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
{
|
{
|
||||||
// just reshow the login dialog lol
|
// just reshow the login dialog lol
|
||||||
llblForgotPassword frmLogin = new llblForgotPassword(_apiService);
|
Login frmLogin = new Login(_apiService);
|
||||||
var result = frmLogin.ShowDialog();
|
var result = frmLogin.ShowDialog();
|
||||||
|
|
||||||
if (result == DialogResult.OK)
|
if (result == DialogResult.OK)
|
||||||
@ -172,12 +172,29 @@ namespace qtc_net_client_2
|
|||||||
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
||||||
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
||||||
|
|
||||||
|
// get cosmetic
|
||||||
|
byte[]? cosmeticData = null;
|
||||||
|
if (user.ProfileCosmeticId != 0)
|
||||||
|
{
|
||||||
|
var storeRes = await _apiService.GetStoreItem(user.ProfileCosmeticId);
|
||||||
|
if (storeRes != null && storeRes.Success && storeRes.Data != null)
|
||||||
|
{
|
||||||
|
using var client = new HttpClient();
|
||||||
|
using var response = await client.GetAsync(storeRes.Data.AssetUrl);
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
cosmeticData = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
}
|
||||||
|
else LoggingService.LogString($"Could Not Get User Cosmetic.\nStatus Code: {response.StatusCode}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pfpRes != null && !pfpRes.Success) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
|
if (pfpRes != null && !pfpRes.Success) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
|
||||||
|
|
||||||
if (res.Data != null && res.Success)
|
if (res.Data != null && res.Success)
|
||||||
{
|
{
|
||||||
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
|
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
|
||||||
Profile frmProfile = new Profile(res.Data, pfpRes, Contacts, _apiService, _gatewayService);
|
Profile frmProfile = new Profile(res.Data, pfpRes, Contacts, _apiService, _gatewayService, cosmeticData);
|
||||||
frmProfile.Show();
|
frmProfile.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,12 +313,29 @@ namespace qtc_net_client_2
|
|||||||
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
||||||
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
||||||
|
|
||||||
|
// get cosmetic
|
||||||
|
byte[]? cosmeticData = null;
|
||||||
|
if (user.ProfileCosmeticId != 0)
|
||||||
|
{
|
||||||
|
var storeRes = await _apiService.GetStoreItem(user.ProfileCosmeticId);
|
||||||
|
if (storeRes != null && storeRes.Success && storeRes.Data != null)
|
||||||
|
{
|
||||||
|
using var client = new HttpClient();
|
||||||
|
using var response = await client.GetAsync(storeRes.Data.AssetUrl);
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
cosmeticData = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
}
|
||||||
|
else LoggingService.LogString($"Could Not Get User Cosmetic.\nStatus Code: {response.StatusCode}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pfpRes != null && !pfpRes.Success) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
|
if (pfpRes != null && !pfpRes.Success) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
|
||||||
|
|
||||||
if (res.Data != null && res.Success)
|
if (res.Data != null && res.Success)
|
||||||
{
|
{
|
||||||
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
|
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
|
||||||
Profile frmProfile = new Profile(res.Data, pfpRes, Contacts, _apiService, _gatewayService);
|
Profile frmProfile = new Profile(res.Data, pfpRes, Contacts, _apiService, _gatewayService, cosmeticData);
|
||||||
frmProfile.Show();
|
frmProfile.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
20
qtc-net-client-2/Forms/Profile.Designer.cs
generated
20
qtc-net-client-2/Forms/Profile.Designer.cs
generated
@ -37,13 +37,11 @@
|
|||||||
btnDecline = new Button();
|
btnDecline = new Button();
|
||||||
btnCancelRequest = new Button();
|
btnCancelRequest = new Button();
|
||||||
btnMessage = new Button();
|
btnMessage = new Button();
|
||||||
pbUserStatus = new PictureBox();
|
|
||||||
pbCurrencyIcon = new PictureBox();
|
pbCurrencyIcon = new PictureBox();
|
||||||
lblCurrencyAmount = new Label();
|
lblCurrencyAmount = new Label();
|
||||||
flpUsernameCurrency = new FlowLayoutPanel();
|
flpUsernameCurrency = new FlowLayoutPanel();
|
||||||
pCurrency = new Panel();
|
pCurrency = new Panel();
|
||||||
((System.ComponentModel.ISupportInitialize)pbUserPfp).BeginInit();
|
((System.ComponentModel.ISupportInitialize)pbUserPfp).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)pbUserStatus).BeginInit();
|
|
||||||
((System.ComponentModel.ISupportInitialize)pbCurrencyIcon).BeginInit();
|
((System.ComponentModel.ISupportInitialize)pbCurrencyIcon).BeginInit();
|
||||||
flpUsernameCurrency.SuspendLayout();
|
flpUsernameCurrency.SuspendLayout();
|
||||||
pCurrency.SuspendLayout();
|
pCurrency.SuspendLayout();
|
||||||
@ -52,9 +50,9 @@
|
|||||||
// pbUserPfp
|
// pbUserPfp
|
||||||
//
|
//
|
||||||
pbUserPfp.Image = Properties.Resources.DefaultPfp;
|
pbUserPfp.Image = Properties.Resources.DefaultPfp;
|
||||||
pbUserPfp.Location = new Point(13, 11);
|
pbUserPfp.Location = new Point(9, 5);
|
||||||
pbUserPfp.Name = "pbUserPfp";
|
pbUserPfp.Name = "pbUserPfp";
|
||||||
pbUserPfp.Size = new Size(128, 128);
|
pbUserPfp.Size = new Size(139, 138);
|
||||||
pbUserPfp.SizeMode = PictureBoxSizeMode.StretchImage;
|
pbUserPfp.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
pbUserPfp.TabIndex = 2;
|
pbUserPfp.TabIndex = 2;
|
||||||
pbUserPfp.TabStop = false;
|
pbUserPfp.TabStop = false;
|
||||||
@ -148,17 +146,6 @@
|
|||||||
btnMessage.Visible = false;
|
btnMessage.Visible = false;
|
||||||
btnMessage.Click += btnMessage_Click;
|
btnMessage.Click += btnMessage_Click;
|
||||||
//
|
//
|
||||||
// pbUserStatus
|
|
||||||
//
|
|
||||||
pbUserStatus.BackColor = Color.Transparent;
|
|
||||||
pbUserStatus.Image = Properties.Resources.OfflineIcon;
|
|
||||||
pbUserStatus.Location = new Point(115, 1);
|
|
||||||
pbUserStatus.Name = "pbUserStatus";
|
|
||||||
pbUserStatus.Size = new Size(32, 32);
|
|
||||||
pbUserStatus.SizeMode = PictureBoxSizeMode.StretchImage;
|
|
||||||
pbUserStatus.TabIndex = 10;
|
|
||||||
pbUserStatus.TabStop = false;
|
|
||||||
//
|
|
||||||
// pbCurrencyIcon
|
// pbCurrencyIcon
|
||||||
//
|
//
|
||||||
pbCurrencyIcon.Image = Properties.Resources.CurrencyIcon;
|
pbCurrencyIcon.Image = Properties.Resources.CurrencyIcon;
|
||||||
@ -213,7 +200,6 @@
|
|||||||
Controls.Add(btnAccept);
|
Controls.Add(btnAccept);
|
||||||
Controls.Add(btnDecline);
|
Controls.Add(btnDecline);
|
||||||
Controls.Add(btnCancelRequest);
|
Controls.Add(btnCancelRequest);
|
||||||
Controls.Add(pbUserStatus);
|
|
||||||
Controls.Add(btnAddContact);
|
Controls.Add(btnAddContact);
|
||||||
Controls.Add(rtxtBio);
|
Controls.Add(rtxtBio);
|
||||||
Controls.Add(pbUserPfp);
|
Controls.Add(pbUserPfp);
|
||||||
@ -230,7 +216,6 @@
|
|||||||
FormClosed += Profile_FormClosed;
|
FormClosed += Profile_FormClosed;
|
||||||
Load += frmProfile_Load;
|
Load += frmProfile_Load;
|
||||||
((System.ComponentModel.ISupportInitialize)pbUserPfp).EndInit();
|
((System.ComponentModel.ISupportInitialize)pbUserPfp).EndInit();
|
||||||
((System.ComponentModel.ISupportInitialize)pbUserStatus).EndInit();
|
|
||||||
((System.ComponentModel.ISupportInitialize)pbCurrencyIcon).EndInit();
|
((System.ComponentModel.ISupportInitialize)pbCurrencyIcon).EndInit();
|
||||||
flpUsernameCurrency.ResumeLayout(false);
|
flpUsernameCurrency.ResumeLayout(false);
|
||||||
flpUsernameCurrency.PerformLayout();
|
flpUsernameCurrency.PerformLayout();
|
||||||
@ -249,7 +234,6 @@
|
|||||||
private Button btnDecline;
|
private Button btnDecline;
|
||||||
private Button btnCancelRequest;
|
private Button btnCancelRequest;
|
||||||
private Button btnMessage;
|
private Button btnMessage;
|
||||||
private PictureBox pbUserStatus;
|
|
||||||
private PictureBox pbCurrencyIcon;
|
private PictureBox pbCurrencyIcon;
|
||||||
private Label lblCurrencyAmount;
|
private Label lblCurrencyAmount;
|
||||||
private FlowLayoutPanel flpUsernameCurrency;
|
private FlowLayoutPanel flpUsernameCurrency;
|
||||||
|
@ -1,24 +1,25 @@
|
|||||||
using QtCNETAPI.Dtos.User;
|
using qtc_net_client_2.ClientModel;
|
||||||
using QtCNETAPI.Services.ApiService;
|
using qtc_net_client_2.Properties;
|
||||||
|
using qtc_net_client_2.Services;
|
||||||
|
using QtCNETAPI.Dtos.User;
|
||||||
using QtCNETAPI.Models;
|
using QtCNETAPI.Models;
|
||||||
|
using QtCNETAPI.Schema;
|
||||||
|
using QtCNETAPI.Services.ApiService;
|
||||||
|
using QtCNETAPI.Services.GatewayService;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Design;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using QtCNETAPI.Services.GatewayService;
|
|
||||||
using qtc_net_client_2.ClientModel;
|
|
||||||
using qtc_net_client_2.Properties;
|
|
||||||
using qtc_net_client_2.Services;
|
|
||||||
using QtCNETAPI.Schema;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using System.Drawing.Design;
|
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
|
|
||||||
namespace qtc_net_client_2.Forms
|
namespace qtc_net_client_2.Forms
|
||||||
{
|
{
|
||||||
@ -29,13 +30,16 @@ namespace qtc_net_client_2.Forms
|
|||||||
private IGatewayService _gatewayService;
|
private IGatewayService _gatewayService;
|
||||||
|
|
||||||
private ServiceResponse<byte[]>? pfpRes;
|
private ServiceResponse<byte[]>? pfpRes;
|
||||||
|
byte[]? cosmeticRes;
|
||||||
|
|
||||||
private List<Contact> contactsList;
|
private List<Contact> contactsList;
|
||||||
public Profile(UserInformationDto userInfo, ServiceResponse<byte[]>? pfp, List<Contact> contacts, IApiService apiService, IGatewayService gatewayService)
|
public Profile(UserInformationDto userInfo, ServiceResponse<byte[]>? pfp, List<Contact> contacts, IApiService apiService, IGatewayService gatewayService, byte[]? cosmetic = null)
|
||||||
{
|
{
|
||||||
_userInformationDto = userInfo;
|
_userInformationDto = userInfo;
|
||||||
_apiService = apiService;
|
_apiService = apiService;
|
||||||
_gatewayService = gatewayService;
|
_gatewayService = gatewayService;
|
||||||
pfpRes = pfp;
|
pfpRes = pfp;
|
||||||
|
cosmeticRes = cosmetic;
|
||||||
contactsList = contacts;
|
contactsList = contacts;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -47,53 +51,45 @@ namespace qtc_net_client_2.Forms
|
|||||||
lblCurrencyAmount.Text = _userInformationDto.CurrencyAmount.ToString("N0");
|
lblCurrencyAmount.Text = _userInformationDto.CurrencyAmount.ToString("N0");
|
||||||
rtxtBio.Text = _userInformationDto.Bio;
|
rtxtBio.Text = _userInformationDto.Bio;
|
||||||
|
|
||||||
pbUserPfp.Location = new(13, 11);
|
Bitmap? pfp = null;
|
||||||
pbUserPfp.Size = new(128, 128);
|
|
||||||
|
|
||||||
if (pfpRes != null && pfpRes.Success && pfpRes.Data != null)
|
if (pfpRes != null && pfpRes.Success && pfpRes.Data != null)
|
||||||
{
|
{
|
||||||
using (var ms = new MemoryStream(pfpRes.Data))
|
using (var ms = new MemoryStream(pfpRes.Data))
|
||||||
{
|
{
|
||||||
pbUserPfp.Image = new Bitmap(ms);
|
pfp = new Bitmap(ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var userStatus = (UserStatus)_userInformationDto.Status;
|
var userStatus = (UserStatus)_userInformationDto.Status;
|
||||||
|
Bitmap precenseImage = Resources.OnlineIcon;
|
||||||
switch (userStatus)
|
switch (userStatus)
|
||||||
{
|
{
|
||||||
case UserStatus.Online:
|
case UserStatus.Online:
|
||||||
pbUserStatus.Image = Resources.OnlineIcon;
|
precenseImage = Resources.OnlineIcon;
|
||||||
break;
|
break;
|
||||||
case UserStatus.Away:
|
case UserStatus.Away:
|
||||||
pbUserStatus.Image = Resources.AwayIcon;
|
precenseImage = Resources.AwayIcon;
|
||||||
break;
|
break;
|
||||||
case UserStatus.DoNotDisturb:
|
case UserStatus.DoNotDisturb:
|
||||||
pbUserStatus.Image = Resources.DNDIcon;
|
precenseImage = Resources.DNDIcon;
|
||||||
break;
|
break;
|
||||||
case UserStatus.Offline:
|
case UserStatus.Offline:
|
||||||
pbUserStatus.Image = Resources.OfflineIcon;
|
precenseImage = Resources.OfflineIcon;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_userInformationDto.ProfileCosmeticId != 0)
|
Bitmap? cosmetic = null;
|
||||||
|
if(cosmeticRes != null)
|
||||||
{
|
{
|
||||||
var res = await _apiService.GetStoreItem(_userInformationDto.ProfileCosmeticId);
|
using var ms = new MemoryStream(cosmeticRes);
|
||||||
if (res != null && res.Success && res.Data != null)
|
cosmetic = new Bitmap(ms);
|
||||||
{
|
|
||||||
var client = new HttpClient();
|
|
||||||
var response = await client.GetAsync(res.Data.AssetUrl);
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
using (var stream = await response.Content.ReadAsStreamAsync())
|
|
||||||
{
|
|
||||||
CombineProfileImageWithCosmetic(pbUserPfp.Image, new Bitmap(stream));
|
|
||||||
}
|
|
||||||
response.Dispose();
|
|
||||||
}
|
|
||||||
client.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreateProfileImage(precenseImage, pfp, cosmetic);
|
||||||
|
precenseImage.Dispose();
|
||||||
|
pfp?.Dispose();
|
||||||
|
cosmetic?.Dispose();
|
||||||
|
|
||||||
if (_userInformationDto.Id == _apiService.CurrentUser!.Id)
|
if (_userInformationDto.Id == _apiService.CurrentUser!.Id)
|
||||||
{
|
{
|
||||||
btnAddContact.Visible = false;
|
btnAddContact.Visible = false;
|
||||||
@ -243,22 +239,30 @@ namespace qtc_net_client_2.Forms
|
|||||||
frmDirectMessage.Show();
|
frmDirectMessage.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CombineProfileImageWithCosmetic(Image pfp, Bitmap cosmetic)
|
private void CreateProfileImage(Bitmap precenseImage, Bitmap? pfp = null, Bitmap? cosmetic = null)
|
||||||
{
|
{
|
||||||
cosmetic.MakeTransparent();
|
|
||||||
Bitmap combined = new Bitmap(139, 138);
|
Bitmap combined = new Bitmap(139, 138);
|
||||||
|
|
||||||
using (Graphics g = Graphics.FromImage(combined))
|
using Graphics g = Graphics.FromImage(combined);
|
||||||
{
|
|
||||||
g.Clear(Color.Transparent);
|
g.Clear(Color.Transparent);
|
||||||
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
|
g.CompositingMode = CompositingMode.SourceOver;
|
||||||
|
|
||||||
|
if (pfp != null)
|
||||||
|
{
|
||||||
|
pfp.MakeTransparent();
|
||||||
g.DrawImage(pfp, 4, 6, 128, 128);
|
g.DrawImage(pfp, 4, 6, 128, 128);
|
||||||
|
}
|
||||||
|
else g.DrawImage(pbUserPfp.Image, 4, 6, 128, 128);
|
||||||
|
|
||||||
|
if (cosmetic != null)
|
||||||
|
{
|
||||||
|
cosmetic.MakeTransparent();
|
||||||
g.DrawImage(cosmetic, 0, 0, 139, 138);
|
g.DrawImage(cosmetic, 0, 0, 139, 138);
|
||||||
}
|
}
|
||||||
|
|
||||||
pbUserPfp.Location = new(9, 5);
|
precenseImage.MakeTransparent();
|
||||||
pbUserPfp.Size = new(139, 138);
|
g.DrawImage(precenseImage, 104, 0, 35, 35);
|
||||||
|
|
||||||
pbUserPfp.Image = combined;
|
pbUserPfp.Image = combined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ namespace qtc_net_client_2.Properties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to 6.3.
|
/// Looks up a localized string similar to 6.3.4.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string AssemblyVersion {
|
internal static string AssemblyVersion {
|
||||||
get {
|
get {
|
||||||
|
@ -173,7 +173,7 @@
|
|||||||
<value>..\Icons\MessageIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Icons\MessageIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AssemblyVersion" xml:space="preserve">
|
<data name="AssemblyVersion" xml:space="preserve">
|
||||||
<value>6.3</value>
|
<value>6.3.4</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="cobalt_sittingatputer" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="cobalt_sittingatputer" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\cobalt_sittingatputer.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Resources\cobalt_sittingatputer.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user