Compare commits
26 Commits
Author | SHA1 | Date | |
---|---|---|---|
a95d012d69 | |||
d1d3af2ec9 | |||
4e61a1d7b9 | |||
446745d4df | |||
00df7505a7 | |||
b17d391406 | |||
2092d2c6d3 | |||
fd743dcb42 | |||
9214460927 | |||
1b30636937 | |||
72d9b99c4c | |||
c7137e4c7e | |||
4ee524778d | |||
cfcc5ad4c1 | |||
b81b059177 | |||
5d553cdf58 | |||
8cb59e1b21 | |||
6acb72975e | |||
098a59f555 | |||
e6c842cb19 | |||
758a5a96dc | |||
6bf77aa12e | |||
f98e5a490c | |||
75b61c0a8c | |||
0432fec3cd | |||
de2a81d485 |
14
QtCNETAPI/Dtos/User/UserPasswordResetDto.cs
Normal file
14
QtCNETAPI/Dtos/User/UserPasswordResetDto.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Dtos.User
|
||||||
|
{
|
||||||
|
public class UserPasswordResetDto
|
||||||
|
{
|
||||||
|
public string Token { get; set; } = string.Empty;
|
||||||
|
public string Password { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
||||||
|
@ -13,6 +13,9 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
{
|
{
|
||||||
private User? user;
|
private User? user;
|
||||||
private RestClient _client;
|
private RestClient _client;
|
||||||
|
private LoggingService _loggingService;
|
||||||
|
|
||||||
|
private CredentialService _credService = new();
|
||||||
|
|
||||||
internal string? sessionToken;
|
internal string? sessionToken;
|
||||||
internal string apiUri;
|
internal string apiUri;
|
||||||
@ -30,9 +33,10 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
get { return user; }
|
get { return user; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApiService(string apiUrl)
|
public ApiService(string apiUrl, LoggingService loggingService)
|
||||||
{
|
{
|
||||||
apiUri = apiUrl;
|
apiUri = apiUrl;
|
||||||
|
_loggingService = loggingService;
|
||||||
_client = new RestClient(apiUri);
|
_client = new RestClient(apiUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,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
|
||||||
{
|
{
|
||||||
@ -255,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
|
||||||
{
|
{
|
||||||
@ -278,6 +280,72 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
return serviceResponse;
|
return serviceResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<bool>> ResendVerificationEmail(string email)
|
||||||
|
{
|
||||||
|
var serviceResponse = new ServiceResponse<bool>();
|
||||||
|
|
||||||
|
var restRequest = new RestRequest($"auth/resend-verification-email")
|
||||||
|
.AddQueryParameter("email", email);
|
||||||
|
var response = await _client.PostAsync<ServiceResponse<bool>>(restRequest);
|
||||||
|
|
||||||
|
if (response != null)
|
||||||
|
{
|
||||||
|
serviceResponse.Success = true;
|
||||||
|
serviceResponse.Data = response.Data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serviceResponse.Success = false;
|
||||||
|
serviceResponse.Message = "API never responded.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<bool>> SendPasswordResetEmail(string email)
|
||||||
|
{
|
||||||
|
var serviceResponse = new ServiceResponse<bool>();
|
||||||
|
|
||||||
|
var restRequest = new RestRequest($"auth/request-password-reset")
|
||||||
|
.AddQueryParameter("email", email);
|
||||||
|
var response = await _client.PostAsync<ServiceResponse<bool>>(restRequest);
|
||||||
|
|
||||||
|
if (response != null)
|
||||||
|
{
|
||||||
|
serviceResponse.Success = true;
|
||||||
|
serviceResponse.Data = response.Data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serviceResponse.Success = false;
|
||||||
|
serviceResponse.Message = "API never responded.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<bool>> ResetPassword(UserPasswordResetDto request)
|
||||||
|
{
|
||||||
|
var serviceResponse = new ServiceResponse<bool>();
|
||||||
|
|
||||||
|
var restRequest = new RestRequest($"auth/reset-password")
|
||||||
|
.AddJsonBody(request);
|
||||||
|
var response = await _client.PostAsync<ServiceResponse<bool>>(restRequest);
|
||||||
|
|
||||||
|
if (response != null)
|
||||||
|
{
|
||||||
|
serviceResponse.Success = true;
|
||||||
|
serviceResponse.Data = response.Data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serviceResponse.Success = false;
|
||||||
|
serviceResponse.Message = "API never responded.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<User> SetCurrentUser()
|
public async Task<User> SetCurrentUser()
|
||||||
{
|
{
|
||||||
var userRequest = new RestRequest("users/user-authorized")
|
var userRequest = new RestRequest("users/user-authorized")
|
||||||
@ -287,6 +355,9 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
if (userResponse != null && userResponse.Success && userResponse.Data != null)
|
if (userResponse != null && userResponse.Success && userResponse.Data != null)
|
||||||
{
|
{
|
||||||
user = userResponse.Data;
|
user = userResponse.Data;
|
||||||
|
|
||||||
|
_loggingService.LogString($"Current User's Status Is {userResponse.Data.Status}");
|
||||||
|
|
||||||
return userResponse.Data;
|
return userResponse.Data;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
@ -342,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 };
|
||||||
}
|
}
|
||||||
@ -852,5 +925,29 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
|
|
||||||
return serviceResponse;
|
return serviceResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<User>> DeleteUserById(string id)
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<User>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("users/delete-user")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}")
|
||||||
|
.AddQueryParameter("id", id);
|
||||||
|
var response = await _client.DeleteAsync<ServiceResponse<User>>(restRequest);
|
||||||
|
|
||||||
|
if (response == null) { serviceResponse.Success = false; serviceResponse.Message = "API did not respond."; return serviceResponse; }
|
||||||
|
|
||||||
|
if (response.Success)
|
||||||
|
{
|
||||||
|
serviceResponse.Success = true;
|
||||||
|
serviceResponse.Data = response.Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,11 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
public Task<ServiceResponse<string>> PingServerAsync();
|
public Task<ServiceResponse<string>> PingServerAsync();
|
||||||
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>> LoginAsync(UserLoginDto userLoginDto);
|
public Task<ServiceResponse<User>> DeleteUserById(string id);
|
||||||
|
public Task<ServiceResponse<string>> LoginAsync(UserLoginDto userLoginDto);
|
||||||
|
public Task<ServiceResponse<bool>> ResendVerificationEmail(string email);
|
||||||
|
public Task<ServiceResponse<bool>> SendPasswordResetEmail(string email);
|
||||||
|
public Task<ServiceResponse<bool>> ResetPassword(UserPasswordResetDto request);
|
||||||
public Task<ServiceResponse<User>> RefreshLogin(string refreshToken);
|
public Task<ServiceResponse<User>> RefreshLogin(string refreshToken);
|
||||||
public Task<ServiceResponse<string>> RefreshSessionIfInvalid();
|
public Task<ServiceResponse<string>> RefreshSessionIfInvalid();
|
||||||
public Task<User> SetCurrentUser();
|
public Task<User> SetCurrentUser();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using QtCNETAPI.Dtos.User;
|
using QtCNETAPI.Dtos.User;
|
||||||
using QtCNETAPI.Events;
|
using QtCNETAPI.Events;
|
||||||
using QtCNETAPI.Models;
|
using QtCNETAPI.Models;
|
||||||
@ -6,48 +7,55 @@ using QtCNETAPI.Services.ApiService;
|
|||||||
|
|
||||||
namespace QtCNETAPI.Services.GatewayService
|
namespace QtCNETAPI.Services.GatewayService
|
||||||
{
|
{
|
||||||
public class GatewayService : IGatewayService, IAsyncDisposable
|
public class GatewayService(string GWUrl, IApiService apiService, LoggingService loggingService) : IGatewayService, IAsyncDisposable
|
||||||
{
|
{
|
||||||
internal string gwBaseUri = "127.0.0.1";
|
internal string gwBaseUri = GWUrl;
|
||||||
|
|
||||||
public Room? CurrentRoom { get; private set; }
|
public Room? CurrentRoom { get; private set; }
|
||||||
public bool InLobby { get; private set; }
|
public bool InLobby { get; private set; }
|
||||||
public HubConnection? HubConnection { get; private set; }
|
public HubConnection? HubConnection { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
public event EventHandler OnRoomMessageReceived;
|
public event EventHandler? OnRoomMessageReceived;
|
||||||
public event EventHandler OnRoomUserListReceived;
|
public event EventHandler? OnRoomUserListReceived;
|
||||||
public event EventHandler OnGuestUserJoin;
|
public event EventHandler? OnGuestUserJoin;
|
||||||
public event EventHandler OnRefreshUserListsReceived;
|
public event EventHandler? OnRefreshUserListsReceived;
|
||||||
public event EventHandler OnRefreshRoomListReceived;
|
public event EventHandler? OnRefreshRoomListReceived;
|
||||||
public event EventHandler OnRefreshContactsListReceived;
|
public event EventHandler? OnRoomDeleted;
|
||||||
public event EventHandler OnClientFunctionReceived;
|
public event EventHandler? OnRefreshContactsListReceived;
|
||||||
public event EventHandler OnDirectMessageReceived;
|
public event EventHandler? OnClientFunctionReceived;
|
||||||
public event EventHandler OnServerConfigReceived;
|
public event EventHandler? OnDirectMessageReceived;
|
||||||
public event EventHandler OnServerDisconnect;
|
public event EventHandler? OnServerConfigReceived;
|
||||||
public event EventHandler OnServerReconnecting;
|
public event EventHandler? OnServerDisconnect;
|
||||||
public event EventHandler OnServerReconnected;
|
public event EventHandler? OnServerReconnecting;
|
||||||
|
public event EventHandler? OnServerReconnected;
|
||||||
|
public event EventHandler? OnUserForceLogout;
|
||||||
|
|
||||||
private IApiService _apiService;
|
private IApiService _apiService = apiService;
|
||||||
|
private LoggingService _loggingService = loggingService;
|
||||||
public GatewayService(string GWUrl, IApiService apiService)
|
|
||||||
{
|
|
||||||
gwBaseUri = GWUrl;
|
|
||||||
_apiService = apiService;
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
||||||
|
.ConfigureLogging((builder) =>
|
||||||
|
{
|
||||||
|
builder.AddProvider(new LoggingServiceProvider(_loggingService));
|
||||||
|
|
||||||
|
if (System.Diagnostics.Debugger.IsAttached) builder.SetMinimumLevel(LogLevel.Debug);
|
||||||
|
else builder.SetMinimumLevel(LogLevel.Error);
|
||||||
|
})
|
||||||
.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
|
||||||
@ -60,13 +68,26 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
HubConnection.On<ServerConfig>("ReceiveServerConfig", (serverConfig) => OnServerConfigReceived?.Invoke(this, new ServerConfigEventArgs { ServerConfig = serverConfig }));
|
HubConnection.On<ServerConfig>("ReceiveServerConfig", (serverConfig) => OnServerConfigReceived?.Invoke(this, new ServerConfigEventArgs { ServerConfig = serverConfig }));
|
||||||
HubConnection.On<List<User>>("RoomUserList", (userList) => OnRoomUserListReceived?.Invoke(this, new RoomListEventArgs { UserList = userList }));
|
HubConnection.On<List<User>>("RoomUserList", (userList) => OnRoomUserListReceived?.Invoke(this, new RoomListEventArgs { UserList = userList }));
|
||||||
HubConnection.On<string>("GuestJoin", (username) => OnGuestUserJoin?.Invoke(this, new GuestUserJoinEventArgs { Username = username }));
|
HubConnection.On<string>("GuestJoin", (username) => OnGuestUserJoin?.Invoke(this, new GuestUserJoinEventArgs { Username = username }));
|
||||||
|
HubConnection.On("RoomDeleted", () => OnRoomDeleted?.Invoke(this, EventArgs.Empty));
|
||||||
|
HubConnection.On("ForceSignOut", () => OnUserForceLogout?.Invoke(this, EventArgs.Empty));
|
||||||
|
|
||||||
HubConnection.Closed += HubConnection_Closed;
|
HubConnection.Closed += HubConnection_Closed;
|
||||||
HubConnection.Reconnecting += HubConnection_Reconnecting;
|
HubConnection.Reconnecting += HubConnection_Reconnecting;
|
||||||
HubConnection.Reconnected += HubConnection_Reconnected;
|
HubConnection.Reconnected += HubConnection_Reconnected;
|
||||||
|
|
||||||
// start connection
|
// start connection
|
||||||
await HubConnection.StartAsync();
|
try
|
||||||
|
{
|
||||||
|
await HubConnection.StartAsync();
|
||||||
|
}
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
_loggingService.LogString($"Unable To Connect To SignalR.\n{ex.Message}\n{ex.StackTrace}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure current user is up to date (particularly status)
|
||||||
|
await _apiService.SetCurrentUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StopAsync()
|
public async Task StopAsync()
|
||||||
@ -101,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);
|
||||||
@ -112,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)
|
||||||
@ -132,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)
|
||||||
@ -150,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);
|
||||||
@ -168,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);
|
||||||
|
@ -104,6 +104,11 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler OnRoomUserListReceived;
|
public event EventHandler OnRoomUserListReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires When The Room The User Is In Gets Deleted By An Admin
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler OnRoomDeleted;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fires When A Guest User Joins Your Room
|
/// Fires When A Guest User Joins Your Room
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -153,5 +158,10 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
/// When the Connection Reconnects, This Event Fires
|
/// When the Connection Reconnects, This Event Fires
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler OnServerReconnected;
|
public event EventHandler OnServerReconnected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires When The Current User Is Signed Out By The Server
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler OnUserForceLogout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,12 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.IdentityModel.Abstractions;
|
||||||
|
|
||||||
namespace qtc_net_client_2.Services
|
namespace QtCNETAPI.Services
|
||||||
{
|
{
|
||||||
public class LoggingService : IDisposable
|
public class LoggingService : IDisposable, ILogger
|
||||||
{
|
{
|
||||||
private DateTime LogDate { get; set; }
|
private DateTime LogDate { get; set; }
|
||||||
private string LogFilePath { get; set; }
|
private string LogFilePath { get; set; }
|
||||||
@ -16,7 +18,7 @@ namespace qtc_net_client_2.Services
|
|||||||
public LoggingService()
|
public LoggingService()
|
||||||
{
|
{
|
||||||
LogDate = DateTime.Now;
|
LogDate = DateTime.Now;
|
||||||
LogFilePath = $"./Logs/QtCClientLog_{LogDate.ToString("ddMMyyy-hhmm")}.log";
|
LogFilePath = $"./Logs/QtCClientLog_{LogDate:ddMMyyy-hhmm}.log";
|
||||||
|
|
||||||
// create log file
|
// create log file
|
||||||
|
|
||||||
@ -30,8 +32,8 @@ namespace qtc_net_client_2.Services
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"({DateTime.Now.ToLocalTime().ToString("hh:mm")}) {message}");
|
Debug.WriteLine($"({DateTime.Now.ToLocalTime():hh:mm}) {message}");
|
||||||
LogFile.WriteLine($"({DateTime.Now.ToLocalTime().ToString("hh:mm")}) {message}");
|
LogFile.WriteLine($"({DateTime.Now.ToLocalTime():hh:mm}) {message}");
|
||||||
} catch (ObjectDisposedException)
|
} catch (ObjectDisposedException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -45,8 +47,8 @@ namespace qtc_net_client_2.Services
|
|||||||
string modelSerialized = JsonSerializer.Serialize(model, options: new JsonSerializerOptions { WriteIndented = true });
|
string modelSerialized = JsonSerializer.Serialize(model, options: new JsonSerializerOptions { WriteIndented = true });
|
||||||
|
|
||||||
// log it
|
// log it
|
||||||
Debug.WriteLine($"({DateTime.Now.ToLocalTime().ToString("hh:mm")}) {modelSerialized}");
|
Debug.WriteLine($"({DateTime.Now.ToLocalTime():hh:mm}) {modelSerialized}");
|
||||||
LogFile.WriteLine($"({DateTime.Now.ToLocalTime().ToString("hh:mm")}) {modelSerialized}");
|
LogFile.WriteLine($"({DateTime.Now.ToLocalTime():hh:mm}) {modelSerialized}");
|
||||||
} catch (ObjectDisposedException)
|
} catch (ObjectDisposedException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -58,5 +60,34 @@ namespace qtc_net_client_2.Services
|
|||||||
LogFile.Close();
|
LogFile.Close();
|
||||||
LogFile.Dispose();
|
LogFile.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// format message
|
||||||
|
string message = $"({DateTime.Now.ToLocalTime():hh:mm}) [{logLevel}] {formatter(state, exception)}";
|
||||||
|
|
||||||
|
// log it
|
||||||
|
Debug.WriteLine(message);
|
||||||
|
LogFile.WriteLine(message);
|
||||||
|
} catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEnabled(LogLevel logLevel) => true;
|
||||||
|
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => default!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LoggingServiceProvider(LoggingService? loggingService = null) : ILoggerProvider
|
||||||
|
{
|
||||||
|
public ILogger CreateLogger(string categoryName)
|
||||||
|
{
|
||||||
|
if (loggingService != null) return loggingService;
|
||||||
|
else return new LoggingService();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,6 +15,9 @@ namespace qtc_net_client_2.ClientModel
|
|||||||
[JsonPropertyName("minimizeToTray")]
|
[JsonPropertyName("minimizeToTray")]
|
||||||
[JsonRequired]
|
[JsonRequired]
|
||||||
public bool MinimizeToTray { get; set; } = true;
|
public bool MinimizeToTray { get; set; } = true;
|
||||||
|
[JsonPropertyName("enableDebugLogs")]
|
||||||
|
[JsonRequired]
|
||||||
|
public bool EnableDebugLogs { get; set; } = false;
|
||||||
|
|
||||||
[JsonPropertyName("serverUrl")]
|
[JsonPropertyName("serverUrl")]
|
||||||
[JsonRequired]
|
[JsonRequired]
|
||||||
|
@ -1,17 +1,7 @@
|
|||||||
using qtc_net_client_2.Services;
|
using qtc_net_client_2.Services;
|
||||||
using QtCNETAPI.Events;
|
using QtCNETAPI.Events;
|
||||||
using QtCNETAPI.Models;
|
|
||||||
using QtCNETAPI.Services.ApiService;
|
using QtCNETAPI.Services.ApiService;
|
||||||
using QtCNETAPI.Services.GatewayService;
|
using QtCNETAPI.Services.GatewayService;
|
||||||
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 qtc_net_client_2.Forms
|
namespace qtc_net_client_2.Forms
|
||||||
{
|
{
|
||||||
@ -33,6 +23,7 @@ namespace qtc_net_client_2.Forms
|
|||||||
// subscribe to server message event
|
// subscribe to server message event
|
||||||
_gatewayService.OnRoomMessageReceived += _gatewayService_OnServerMessageReceived;
|
_gatewayService.OnRoomMessageReceived += _gatewayService_OnServerMessageReceived;
|
||||||
_gatewayService.OnRoomUserListReceived += _gatewayService_OnRoomUserListReceived;
|
_gatewayService.OnRoomUserListReceived += _gatewayService_OnRoomUserListReceived;
|
||||||
|
_gatewayService.OnRoomDeleted += _gatewayService_OnRoomDeleted;
|
||||||
_gatewayService.OnGuestUserJoin += _gatewayService_OnGuestUserJoin;
|
_gatewayService.OnGuestUserJoin += _gatewayService_OnGuestUserJoin;
|
||||||
|
|
||||||
if (_gatewayService.CurrentRoom != null) { Text = $"QtC.NET Client - Chat Room - {_gatewayService.CurrentRoom.Name}"; lblRoomName.Text = _gatewayService.CurrentRoom.Name; }
|
if (_gatewayService.CurrentRoom != null) { Text = $"QtC.NET Client - Chat Room - {_gatewayService.CurrentRoom.Name}"; lblRoomName.Text = _gatewayService.CurrentRoom.Name; }
|
||||||
@ -94,13 +85,16 @@ namespace qtc_net_client_2.Forms
|
|||||||
{
|
{
|
||||||
// get user info and open profile dialog
|
// get user info and open profile dialog
|
||||||
var user = mainForm.UserDirectory.FirstOrDefault(e => e.Username == selectedUser);
|
var user = mainForm.UserDirectory.FirstOrDefault(e => e.Username == selectedUser);
|
||||||
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
if (user != null)
|
||||||
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
|
||||||
|
|
||||||
if (res.Data != null && res.Success)
|
|
||||||
{
|
{
|
||||||
Profile frmProfile = new Profile(res.Data, pfpRes, mainForm.Contacts, _apiService, _gatewayService);
|
var res = await _apiService.GetUserInformationAsync(user.Id);
|
||||||
frmProfile.Show();
|
var pfpRes = await _apiService.GetUserProfilePic(user.Id);
|
||||||
|
|
||||||
|
if (res.Data != null && res.Success)
|
||||||
|
{
|
||||||
|
Profile frmProfile = new Profile(res.Data, pfpRes, mainForm.Contacts, _apiService, _gatewayService);
|
||||||
|
frmProfile.Show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,12 +113,16 @@ namespace qtc_net_client_2.Forms
|
|||||||
{
|
{
|
||||||
var args = (RoomListEventArgs)e;
|
var args = (RoomListEventArgs)e;
|
||||||
|
|
||||||
if (!IsHandleCreated) return;
|
if (IsHandleCreated && !IsDisposed)
|
||||||
|
|
||||||
lvUserList.BeginInvoke(lvUserList.Clear);
|
|
||||||
foreach (var user in args.UserList)
|
|
||||||
{
|
{
|
||||||
lvUserList.BeginInvoke(delegate () { lvUserList.Items.Add(user.Username, user.Status); });
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
lvUserList.Clear();
|
||||||
|
foreach (var user in args.UserList)
|
||||||
|
{
|
||||||
|
lvUserList.Items.Add(user.Username, user.Status);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void _gatewayService_OnGuestUserJoin(object? sender, EventArgs e)
|
private void _gatewayService_OnGuestUserJoin(object? sender, EventArgs e)
|
||||||
@ -133,12 +131,32 @@ namespace qtc_net_client_2.Forms
|
|||||||
AddMessage($"[SERVER] Guest User {args.Username} Has Joined {_gatewayService.CurrentRoom?.Name}");
|
AddMessage($"[SERVER] Guest User {args.Username} Has Joined {_gatewayService.CurrentRoom?.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void _gatewayService_OnRoomDeleted(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(IsHandleCreated && !IsDisposed)
|
||||||
|
{
|
||||||
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
AddMessage($"[SERVER] This Room Was Deleted By An Admin.");
|
||||||
|
lvUserList.Clear();
|
||||||
|
|
||||||
|
lvUserList.Enabled = false;
|
||||||
|
rtxtChatbox.Enabled = false;
|
||||||
|
btnSend.Enabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void AddMessage(string message)
|
private void AddMessage(string message)
|
||||||
{
|
{
|
||||||
if (InvokeRequired)
|
if(IsHandleCreated && !IsDisposed)
|
||||||
Invoke(delegate { rtxtChat.AppendText(message + Environment.NewLine); });
|
{
|
||||||
else rtxtChat.AppendText(message + Environment.NewLine);
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
rtxtChat.AppendText(message + Environment.NewLine);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
qtc-net-client-2/Forms/ConnectionClosed.Designer.cs
generated
21
qtc-net-client-2/Forms/ConnectionClosed.Designer.cs
generated
@ -31,18 +31,17 @@
|
|||||||
lblHead = new Label();
|
lblHead = new Label();
|
||||||
btnReconnect = new Button();
|
btnReconnect = new Button();
|
||||||
btnQuit = new Button();
|
btnQuit = new Button();
|
||||||
lblReason = new Label();
|
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// lblHead
|
// lblHead
|
||||||
//
|
//
|
||||||
lblHead.AutoSize = true;
|
|
||||||
lblHead.Font = new Font("Segoe UI", 11F, FontStyle.Bold);
|
lblHead.Font = new Font("Segoe UI", 11F, FontStyle.Bold);
|
||||||
lblHead.Location = new Point(12, 9);
|
lblHead.Location = new Point(12, 9);
|
||||||
lblHead.Name = "lblHead";
|
lblHead.Name = "lblHead";
|
||||||
lblHead.Size = new Size(444, 20);
|
lblHead.Size = new Size(444, 20);
|
||||||
lblHead.TabIndex = 0;
|
lblHead.TabIndex = 0;
|
||||||
lblHead.Text = "Your Connection To The QtC.NET Server Was Lost. What Now?";
|
lblHead.Text = "Your Connection To The QtC.NET Server Was Lost. What Now?";
|
||||||
|
lblHead.TextAlign = ContentAlignment.MiddleCenter;
|
||||||
//
|
//
|
||||||
// btnReconnect
|
// btnReconnect
|
||||||
//
|
//
|
||||||
@ -66,23 +65,12 @@
|
|||||||
btnQuit.UseVisualStyleBackColor = true;
|
btnQuit.UseVisualStyleBackColor = true;
|
||||||
btnQuit.Click += btnQuit_Click;
|
btnQuit.Click += btnQuit_Click;
|
||||||
//
|
//
|
||||||
// lblReason
|
// ConnectionClosed
|
||||||
//
|
|
||||||
lblReason.AutoSize = true;
|
|
||||||
lblReason.Font = new Font("Segoe UI", 5F, FontStyle.Bold);
|
|
||||||
lblReason.Location = new Point(88, 40);
|
|
||||||
lblReason.Name = "lblReason";
|
|
||||||
lblReason.Size = new Size(72, 10);
|
|
||||||
lblReason.TabIndex = 3;
|
|
||||||
lblReason.Text = "Reason: ${REASON}";
|
|
||||||
//
|
|
||||||
// frmConnectionClosed
|
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
AutoScaleMode = AutoScaleMode.Font;
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
BackColor = Color.DodgerBlue;
|
BackColor = Color.DodgerBlue;
|
||||||
ClientSize = new Size(463, 65);
|
ClientSize = new Size(463, 65);
|
||||||
Controls.Add(lblReason);
|
|
||||||
Controls.Add(btnQuit);
|
Controls.Add(btnQuit);
|
||||||
Controls.Add(btnReconnect);
|
Controls.Add(btnReconnect);
|
||||||
Controls.Add(lblHead);
|
Controls.Add(lblHead);
|
||||||
@ -92,12 +80,10 @@
|
|||||||
Margin = new Padding(4, 3, 4, 3);
|
Margin = new Padding(4, 3, 4, 3);
|
||||||
MaximizeBox = false;
|
MaximizeBox = false;
|
||||||
MinimizeBox = false;
|
MinimizeBox = false;
|
||||||
Name = "frmConnectionClosed";
|
Name = "ConnectionClosed";
|
||||||
StartPosition = FormStartPosition.CenterScreen;
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
Text = "QtC.NET Client - Connection Lost";
|
Text = "QtC.NET Client - Connection Lost";
|
||||||
Load += frmConnectionClosed_Load;
|
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
PerformLayout();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -105,6 +91,5 @@
|
|||||||
private Label lblHead;
|
private Label lblHead;
|
||||||
private Button btnReconnect;
|
private Button btnReconnect;
|
||||||
private Button btnQuit;
|
private Button btnQuit;
|
||||||
private Label lblReason;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,19 +12,12 @@ namespace qtc_net_client_2.Forms
|
|||||||
{
|
{
|
||||||
public partial class ConnectionClosed : Form
|
public partial class ConnectionClosed : Form
|
||||||
{
|
{
|
||||||
public string? Reason { get; set; } = string.Empty;
|
public Label StatusLabel { get { return lblHead; } }
|
||||||
public ConnectionClosed(string? reason = "")
|
public ConnectionClosed()
|
||||||
{
|
{
|
||||||
Reason = reason;
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void frmConnectionClosed_Load(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(Reason)) lblReason.Visible = false;
|
|
||||||
else lblReason.Text = $"Reason: {Reason}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private void btnReconnect_Click(object sender, EventArgs e)
|
private void btnReconnect_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
DialogResult = DialogResult.OK;
|
DialogResult = DialogResult.OK;
|
||||||
|
@ -42,6 +42,11 @@ namespace qtc_net_client_2.Forms
|
|||||||
Text = $"QtC.NET Client - Direct Message With {User.Username}";
|
Text = $"QtC.NET Client - Direct Message With {User.Username}";
|
||||||
Messages.CollectionChanged += Messages_CollectionChanged;
|
Messages.CollectionChanged += Messages_CollectionChanged;
|
||||||
|
|
||||||
|
if (User.Role == "Admin")
|
||||||
|
{
|
||||||
|
Messages.Add($"[SERVER] This User Is A Server Admin. You should comply with anything this user asks. however admins should not ask for personal information.\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (InitMessage != null)
|
if (InitMessage != null)
|
||||||
{
|
{
|
||||||
Messages.Add($"[{User.Username}] {InitMessage.Content}\n");
|
Messages.Add($"[{User.Username}] {InitMessage.Content}\n");
|
||||||
@ -58,7 +63,7 @@ namespace qtc_net_client_2.Forms
|
|||||||
if (!string.IsNullOrEmpty(rtxtChatbox.Text))
|
if (!string.IsNullOrEmpty(rtxtChatbox.Text))
|
||||||
{
|
{
|
||||||
await _gatewayService.SendDirectMessageAsync(User, new QtCNETAPI.Models.Message { Content = rtxtChatbox.Text, AuthorId = _apiService.CurrentUser.Id });
|
await _gatewayService.SendDirectMessageAsync(User, new QtCNETAPI.Models.Message { Content = rtxtChatbox.Text, AuthorId = _apiService.CurrentUser.Id });
|
||||||
Messages.Add($"[{_apiService.CurrentUser.Username}] {rtxtChatbox.Text}");
|
Messages.Add($"[{_apiService.CurrentUser.Username}] {rtxtChatbox.Text}\n");
|
||||||
rtxtChatbox.Clear();
|
rtxtChatbox.Clear();
|
||||||
AudioService.PlaySoundEffect("sndSendClick");
|
AudioService.PlaySoundEffect("sndSendClick");
|
||||||
}
|
}
|
||||||
@ -69,7 +74,7 @@ namespace qtc_net_client_2.Forms
|
|||||||
if (!string.IsNullOrEmpty(rtxtChatbox.Text))
|
if (!string.IsNullOrEmpty(rtxtChatbox.Text))
|
||||||
{
|
{
|
||||||
await _gatewayService.SendDirectMessageAsync(User, new QtCNETAPI.Models.Message { Content = rtxtChatbox.Text, AuthorId = _apiService.CurrentUser.Id });
|
await _gatewayService.SendDirectMessageAsync(User, new QtCNETAPI.Models.Message { Content = rtxtChatbox.Text, AuthorId = _apiService.CurrentUser.Id });
|
||||||
Messages.Add($"[{_apiService.CurrentUser.Username}] {rtxtChatbox.Text}");
|
Messages.Add($"[{_apiService.CurrentUser.Username}] {rtxtChatbox.Text}\n");
|
||||||
rtxtChatbox.Clear();
|
rtxtChatbox.Clear();
|
||||||
AudioService.PlaySoundEffect("sndSendClick");
|
AudioService.PlaySoundEffect("sndSendClick");
|
||||||
}
|
}
|
||||||
|
60
qtc-net-client-2/Forms/Login.Designer.cs
generated
60
qtc-net-client-2/Forms/Login.Designer.cs
generated
@ -32,11 +32,13 @@
|
|||||||
pbLoginBanner = new PictureBox();
|
pbLoginBanner = new PictureBox();
|
||||||
tbEmail = new TextBox();
|
tbEmail = new TextBox();
|
||||||
lblEmail = new Label();
|
lblEmail = new Label();
|
||||||
label1 = new Label();
|
lblPassword = new Label();
|
||||||
tbPassword = new TextBox();
|
tbPassword = new TextBox();
|
||||||
btnLogin = new Button();
|
btnLogin = new Button();
|
||||||
llblRegister = new LinkLabel();
|
llblRegister = new LinkLabel();
|
||||||
cbRememberMe = new CheckBox();
|
cbRememberMe = new CheckBox();
|
||||||
|
llblResendEmail = new LinkLabel();
|
||||||
|
llblForgotPasswor = new LinkLabel();
|
||||||
((System.ComponentModel.ISupportInitialize)pbLoginBanner).BeginInit();
|
((System.ComponentModel.ISupportInitialize)pbLoginBanner).BeginInit();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
@ -68,16 +70,16 @@
|
|||||||
lblEmail.TabIndex = 2;
|
lblEmail.TabIndex = 2;
|
||||||
lblEmail.Text = "Email";
|
lblEmail.Text = "Email";
|
||||||
//
|
//
|
||||||
// label1
|
// lblPassword
|
||||||
//
|
//
|
||||||
label1.AutoSize = true;
|
lblPassword.AutoSize = true;
|
||||||
label1.Font = new Font("Segoe UI Light", 9F);
|
lblPassword.Font = new Font("Segoe UI Light", 9F);
|
||||||
label1.ForeColor = SystemColors.ControlLight;
|
lblPassword.ForeColor = SystemColors.ControlLight;
|
||||||
label1.Location = new Point(11, 138);
|
lblPassword.Location = new Point(11, 138);
|
||||||
label1.Name = "label1";
|
lblPassword.Name = "lblPassword";
|
||||||
label1.Size = new Size(55, 15);
|
lblPassword.Size = new Size(55, 15);
|
||||||
label1.TabIndex = 4;
|
lblPassword.TabIndex = 4;
|
||||||
label1.Text = "Password";
|
lblPassword.Text = "Password";
|
||||||
//
|
//
|
||||||
// tbPassword
|
// tbPassword
|
||||||
//
|
//
|
||||||
@ -122,16 +124,44 @@
|
|||||||
cbRememberMe.Text = "Remember Me For 7 Days";
|
cbRememberMe.Text = "Remember Me For 7 Days";
|
||||||
cbRememberMe.UseVisualStyleBackColor = true;
|
cbRememberMe.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// frmLogin
|
// llblResendEmail
|
||||||
|
//
|
||||||
|
llblResendEmail.AutoSize = true;
|
||||||
|
llblResendEmail.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
llblResendEmail.LinkColor = SystemColors.ControlLight;
|
||||||
|
llblResendEmail.Location = new Point(369, 164);
|
||||||
|
llblResendEmail.Name = "llblResendEmail";
|
||||||
|
llblResendEmail.Size = new Size(129, 15);
|
||||||
|
llblResendEmail.TabIndex = 8;
|
||||||
|
llblResendEmail.TabStop = true;
|
||||||
|
llblResendEmail.Text = "Resend Verification Email";
|
||||||
|
llblResendEmail.LinkClicked += llblResendEmail_LinkClicked;
|
||||||
|
//
|
||||||
|
// llblForgotPasswor
|
||||||
|
//
|
||||||
|
llblForgotPasswor.AutoSize = true;
|
||||||
|
llblForgotPasswor.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
llblForgotPasswor.LinkColor = SystemColors.ControlLight;
|
||||||
|
llblForgotPasswor.Location = new Point(401, 181);
|
||||||
|
llblForgotPasswor.Name = "llblForgotPasswor";
|
||||||
|
llblForgotPasswor.Size = new Size(98, 15);
|
||||||
|
llblForgotPasswor.TabIndex = 9;
|
||||||
|
llblForgotPasswor.TabStop = true;
|
||||||
|
llblForgotPasswor.Text = "Forgot Password?";
|
||||||
|
llblForgotPasswor.LinkClicked += llblForgotPasswor_LinkClicked;
|
||||||
|
//
|
||||||
|
// llblForgotPassword
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
AutoScaleMode = AutoScaleMode.Font;
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
BackColor = Color.DodgerBlue;
|
BackColor = Color.DodgerBlue;
|
||||||
ClientSize = new Size(515, 203);
|
ClientSize = new Size(515, 203);
|
||||||
|
Controls.Add(llblForgotPasswor);
|
||||||
|
Controls.Add(llblResendEmail);
|
||||||
Controls.Add(cbRememberMe);
|
Controls.Add(cbRememberMe);
|
||||||
Controls.Add(llblRegister);
|
Controls.Add(llblRegister);
|
||||||
Controls.Add(btnLogin);
|
Controls.Add(btnLogin);
|
||||||
Controls.Add(label1);
|
Controls.Add(lblPassword);
|
||||||
Controls.Add(tbPassword);
|
Controls.Add(tbPassword);
|
||||||
Controls.Add(lblEmail);
|
Controls.Add(lblEmail);
|
||||||
Controls.Add(tbEmail);
|
Controls.Add(tbEmail);
|
||||||
@ -139,7 +169,7 @@
|
|||||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||||
MaximizeBox = false;
|
MaximizeBox = false;
|
||||||
Name = "frmLogin";
|
Name = "llblForgotPassword";
|
||||||
StartPosition = FormStartPosition.CenterParent;
|
StartPosition = FormStartPosition.CenterParent;
|
||||||
Text = "QtC.NET Client - Login";
|
Text = "QtC.NET Client - Login";
|
||||||
Load += frmLogin_Load;
|
Load += frmLogin_Load;
|
||||||
@ -153,10 +183,12 @@
|
|||||||
private PictureBox pbLoginBanner;
|
private PictureBox pbLoginBanner;
|
||||||
private TextBox tbEmail;
|
private TextBox tbEmail;
|
||||||
private Label lblEmail;
|
private Label lblEmail;
|
||||||
private Label label1;
|
private Label lblPassword;
|
||||||
private TextBox tbPassword;
|
private TextBox tbPassword;
|
||||||
private Button btnLogin;
|
private Button btnLogin;
|
||||||
private LinkLabel llblRegister;
|
private LinkLabel llblRegister;
|
||||||
private CheckBox cbRememberMe;
|
private CheckBox cbRememberMe;
|
||||||
|
private LinkLabel llblResendEmail;
|
||||||
|
private LinkLabel llblForgotPasswor;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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,12 +10,14 @@ 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 Login : Form
|
public partial class Login : Form
|
||||||
{
|
{
|
||||||
private IApiService _apiService;
|
private IApiService _apiService;
|
||||||
|
private CredentialService _credService = new();
|
||||||
public Login(IApiService apiService)
|
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();
|
||||||
}
|
}
|
||||||
@ -68,6 +72,24 @@ namespace qtc_net_client_2.Forms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void llblRegister_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
|
{
|
||||||
|
Register frmRegister = new Register(_apiService);
|
||||||
|
frmRegister.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void llblResendEmail_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
|
{
|
||||||
|
ResendVerificationEmail resendVerificationEmail = new ResendVerificationEmail(_apiService);
|
||||||
|
resendVerificationEmail.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void llblForgotPasswor_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
|
{
|
||||||
|
ResetPassword resetPassword = new ResetPassword(_apiService);
|
||||||
|
resetPassword.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
private void ToggleControls(bool enable, bool clearText)
|
private void ToggleControls(bool enable, bool clearText)
|
||||||
{
|
{
|
||||||
tbEmail.Enabled = enable;
|
tbEmail.Enabled = enable;
|
||||||
@ -81,11 +103,5 @@ namespace qtc_net_client_2.Forms
|
|||||||
tbPassword.Text = string.Empty;
|
tbPassword.Text = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void llblRegister_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
|
||||||
{
|
|
||||||
Register frmRegister = new Register(_apiService);
|
|
||||||
frmRegister.ShowDialog();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
128
qtc-net-client-2/Forms/Main.Designer.cs
generated
128
qtc-net-client-2/Forms/Main.Designer.cs
generated
@ -40,7 +40,6 @@
|
|||||||
refreshToolStripMenuItem = new ToolStripMenuItem();
|
refreshToolStripMenuItem = new ToolStripMenuItem();
|
||||||
ilProfilePics = new ImageList(components);
|
ilProfilePics = new ImageList(components);
|
||||||
tbpRooms = new TabPage();
|
tbpRooms = new TabPage();
|
||||||
btnAddRoom = new Button();
|
|
||||||
lbRooms = new ListBox();
|
lbRooms = new ListBox();
|
||||||
tbpUsers = new TabPage();
|
tbpUsers = new TabPage();
|
||||||
lvUserDirectory = new ListView();
|
lvUserDirectory = new ListView();
|
||||||
@ -70,6 +69,18 @@
|
|||||||
lblWelcome = new Label();
|
lblWelcome = new Label();
|
||||||
pbUserPfp = new PictureBox();
|
pbUserPfp = new PictureBox();
|
||||||
pbDonate = new PictureBox();
|
pbDonate = new PictureBox();
|
||||||
|
ctxmAdminUserList = new ContextMenuStrip(components);
|
||||||
|
refreshToolStripMenuItem1 = new ToolStripMenuItem();
|
||||||
|
toolStripSeparator1 = new ToolStripSeparator();
|
||||||
|
copyUserIDToClipboardToolStripMenuItem = new ToolStripMenuItem();
|
||||||
|
deleteUserToolStripMenuItem = new ToolStripMenuItem();
|
||||||
|
adminDirectMessageToolStripMenuItem = new ToolStripMenuItem();
|
||||||
|
ctxmAdminRoomList = new ContextMenuStrip(components);
|
||||||
|
toolStripMenuItem1 = new ToolStripMenuItem();
|
||||||
|
toolStripSeparator2 = new ToolStripSeparator();
|
||||||
|
addRoomToolStripMenuItem = new ToolStripMenuItem();
|
||||||
|
deleteRoomToolStripMenuItem = new ToolStripMenuItem();
|
||||||
|
lblConnectionLost = new Label();
|
||||||
tbcMain.SuspendLayout();
|
tbcMain.SuspendLayout();
|
||||||
tbpContacts.SuspendLayout();
|
tbpContacts.SuspendLayout();
|
||||||
ctxmRefresh.SuspendLayout();
|
ctxmRefresh.SuspendLayout();
|
||||||
@ -83,6 +94,8 @@
|
|||||||
pCurrentUser.SuspendLayout();
|
pCurrentUser.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)pbUserPfp).BeginInit();
|
((System.ComponentModel.ISupportInitialize)pbUserPfp).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)pbDonate).BeginInit();
|
((System.ComponentModel.ISupportInitialize)pbDonate).BeginInit();
|
||||||
|
ctxmAdminUserList.SuspendLayout();
|
||||||
|
ctxmAdminRoomList.SuspendLayout();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// tbcMain
|
// tbcMain
|
||||||
@ -152,7 +165,6 @@
|
|||||||
//
|
//
|
||||||
// tbpRooms
|
// tbpRooms
|
||||||
//
|
//
|
||||||
tbpRooms.Controls.Add(btnAddRoom);
|
|
||||||
tbpRooms.Controls.Add(lbRooms);
|
tbpRooms.Controls.Add(lbRooms);
|
||||||
tbpRooms.ImageKey = "RoomsChatIcon.png";
|
tbpRooms.ImageKey = "RoomsChatIcon.png";
|
||||||
tbpRooms.Location = new Point(4, 24);
|
tbpRooms.Location = new Point(4, 24);
|
||||||
@ -163,17 +175,6 @@
|
|||||||
tbpRooms.Text = "Rooms";
|
tbpRooms.Text = "Rooms";
|
||||||
tbpRooms.UseVisualStyleBackColor = true;
|
tbpRooms.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// btnAddRoom
|
|
||||||
//
|
|
||||||
btnAddRoom.FlatAppearance.BorderSize = 0;
|
|
||||||
btnAddRoom.FlatStyle = FlatStyle.Flat;
|
|
||||||
btnAddRoom.Location = new Point(342, 485);
|
|
||||||
btnAddRoom.Name = "btnAddRoom";
|
|
||||||
btnAddRoom.Size = new Size(20, 22);
|
|
||||||
btnAddRoom.TabIndex = 7;
|
|
||||||
btnAddRoom.UseVisualStyleBackColor = true;
|
|
||||||
btnAddRoom.Click += btnAddRoom_Click;
|
|
||||||
//
|
|
||||||
// lbRooms
|
// lbRooms
|
||||||
//
|
//
|
||||||
lbRooms.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
lbRooms.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
@ -493,6 +494,91 @@
|
|||||||
pbDonate.TabStop = false;
|
pbDonate.TabStop = false;
|
||||||
pbDonate.Click += pbDonate_Click;
|
pbDonate.Click += pbDonate_Click;
|
||||||
//
|
//
|
||||||
|
// ctxmAdminUserList
|
||||||
|
//
|
||||||
|
ctxmAdminUserList.Items.AddRange(new ToolStripItem[] { refreshToolStripMenuItem1, toolStripSeparator1, copyUserIDToClipboardToolStripMenuItem, deleteUserToolStripMenuItem, adminDirectMessageToolStripMenuItem });
|
||||||
|
ctxmAdminUserList.Name = "contextMenuStrip1";
|
||||||
|
ctxmAdminUserList.Size = new Size(213, 98);
|
||||||
|
ctxmAdminUserList.Opening += ctxmAdminUserList_Opening;
|
||||||
|
//
|
||||||
|
// refreshToolStripMenuItem1
|
||||||
|
//
|
||||||
|
refreshToolStripMenuItem1.Name = "refreshToolStripMenuItem1";
|
||||||
|
refreshToolStripMenuItem1.Size = new Size(212, 22);
|
||||||
|
refreshToolStripMenuItem1.Text = "Refresh";
|
||||||
|
refreshToolStripMenuItem1.Click += refreshToolStripMenuItem_Click;
|
||||||
|
//
|
||||||
|
// toolStripSeparator1
|
||||||
|
//
|
||||||
|
toolStripSeparator1.Name = "toolStripSeparator1";
|
||||||
|
toolStripSeparator1.Size = new Size(209, 6);
|
||||||
|
//
|
||||||
|
// copyUserIDToClipboardToolStripMenuItem
|
||||||
|
//
|
||||||
|
copyUserIDToClipboardToolStripMenuItem.Name = "copyUserIDToClipboardToolStripMenuItem";
|
||||||
|
copyUserIDToClipboardToolStripMenuItem.Size = new Size(212, 22);
|
||||||
|
copyUserIDToClipboardToolStripMenuItem.Text = "Copy User ID To Clipboard";
|
||||||
|
copyUserIDToClipboardToolStripMenuItem.Click += copyUserIDToClipboardToolStripMenuItem_Click;
|
||||||
|
//
|
||||||
|
// deleteUserToolStripMenuItem
|
||||||
|
//
|
||||||
|
deleteUserToolStripMenuItem.Name = "deleteUserToolStripMenuItem";
|
||||||
|
deleteUserToolStripMenuItem.Size = new Size(212, 22);
|
||||||
|
deleteUserToolStripMenuItem.Text = "Delete User";
|
||||||
|
deleteUserToolStripMenuItem.Click += deleteUserToolStripMenuItem_Click;
|
||||||
|
//
|
||||||
|
// adminDirectMessageToolStripMenuItem
|
||||||
|
//
|
||||||
|
adminDirectMessageToolStripMenuItem.Name = "adminDirectMessageToolStripMenuItem";
|
||||||
|
adminDirectMessageToolStripMenuItem.Size = new Size(212, 22);
|
||||||
|
adminDirectMessageToolStripMenuItem.Text = "Admin Direct Message";
|
||||||
|
adminDirectMessageToolStripMenuItem.Click += adminDirectMessageToolStripMenuItem_Click;
|
||||||
|
//
|
||||||
|
// ctxmAdminRoomList
|
||||||
|
//
|
||||||
|
ctxmAdminRoomList.Items.AddRange(new ToolStripItem[] { toolStripMenuItem1, toolStripSeparator2, addRoomToolStripMenuItem, deleteRoomToolStripMenuItem });
|
||||||
|
ctxmAdminRoomList.Name = "contextMenuStrip1";
|
||||||
|
ctxmAdminRoomList.Size = new Size(143, 76);
|
||||||
|
ctxmAdminRoomList.Opening += ctxmAdminRoomList_Opening;
|
||||||
|
//
|
||||||
|
// toolStripMenuItem1
|
||||||
|
//
|
||||||
|
toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||||
|
toolStripMenuItem1.Size = new Size(142, 22);
|
||||||
|
toolStripMenuItem1.Text = "Refresh";
|
||||||
|
toolStripMenuItem1.Click += refreshToolStripMenuItem_Click;
|
||||||
|
//
|
||||||
|
// toolStripSeparator2
|
||||||
|
//
|
||||||
|
toolStripSeparator2.Name = "toolStripSeparator2";
|
||||||
|
toolStripSeparator2.Size = new Size(139, 6);
|
||||||
|
//
|
||||||
|
// addRoomToolStripMenuItem
|
||||||
|
//
|
||||||
|
addRoomToolStripMenuItem.Name = "addRoomToolStripMenuItem";
|
||||||
|
addRoomToolStripMenuItem.Size = new Size(142, 22);
|
||||||
|
addRoomToolStripMenuItem.Text = "Add Room";
|
||||||
|
addRoomToolStripMenuItem.Click += addRoomToolStripMenuItem_Click;
|
||||||
|
//
|
||||||
|
// deleteRoomToolStripMenuItem
|
||||||
|
//
|
||||||
|
deleteRoomToolStripMenuItem.Name = "deleteRoomToolStripMenuItem";
|
||||||
|
deleteRoomToolStripMenuItem.Size = new Size(142, 22);
|
||||||
|
deleteRoomToolStripMenuItem.Text = "Delete Room";
|
||||||
|
deleteRoomToolStripMenuItem.Click += deleteRoomToolStripMenuItem_Click;
|
||||||
|
//
|
||||||
|
// lblConnectionLost
|
||||||
|
//
|
||||||
|
lblConnectionLost.AutoSize = true;
|
||||||
|
lblConnectionLost.Font = new Font("Segoe UI", 6F, FontStyle.Bold);
|
||||||
|
lblConnectionLost.ForeColor = Color.Red;
|
||||||
|
lblConnectionLost.Location = new Point(12, 67);
|
||||||
|
lblConnectionLost.Name = "lblConnectionLost";
|
||||||
|
lblConnectionLost.Size = new Size(175, 11);
|
||||||
|
lblConnectionLost.TabIndex = 15;
|
||||||
|
lblConnectionLost.Text = "Server Connection Lost. Trying To Reconnect...";
|
||||||
|
lblConnectionLost.Visible = false;
|
||||||
|
//
|
||||||
// Main
|
// Main
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
@ -504,6 +590,7 @@
|
|||||||
Controls.Add(pCurrencyArea);
|
Controls.Add(pCurrencyArea);
|
||||||
Controls.Add(lblRequestNotif);
|
Controls.Add(lblRequestNotif);
|
||||||
Controls.Add(tbcMain);
|
Controls.Add(tbcMain);
|
||||||
|
Controls.Add(lblConnectionLost);
|
||||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||||
MaximizeBox = false;
|
MaximizeBox = false;
|
||||||
@ -528,6 +615,8 @@
|
|||||||
pCurrentUser.PerformLayout();
|
pCurrentUser.PerformLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)pbUserPfp).EndInit();
|
((System.ComponentModel.ISupportInitialize)pbUserPfp).EndInit();
|
||||||
((System.ComponentModel.ISupportInitialize)pbDonate).EndInit();
|
((System.ComponentModel.ISupportInitialize)pbDonate).EndInit();
|
||||||
|
ctxmAdminUserList.ResumeLayout(false);
|
||||||
|
ctxmAdminRoomList.ResumeLayout(false);
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
PerformLayout();
|
PerformLayout();
|
||||||
}
|
}
|
||||||
@ -548,7 +637,6 @@
|
|||||||
private ToolStripMenuItem awayToolStripMenuItem;
|
private ToolStripMenuItem awayToolStripMenuItem;
|
||||||
private ToolStripMenuItem doNotDisturbToolStripMenuItem;
|
private ToolStripMenuItem doNotDisturbToolStripMenuItem;
|
||||||
private ToolStripMenuItem invisibleToolStripMenuItem;
|
private ToolStripMenuItem invisibleToolStripMenuItem;
|
||||||
private Button btnAddRoom;
|
|
||||||
private LinkLabel llblClaimSpin;
|
private LinkLabel llblClaimSpin;
|
||||||
private Panel pCurrencyArea;
|
private Panel pCurrencyArea;
|
||||||
private Panel pCurrentUser;
|
private Panel pCurrentUser;
|
||||||
@ -571,5 +659,17 @@
|
|||||||
private TabPage tbpStore;
|
private TabPage tbpStore;
|
||||||
private ListView lvStoreItems;
|
private ListView lvStoreItems;
|
||||||
private ImageList ilStoreThumbnails;
|
private ImageList ilStoreThumbnails;
|
||||||
|
private ContextMenuStrip ctxmAdminUserList;
|
||||||
|
private ToolStripMenuItem refreshToolStripMenuItem1;
|
||||||
|
private ToolStripSeparator toolStripSeparator1;
|
||||||
|
private ToolStripMenuItem copyUserIDToClipboardToolStripMenuItem;
|
||||||
|
private ToolStripMenuItem deleteUserToolStripMenuItem;
|
||||||
|
private ToolStripMenuItem adminDirectMessageToolStripMenuItem;
|
||||||
|
private ContextMenuStrip ctxmAdminRoomList;
|
||||||
|
private ToolStripMenuItem toolStripMenuItem1;
|
||||||
|
private ToolStripSeparator toolStripSeparator2;
|
||||||
|
private ToolStripMenuItem addRoomToolStripMenuItem;
|
||||||
|
private ToolStripMenuItem deleteRoomToolStripMenuItem;
|
||||||
|
private Label lblConnectionLost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ using qtc_net_client_2.Services;
|
|||||||
using qtc_net_client_2.ClientModel;
|
using qtc_net_client_2.ClientModel;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using QtCNETAPI.Schema;
|
using QtCNETAPI.Schema;
|
||||||
|
using QtCNETAPI.Services;
|
||||||
|
|
||||||
namespace qtc_net_client_2
|
namespace qtc_net_client_2
|
||||||
{
|
{
|
||||||
@ -15,7 +16,9 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
private IApiService _apiService;
|
private IApiService _apiService;
|
||||||
private IGatewayService _gatewayService;
|
private IGatewayService _gatewayService;
|
||||||
|
|
||||||
private Config _config;
|
private Config _config;
|
||||||
|
private ServerConfig _serverConfig;
|
||||||
private AudioService AudioService = new();
|
private AudioService AudioService = new();
|
||||||
private LoggingService LoggingService;
|
private LoggingService LoggingService;
|
||||||
|
|
||||||
@ -169,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -293,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,6 +387,8 @@ namespace qtc_net_client_2
|
|||||||
var storeItems = await _apiService.GetStoreItems();
|
var storeItems = await _apiService.GetStoreItems();
|
||||||
if (storeItems != null && storeItems.Success && storeItems.Data != null)
|
if (storeItems != null && storeItems.Success && storeItems.Data != null)
|
||||||
{
|
{
|
||||||
|
if (lvStoreItems.Items.Count == storeItems.Data.Count) return;
|
||||||
|
|
||||||
ilStoreThumbnails.Images.Clear();
|
ilStoreThumbnails.Images.Clear();
|
||||||
foreach (var item in storeItems.Data)
|
foreach (var item in storeItems.Data)
|
||||||
{
|
{
|
||||||
@ -359,7 +398,6 @@ namespace qtc_net_client_2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else lvStoreItems.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void lvStoreItems_DoubleClick(object sender, EventArgs e)
|
private async void lvStoreItems_DoubleClick(object sender, EventArgs e)
|
||||||
@ -367,11 +405,11 @@ namespace qtc_net_client_2
|
|||||||
if (lvStoreItems.SelectedItems.Count > 0)
|
if (lvStoreItems.SelectedItems.Count > 0)
|
||||||
{
|
{
|
||||||
string? itemSelected = (string?)lvStoreItems.SelectedItems[lvStoreItems.SelectedItems.Count - 1].Name;
|
string? itemSelected = (string?)lvStoreItems.SelectedItems[lvStoreItems.SelectedItems.Count - 1].Name;
|
||||||
if(itemSelected != null)
|
if (itemSelected != null)
|
||||||
{
|
{
|
||||||
// get item
|
// get item
|
||||||
var item = await _apiService.GetStoreItem(int.Parse(itemSelected));
|
var item = await _apiService.GetStoreItem(int.Parse(itemSelected));
|
||||||
if(item != null && item.Success && item.Data != null)
|
if (item != null && item.Success && item.Data != null)
|
||||||
{
|
{
|
||||||
StoreItemDisplay storeItemDisplay = new StoreItemDisplay(item.Data, LoggingService, _apiService);
|
StoreItemDisplay storeItemDisplay = new StoreItemDisplay(item.Data, LoggingService, _apiService);
|
||||||
storeItemDisplay.ShowDialog();
|
storeItemDisplay.ShowDialog();
|
||||||
@ -380,6 +418,153 @@ namespace qtc_net_client_2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addRoomToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
CreateRoom createRoom = new CreateRoom(_apiService);
|
||||||
|
createRoom.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ctxmAdminRoomList_Opening(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
|
{
|
||||||
|
if (lbRooms.SelectedItem == null)
|
||||||
|
deleteRoomToolStripMenuItem.Enabled = false;
|
||||||
|
else deleteRoomToolStripMenuItem.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ctxmAdminUserList_Opening(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
|
{
|
||||||
|
if (lvUserDirectory.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
string? lvUserDirectoryItemSelected = (string?)lvUserDirectory.SelectedItems[lvUserDirectory.SelectedItems.Count - 1].Text;
|
||||||
|
if (lvUserDirectoryItemSelected != null && lvUserDirectoryItemSelected == _apiService.CurrentUser.Username)
|
||||||
|
{
|
||||||
|
deleteUserToolStripMenuItem.Enabled = false;
|
||||||
|
adminDirectMessageToolStripMenuItem.Enabled = false;
|
||||||
|
copyUserIDToClipboardToolStripMenuItem.Enabled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
deleteUserToolStripMenuItem.Enabled = false;
|
||||||
|
adminDirectMessageToolStripMenuItem.Enabled = false;
|
||||||
|
copyUserIDToClipboardToolStripMenuItem.Enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteUserToolStripMenuItem.Enabled = true;
|
||||||
|
adminDirectMessageToolStripMenuItem.Enabled = true;
|
||||||
|
copyUserIDToClipboardToolStripMenuItem.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void copyUserIDToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lvUserDirectory.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
string? itemSelected = (string?)lvUserDirectory.SelectedItems[lvUserDirectory.SelectedItems.Count - 1].Text;
|
||||||
|
if (itemSelected != null)
|
||||||
|
{
|
||||||
|
// get user
|
||||||
|
var user = UserDirectory.FirstOrDefault(e => e.Username == itemSelected);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
// clipboard requires STA apartment state
|
||||||
|
Thread thread = new(delegate () { Clipboard.SetText(user.Id); });
|
||||||
|
thread.SetApartmentState(ApartmentState.STA);
|
||||||
|
thread.Start();
|
||||||
|
|
||||||
|
MessageBox.Show("Copied!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void deleteRoomToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lbRooms.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
string? itemSelected = (string?)lbRooms.SelectedItems[lbRooms.SelectedItems.Count - 1];
|
||||||
|
if (itemSelected != null)
|
||||||
|
{
|
||||||
|
var dialogResult = MessageBox.Show("Are You Sure You Want To Delete This Room?\nThis will kick everyone currently in the room out.",
|
||||||
|
"are you sure..?",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Question);
|
||||||
|
|
||||||
|
if (dialogResult == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
// get the room
|
||||||
|
var room = RoomList.FirstOrDefault(e => e.Name == itemSelected);
|
||||||
|
if (room != null)
|
||||||
|
{
|
||||||
|
var apiResult = await _apiService.DeleteRoomAsync(room.Id);
|
||||||
|
if (apiResult != null && apiResult.Success)
|
||||||
|
MessageBox.Show("Deleted!");
|
||||||
|
else
|
||||||
|
MessageBox.Show("There was an error deleting the room. Try Again?", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
else MessageBox.Show("This room is unknown. It may have already been deleted.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void deleteUserToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lvUserDirectory.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
string? itemSelected = (string?)lvUserDirectory.SelectedItems[lvUserDirectory.SelectedItems.Count - 1].Text;
|
||||||
|
if (itemSelected != null)
|
||||||
|
{
|
||||||
|
var dialogResult = MessageBox.Show("Are You Sure You Want To Delete This User?\n" +
|
||||||
|
"This should only be done as a last resort. You should take the proper percautions to ensure the user cannot make a new account.\n" +
|
||||||
|
"Proper moderation tools are coming soon.\n" +
|
||||||
|
"Doing this will also log out the user if they are logged in.",
|
||||||
|
"are you sure...?",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Warning);
|
||||||
|
|
||||||
|
if (dialogResult == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
// get the user
|
||||||
|
var user = UserDirectory.FirstOrDefault(e => e.Username == itemSelected);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
var apiResult = await _apiService.DeleteUserById(user.Id);
|
||||||
|
if (apiResult != null && apiResult.Success)
|
||||||
|
MessageBox.Show("User Deleted!");
|
||||||
|
else
|
||||||
|
MessageBox.Show("There was an error deleting the user. Try Again?", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
else MessageBox.Show("This user is unknown. They may have already been deleted.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void adminDirectMessageToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lvUserDirectory.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
string? itemSelected = (string?)lvUserDirectory.SelectedItems[lvUserDirectory.SelectedItems.Count - 1].Text;
|
||||||
|
if (itemSelected != null)
|
||||||
|
{
|
||||||
|
// get the user
|
||||||
|
var user = UserDirectory.FirstOrDefault(e => e.Username == itemSelected);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
var userDto = await _apiService.GetUserInformationAsync(user.Id);
|
||||||
|
if(userDto != null && userDto.Success && userDto.Data != null)
|
||||||
|
{
|
||||||
|
// immediately start a dm chat with the user, the user will be informed immediately if the user is an admin
|
||||||
|
DirectMessage directMessage = new DirectMessage(_gatewayService, _apiService, userDto.Data, null);
|
||||||
|
directMessage.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task OnSuccessfulLogin()
|
private async Task OnSuccessfulLogin()
|
||||||
{
|
{
|
||||||
// double check
|
// double check
|
||||||
@ -400,12 +585,14 @@ namespace qtc_net_client_2
|
|||||||
_gatewayService.OnRefreshRoomListReceived += _gatewayService_OnRefreshRoomListReceived;
|
_gatewayService.OnRefreshRoomListReceived += _gatewayService_OnRefreshRoomListReceived;
|
||||||
_gatewayService.OnRefreshContactsListReceived += _gatewayService_OnRefreshContactsListReceived;
|
_gatewayService.OnRefreshContactsListReceived += _gatewayService_OnRefreshContactsListReceived;
|
||||||
_gatewayService.OnServerConfigReceived += _gatewayService_OnServerConfigReceived;
|
_gatewayService.OnServerConfigReceived += _gatewayService_OnServerConfigReceived;
|
||||||
|
_gatewayService.OnUserForceLogout += _gatewayService_OnUserForceLogout;
|
||||||
|
|
||||||
_apiService.OnCurrentUserUpdate += _apiService_OnCurrentUserUpdate;
|
_apiService.OnCurrentUserUpdate += _apiService_OnCurrentUserUpdate;
|
||||||
|
|
||||||
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
|
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
|
||||||
{
|
{
|
||||||
LoggingService.LogString("Connected To SignalR Succesfully.");
|
LoggingService.LogString("Connected To SignalR Succesfully.");
|
||||||
|
LoggingService.LogString("Building UI...");
|
||||||
|
|
||||||
// we are fully logged in, get current user profile pic and set up ui
|
// we are fully logged in, get current user profile pic and set up ui
|
||||||
llblSignIn.Visible = false;
|
llblSignIn.Visible = false;
|
||||||
@ -427,13 +614,14 @@ namespace qtc_net_client_2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lvUserDirectory.Items.Count <= 0)
|
||||||
|
await RefreshUsers(); // prevent edge case where the refresh event never gets sent to connecting client
|
||||||
|
|
||||||
await RefreshContactsList();
|
await RefreshContactsList();
|
||||||
await RefreshRoomsList();
|
await RefreshRoomsList();
|
||||||
|
|
||||||
// TODO - figure out server side why online status is invisible on login
|
|
||||||
_apiService.CurrentUser.Status = 1;
|
|
||||||
|
|
||||||
// set status context menu checked
|
// set status context menu checked
|
||||||
|
// TODO - figure out more efficient way to do this
|
||||||
UserStatus cuStatus = (UserStatus)_apiService.CurrentUser.Status;
|
UserStatus cuStatus = (UserStatus)_apiService.CurrentUser.Status;
|
||||||
switch (cuStatus)
|
switch (cuStatus)
|
||||||
{
|
{
|
||||||
@ -463,15 +651,19 @@ namespace qtc_net_client_2
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_apiService.CurrentUser.Role == "Admin") btnAddRoom.Enabled = true;
|
|
||||||
else btnAddRoom.Enabled = false;
|
|
||||||
|
|
||||||
var current = DateTime.UtcNow;
|
var current = DateTime.UtcNow;
|
||||||
if (current > _apiService.CurrentUser.LastCurrencySpin.ToUniversalTime() || _apiService.CurrentUser.LastCurrencySpin == new DateTime()) llblClaimSpin.Visible = true;
|
if (current > _apiService.CurrentUser.LastCurrencySpin.ToUniversalTime() || _apiService.CurrentUser.LastCurrencySpin == new DateTime()) llblClaimSpin.Visible = true;
|
||||||
else llblClaimSpin.Visible = false;
|
else llblClaimSpin.Visible = false;
|
||||||
|
|
||||||
if (_config.StartMinimized) WindowState = FormWindowState.Minimized;
|
if (_config.StartMinimized) WindowState = FormWindowState.Minimized;
|
||||||
|
|
||||||
|
if (_apiService.CurrentUser.Role == "Admin")
|
||||||
|
{
|
||||||
|
LoggingService.LogString("Current User Is An Admin. Using Admin Context Menu Strips...");
|
||||||
|
lvUserDirectory.ContextMenuStrip = ctxmAdminUserList;
|
||||||
|
lbRooms.ContextMenuStrip = ctxmAdminRoomList;
|
||||||
|
}
|
||||||
|
|
||||||
LoggingService.LogString("Client Ready");
|
LoggingService.LogString("Client Ready");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -481,29 +673,30 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
LoggingService.LogString("Refreshing All Users List...");
|
LoggingService.LogString("Refreshing All Users List...");
|
||||||
|
|
||||||
// get all users on server
|
if (IsHandleCreated && !IsDisposed)
|
||||||
var userList = await _apiService.GetAllUsersAsync();
|
|
||||||
|
|
||||||
if (userList != null && userList.Success && userList.Data != null)
|
|
||||||
{
|
{
|
||||||
// clear the list
|
await Invoke(async delegate ()
|
||||||
if (lvUserDirectory.InvokeRequired) lvUserDirectory.BeginInvoke(lvUserDirectory.Items.Clear);
|
|
||||||
else lvUserDirectory.Items.Clear();
|
|
||||||
UserDirectory.Clear();
|
|
||||||
|
|
||||||
// populate list
|
|
||||||
foreach (var user in userList.Data)
|
|
||||||
{
|
{
|
||||||
if (lvUserDirectory.InvokeRequired)
|
// get all users on server
|
||||||
|
var userList = await _apiService.GetAllUsersAsync();
|
||||||
|
|
||||||
|
if (userList != null && userList.Success && userList.Data != null)
|
||||||
{
|
{
|
||||||
lvUserDirectory.BeginInvoke(delegate () { lvUserDirectory.Items.Add(user.Username, user.Status); });
|
// clear the list
|
||||||
|
lvUserDirectory.Items.Clear();
|
||||||
|
UserDirectory.Clear();
|
||||||
|
|
||||||
|
// populate list
|
||||||
|
foreach (var user in userList.Data)
|
||||||
|
{
|
||||||
|
lvUserDirectory.Items.Add(user.Username, user.Status);
|
||||||
|
UserDirectory.Add(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (System.Diagnostics.Debugger.IsAttached || _config.EnableDebugLogs)
|
||||||
|
LoggingService.LogModel(userList.Data);
|
||||||
}
|
}
|
||||||
else
|
});
|
||||||
{
|
|
||||||
lvUserDirectory.Items.Add(user.Username, user.Status);
|
|
||||||
}
|
|
||||||
UserDirectory.Add(user);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,7 +704,7 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
LoggingService.LogString("Refreshing Rooms List...");
|
LoggingService.LogString("Refreshing Rooms List...");
|
||||||
|
|
||||||
if (InvokeRequired)
|
if (IsHandleCreated && !IsDisposed)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
{
|
{
|
||||||
@ -524,35 +717,21 @@ namespace qtc_net_client_2
|
|||||||
lbRooms.Items.Add(room.Name);
|
lbRooms.Items.Add(room.Name);
|
||||||
}
|
}
|
||||||
RoomList = roomsRes.Data;
|
RoomList = roomsRes.Data;
|
||||||
|
if (System.Diagnostics.Debugger.IsAttached || _config.EnableDebugLogs)
|
||||||
|
LoggingService.LogModel(roomsRes.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// always add lobby room to rooms list
|
// always add lobby room to rooms list
|
||||||
lbRooms.Items.Add("Lobby");
|
lbRooms.Items.Add("Lobby");
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lbRooms.Items.Clear();
|
|
||||||
var roomsRes = await _apiService.GetAllRoomsAsync();
|
|
||||||
if (roomsRes.Success && roomsRes.Data != null)
|
|
||||||
{
|
|
||||||
lbRooms.Items.Clear();
|
|
||||||
foreach (var room in roomsRes.Data)
|
|
||||||
{
|
|
||||||
lbRooms.Items.Add(room.Name);
|
|
||||||
}
|
|
||||||
RoomList = roomsRes.Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// always add lobby room to rooms list
|
|
||||||
lbRooms.Items.Add("Lobby");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshContactsList()
|
private async Task RefreshContactsList()
|
||||||
{
|
{
|
||||||
LoggingService.LogString("Refreshing Contacts List...");
|
LoggingService.LogString("Refreshing Contacts List...");
|
||||||
|
|
||||||
if (InvokeRequired)
|
if (IsHandleCreated && !IsDisposed)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
{
|
{
|
||||||
@ -621,76 +800,11 @@ namespace qtc_net_client_2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (System.Diagnostics.Debugger.IsAttached || _config.EnableDebugLogs)
|
||||||
|
LoggingService.LogModel(contactsRes.Data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lvContacts.Items.Clear();
|
|
||||||
Contacts.Clear();
|
|
||||||
lblRequestNotif.Visible = false;
|
|
||||||
var contactsRes = await _apiService.GetCurrentUserContacts();
|
|
||||||
if (contactsRes.Success && contactsRes.Data != null)
|
|
||||||
{
|
|
||||||
if (contactsRes.Data.Where(e => e.UserId == _apiService.CurrentUser!.Id && e.UserStatus == Contact.ContactStatus.AwaitingApprovalFromSelf).Count() >= 1)
|
|
||||||
lblRequestNotif.Visible = true;
|
|
||||||
else
|
|
||||||
lblRequestNotif.Visible = false;
|
|
||||||
|
|
||||||
foreach (var contact in contactsRes.Data)
|
|
||||||
{
|
|
||||||
ServiceResponse<UserInformationDto> user = null!;
|
|
||||||
if (contact.OwnerId == _apiService.CurrentUser!.Id)
|
|
||||||
user = await _apiService.GetUserInformationAsync(contact.UserId);
|
|
||||||
else if (contact.UserId == _apiService.CurrentUser!.Id)
|
|
||||||
user = await _apiService.GetUserInformationAsync(contact.OwnerId);
|
|
||||||
|
|
||||||
if (user.Data != null)
|
|
||||||
{
|
|
||||||
Contacts.Add(contact);
|
|
||||||
if (contact.OwnerId == _apiService.CurrentUser!.Id)
|
|
||||||
{
|
|
||||||
switch (contact.OwnerStatus)
|
|
||||||
{
|
|
||||||
case Contact.ContactStatus.AwaitingApprovalFromOther:
|
|
||||||
var lvi = lvContacts.Items.Add($"{user.Data.Username} [Request Sent]");
|
|
||||||
await AddProfilePicToList(user.Data.Id);
|
|
||||||
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
|
|
||||||
lvi.ImageKey = user.Data.Id;
|
|
||||||
else lvi.ImageKey = "DEFAULT";
|
|
||||||
break;
|
|
||||||
case Contact.ContactStatus.Accepted:
|
|
||||||
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
|
|
||||||
await AddProfilePicToList(user.Data.Id);
|
|
||||||
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
|
|
||||||
lvi2.ImageKey = user.Data.Id;
|
|
||||||
else lvi2.ImageKey = "DEFAULT";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (contact.UserId == _apiService.CurrentUser!.Id)
|
|
||||||
{
|
|
||||||
switch (contact.UserStatus)
|
|
||||||
{
|
|
||||||
case Contact.ContactStatus.AwaitingApprovalFromSelf:
|
|
||||||
var lvi = lvContacts.Items.Add($"{user.Data.Username} [Contact Request]");
|
|
||||||
await AddProfilePicToList(user.Data.Id);
|
|
||||||
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
|
|
||||||
lvi.ImageKey = user.Data.Id;
|
|
||||||
else lvi.ImageKey = "DEFAULT";
|
|
||||||
AudioService.PlaySoundEffect("sndContactRequest");
|
|
||||||
break;
|
|
||||||
case Contact.ContactStatus.Accepted:
|
|
||||||
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
|
|
||||||
await AddProfilePicToList(user.Data.Id);
|
|
||||||
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
|
|
||||||
lvi2.ImageKey = user.Data.Id;
|
|
||||||
else lvi2.ImageKey = "DEFAULT";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,11 +812,9 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (!IsHandleCreated) { LoggingService.LogString("Form Handle Wasn't Created"); return; }
|
if(IsHandleCreated && !IsDisposed)
|
||||||
|
|
||||||
if (InvokeRequired && !IsDisposed)
|
|
||||||
{
|
{
|
||||||
BeginInvoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
{
|
{
|
||||||
label.ForeColor = Color.Red;
|
label.ForeColor = Color.Red;
|
||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
@ -710,11 +822,6 @@ namespace qtc_net_client_2
|
|||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
label.ForeColor = Color.Red;
|
|
||||||
await Task.Delay(500);
|
|
||||||
label.ForeColor = Color.Blue;
|
|
||||||
await Task.Delay(500);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,16 +864,9 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
public void RefreshCurrencyCounter()
|
public void RefreshCurrencyCounter()
|
||||||
{
|
{
|
||||||
if (lblCurrencyAmount.InvokeRequired)
|
if (IsHandleCreated && !IsDisposed)
|
||||||
{
|
{
|
||||||
lblCurrencyAmount.BeginInvoke(delegate ()
|
Invoke(delegate () { lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString("N0"); });
|
||||||
{
|
|
||||||
lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString("N0");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString("N0");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -785,9 +885,9 @@ namespace qtc_net_client_2
|
|||||||
await _gatewayService.StartAsync();
|
await _gatewayService.StartAsync();
|
||||||
|
|
||||||
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
|
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
|
||||||
{ BeginInvoke(delegate () { Enabled = true; }); return; }
|
{ BeginInvoke(delegate () { tbcMain.Enabled = true; lblConnectionLost.Visible = false; }); return; }
|
||||||
|
|
||||||
ConnectionClosed frmConnectionClosed = new ConnectionClosed(error);
|
ConnectionClosed frmConnectionClosed = new ConnectionClosed();
|
||||||
var result = frmConnectionClosed.ShowDialog();
|
var result = frmConnectionClosed.ShowDialog();
|
||||||
|
|
||||||
if (result == DialogResult.OK)
|
if (result == DialogResult.OK)
|
||||||
@ -796,18 +896,19 @@ namespace qtc_net_client_2
|
|||||||
Reconnect:
|
Reconnect:
|
||||||
if (_gatewayService.HubConnection != null)
|
if (_gatewayService.HubConnection != null)
|
||||||
{
|
{
|
||||||
try
|
await _gatewayService.StopAsync();
|
||||||
|
await _gatewayService.StartAsync();
|
||||||
|
|
||||||
|
if (_gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
|
||||||
{
|
{
|
||||||
await _gatewayService.StopAsync();
|
Invoke(delegate () { tbcMain.Enabled = true; lblConnectionLost.Visible = false; });
|
||||||
await _gatewayService.StartAsync();
|
|
||||||
if (_gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
|
|
||||||
BeginInvoke(delegate () { Enabled = true; });
|
|
||||||
}
|
}
|
||||||
catch (HttpRequestException ex)
|
else
|
||||||
{
|
{
|
||||||
// reshow the dialog
|
// reshow the dialog
|
||||||
frmConnectionClosed.Reason = ex.Message;
|
frmConnectionClosed.StatusLabel.Text = "Couldn't Reconnect. The Server Could Be Down.";
|
||||||
var result1 = frmConnectionClosed.ShowDialog();
|
var result1 = frmConnectionClosed.ShowDialog();
|
||||||
|
|
||||||
if (result1 == DialogResult.OK) goto Reconnect;
|
if (result1 == DialogResult.OK) goto Reconnect;
|
||||||
else Environment.Exit(0);
|
else Environment.Exit(0);
|
||||||
}
|
}
|
||||||
@ -816,8 +917,47 @@ namespace qtc_net_client_2
|
|||||||
else Environment.Exit(0);
|
else Environment.Exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _gatewayService_OnServerReconnecting(object? sender, EventArgs e) => BeginInvoke(delegate () { Enabled = false; });
|
private void _gatewayService_OnServerReconnecting(object? sender, EventArgs e)
|
||||||
private void _gatewayService_OnServerReconnected(object? sender, EventArgs e) => BeginInvoke(delegate () { Enabled = true; });
|
{
|
||||||
|
var args = (ServerConnectionReconnectingEventArgs)e;
|
||||||
|
|
||||||
|
if (args.Error == null)
|
||||||
|
LoggingService.LogString("Server Requested Reconnect. Reconnecting...");
|
||||||
|
else
|
||||||
|
LoggingService.LogString($"SignalR Reconnecting Due To An Error.\n{args.Error.Message}\n{args.Error.StackTrace}");
|
||||||
|
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
|
{
|
||||||
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
tbcMain.Enabled = false;
|
||||||
|
lblConnectionLost.Visible = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void _gatewayService_OnServerReconnected(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
LoggingService.LogString("SignalR Reconnected");
|
||||||
|
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
|
{
|
||||||
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
tbcMain.Enabled = true;
|
||||||
|
lblConnectionLost.Visible = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure status is set to whatever the current user was set to
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _gatewayService.UpdateStatus(_apiService.CurrentUser.Status);
|
||||||
|
} catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
LoggingService.LogString("Could Not Set Status Back To Online");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void _gatewayService_OnServerConfigReceived(object? sender, EventArgs e)
|
private async void _gatewayService_OnServerConfigReceived(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@ -826,8 +966,11 @@ namespace qtc_net_client_2
|
|||||||
LoggingService.LogString($"Server Config Received");
|
LoggingService.LogString($"Server Config Received");
|
||||||
LoggingService.LogModel(args.ServerConfig);
|
LoggingService.LogModel(args.ServerConfig);
|
||||||
|
|
||||||
|
if (_serverConfig != null) return; // only set server config upon client restart, not during reconnect (preventing log spam)
|
||||||
|
|
||||||
if (args.ServerConfig != null)
|
if (args.ServerConfig != null)
|
||||||
{
|
{
|
||||||
|
_serverConfig = args.ServerConfig;
|
||||||
if (args.ServerConfig.IsDown)
|
if (args.ServerConfig.IsDown)
|
||||||
{
|
{
|
||||||
LoggingService.LogString("Server Is Marked As Down");
|
LoggingService.LogString("Server Is Marked As Down");
|
||||||
@ -863,6 +1006,17 @@ namespace qtc_net_client_2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void _gatewayService_OnUserForceLogout(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Connection To Server Lost. You Were Logged Out.\nTry Signing In Again.\nThe Application Will Now Close.", "oops.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
|
||||||
|
await _gatewayService.StopAsync();
|
||||||
|
|
||||||
|
if (File.Exists("./session.token")) File.Delete("./session.token");
|
||||||
|
|
||||||
|
Environment.Exit(0); // dont want the user to try and make a new account right away
|
||||||
|
}
|
||||||
|
|
||||||
private void _apiService_OnCurrentUserUpdate(object? sender, EventArgs e)
|
private void _apiService_OnCurrentUserUpdate(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
lblWelcome.Text = $"Welcome, {_apiService.CurrentUser.Username}";
|
lblWelcome.Text = $"Welcome, {_apiService.CurrentUser.Username}";
|
||||||
|
@ -128,7 +128,7 @@
|
|||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA0A0AAAJNU0Z0AUkBTAMBAQAB
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA0A0AAAJNU0Z0AUkBTAMBAQAB
|
||||||
MAEBATABAQEgAQABIAEABP8BIQEACP8BQgFNATYHAAE2AwABKAMAAYADAAEgAwABAQEAASAGAAFAEgAD
|
mAEBAZgBAQEgAQABIAEABP8BIQEACP8BQgFNATYHAAE2AwABKAMAAYADAAEgAwABAQEAASAGAAFAEgAD
|
||||||
rQH/A7oB/wO6Af8DuQH/A7oB/wO6Af8D2gX/A/wB/wP+Df8D/QH/A/wR/wP8Af8D/g3/A/0B/wPZAf8D
|
rQH/A7oB/wO6Af8DuQH/A7oB/wO6Af8D2gX/A/wB/wP+Df8D/QH/A/wR/wP8Af8D/g3/A/0B/wPZAf8D
|
||||||
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af//AIEAA58B/wO6Af8DugH/A7oB/wO6Af8DugH/A9oJ/wP9Af8D
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af//AIEAA58B/wO6Af8DugH/A7oB/wO6Af8DugH/A9oJ/wP9Af8D
|
||||||
/g3/A/0B/wP9Ef8D/AH/A/4N/wPaAf8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af//AIEAA6IB/wO6Af8D
|
/g3/A/0B/wP9Ef8D/AH/A/4N/wPaAf8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af//AIEAA6IB/wO6Af8D
|
||||||
@ -196,92 +196,91 @@
|
|||||||
<value>
|
<value>
|
||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA4hMAAAJNU0Z0AUkBTAIBAQQB
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAohMAAAJNU0Z0AUkBTAIBAQQB
|
||||||
AAHoAQAB6AEAARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABIAYAASD/
|
AAFQAQEBUAEBARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABIAYAASD/
|
||||||
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AC4AAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B
|
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AC4AAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B
|
||||||
0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYB
|
0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYB
|
||||||
BwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekD
|
BwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekD
|
||||||
YAHoA10B0QNQAZ8DMQFNAwUBBhQAAyABLQNUAasDWwHkA1oB9QMkAfsDQQH+A0EB/gMkAfsDUwH0A2IB
|
YAHoA10B0QNQAZ8DMQFNAwUBBhQAAyABLQNUAasDWwHkA1oB9QMkAfsDTgH+A04B/gMkAfsDUwH0A2IB
|
||||||
4QNRAaEDHgEqEAADIAEtA1QBqwNbAeQBUwFaAVMB9QEhAV0BIQH7AR0BXQEdAf4BHQFdAR0B/gEhAV0B
|
4QNRAaEDHgEqEAADIAEtA1QBqwNbAeQDWgH1ASEBXgEhAfsBKgFqASoB/gEqAWoBKgH+ASEBXgEhAfsD
|
||||||
IQH7A1MB9ANiAeEDUQGhAx4BKhAAAyABLQNUAasDWwHkAVMCWgH1ASECXQH7AR0CXQH+AR0CXQH+ASEC
|
UwH0A2IB4QNRAaEDHgEqEAADIAEtA1QBqwNbAeQDWgH1ASECXgH7ASoCagH+ASoCagH+ASECXgH7A1MB
|
||||||
XQH7A1MB9ANiAeEDUQGhAx4BKhAAAyABLQNUAasDWwHkAlMBWgH1AiEBXQH7Ah0BXQH+Ah0BXQH+AiEB
|
9ANiAeEDUQGhAx4BKhAAAyABLQNUAasDWwHkA1oB9QIhAV4B+wIqAWoB/gIqAWoB/gIhAV4B+wNTAfQD
|
||||||
XQH7A1MB9ANiAeEDUQGhAx4BKgwAAxsBJQNYAb0DWgHyA0UB/gMwAf8DOQH/AzwB/wM2Af8DKgH/AyQB
|
YgHhA1EBoQMeASoMAAMbASUDWAG9A1oB8gNSAf4DMAH/AzkB/wM8Af8DNgH/AyoB/wMkAf8DQAH9A14B
|
||||||
/wNAAf0DXgHwA1YBsgMaASMIAAMbASUDWAG9A1oB8gEdAWUBHQH+AQABVwEAAf8BAAFnAQAB/wEAAWwB
|
8ANWAbIDGgEjCAADGwElA1gBvQNaAfIBKgFyASoB/gEAAVcBAAH/AQABZwEAAf8BAAFsAQAB/wEAAWEB
|
||||||
AAH/AQABYQEAAf8BAAFMAQAB/wEAAUABAAH/AToBQAE6Af0DXgHwA1YBsgEZARoBGQEjCAADGwElA1gB
|
AAH/AQABTAEAAf8BAAFAAQAB/wNAAf0DXgHwA1YBsgEZARoBGQEjCAADGwElA1gBvQNaAfIBKgJyAf4B
|
||||||
vQNaAfIBHQJlAf4BAAJXAf8BAAJnAf8BAAJsAf8BAAJhAf8BAAJMAf8BAAJAAf8BOgJAAf0DXgHwA1YB
|
AAJXAf8BAAJnAf8BAAJsAf8BAAJhAf8BAAJMAf8BAAJAAf8DQAH9A14B8ANWAbIBGQIaASMIAAMbASUD
|
||||||
sgEZAhoBIwgAAxsBJQNYAb0DWgHyAh0BZQH+AgABVwH/AgABZwH/AgABbAH/AgABYQH/AgABTAH/AgAB
|
WAG9A1oB8gIqAXIB/gIAAVcB/wIAAWcB/wIAAWwB/wIAAWEB/wIAAUwB/wIAAUAB/wNAAf0DXgHwA1YB
|
||||||
QAH/AjoBQAH9A14B8ANWAbICGQEaASMEAAMDAQQDUgGlA2AB8wNJAf8DVQH/A2UB/wNxAf8DdQH/A3EB
|
sgIZARoBIwQAAwMBBANSAaUDYAHzA0kB/wNVAf8DZQH/A3EB/wN1Af8DcQH/A2QB/wNMAf8DMQH/A04B
|
||||||
/wNkAf8DTAH/AzEB/wNBAf4DYgHuA1ABmgMDAQQDAwEEAVIBUwFSAaUBXQFvAV0B8wEAAYIBAAH/AQAB
|
/gNiAe4DUAGaAwMBBAMDAQQBUgFTAVIBpQFgAW8BYAHzAQABggEAAf8BAAGZAQAB/wEAAbYBAAH/AQAB
|
||||||
mQEAAf8BAAG2AQAB/wEAAcwBAAH/AQAB0wEAAf8BAAHLAQAB/wEAAbMBAAH/AQABiAEAAf8BAAFXAQAB
|
zAEAAf8BAAHTAQAB/wEAAcsBAAH/AQABswEAAf8BAAGIAQAB/wEAAVcBAAH/ASoBagEqAf4DYgHuA1AB
|
||||||
/wEdAV0BHQH+A2IB7gNQAZoDAwEEAwMBBAFSAlMBpQFdAm8B8wEAAoIB/wEAApkB/wEAArYB/wEAAswB
|
mgMDAQQDAwEEAVICUwGlAWACbwHzAQACggH/AQACmQH/AQACtgH/AQACzAH/AQAC0wH/AQACywH/AQAC
|
||||||
/wEAAtMB/wEAAssB/wEAArMB/wEAAogB/wEAAlcB/wEdAl0B/gNiAe4DUAGaAwMBBAMDAQQCUgFTAaUC
|
swH/AQACiAH/AQACVwH/ASoCagH+A2IB7gNQAZoDAwEEAwMBBAJSAVMBpQJgAW8B8wIAAYIB/wIAAZkB
|
||||||
XQFvAfMCAAGCAf8CAAGZAf8CAAG2Af8CAAHMAf8CAAHTAf8CAAHLAf8CAAGzAf8CAAGIAf8CAAFXAf8C
|
/wIAAbYB/wIAAcwB/wIAAdMB/wIAAcsB/wIAAbMB/wIAAYgB/wIAAVcB/wIqAWoB/gNiAe4DUAGaAwMB
|
||||||
HQFdAf4DYgHuA1ABmgMDAQQDLQFEA2AB6AOAAf4DbgH/A3sB/wOFAf8DigH/A4wB/wOKAf8DhQH/A3YB
|
BAMtAUQDYAHoA4AB/gNuAf8DewH/A4UB/wOKAf8DjAH/A4oB/wOFAf8DdgH/A1cB/wMyAf8DQAH9A14B
|
||||||
/wNXAf8DMgH/A0AB/QNeAd0DKgE/Ay0BRAFgAWkBYAHoAR0BgAEdAf4BAAHGAQAB/wEAAdwBAAH/AQAB
|
3QMqAT8DLQFEAWABaQFgAegBKgGAASoB/gEAAcYBAAH/AQAB3AEAAf8BAAHuAQAB/wEAAfgBAAH/AQAB
|
||||||
7gEAAf8BAAH4AQAB/wEAAfsBAAH/AQAB+QEAAf8BAAHvAQAB/wEAAdQBAAH/AQABnAEAAf8BAAFaAQAB
|
+wEAAf8BAAH5AQAB/wEAAe8BAAH/AQAB1AEAAf8BAAGcAQAB/wEAAVoBAAH/A0AB/QNeAd0DKgE/Ay0B
|
||||||
/wE6AUABOgH9A14B3QMqAT8DLQFEAWACaQHoAR0CgAH+AQACxgH/AQAC3AH/AQAC7gH/AQAC+AH/AQAC
|
RAFgAmkB6AEqAoAB/gEAAsYB/wEAAtwB/wEAAu4B/wEAAvgB/wEAAvsB/wEAAvkB/wEAAu8B/wEAAtQB
|
||||||
+wH/AQAC+QH/AQAC7wH/AQAC1AH/AQACnAH/AQACWgH/AToCQAH9A14B3QMqAT8DLQFEAmABaQHoAh0B
|
/wEAApwB/wEAAloB/wNAAf0DXgHdAyoBPwMtAUQCYAFpAegCKgGAAf4CAAHGAf8CAAHcAf8CAAHuAf8C
|
||||||
gAH+AgABxgH/AgAB3AH/AgAB7gH/AgAB+AH/AgAB+wH/AgAB+QH/AgAB7wH/AgAB1AH/AgABnAH/AgAB
|
AAH4Af8CAAH7Af8CAAH5Af8CAAHvAf8CAAHUAf8CAAGcAf8CAAFaAf8DQAH9A14B3QMqAT8DTgGVA3cB
|
||||||
WgH/AjoBQAH9A14B3QMqAT8DTgGVA3cB+AN/Af8DhQH/A4oB/wONAf8DjgH/A44B/wOOAf8DjQH/A4kB
|
+AN/Af8DhQH/A4oB/wONAf8DjgH/A44B/wOOAf8DjQH/A4kB/wN3Af8DTQH/AyUB/wNaAfIDSgGLA04B
|
||||||
/wN3Af8DTQH/AyUB/wNaAfIDSgGLA04BlQFHAXwBRwH4AQAB5QEAAf8BAAHvAQAB/wEAAfgBAAH/AQAB
|
lQFcAXwBXAH4AQAB5QEAAf8BAAHvAQAB/wEAAfgBAAH/AQAB/QEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
/QEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH+AQAB/wEAAfYBAAH/AQAB1QEAAf8BAAGLAQAB
|
/wEAAf8BAAH+AQAB/wEAAfYBAAH/AQAB1QEAAf8BAAGLAQAB/wEAAUEBAAH/A1oB8gNKAYsDTgGVAVwC
|
||||||
/wEAAUEBAAH/A1oB8gNKAYsDTgGVAUcCfAH4AQAC5QH/AQAC7wH/AQAC+AH/AQAC/QH/AQAD/wEAA/8B
|
fAH4AQAC5QH/AQAC7wH/AQAC+AH/AQAC/QH/AQAD/wEAA/8BAAP/AQAC/gH/AQAC9gH/AQAC1QH/AQAC
|
||||||
AAP/AQAC/gH/AQAC9gH/AQAC1QH/AQACiwH/AQACQQH/A1oB8gNKAYsDTgGVAkcBfAH4AgAB5QH/AgAB
|
iwH/AQACQQH/A1oB8gNKAYsDTgGVAlwBfAH4AgAB5QH/AgAB7wH/AgAB+AH/AgAB/QH/AgAC/wIAAv8C
|
||||||
7wH/AgAB+AH/AgAB/QH/AgAC/wIAAv8CAAL/AgAB/gH/AgAB9gH/AgAB1QH/AgABiwH/AgABQQH/A1oB
|
AAL/AgAB/gH/AgAB9gH/AgAB1QH/AgABiwH/AgABQQH/A1oB8gNKAYsDXwHTA34B/AOTAf8DjgH/A40B
|
||||||
8gNKAYsDXwHTA34B/AOTAf8DjgH/A40B/wOOAf8DjgH/A44B/wOOAf8DjgH/A40B/wOFAf8DZwH/AzQB
|
/wOOAf8DjgH/A44B/wOOAf8DjgH/A40B/wOFAf8DZwH/AzQB/wNBAfkDWgHEAVsBXwFbAdMBKwF+ASsB
|
||||||
/wNBAfkDWgHEAVsBXwFbAdMBKwGkASsB/AEOAfsBDgH/AQMB/QEDAf8BAAH+AQAB/wEAAf8BAAH/AQAB
|
/AEOAfsBDgH/AQMB/QEDAf8BAAH+AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH9AQAB/wEAAe8BAAH/AQABuQEAAf8BAAFdAQAB
|
/wEAAf8BAAH9AQAB/wEAAe8BAAH/AQABuQEAAf8BAAFdAQAB/wNBAfkDWgHEAVsCXwHTASsCfgH8AQ4C
|
||||||
/wNBAfkDWgHEAVsCXwHTASsCpAH8AQ4C+wH/AQMC/QH/AQAC/gH/AQAD/wEAA/8BAAP/AQAD/wEAA/8B
|
+wH/AQMC/QH/AQAC/gH/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAL9Af8BAALvAf8BAAK5Af8BAAJdAf8D
|
||||||
AAL9Af8BAALvAf8BAAK5Af8BAAJdAf8DQQH5A1oBxAJbAV8B0wIrAaQB/AIOAfsB/wIDAf0B/wIAAf4B
|
QQH5A1oBxAJbAV8B0wIrAX4B/AIOAfsB/wIDAf0B/wIAAf4B/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAB
|
||||||
/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAB/QH/AgAB7wH/AgABuQH/AgABXQH/A0EB+QNaAcQDbgH1A4AB
|
/QH/AgAB7wH/AgABuQH/AgABXQH/A0EB+QNaAcQDbgH1A4AB/gOfAf8DkwH/A48B/wOOAf8DjgH/A44B
|
||||||
/gOfAf8DkwH/A48B/wOOAf8DjgH/A44B/wOOAf8DjgH/A44B/wOLAf8DdwH/A0gB/wNAAf0DYgHhAVkB
|
/wOOAf8DjgH/A44B/wOLAf8DdwH/A0gB/wNAAf0DYgHhAVoBbgFaAfUBTgGrAU4B/gEnAf8BJwH/AQsB
|
||||||
bgFZAfUBQQHFAUEB/gEnAf8BJwH/AQsB/wELAf8BAQH/AQEB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
/wELAf8BAQH/AQEB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAfkBAAH/AQAB1gEAAf8BAAGBAQAB/wE6AUABOgH9A2IB
|
/wEAAfkBAAH/AQAB1gEAAf8BAAGBAQAB/wNAAf0DYgHhAVoCbgH1AU4CqwH+AScD/wELA/8BAQP/AQAD
|
||||||
4QFZAm4B9QFBAsUB/gEnA/8BCwP/AQED/wEAA/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAAvkB/wEAAtYB
|
/wEAA/8BAAP/AQAD/wEAA/8BAAP/AQAC+QH/AQAC1gH/AQACgQH/A0AB/QNiAeECWgFuAfUCTgGrAf4C
|
||||||
/wEAAoEB/wE6AkAB/QNiAeECWQFuAfUCQQHFAf4CJwL/AgsC/wIBAv8CAAL/AgAC/wIAAv8CAAL/AgAC
|
JwL/AgsC/wIBAv8CAAL/AgAC/wIAAv8CAAL/AgAC/wIAAv8CAAH5Af8CAAHWAf8CAAGBAf8DQAH9A2IB
|
||||||
/wIAAv8CAAH5Af8CAAHWAf8CAAGBAf8COgFAAf0DYgHhA2MB9gOAAf4DqwH/A5kB/wOQAf8DjgH/A44B
|
4QNjAfYDgAH+A6sB/wOZAf8DkAH/A44B/wOOAf8DjgH/A44B/wOOAf8DjgH/A40B/wN/Af8DVQH/A0AB
|
||||||
/wOOAf8DjgH/A44B/wOOAf8DjQH/A38B/wNVAf8DQAH9A14B4gFIAXUBSAH2AWQBxQFkAf4BQgH/AUIB
|
/QNeAeIBSAFjAUgB9gFxAasBcQH+AUIB/wFCAf8BGQH/ARkB/wEEAf8BBAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
/wEZAf8BGQH/AQQB/wEEAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/QEAAf8BAAHkAQAB/wEAAZgBAAH/A0AB
|
||||||
/wEAAf8BAAH9AQAB/wEAAeQBAAH/AQABmAEAAf8BOgFAAToB/QNeAeIBSAJ1AfYBZALFAf4BQgP/ARkD
|
/QNeAeIBSAJjAfYBcQKrAf4BQgP/ARkD/wEEA/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAL9Af8B
|
||||||
/wEEA/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAL9Af8BAALkAf8BAAKYAf8BOgJAAf0DXgHiAkgB
|
AALkAf8BAAKYAf8DQAH9A14B4gJIAWMB9gJxAasB/gJCAv8CGQL/AgQC/wIAAv8CAAL/AgAC/wIAAv8C
|
||||||
dQH2AmQBxQH+AkIC/wIZAv8CBAL/AgAC/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAB/QH/AgAB5AH/AgAB
|
AAL/AgAC/wIAAf0B/wIAAeQB/wIAAZgB/wNAAf0DXgHiA2EB1gN+AfwDuAH/A6MB/wOTAf8DjgH/A44B
|
||||||
mAH/AjoBQAH9A14B4gNhAdYDfgH8A7gB/wOjAf8DkwH/A44B/wOOAf8DjgH/A44B/wOOAf8DjgH/A40B
|
/wOOAf8DjgH/A44B/wOOAf8DjQH/A4IB/wNcAf8DTQH6A1oBxwFcAWEBXAHWAWQBgwFkAfwBXwH/AV8B
|
||||||
/wOCAf8DXAH/A00B+gNaAccBXAFhAVwB1gFkAaoBZAH8AV8B/wFfAf8BLwH/AS8B/wEMAf8BDAH/AQEB
|
/wEvAf8BLwH/AQwB/wEMAf8BAQH/AQEB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
/wEBAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/gEAAf8BAAHqAQAB
|
/wEAAf8BAAH+AQAB/wEAAeoBAAH/AQABpQEAAf8BSAFNAUgB+gNaAccBXAJhAdYBZAKDAfwBXwP/AS8D
|
||||||
/wEAAaUBAAH/ATEBTQExAfoDWgHHAVwCYQHWAWQCqgH8AV8D/wEvA/8BDAP/AQED/wEAA/8BAAP/AQAD
|
/wEMA/8BAQP/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAL+Af8BAALqAf8BAAKlAf8BSAJNAfoDWgHHAlwB
|
||||||
/wEAA/8BAAP/AQAC/gH/AQAC6gH/AQACpQH/ATECTQH6A1oBxwJcAWEB1gJkAaoB/AJfAv8CLwL/AgwC
|
YQHWAmQBgwH8Al8C/wIvAv8CDAL/AgEC/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAB/gH/AgAB6gH/AgAB
|
||||||
/wIBAv8CAAL/AgAC/wIAAv8CAAL/AgAC/wIAAf4B/wIAAeoB/wIAAaUB/wIxAU0B+gNaAccDUAGaA4MB
|
pQH/AkgBTQH6A1oBxwNQAZoDbQH5A8UB/wOyAf8DnAH/A5EB/wOOAf8DjgH/A44B/wOOAf8DjwH/A44B
|
||||||
+QPFAf8DsgH/A5wB/wORAf8DjgH/A44B/wOOAf8DjgH/A48B/wOOAf8DgwH/A2AB/wNaAfIDTAGQA1AB
|
/wODAf8DYAH/A1oB8gNMAZADUAGaAWoBfwFqAfkBfAH/AXwB/wFRAf8BUQH/AR8B/wEfAf8BBwH/AQcB
|
||||||
mgFqAYwBagH5AXwB/wF8Af8BUQH/AVEB/wEfAf8BHwH/AQcB/wEHAf8BAQH/AQEB/wEAAf8BAAH/AQAB
|
/wEBAf8BAQH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQIB/wECAf8BAgH+AQIB/wEAAesBAAH/AQAB
|
||||||
/wEAAf8BAAH/AQAB/wECAf8BAgH/AQIB/gECAf8BAAHrAQAB/wEAAa0BAAH/AVoBawFaAfIDTAGQA1AB
|
rQEAAf8BWgFrAVoB8gNMAZADUAGaAWoCfwH5AXwD/wFRA/8BHwP/AQcD/wEBA/8BAAP/AQAD/wEAA/8B
|
||||||
mgFqAowB+QF8A/8BUQP/AR8D/wEHA/8BAQP/AQAD/wEAA/8BAAP/AQID/wECAv4B/wEAAusB/wEAAq0B
|
AgP/AQIC/gH/AQAC6wH/AQACrQH/AVoCawHyA0wBkANQAZoCagF/AfkCfAL/AlEC/wIfAv8CBwL/AgEC
|
||||||
/wFaAmsB8gNMAZADUAGaAmoBjAH5AnwC/wJRAv8CHwL/AgcC/wIBAv8CAAL/AgAC/wIAAv8CAgL/AgIB
|
/wIAAv8CAAL/AgAC/wICAv8CAgH+Af8CAAHrAf8CAAGtAf8CWgFrAfIDTAGQAy8BSQNsAesDgAH+A8YB
|
||||||
/gH/AgAB6wH/AgABrQH/AloBawHyA0wBkAMvAUkDbAHrA5YB/gPGAf8DrgH/A5wB/wOTAf8DkAH/A48B
|
/wOuAf8DnAH/A5MB/wOQAf8DjwH/A5AB/wOTAf8DkwH/A4UB/wNAAf0DYAHgAy0BRQMvAUkDbAHrAYAB
|
||||||
/wOQAf8DkwH/A5MB/wOFAf8DSQH9A2AB4AMtAUUDLwFJA2wB6wGAAcUBgAH+AX8B/wF/Af8BSQH/AUkB
|
qwGAAf4BfwH/AX8B/wFJAf8BSQH/AR8B/wEfAf8BDAH/AQwB/wEFAf8BBQH/AQMB/wEDAf8BBQH/AQUB
|
||||||
/wEfAf8BHwH/AQwB/wEMAf8BBQH/AQUB/wEDAf8BAwH/AQUB/wEFAf8BCgH/AQoB/wEKAf4BCgH/AQEB
|
/wEKAf8BCgH/AQoB/gEKAf8BAQHtAQEB/wFAAbYBQAH9AWABZgFgAeADLQFFAy8BSQNsAesBgAKrAf4B
|
||||||
7QEBAf8BOgG2AToB/QFgAWYBYAHgAy0BRQMvAUkDbAHrAYACxQH+AX8D/wFJA/8BHwP/AQwD/wEFA/8B
|
fwP/AUkD/wEfA/8BDAP/AQUD/wEDA/8BBQP/AQoD/wEKAv4B/wEBAu0B/wFAArYB/QFgAmYB4AMtAUUD
|
||||||
AwP/AQUD/wEKA/8BCgL+Af8BAQLtAf8BOgK2Af0BYAJmAeADLQFFAy8BSQNsAesCgAHFAf4CfwL/AkkC
|
LwFJA2wB6wKAAasB/gJ/Av8CSQL/Ah8C/wIMAv8CBQL/AgMC/wIFAv8CCgL/AgoB/gH/AgEB7QH/AkAB
|
||||||
/wIfAv8CDAL/AgUC/wIDAv8CBQL/AgoC/wIKAf4B/wIBAe0B/wI6AbYB/QJgAWYB4AMtAUUDAwEEA1YB
|
tgH9AmABZgHgAy0BRQMDAQQDVgGuA24B9QPZAf8DywH/A7cB/wOnAf8DnQH/A5oB/wOcAf8DnwH/A5sB
|
||||||
rgNuAfUD2QH/A8sB/wO3Af8DpwH/A50B/wOaAf8DnAH/A58B/wObAf8DiQH/A2gB8ANSAaMDAwEEAwMB
|
/wOJAf8DaAHwA1IBowMDAQQDAwEEA1YBrgNuAfUBqAH/AagB/wGJAf8BiQH/AVwB/wFcAf8BNwH/ATcB
|
||||||
BANWAa4DbgH1AagB/wGoAf8BiQH/AYkB/wFcAf8BXAH/ATcB/wE3Af8BIgH/ASIB/wEbAf8BGwH/AR8B
|
/wEiAf8BIgH/ARsB/wEbAf8BHwH/AR8B/wEmAf8BJgH/AR0B/wEdAf8BBQHzAQUB/wFeAWgBXgHwA1IB
|
||||||
/wEfAf8BJgH/ASYB/wEdAf8BHQH/AQUB8wEFAf8BXgFoAV4B8ANSAaMDAwEEAwMBBANWAa4DbgH1AagD
|
owMDAQQDAwEEA1YBrgNuAfUBqAP/AYkD/wFcA/8BNwP/ASID/wEbA/8BHwP/ASYD/wEdA/8BBQLzAf8B
|
||||||
/wGJA/8BXAP/ATcD/wEiA/8BGwP/AR8D/wEmA/8BHQP/AQUC8wH/AV4CaAHwA1IBowMDAQQDAwEEA1YB
|
XgJoAfADUgGjAwMBBAMDAQQDVgGuA24B9QKoAv8CiQL/AlwC/wI3Av8CIgL/AhsC/wIfAv8CJgL/Ah0C
|
||||||
rgNuAfUCqAL/AokC/wJcAv8CNwL/AiIC/wIbAv8CHwL/AiYC/wIdAv8CBQHzAf8CXgFoAfADUgGjAwMB
|
/wIFAfMB/wJeAWgB8ANSAaMDAwEEBAADHAEnA10BxwNjAfYDiwH+A9cB/wPMAf8DwgH/A7sB/wO3Af8D
|
||||||
BAQAAxwBJwNdAccDcgH2A6UB/gPXAf8DzAH/A8IB/wO7Af8DtwH/A7EB/wOAAf4DaAH0A1kBvAMbASYI
|
sQH/A4AB/gNoAfQDWQG8AxsBJggAAxwBJwNdAccDYwH2AYABqwGAAf4BpQH/AaUB/wGLAf8BiwH/AXQB
|
||||||
AAMcAScDXQHHAWkBdQFpAfYBgAHFAYAB/gGlAf8BpQH/AYsB/wGLAf8BdAH/AXQB/wFmAf8BZgH/AVwB
|
/wF0Af8BZgH/AWYB/wFcAf8BXAH/AU4B/wFOAf8BWgGrAVoB/gFTAWgBUwH0AVcBWQFXAbwDGwEmCAAD
|
||||||
/wFcAf8BTgH/AU4B/wFNAcUBTQH+AVMBcQFTAfQBVwFZAVcBvAMbASYIAAMcAScDXQHHAWkCdQH2AYAC
|
HAEnA10BxwNjAfYBgAKrAf4BpQP/AYsD/wF0A/8BZgP/AVwD/wFOA/8BWgKrAf4BUwJoAfQBVwJZAbwD
|
||||||
xQH+AaUD/wGLA/8BdAP/AWYD/wFcA/8BTgP/AU0CxQH+AVMCcQH0AVcCWQG8AxsBJggAAxwBJwNdAccC
|
GwEmCAADHAEnA10BxwNjAfYCgAGrAf4CpQL/AosC/wJ0Av8CZgL/AlwC/wJOAv8CWgGrAf4CUwFoAfQC
|
||||||
aQF1AfYCgAHFAf4CpQL/AosC/wJ0Av8CZgL/AlwC/wJOAv8CTQHFAf4CUwFxAfQCVwFZAbwDGwEmDAAD
|
VwFZAbwDGwEmDAADIQEwA1kBtgNiAe4DfQH6A74B/QPUAf8DzAH/A74B/QNqAfkDbAHrA1UBrAMfASwQ
|
||||||
IQEwA1kBtgNiAe4DhAH6A74B/QPUAf8DzAH/A74B/QN/AfkDbAHrA1UBrAMfASwQAAMhATADWQG2AWIB
|
AAMhATADWQG2A2IB7gN9AfoBrgG+Aa4B/QGfAf8BnwH/AYwB/wGMAf8BTAG+AUwB/QFoAX8BaAH5AWEB
|
||||||
ZAFiAe4BfQGTAX0B+gGuAb4BrgH9AZ8B/wGfAf8BjAH/AYwB/wFZAb4BWQH9AWgBjAFoAfkBYQFsAWEB
|
bAFhAesDVQGsAx8BLBAAAyEBMANZAbYDYgHuA30B+gGuAr4B/QGfA/8BjAP/AUwCvgH9AWgCfwH5AWEC
|
||||||
6wNVAawDHwEsEAADIQEwA1kBtgFiAmQB7gF9ApMB+gGuAr4B/QGfA/8BjAP/AVkCvgH9AWgCjAH5AWEC
|
bAHrA1UBrAMfASwQAAMhATADWQG2A2IB7gN9AfoCrgG+Af0CnwL/AowC/wJMAb4B/QJoAX8B+QJhAWwB
|
||||||
bAHrA1UBrAMfASwQAAMhATADWQG2AmIBZAHuAn0BkwH6Aq4BvgH9Ap8C/wKMAv8CWQG+Af0CaAGMAfkC
|
6wNVAawDHwEsFAADBgEHAzYBWANVAawDZgHlA34B/AOBAfsDZQHiA1MBpwMzAVEDBgEHGAADBgEHAzYB
|
||||||
YQFsAesDVQGsAx8BLBQAAwYBBwM2AVgDVQGsA2YB5QORAfwDjgH7A2UB4gNTAacDMwFRAwYBBxgAAwYB
|
WANVAawDZgHlAX4BgwF+AfwBXwGMAV8B+wNlAeIDUwGnAzMBUQMGAQcYAAMGAQcDNgFYA1UBrANmAeUB
|
||||||
BwM2AVgDVQGsA2YB5QF+AaoBfgH8AWMBmQFjAfsDZQHiA1MBpwMzAVEDBgEHGAADBgEHAzYBWANVAawD
|
fgKDAfwBXwKMAfsDZQHiA1MBpwMzAVEDBgEHGAADBgEHAzYBWANVAawDZgHlAn4BgwH8Al8BjAH7A2UB
|
||||||
ZgHlAX4CqgH8AWMCmQH7A2UB4gNTAacDMwFRAwYBBxgAAwYBBwM2AVgDVQGsA2YB5QJ+AaoB/AJjAZkB
|
4gNTAacDMwFRAwYBBwwAAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/+BAAHgAQcB
|
||||||
+wNlAeIDUwGnAzMBUQMGAQcMAAFCAU0BPgcAAT4DAAEoAwABQAMAASADAAEBAQABAQYAAQEWAAP/gQAB
|
4AEHAeABBwHgAQcBwAEDAcABAwHAAQMBwAEDAYABAQGAAQEBgAEBAYABAVAAAYABAQGAAQEBgAEBAYAB
|
||||||
4AEHAeABBwHgAQcB4AEHAcABAwHAAQMBwAEDAcABAwGAAQEBgAEBAYABAQGAAQFQAAGAAQEBgAEBAYAB
|
AQHAAQMBwAEDAcABAwHAAQMB4AEHAeABBwHgAQcB4AEHCw==
|
||||||
AQGAAQEBwAEDAcABAwHAAQMBwAEDAeABBwHgAQcB4AEHAeABBws=
|
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="ilGames.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="ilGames.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
@ -291,43 +290,43 @@
|
|||||||
<value>
|
<value>
|
||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAALiUAAAJNU0Z0AUkBTAIBAQMB
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAKCUAAAJNU0Z0AUkBTAIBAQMB
|
||||||
AAGoAQEBqAEBASABAAEgAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABgAMAASADAAEBAQABIAYAAUB6
|
AAEQAQIBEAECASABAAEgAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABgAMAASADAAEBAQABIAYAAUB6
|
||||||
AANcAecBCAEKAQAB/wMqAUAMAAMqAUADNgFXAz8BbAM/AWwDPwFsAz8BbAM/AWwDPwFsAz8BbAM/AWwD
|
AANcAecBCAEKAQAB/wMqAUAMAAMqAUADNgFXAz8BbAM/AWwDPwFsAz8BbAM/AWwDPwFsAz8BbAM/AWwD
|
||||||
PwFsAz8BbAM/AWwDPwFsAz8BbAM/AWwDPwFsAz8BbAI7AToBYgMzAVEDGAEhVAADUwGiA1sBwCAAA1QB
|
PwFsAz8BbAM/AWwDPwFsAz8BbAM/AWwDPwFsAz8BbAI7AToBYgMzAVEDGAEhVAADUwGiA1sBwCAAA1QB
|
||||||
pgNZAbzwAAMhATADRgGAFAABFQEfAQQB/wENARUBAAH/AQgBCgEAAf8BCAEKAQAB/wwAA0QBegNTAacC
|
pgNZAbzwAAMhATADRgGAFAABFQEfAQQB/wENARUBAAH/AQgBCgEAAf8BCAEKAQAB/wwAA0QBegNTAacC
|
||||||
YQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8C
|
YQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8C
|
||||||
YQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYAFdAc4DWQG7AlABTwGbAyoBQFQAA18B0ANpAe4g
|
YQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYAFdAc4DWQG7AlABTwGbAyoBQFQAA18B0ANiAe4g
|
||||||
AANhAdQDZgHp5AADWgG/AQgBCgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoB
|
AANhAdQDYwHp5AADWgG/AQgBCgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoB
|
||||||
AAH/AQgBCgEAAf8DWgG/A1oBvwFDAXQBBwH/AUcBdwEMAf8BJQFHAQAB/wEOARkBAAH/DAACSwFKAYoC
|
AAH/AQgBCgEAAf8DWgG/A1oBvwFDAXQBBwH/AUcBdwEMAf8BJQFHAQAB/wEOARkBAAH/DAACSwFKAYoC
|
||||||
WgFYAb0CZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoC
|
WgFYAb0CZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoC
|
||||||
ZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCYwFaAekCXwFbAdMDVQGvAy4BSFQAA18B
|
ZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCYwFaAekCXwFbAdMDVQGvAy4BSFQAA18B
|
||||||
0ANpAe4gAANhAdQDZgHp4AABCAEKAQAB/wEQAR4BAAH/ASEBQQEAAf8BJwFLAQAB/wEmAUoBAAH/ASEB
|
0ANiAe4gAANhAdQDYwHp4AABCAEKAQAB/wEQAR4BAAH/ASEBQQEAAf8BJwFLAQAB/wEmAUoBAAH/ASEB
|
||||||
QQEAAf8BEAEeAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEpAU4BAAH/AVoBlgEQAf8BWgGcARAB
|
QQEAAf8BEAEeAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEpAU4BAAH/AVoBlgEQAf8BWgGcARAB
|
||||||
/wFzAbYBJgH/ARgBLgEAAf8MAANJAYYCWgFYAbcCZQFgAeMCZQFgAeMCZQFgAeMCZQFgAeMCagFhAeYC
|
/wFzAbYBJgH/ARgBLgEAAf8MAANJAYYCWgFYAbcCZQFgAeMCZQFgAeMCZQFgAeMCZQFgAeMCagFhAeYC
|
||||||
agFeAe0CaAFTAfQBjwF3ASsB/AH/AXgBAAL/AXgBAAH/Am4BWgH1AmoBYQHmAmUBYAHjAmUBYAHjAmUB
|
agFeAe0CaAFTAfQBfgF3ASsB/AH/AXgBAAL/AXgBAAH/Am4BWgH1AmoBYQHmAmUBYAHjAmUBYAHjAmUB
|
||||||
YAHjAmUBXgHiAl4BWwHNAlUBUwGqAi4BLQFGVAADXwHQA2kB7iAAA2EB1ANmAencAAEIAQoBAAH/AT0B
|
YAHjAmUBXgHiAl4BWwHNAlUBUwGqAi4BLQFGVAADXwHQA2IB7iAAA2EB1ANjAencAAEIAQoBAAH/AT0B
|
||||||
cQECAf8BTAGGAQcB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BTAF/AQ8B
|
cQECAf8BTAGGAQcB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BTAF/AQ8B
|
||||||
/wE7AWcBCAH/ASEBNAEIAf8BUwGOAQsB/wFaAZwBEAH/AXIBswEnAf8BUwGBARsB/xAAAysBQQM2AVkC
|
/wE7AWcBCAH/ASEBNAEIAf8BUwGOAQsB/wFaAZwBEAH/AXIBswEnAf8BUwGBARsB/xAAAysBQQM2AVkC
|
||||||
QAE/AW4CQAE/AW4CQAE/AW4CQAE/AW4DRAF7AlEBUAGfAl0BWwHFA2IB7gH/AXgBAAL/AXgBAAH/Al8B
|
QAE/AW4CQAE/AW4CQAE/AW4CQAE/AW4DRAF7AlEBUAGfAl0BWwHFA2IB7gH/AXgBAAL/AXgBAAH/Al8B
|
||||||
XQHJA0UBfAJAAT8BbgJAAT8BbgJAAT8BbgM/AW0DOwFjAzMBUgMZASJUAANfAdADaQHuIAADYQHUA2YB
|
XQHJA0UBfAJAAT8BbgJAAT8BbgJAAT8BbgM/AW0DOwFjAzMBUgMZASJUAANfAdADYgHuIAADYQHUA2MB
|
||||||
6dgAARUBKQEAAf8BSgGEAQQB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
6dgAARUBKQEAAf8BSgGEAQQB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
||||||
UgGMARAB/wFSAYwBEAH/AVIBjAEQAf8BWgGUARAB/wFWAZABDAH/AVoBmgEQAf8BWgGcARAB/wFyAakB
|
UgGMARAB/wFSAYwBEAH/AVIBjAEQAf8BWgGUARAB/wFWAZABDAH/AVoBmgEQAf8BWgGcARAB/wFyAakB
|
||||||
MAH/AQgBCgEAAf8BCAEKAQAB/wwAAwwBEAMRARYDFQEcAxUBHAMVARwDFQEcAyEBMAI+AT0BaQJTAVIB
|
MAH/AQgBCgEAAf8BCAEKAQAB/wwAAwwBEAMRARYDFQEcAxUBHAMVARwDFQEcAyEBMAI+AT0BaQJTAVIB
|
||||||
pQJmAV8B5QH/AXgBAAL/AXgBAAH/AlUBUwGqAyIBMQMVARwDFQEcAxUBHAMUARsDEwEZAxABFQMHAQlU
|
pQJmAV8B5QH/AXgBAAL/AXgBAAH/AlUBUwGqAyIBMQMVARwDFQEcAxUBHAMUARsDEwEZAxABFQMHAQlU
|
||||||
AANfAdADaQHuIAADYQHUA2YB6dQAARYBJwECAf8BSQGAAQcB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB
|
AANfAdADYgHuIAADYQHUA2MB6dQAARYBJwECAf8BSQGAAQcB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB
|
||||||
/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQsB/wFSAYwBEAH/AVIBjAEQAf8BWAGSARAB/wFaAZQBEAH/AVoB
|
/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQsB/wFSAYwBEAH/AVIBjAEQAf8BWAGSARAB/wFaAZQBEAH/AVoB
|
||||||
mwEQAf8BWgGcARAB/wFcAZ4BEgH/ATsBbQEDAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8IAAMFBAYE
|
mwEQAf8BWgGcARAB/wFcAZ4BEgH/ATsBbQEDAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8IAAMFBAYE
|
||||||
CAEKAwgBCgMIAQoDCAEKAxcBHwI5ATgBXQNRAZ4CZQFgAeMB/wF4AQAC/wF4AQAB/wNSAaMDGAEhAwgB
|
CAEKAwgBCgMIAQoDCAEKAxcBHwI5ATgBXQNRAZ4CZQFgAeMB/wF4AQAC/wF4AQAB/wNSAaMDGAEhAwgB
|
||||||
CgMIAQoDCAEKAwgBCgMHAQkDBgEHAwIBA1QAA18B0ANpAe4gAANhAdQDZgHp0AADXQHfAUcBgAEDAf8B
|
CgMIAQoDCAEKAwgBCgMHAQkDBgEHAwIBA1QAA18B0ANiAe4gAANhAdQDYwHp0AADXQHfAUcBgAEDAf8B
|
||||||
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMARAB/wFSAYwB
|
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMARAB/wFSAYwB
|
||||||
EAH/AVIBjAEQAf8BWgGUARAB/wFaAZQBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAEQAf8B
|
EAH/AVIBjAEQAf8BWgGUARAB/wFaAZQBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAEQAf8B
|
||||||
WgGYARAB/wEWASoBAAH/AQgBCgEAAf8BCAEKAQAB/xwAAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgB
|
WgGYARAB/wEWASoBAAH/AQgBCgEAAf8BCAEKAQAB/xwAAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgB
|
||||||
AAH/AlEBUAGfAxIBGHAAA18B0ANpAe4gAANhAdQDZgHp0AABLAFQAQAB/wFKAYwBAAH/AVIBjAEIAf8B
|
AAH/AlEBUAGfAxIBGHAAA18B0ANiAe4gAANhAdQDYwHp0AABLAFQAQAB/wFKAYwBAAH/AVIBjAEIAf8B
|
||||||
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBDgH/AVUBkgEQAf8BWgGcARAB/wFaAZwB
|
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBDgH/AVUBkgEQAf8BWgGcARAB/wFaAZwB
|
||||||
EAH/AVoBlAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBlAEYAf8B
|
EAH/AVoBlAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBlAEYAf8B
|
||||||
WAGSARYB/wEQAR4BAAH/AQgBCgEAAf8cAAMSARcDNQFWA1ABmgNiAeEB/wF4AQAC/wF4AQAB/wJRAVAB
|
WAGSARYB/wEQAR4BAAH/AQgBCgEAAf8cAAMSARcDNQFWA1ABmgNiAeEB/wF4AQAC/wF4AQAB/wJRAVAB
|
||||||
nwMSARhwAANfAdADaQHuIAADYQHUA2YB6dQAA0sBjwEzAV4BAAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwB
|
nwMSARhwAANfAdADYgHuIAADYQHUA2MB6dQAA0sBjwEzAV4BAAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwB
|
||||||
CAH/AVIBjAEQAf8BfwHAATMB/wFfAZ4BFwH/ASABPwEAAf8BCAEKAQAB/wFSAYwBEAH/AVoBnAEQAf8B
|
CAH/AVIBjAEQAf8BfwHAATMB/wFfAZ4BFwH/ASABPwEAAf8BCAEKAQAB/wFSAYwBEAH/AVoBnAEQAf8B
|
||||||
WgGcARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGVARcB/wFaAZQBGAH/AVoBlAEYAf8BWgGUARgB/wEIAQoB
|
WgGcARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGVARcB/wFaAZQBGAH/AVoBlAEYAf8BWgGUARgB/wEIAQoB
|
||||||
AAH/AQgBCgEAAf8YAAMSARcDNQFWA1ABmgNiAeEB/wF4AQAC/wF4AQAB/wJRAVABnwMSARgUAAQBAwMB
|
AAH/AQgBCgEAAf8YAAMSARcDNQFWA1ABmgNiAeEB/wF4AQAC/wF4AQAB/wJRAVABnwMSARgUAAQBAwMB
|
||||||
@ -343,44 +342,44 @@
|
|||||||
AAH/AVoBlAESAf8BWgGUARgB/wFaAZQBGAH/AWMBnAEYAf8BYwGlARcB/wFrAaUBIQH/ARABHgEAAf8Y
|
AAH/AVoBlAESAf8BWgGUARgB/wFaAZQBGAH/AWMBnAEYAf8BYwGlARcB/wFrAaUBIQH/ARABHgEAAf8Y
|
||||||
AAMSARcDNQFWA1ABmgNiAeEB/wF4AQAC/wF4AQAB/wJRAVABnwMSARgUAAMFAQYDHQEpAzABSgI7ATwB
|
AAMSARcDNQFWA1ABmgNiAeEB/wF4AQAC/wF4AQAB/wJRAVABnwMSARgUAAMFAQYDHQEpAzABSgI7ATwB
|
||||||
ZQI7ATwBZAMoATwCFQEWAR0DBgEIFAADPAFkA0wBjwNMAY8DTAGPA0wBjwNMAY8DTAGPA0wBjwNMAY8D
|
ZQI7ATwBZAMoATwCFQEWAR0DBgEIFAADPAFkA0wBjwNMAY8DTAGPA0wBjwNMAY8DTAGPA0wBjwNMAY8D
|
||||||
TAGPA2cB6gN8AfgDTAGPA0wBjwNMAY8DTAGPA0wBjwNMAY8DTAGPA0wBjwNrAewDbgH1A0wBjwNMAY8D
|
TAGPA2cB6gN8AfgDTAGPA0wBjwNMAY8DTAGPA0wBjwNMAY8DTAGPA0wBjwNlAewDbgH1A0wBjwNMAY8D
|
||||||
TAGPA0wBjwNMAY8DTAGPA0wBjwNMAY8DTAGPAzUBVqgAA10B3wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB
|
TAGPA0wBjwNMAY8DTAGPA0wBjwNMAY8DTAGPAzUBVqgAA10B3wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB
|
||||||
/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wMzAVADOgFgAUsBhQEHAf8BWgGUARAB/wFaAZwBEAH/ATkB
|
/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wMzAVADOgFgAUsBhQEHAf8BWgGUARAB/wFaAZwBEAH/ATkB
|
||||||
awEAAf8DCQEMARABHgEAAf8BVAGOARIB/wFaAZQBGAH/AWMBnAEYAf8BYwGcARgB/wFjAaUBFwH/AXMB
|
awEAAf8DCQEMARABHgEAAf8BVAGOARIB/wFaAZQBGAH/AWMBnAEYAf8BYwGcARgB/wFjAaUBFwH/AXMB
|
||||||
tAEpAf8BEAEeAQAB/xgAAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwkB
|
tAEpAf8BEAEeAQAB/xgAAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwkB
|
||||||
DAMzAVACTAFNAZECXQFfAckCWwFdAcoDRAF6AykBPQMMARA8AANfAdADaQHuIAADYQHUA2YB6cwAAQgB
|
DAMzAVACTAFNAZECXQFfAckCWwFdAcoDRAF6AykBPQMMARA8AANfAdADYgHuIAADYQHUA2MB6cwAAQgB
|
||||||
CgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB
|
CgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB
|
||||||
/wEIAQoBAAH/ATMBXwECAf8BWgGUARAB/wFaAZwBEAH/Aa0B5wFjAf8BEAEeAQAB/wEIAQoBAAH/ARQB
|
/wEIAQoBAAH/ATMBXwECAf8BWgGUARAB/wFaAZwBEAH/Aa0B5wFjAf8BEAEeAQAB/wEIAQoBAAH/ARQB
|
||||||
JgEAAf8BVAGOARIB/wFiAZsBGAH/AWMBnAEYAf8BYwGlARcB/wFjAaUBFwH/AWMBnAEhAf8BGAEuAQAB
|
JgEAAf8BVAGOARIB/wFiAZsBGAH/AWMBnAEYAf8BYwGlARcB/wFjAaUBFwH/AWMBnAEhAf8BGAEuAQAB
|
||||||
/xgAAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwkBCwMuAUcDSAGEAlkB
|
/xgAAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwkBCwMuAUcDSAGEAlkB
|
||||||
XAHDAlwBXwHLA0kBhQMuAUcDDwETPAADXwHQA2kB7iAAA2EB1ANmAenIAAEIAQoBAAH/ASsBUgEAAf8B
|
XAHDAlwBXwHLA0kBhQMuAUcDDwETPAADXwHQA2IB7iAAA2EB1ANjAenIAAEIAQoBAAH/ASsBUgEAAf8B
|
||||||
QQFyAQUB/wFKAYQBBgH/AUoBhAEGAf8BSgGEAQYB/wFCAXMBBgH/ASkBUAEAAf8BEAEeAQAB/wEfAToB
|
QQFyAQUB/wFKAYQBBgH/AUoBhAEGAf8BSgGEAQYB/wFCAXMBBgH/ASkBUAEAAf8BEAEeAQAB/wEfAToB
|
||||||
AAH/AVUBjwELAf8BWgGVARAB/wFaAZwBEAH/AdYB/wGMAf8BEAEeAQAB/wEYAS4BAAH/AUIBeAEDAf8B
|
AAH/AVUBjwELAf8BWgGVARAB/wFaAZwBEAH/AdYB/wGMAf8BEAEeAQAB/wEYAS4BAAH/AUIBeAEDAf8B
|
||||||
WgGUARgB/wFiAZsBGAH/AWMBnAEYAf8BYwGlARcB/wFjAaUBFwH/AXMBtAEpAf8BEAEeAQAB/xgAAxIB
|
WgGUARgB/wFiAZsBGAH/AWMBnAEYAf8BYwGlARcB/wFjAaUBFwH/AXMBtAEpAf8BEAEeAQAB/xgAAxIB
|
||||||
FwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwYBCAMkATQDPAFmA1MBpwNYAbgC
|
FwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwYBCAMkATQDPAFmA1MBpwNYAbgC
|
||||||
RwFIAYMDMQFNAw8BFDwAA18B0ANpAe4gAANhAdQDZgHpxAABKAFNAQAB/wFOAYgBBwH/AVIBjAEIAf8B
|
RwFIAYMDMQFNAw8BFDwAA18B0ANiAe4gAANhAdQDYwHpxAABKAFNAQAB/wFOAYgBBwH/AVIBjAEIAf8B
|
||||||
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFSAYwB
|
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFSAYwB
|
||||||
EAH/AVoBlAEQAf8BWgGcARAB/wFjAaUBFwH/AUIBewEAAf8BSgGEAQYB/wFSAYwBCAH/AVoBmAEUAf8B
|
EAH/AVoBlAEQAf8BWgGcARAB/wFjAaUBFwH/AUIBewEAAf8BSgGEAQYB/wFSAYwBCAH/AVoBmAEUAf8B
|
||||||
WgGUARgB/wFjAZwBGAH/AWMBpQEXAf8BYwGlARcB/wFjAaUBFwH/AZQByQFNAf8EAAMQARUDGgEkAyEB
|
WgGUARgB/wFjAZwBGAH/AWMBpQEXAf8BYwGlARcB/wFjAaUBFwH/AZQByQFNAf8EAAMQARUDGgEkAyEB
|
||||||
LwMRARYEAgQBAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwMBBAMTARkD
|
LwMRARYEAgQBAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwMBBAMTARkD
|
||||||
JQE2AjsBPAFkAkEBQgFyAzMBUQMhAS8DCQEMPAADXwHQA2kB7iAAA2EB1ANmAenAAAEpAU4BAgH/AVIB
|
JQE2AjsBPAFkAkEBQgFyAzMBUQMhAS8DCQEMPAADXwHQA2IB7iAAA2EB1ANjAenAAAEpAU4BAgH/AVIB
|
||||||
jAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMARAB
|
jAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMARAB
|
||||||
/wFSAYwBEAH/AVIBjAEQAf8BWgGUARAB/wFaAZUBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoB
|
/wFSAYwBEAH/AVIBjAEQAf8BWgGUARAB/wFaAZUBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoB
|
||||||
nAEQAf8BWgGUARgB/wFaAZQBGAH/AWMBnAEYAf8BYwGcARgB/wFjAaUBFwH/AWMBpQEXAf8BYwGlARcB
|
nAEQAf8BWgGUARgB/wFaAZQBGAH/AWMBnAEYAf8BYwGcARgB/wFjAaUBFwH/AWMBpQEXAf8BYwGlARcB
|
||||||
/wFlAaABIQH/BAADHgErAjEBMAFMAzsBYwMiATEDBwEJAwQBBQMSARgDNgFXA1ABmgNiAeEB/wF4AQAC
|
/wFlAaABIQH/BAADHgErAjEBMAFMAzsBYwMiATEDBwEJAwQBBQMSARgDNgFXA1ABmgNiAeEB/wF4AQAC
|
||||||
/wF4AQAB/wJRAVABnwMSARgcAAMHAQkDHAEnAyMBMgIZARoBIwMPARQDBAEFPAADXwHQA2kB7iAAA2EB
|
/wF4AQAB/wJRAVABnwMSARgcAAMHAQkDHAEnAyMBMgIZARoBIwMPARQDBAEFPAADXwHQA2IB7iAAA2EB
|
||||||
1ANmAem8AANGAYABTgGIAQcB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
1ANjAem8AANGAYABTgGIAQcB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
||||||
UgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFSAYwBEAH/AVoBlAEQAf8BWgGXARAB/wFaAZwB
|
UgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFSAYwBEAH/AVoBlAEQAf8BWgGXARAB/wFaAZwB
|
||||||
EAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBlAEYAf8BWgGUARgB/wFjAZwBGAH/AWMBoQEYAf8B
|
EAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBlAEYAf8BWgGUARgB/wFjAZwBGAH/AWMBoQEYAf8B
|
||||||
YwGlARcB/wFjAaUBFwH/AXgBugEsAf8BCAEKAQAB/wQAAyQBNANFAXwCWgFYAbcDTgGUAz8BbQMoATsD
|
YwGlARcB/wFjAaUBFwH/AXgBugEsAf8BCAEKAQAB/wQAAyQBNANFAXwCWgFYAbcDTgGUAz8BbQMoATsD
|
||||||
HwEsAzkBXgNQAZoDYgHhAf8BeAEAAv8BeAEAAf8CUQFQAZ8DEgEYHAADEgEXAzwBZgNKAYkDQAFvAy4B
|
HwEsAzkBXgNQAZoDYgHhAf8BeAEAAv8BeAEAAf8CUQFQAZ8DEgEYHAADEgEXAzwBZgNKAYkDQAFvAy4B
|
||||||
RwMOARI8AANfAdADaQHuIAADYQHUA2YB6bwAATUBXgEHAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
RwMOARI8AANfAdADYgHuIAADYQHUA2MB6bwAATUBXgEHAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
||||||
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFaAZQB
|
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFaAZQB
|
||||||
EAH/AVoBlAEQAf8BWgGbARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZYBFgH/AVoBlAEYAf8B
|
EAH/AVoBlAEQAf8BWgGbARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZYBFgH/AVoBlAEYAf8B
|
||||||
XQGXARgB/wFjAZwBGAH/AWMBpQEXAf8BYwGlARcB/wFwAbMBIAH/ASsBUAEEAf8IAAMnAToCUwFRAaIB
|
XQGXARgB/wFjAZwBGAH/AWMBpQEXAf8BYwGlARcB/wFwAbMBIAH/ASsBUAEEAf8IAAMnAToCUwFRAaIB
|
||||||
kAFfASEB+wJlAVwB5wJcAVoBxAJDAUIBdQMxAU0CQAE/AW4CUQFQAZ8CZQFgAeMB/wF4AQAC/wF4AQAB
|
gwFfASEB+wJlAVwB5wJcAVoBxAJDAUIBdQMxAU0CQAE/AW4CUQFQAZ8CZQFgAeMB/wF4AQAC/wF4AQAB
|
||||||
/wJRAVABnwMSARgcAAMZASIDTgGVAlsBXgHNAlYBVwGyA0QBegMdASkDBgEIBAIEATAAA18B0ANpAe4g
|
/wJRAVABnwMSARgcAAMZASIDTgGVAlsBXgHNAlYBVwGyA0QBegMdASkDBgEIBAIEATAAA18B0ANiAe4g
|
||||||
AANhAdQDZgHpvAABSgGEAQYB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
AANhAdQDYwHpvAABSgGEAQYB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
||||||
ZwGpARcB/wFSAYwBCAH/AUoBhAEGAf8BSgGEAQYB/wFSAYwBEAH/AVoBlAEQAf8BWgGXARAB/wFaAZwB
|
ZwGpARcB/wFSAYwBCAH/AUoBhAEGAf8BSgGEAQYB/wFSAYwBEAH/AVoBlAEQAf8BWgGXARAB/wFaAZwB
|
||||||
EAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBlAEYAf8BWgGUARgB/wFfAZgBGAH/AWMBngEYAf8B
|
EAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBlAEYAf8BWgGUARgB/wFfAZgBGAH/AWMBngEYAf8B
|
||||||
YwGlARcB/wFrAakBHQH/ASkBUAEAAf8MAAMiATEDTgGYAm8BYAHzAmgBXgHwAmoBYQHmAloBVwHCAlUB
|
YwGlARcB/wFrAakBHQH/ASkBUAEAAf8MAAMiATEDTgGYAm8BYAHzAmgBXgHwAmoBYQHmAloBVwHCAlUB
|
||||||
@ -398,59 +397,59 @@
|
|||||||
YgHclAABSgGMAQAB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AWcBnQEnAf8BCAEKAQAB
|
YgHclAABSgGMAQAB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AWcBnQEnAf8BCAEKAQAB
|
||||||
/wEKAQ8BAAH/AUIBdwEDAf8BUgGMARAB/wFaAZwBEAH/ASUBQQEFAf8EAAM6AWABCAEKAQAB/wEIAQoB
|
/wEKAQ8BAAH/AUIBdwEDAf8BUgGMARAB/wFaAZwBEAH/ASUBQQEFAf8EAAM6AWABCAEKAQAB/wEIAQoB
|
||||||
AAH/BAADRgGAA0YBgANGAYAcAAMKAQ0DIgExAzQBVANEAXgCUQFQAZ8CYQFdAc8CagFeAe0CZQFdAewC
|
AAH/BAADRgGAA0YBgANGAYAcAAMKAQ0DIgExAzQBVANEAXgCUQFQAZ8CYQFdAc8CagFeAe0CZQFdAewC
|
||||||
aAFeAfABkAFfASEB+wH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBwAAwYBCAMYASEDMQFNAkwBTQGRAlgB
|
aAFeAfABgwFfASEB+wH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBwAAwYBCAMYASEDMQFNAkwBTQGRAlgB
|
||||||
WgG9Al0BYQHRAlkBXAHDAlEBUwGiAz0BZwIZARoBIwMMAQ8DQAFvA1UBrQNVAa0DVQGtA1UBrQNVAa0D
|
WgG9Al0BYQHRAlkBXAHDAlEBUwGiAz0BZwIZARoBIwMMAQ8DQAFvA1UBrQNVAa0DVQGtA1UBrQNVAa0D
|
||||||
VQGtA1UBrQNVAa0DVQGtA2gB8AN9AfoDVQGtA1UBrQNVAa0DVQGtA1UBrQNVAa0DVQGtA1UBrQNwAfED
|
VQGtA1UBrQNVAa0DVQGtA2gB8AN9AfoDVQGtA1UBrQNVAa0DVQGtA1UBrQNVAa0DVQGtA1UBrQNwAfED
|
||||||
fAH4A1UBrQNVAa0DVQGtA1UBrQNVAa0DVQGtA1UBrQNVAa0DVQGtA0cBgZQAATsBbQECAf8BUgGMAQgB
|
fAH4A1UBrQNVAa0DVQGtA1UBrQNVAa0DVQGtA1UBrQNVAa0DVQGtA0cBgZQAATsBbQECAf8BUgGMAQgB
|
||||||
/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFTAY4BEAH/AQ8BGwEAAf8BIwFDAQAB/wFSAYwBEAH/AVIB
|
/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFTAY4BEAH/AQ8BGwEAAf8BIwFDAQAB/wFSAYwBEAH/AVIB
|
||||||
jAEQAf8BewG9ATAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB
|
jAEQAf8BewG9ATAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB
|
||||||
/wEIAQoBAAH/KAADAwEEAwkBCwMiATEDOAFbAk8BTgGXAl8BXAHIAmYBXwHlAXcBbwFRAfcBvgFSAUAB
|
/wEIAQoBAAH/KAADAwEEAwkBCwMiATEDOAFbAk8BTgGXAl8BXAHIAmYBXwHlAm8BUQH3Ab4BRQFAAf0B
|
||||||
/QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBwABAEDAgEDAxUBHAM1AVYCSwFMAY8CXAFfAcgCXQFjAd8C
|
/wF4AQAC/wF4AQAB/wJRAVABnwMSARgcAAQBAwIBAwMVARwDNQFWAksBTAGPAlwBXwHIAl0BYwHfAmAB
|
||||||
YAFlAeMCUgFTAaUDNAFTAxwBJygAA18B0ANpAe4gAANhAdQDZgHpvAABCAEKAQAB/wFSAYwBCAH/AVIB
|
ZQHjAlIBUwGlAzQBUwMcAScoAANfAdADYgHuIAADYQHUA2MB6bwAAQgBCgEAAf8BUgGMAQgB/wFSAYwB
|
||||||
jAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BTgGCAQ8B/wFKAYQBBgH/AVIBjAEQAf8BYwGlARcB
|
CAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AU4BggEPAf8BSgGEAQYB/wFSAYwBEAH/AWMBpQEXAf8B
|
||||||
/wEIAQoBAAH/AQgBCgEAAf8BEwEjAQAB/wFCAXMBBgH/ASABPwEAAf8BCAEKAQAB/wEIAQoBAAH/AQgB
|
CAEKAQAB/wEIAQoBAAH/ARMBIwEAAf8BQgFzAQYB/wEgAT8BAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoB
|
||||||
CgEAAf8BCAEKAQAB/wEIAQoBAAH/IAAEAQMDAQQDDAEQAxgBIAMpAT0DPgFqAlcBVgG1AmYBXwHlAXcB
|
AAH/AQgBCgEAAf8BCAEKAQAB/yAABAEDAwEEAwwBEAMYASADKQE9Az4BagJXAVYBtQJmAV8B5QJvAVEB
|
||||||
bwFRAfcB/wF4AQAC/wF4AQAB/wJRAVABnwMSARggAAQBAwcBCQMUARsDKgFAA0MBdgNVAa8CWgFjAekC
|
9wH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGCAABAEDBwEJAxQBGwMqAUADQwF2A1UBrwJaAWMB6QJbAV8B
|
||||||
WwFfAdACUAFRAZ8DMwFRKAADXwHQA2kB7iAAA2EB1ANmAenAAAFCAXMBBgH/AVIBjAEIAf8BUgGMAQgB
|
0AJQAVEBnwMzAVEoAANfAdADYgHuIAADYQHUA2MB6cAAAUIBcwEGAf8BUgGMAQgB/wFSAYwBCAH/AVIB
|
||||||
/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBEAH/AVIBjAEQAf8BSgGEAQYB/wEQAR4BAAH/ATEB
|
jAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFKAYQBBgH/ARABHgEAAf8BMQFaAQAB
|
||||||
WgEAAf8BTQGEAQ0B/wFaAZwBEAH/AVoBnAEQAf8BUgGMAQgB/wEQAR4BAAH/AQgBCgEAAf8BCAEKAQAB
|
/wFNAYQBDQH/AVoBnAEQAf8BWgGcARAB/wFSAYwBCAH/ARABHgEAAf8BCAEKAQAB/wEIAQoBAAH/A0YB
|
||||||
/wNGAYAsAAMCAQMDCwEOAyABLgNDAXYCVwFVAbECZgFgAeABZwFjAUgB9gGDAWoBQQH5AlEBUAGcAxIB
|
gCwAAwIBAwMLAQ4DIAEuA0MBdgJXAVUBsQJmAWAB4AJjAUgB9gFtAWoBQQH5AlEBUAGcAxIBFwwABAED
|
||||||
FwwABAEDDAEQAxcBHwMdASgDHQEoAwwBDwgAAw8BFAImAScBOQJHAUgBgwNiAeECXAFlAecDXgHSAj8B
|
DAEQAxcBHwMdASgDHQEoAwwBDwgAAw8BFAImAScBOQJHAUgBgwNiAeECXAFlAecDXgHSAj8BQAFuKAAD
|
||||||
QAFuKAADXwHQA2kB7iAAA2EB1ANmAenEAAFJAYkBAAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIB
|
XwHQA2IB7iAAA2EB1ANjAenEAAFJAYkBAAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
||||||
jAEIAf8BUgGMARAB/wFSAYwBEAH/AVIBjAEQAf8BUgGMARAB/wFaAZQBEAH/AVoBnAEQAf8BWgGcARAB
|
UgGMARAB/wFSAYwBEAH/AVIBjAEQAf8BUgGMARAB/wFaAZQBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwB
|
||||||
/wFaAZwBEAH/AVoBnAEQAf8BWgGUARgB/wFCAXMBBgH/AQoBDgEAAf8wAAQBAwMBBAMMAQ8DHgEqAzoB
|
EAH/AVoBnAEQAf8BWgGUARgB/wFCAXMBBgH/AQoBDgEAAf8wAAQBAwMBBAMMAQ8DHgEqAzoBYQJZAVcB
|
||||||
YQJZAVcBuQJjAVsB5ANiAe4CTwFOAZcDEgEXDAADAgEDAyEBLwM2AVkCQgFDAXUCQQFCAXMDHgErCAAD
|
uQJjAVsB5ANiAe4CTwFOAZcDEgEXDAADAgEDAyEBLwM2AVkCQgFDAXUCQQFCAXMDHgErCAADBAEFAwwB
|
||||||
BAEFAwwBDwM4AVwCXQFgAc4CXQFlAewCWQFnAe8DRgF/KAADXwHQA2kB7iAAA2EB1ANmAenIAAE6AWsB
|
DwM4AVwCXQFgAc4CXQFlAewCWQFnAe8DRgF/KAADXwHQA2IB7iAAA2EB1ANjAenIAAE6AWsBAAH/AVIB
|
||||||
AAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFaAZQBEAH/AVoBlAEQAf8B
|
jAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFaAZQBEAH/AVoBlAEQAf8BWgGcARAB
|
||||||
WgGcARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZQBGAH/AVoBlAEYAf8BYwGlARcB/wEZASwB
|
/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZQBGAH/AVoBlAEYAf8BYwGlARcB/wEZASwBAwH/OAAD
|
||||||
AwH/OAADAgEDAwgBCgMgAS0CQQFAAXECTQFMAZEDUAGaAjsBOgFiAwwBDwwAAwMBBAMrAUEDRAF6A1MB
|
AgEDAwgBCgMgAS0CQQFAAXECTQFMAZEDUAGaAjsBOgFiAwwBDwwAAwMBBAMrAUEDRAF6A1MBpwNVAa0D
|
||||||
pwNVAa0DNwFaAxgBIAMJAQsDBgEHAw0BEQM5AV8CXQFhAdECWQFnAe8CYAFvAfMCRgFHAYEoAANfAdAD
|
NwFaAxgBIAMJAQsDBgEHAw0BEQM5AV8CXQFhAdECWQFnAe8CYAFvAfMCRgFHAYEoAANfAdADYgHuIAAD
|
||||||
aQHuIAADYQHUA2YB6cwAASwBVQEAAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFaAZQB
|
YQHUA2MB6cwAASwBVQEAAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFaAZQBEAH/AVoB
|
||||||
EAH/AVoBlAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZQBGAH/AVoBlAEYAf8B
|
lAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZQBGAH/AVoBlAEYAf8BIQFBAQAB
|
||||||
IQFBAQAB/0AABAIDBwEJAxAEFQEcAhYBFQEdAw8BEwMCAQMMAAMDAQQDMANLAUwBjwJbAV0BygJbAWEB
|
/0AABAIDBwEJAxAEFQEcAhYBFQEdAw8BEwMCAQMMAAMDAQQDMANLAUwBjwJbAV0BygJbAWEB3gNOAZQD
|
||||||
3gNOAZQDNAFTAxUBHAMNAREDHgErAkMBRAF3Al0BYwHfAmUBcAHxAloBYwHpA0QBeygAA18B0ANpAe4g
|
NAFTAxUBHAMNAREDHgErAkMBRAF3Al0BYwHfAmUBcAHxAloBYwHpA0QBeygAA18B0ANiAe4gAANhAdQD
|
||||||
AANhAdQDZgHpyAABEgEiAQAB/wFMAYYBBgH/AVIBjAEIAf8BWgGcARAB/wFQAYoBCAH/AVIBjAEQAf8B
|
YwHpyAABEgEiAQAB/wFMAYYBBgH/AVIBjAEIAf8BWgGcARAB/wFQAYoBCAH/AVIBjAEQAf8BWgGUARAB
|
||||||
WgGUARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAERAf8BaQGrAR8B/wEIAQoB
|
/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAERAf8BaQGrAR8B/wEIAQoBAAH/bAAD
|
||||||
AAH/bAADAgEDAyEBLwM6AWEDVQGtAl8BYwHaA1oBvwJQAVEBnwNEAXoCQQFCAXIDSQGFAlYBVwGyAl4B
|
AgEDAyEBLwM6AWEDVQGtAl8BYwHaA1oBvwJQAVEBnwNEAXoCQQFCAXIDSQGFAlYBVwGyAl4BagHtAmAB
|
||||||
agHtAmABZAHbAlUBVwGxAzgBWygAA18B0ANpAe4gAANhAdQDZgHpyAABEAEeAQAB/wFIAX0BBwH/AVkB
|
ZAHbAlUBVwGxAzgBWygAA18B0ANiAe4gAANhAdQDYwHpyAABEAEeAQAB/wFIAX0BBwH/AVkBkwETAf8B
|
||||||
kwETAf8BVQGIARgB/wgAASEBQQEAAf8BQgF7AQAB/wFSAYwBCAH/AVUBkQEIAf8BOQFmAQQB/wNZAe94
|
VQGIARgB/wgAASEBQQEAAf8BQgF7AQAB/wFSAYwBCAH/AVUBkQEIAf8BOQFmAQQB/wNZAe94AAMGAQgD
|
||||||
AAMGAQgDFwEfA0QBewJZAVwBxgJbAWMB5AJTAWgB9ANiAe4DYgHuAmUBcAHxAkgBZwH2AisBjwH8AlkB
|
FwEfA0QBewJZAVwBxgJbAWMB5AJTAWgB9ANiAe4DYgHuAmUBcAHxAkgBYwH2AisBfgH8AlkBXAG+Az4B
|
||||||
XAG+Az4BawMkATQoAANfAdADaQHuIAADYQHUA2YB6dAAAR4BOgEAAf+cAAQCAwkBDAMqAz8BQAFuA04B
|
awMkATQoAANfAdADYgHuIAADYQHUA2MB6dAAAR4BOgEAAf+cAAQCAwkBDAMqAz8BQAFuA04BlgJWAVgB
|
||||||
lgJWAVgBswJZAVwBwQJaAV0BxwJaAV0BxwJXAVkBuQJRAVIBpAJAAUEBcQMlATYDEwEZKAADXwHQA2kB
|
swJZAVwBwQJaAV0BxwJaAV0BxwJXAVkBuQJRAVIBpAJAAUEBcQMlATYDEwEZKAADXwHQA2IB7iAAA2EB
|
||||||
7iAAA2EB1ANmAen/AHkABAEDCwEOAyYBOAM5AV4DRgF9AkoBSwGLA0oBiQM+AWsDKgE/AxcBHwMCAQMs
|
1ANjAen/AHkABAEDCwEOAyYBOAM5AV4DRgF9AkoBSwGLA0oBiQM+AWsDKgE/AxcBHwMCAQMsAANTAaID
|
||||||
AANTAaIDWgG/IAADVAGmA1kBu6gAAUIBTQE+BwABPgMAASgDAAGAAwABIAMAAQEBAAEBBgABAhYAA/8B
|
WgG/IAADVAGmA1kBu6gAAUIBTQE+BwABPgMAASgDAAGAAwABIAMAAQEBAAEBBgABAhYAA/8BAAP/AccC
|
||||||
AAP/AccCAAEHAv8BzwHzAf8EAAL/Ac8BhwIAAQcC/wHPAfMB/wQAAf8B/gEAAQcCAAEHAv8BzwHzAf8E
|
AAEHAv8BzwHzAf8EAAL/Ac8BhwIAAQcC/wHPAfMB/wQAAf8B/gEAAQcCAAEHAv8BzwHzAf8EAAH/AfwB
|
||||||
AAH/AfwBAAEHAgABBwL/Ac8B8wH/BAAB/wH4AQABDwIAAQcC/wHPAfMB/wQAAf8B8AEAAQcCAAEHAv8B
|
AAEHAgABBwL/Ac8B8wH/BAAB/wH4AQABDwIAAQcC/wHPAfMB/wQAAf8B8AEAAQcCAAEHAv8BzwHzAf8E
|
||||||
zwHzAf8EAAH/AeABAAEDAgABBwL/Ac8B8wH/BAAB/wHAAQABAQH8AQMD/wHPAfMB/wQAAf8BwAEAAQEB
|
AAH/AeABAAEDAgABBwL/Ac8B8wH/BAAB/wHAAQABAQH8AQMD/wHPAfMB/wQAAf8BwAEAAQEB/AEDA/8B
|
||||||
/AEDA/8BzwHzAf8EAAH/AeACAAH8AQMB4AEfCAAB/wH8ASABAAH8AQMB4AEfCAAB/wH+AeABAAH8AQMB
|
zwHzAf8EAAH/AeACAAH8AQMB4AEfCAAB/wH8ASABAAH8AQMB4AEfCAAB/wH+AeABAAH8AQMB4AEfCAAB
|
||||||
4AEfCAAB/wHAAgAB/AEDAeABHwH/Ac8B8wH/BAAB/wGAAgAB/AEDAeABHwH/Ac8B8wH/BAAB/wMAAfwB
|
/wHAAgAB/AEDAeABHwH/Ac8B8wH/BAAB/wGAAgAB/AEDAeABHwH/Ac8B8wH/BAAB/wMAAfwBAwHgAR8B
|
||||||
AwHgAR8B/wHPAfMB/wQAAf4CAAEBAQABAwHgAR8B/wHPAfMB/wQAAfwCAAEBAQABAwH4AR8B/wHPAfMB
|
/wHPAfMB/wQAAf4CAAEBAQABAwHgAR8B/wHPAfMB/wQAAfwCAAEBAQABAwH4AR8B/wHPAfMB/wQAAfgC
|
||||||
/wQAAfgCAAEBAQABAwH4AR8B/wHPAfMB/wQAAfgCAAEDAQABAwH4AQMB/wHPAfMB/wQAAfgCAAEHAQAB
|
AAEBAQABAwH4AR8B/wHPAfMB/wQAAfgCAAEDAQABAwH4AQMB/wHPAfMB/wQAAfgCAAEHAQABAwH4AQMI
|
||||||
AwH4AQMIAAH4AgABDwEAAQMB+AkAAfgBAAFEAX8BAAEDAfgJAAH4AQABAQH/AYABAwH4AQAB/wHPAfMB
|
AAH4AgABDwEAAQMB+AkAAfgBAAFEAX8BAAEDAfgJAAH4AQABAQH/AYABAwH4AQAB/wHPAfMB/wQAAfgC
|
||||||
/wQAAfgCAAF/AYABAwH8AQAB/wHPAfMB/wQAAfwCAAF/AfABAwGBAYAB/wHPAfMB/wQAAf4CAAH/AfAB
|
AAF/AYABAwH8AQAB/wHPAfMB/wQAAfwCAAF/AfABAwGBAYAB/wHPAfMB/wQAAf4CAAH/AfABAwGBAYAB
|
||||||
AwGBAYAB/wHPAfMB/wQAAf8CAAH/AfwBAwGAAQAB/wHPAfMB/wQAAf8BgAEBAf8B/gEDAYABAAH/Ac8B
|
/wHPAfMB/wQAAf8CAAH/AfwBAwGAAQAB/wHPAfMB/wQAAf8BgAEBAf8B/gEDAYABAAH/Ac8B8wH/BAAB
|
||||||
8wH/BAAB/wEAAQMD/wGAAQAB/wHPAfMB/wQAAf8BDAEPA/8BwAEAAf8BzwHzAf8EAAH/Ad8E/wHAAQAB
|
/wEAAQMD/wGAAQAB/wHPAfMB/wQAAf8BDAEPA/8BwAEAAf8BzwHzAf8EAAH/Ad8E/wHAAQAB/wHPAfMB
|
||||||
/wHPAfMB/wQABv8B8AEBAf8BzwHzAf8EAAs=
|
/wQABv8B8AEBAf8BzwHzAf8EAAs=
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="ilStoreThumbnails.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="ilStoreThumbnails.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
@ -464,7 +463,7 @@
|
|||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAshIAAAJNU0Z0AUkBTAIBAQQB
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAshIAAAJNU0Z0AUkBTAIBAQQB
|
||||||
AAGoAQIBqAECARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABIAYAASD/
|
AAEQAQMBEAEDARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABIAYAASD/
|
||||||
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ACIAA2cB7wJnAVkB7wFnAV0BWQHvAWcBWwFZAe8B
|
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ACIAA2cB7wJnAVkB7wFnAV0BWQHvAWcBWwFZAe8B
|
||||||
ZwFbAVkB7wFnAlkB7wFnAWQBWQHvA2cB7wNnAe8DZwHvA2cB7wNnAe8DZwHvA2cB7wNnAe8DZwHvAwcB
|
ZwFbAVkB7wFnAlkB7wFnAWQBWQHvA2cB7wNnAe8DZwHvA2cB7wNnAe8DZwHvA2cB7wNnAe8DZwHvAwcB
|
||||||
CQMqAT8DRQF8A1kBuwNjAd8DaAH0A4AB/gOBAf8DgQH/A4EB/wOAAf4DaAH0A2MB3wNaAboDRAF6AycB
|
CQMqAT8DRQF8A1kBuwNjAd8DaAH0A4AB/gOBAf8DgQH/A4EB/wOAAf4DaAH0A2MB3wNaAboDRAF6AycB
|
||||||
@ -490,7 +489,7 @@
|
|||||||
YAH/AYMBggF/Af8BhQGCAX0B/wGzAZMBRAH/Ac8BlAEAAf8B3gHMAZ8B/wOwAf8DsAH/A7AB/wOwAf8D
|
YAH/AYMBggF/Af8BhQGCAX0B/wGzAZMBRAH/Ac8BlAEAAf8B3gHMAZ8B/wOwAf8DsAH/A7AB/wOwAf8D
|
||||||
sAH/A7AB/wOwAf8DsAH/A6gB/wMCAQMDGgEjAzgBXANUAagDYgHXA3AB8QOAAf4DgQH/A4EB/wOBAf8D
|
sAH/A7AB/wOwAf8DsAH/A6gB/wMCAQMDGgEjAzgBXANUAagDYgHXA3AB8QOAAf4DgQH/A4EB/wOBAf8D
|
||||||
gQH9A2gB8ANhAdQDUwGlAzYBWQMYASAIAAMaASQDUgGgAmMBSAH2AaIBcwEAAf8BrgF8AQAB/wGwAX0B
|
gQH9A2gB8ANhAdQDUwGlAzYBWQMYASAIAAMaASQDUgGgAmMBSAH2AaIBcwEAAf8BrgF8AQAB/wGwAX0B
|
||||||
AAH/AagBeAEAAf8BlQFqAQAB/wKAAVUB/gFcAlkBxgNXAbUDFgEeCAAB/wGyAW8B/wH9AYABEQH/AfwB
|
AAH/AagBeAEAAf8BlQFqAQAB/wKAAWIB/gFcAlkBxgNXAbUDFgEeCAAB/wGyAW8B/wH9AYABEQH/AfwB
|
||||||
dwEBAf8B/QF3AQAC/wF4AQAC/wF/AQ8C/wGSATsC/wGzAYMC/wHqAeAC/wGQAT0C/wF7AQoB/wH8AXcB
|
dwEBAf8B/QF3AQAC/wF4AQAC/wF/AQ8C/wGSATsC/wGzAYMC/wHqAeAC/wGQAT0C/wF7AQoB/wH8AXcB
|
||||||
AAH/AeUBbAEAAf8BsQFUAQAB/wGEAUsBGgH/A2MB3wT/AdkBqgE3Af8BvgGYATgB/wHAAZgBNgH/AdwB
|
AAH/AeUBbAEAAf8BsQFUAQAB/wGEAUsBGgH/A2MB3wT/AdkBqgE3Af8BvgGYATgB/wHAAZgBNgH/AdwB
|
||||||
ogEUAf8BzwGUAQAB/wHeAcwBnwH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DkwH/RAAD
|
ogEUAf8BzwGUAQAB/wHeAcwBnwH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DkwH/RAAD
|
||||||
@ -629,6 +628,12 @@
|
|||||||
AB/+AAA//wAAf/+AAP//4AP///4///////8=
|
AB/+AAA//wAAf/+AAP//4AP///4///////8=
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
|
<metadata name="ctxmAdminUserList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>461, 24</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="ctxmAdminRoomList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>461, 49</value>
|
||||||
|
</metadata>
|
||||||
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>90</value>
|
<value>90</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
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 = CompositingMode.SourceOver;
|
||||||
g.CompositingMode = System.Drawing.Drawing2D.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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ namespace qtc_net_client_2.Forms
|
|||||||
|
|
||||||
if(registerResult.Success)
|
if(registerResult.Success)
|
||||||
{
|
{
|
||||||
|
MessageBox.Show("Registration Complete. If the server has email verification on, you may need to check your email for a verification link.\nIf you do not receive one, try logging in.");
|
||||||
DialogResult = DialogResult.OK;
|
DialogResult = DialogResult.OK;
|
||||||
Close();
|
Close();
|
||||||
} else
|
} else
|
||||||
|
104
qtc-net-client-2/Forms/ResendVerificationEmail.Designer.cs
generated
Normal file
104
qtc-net-client-2/Forms/ResendVerificationEmail.Designer.cs
generated
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
partial class ResendVerificationEmail
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
pbLoginBanner = new PictureBox();
|
||||||
|
tbEmail = new TextBox();
|
||||||
|
lblHeader = new Label();
|
||||||
|
btnSend = new Button();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbLoginBanner).BeginInit();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// pbLoginBanner
|
||||||
|
//
|
||||||
|
pbLoginBanner.Image = Properties.Resources.LoginBanner;
|
||||||
|
pbLoginBanner.Location = new Point(-4, 0);
|
||||||
|
pbLoginBanner.Name = "pbLoginBanner";
|
||||||
|
pbLoginBanner.Size = new Size(521, 99);
|
||||||
|
pbLoginBanner.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
pbLoginBanner.TabIndex = 1;
|
||||||
|
pbLoginBanner.TabStop = false;
|
||||||
|
//
|
||||||
|
// tbEmail
|
||||||
|
//
|
||||||
|
tbEmail.Location = new Point(50, 124);
|
||||||
|
tbEmail.Name = "tbEmail";
|
||||||
|
tbEmail.Size = new Size(424, 23);
|
||||||
|
tbEmail.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// lblHeader
|
||||||
|
//
|
||||||
|
lblHeader.AutoSize = true;
|
||||||
|
lblHeader.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblHeader.ForeColor = SystemColors.ControlLight;
|
||||||
|
lblHeader.Location = new Point(54, 106);
|
||||||
|
lblHeader.Name = "lblHeader";
|
||||||
|
lblHeader.Size = new Size(412, 15);
|
||||||
|
lblHeader.TabIndex = 5;
|
||||||
|
lblHeader.Text = "Please Enter Your Email, If An Account Exists With This Email, We'll Send You A Link";
|
||||||
|
//
|
||||||
|
// btnSend
|
||||||
|
//
|
||||||
|
btnSend.Location = new Point(224, 153);
|
||||||
|
btnSend.Name = "btnSend";
|
||||||
|
btnSend.Size = new Size(75, 23);
|
||||||
|
btnSend.TabIndex = 6;
|
||||||
|
btnSend.Text = "Send";
|
||||||
|
btnSend.UseVisualStyleBackColor = true;
|
||||||
|
btnSend.Click += btnSend_Click;
|
||||||
|
//
|
||||||
|
// ResendVerificationEmail
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
BackColor = Color.DodgerBlue;
|
||||||
|
ClientSize = new Size(515, 187);
|
||||||
|
Controls.Add(btnSend);
|
||||||
|
Controls.Add(lblHeader);
|
||||||
|
Controls.Add(tbEmail);
|
||||||
|
Controls.Add(pbLoginBanner);
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
Name = "ResendVerificationEmail";
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
Text = "QtC.NET Client - Resend Verification Email";
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbLoginBanner).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private PictureBox pbLoginBanner;
|
||||||
|
private TextBox tbEmail;
|
||||||
|
private Label lblHeader;
|
||||||
|
private Button btnSend;
|
||||||
|
}
|
||||||
|
}
|
43
qtc-net-client-2/Forms/ResendVerificationEmail.cs
Normal file
43
qtc-net-client-2/Forms/ResendVerificationEmail.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using QtCNETAPI.Services.ApiService;
|
||||||
|
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 qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
public partial class ResendVerificationEmail : Form
|
||||||
|
{
|
||||||
|
private IApiService _apiService;
|
||||||
|
public ResendVerificationEmail(IApiService apiService)
|
||||||
|
{
|
||||||
|
_apiService = apiService;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnSend_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(!string.IsNullOrEmpty(tbEmail.Text))
|
||||||
|
{
|
||||||
|
tbEmail.Enabled = false;
|
||||||
|
btnSend.Enabled = false;
|
||||||
|
|
||||||
|
var result = await _apiService.ResendVerificationEmail(tbEmail.Text);
|
||||||
|
if(result != null && result.Success && result.Data)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Got It! You should receive an email shortly.\nIf you do not receive an email, check your spam.", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
Close();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Sorry, This Server Doesn't Have Email Features Enabled Or Something Went Wrong.\nIf you cannot login, you may need to contact the server admin.", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
qtc-net-client-2/Forms/ResendVerificationEmail.resx
Normal file
120
qtc-net-client-2/Forms/ResendVerificationEmail.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
221
qtc-net-client-2/Forms/ResetPassword.Designer.cs
generated
Normal file
221
qtc-net-client-2/Forms/ResetPassword.Designer.cs
generated
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
partial class ResetPassword
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
pEmailBox = new Panel();
|
||||||
|
btnSend = new Button();
|
||||||
|
lblHeader = new Label();
|
||||||
|
tbEmail = new TextBox();
|
||||||
|
pResetPasswordBox = new Panel();
|
||||||
|
btnResetPassword = new Button();
|
||||||
|
tbConfirmPassword = new TextBox();
|
||||||
|
lblConfirmPassword = new Label();
|
||||||
|
tbNewPassword = new TextBox();
|
||||||
|
lblNewPassword = new Label();
|
||||||
|
tbToken = new TextBox();
|
||||||
|
lblToken = new Label();
|
||||||
|
pbLoginBanner = new PictureBox();
|
||||||
|
pEmailBox.SuspendLayout();
|
||||||
|
pResetPasswordBox.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbLoginBanner).BeginInit();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// pEmailBox
|
||||||
|
//
|
||||||
|
pEmailBox.Anchor = AnchorStyles.Bottom;
|
||||||
|
pEmailBox.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
pEmailBox.Controls.Add(btnSend);
|
||||||
|
pEmailBox.Controls.Add(lblHeader);
|
||||||
|
pEmailBox.Controls.Add(tbEmail);
|
||||||
|
pEmailBox.Location = new Point(101, 125);
|
||||||
|
pEmailBox.Name = "pEmailBox";
|
||||||
|
pEmailBox.Size = new Size(458, 94);
|
||||||
|
pEmailBox.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// btnSend
|
||||||
|
//
|
||||||
|
btnSend.Location = new Point(193, 59);
|
||||||
|
btnSend.Name = "btnSend";
|
||||||
|
btnSend.Size = new Size(75, 23);
|
||||||
|
btnSend.TabIndex = 9;
|
||||||
|
btnSend.Text = "Send";
|
||||||
|
btnSend.UseVisualStyleBackColor = true;
|
||||||
|
btnSend.Click += btnSend_Click;
|
||||||
|
//
|
||||||
|
// lblHeader
|
||||||
|
//
|
||||||
|
lblHeader.AutoSize = true;
|
||||||
|
lblHeader.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblHeader.ForeColor = SystemColors.ControlLight;
|
||||||
|
lblHeader.Location = new Point(23, 12);
|
||||||
|
lblHeader.Name = "lblHeader";
|
||||||
|
lblHeader.Size = new Size(412, 15);
|
||||||
|
lblHeader.TabIndex = 8;
|
||||||
|
lblHeader.Text = "Please Enter Your Email, If An Account Exists With This Email, We'll Send You A Link";
|
||||||
|
//
|
||||||
|
// tbEmail
|
||||||
|
//
|
||||||
|
tbEmail.Location = new Point(19, 30);
|
||||||
|
tbEmail.Name = "tbEmail";
|
||||||
|
tbEmail.Size = new Size(424, 23);
|
||||||
|
tbEmail.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// pResetPasswordBox
|
||||||
|
//
|
||||||
|
pResetPasswordBox.Anchor = AnchorStyles.Bottom;
|
||||||
|
pResetPasswordBox.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
pResetPasswordBox.Controls.Add(btnResetPassword);
|
||||||
|
pResetPasswordBox.Controls.Add(tbConfirmPassword);
|
||||||
|
pResetPasswordBox.Controls.Add(lblConfirmPassword);
|
||||||
|
pResetPasswordBox.Controls.Add(tbNewPassword);
|
||||||
|
pResetPasswordBox.Controls.Add(lblNewPassword);
|
||||||
|
pResetPasswordBox.Controls.Add(tbToken);
|
||||||
|
pResetPasswordBox.Controls.Add(lblToken);
|
||||||
|
pResetPasswordBox.Location = new Point(17, 106);
|
||||||
|
pResetPasswordBox.Name = "pResetPasswordBox";
|
||||||
|
pResetPasswordBox.Size = new Size(596, 138);
|
||||||
|
pResetPasswordBox.TabIndex = 1;
|
||||||
|
pResetPasswordBox.Visible = false;
|
||||||
|
//
|
||||||
|
// btnResetPassword
|
||||||
|
//
|
||||||
|
btnResetPassword.Location = new Point(270, 102);
|
||||||
|
btnResetPassword.Name = "btnResetPassword";
|
||||||
|
btnResetPassword.Size = new Size(100, 23);
|
||||||
|
btnResetPassword.TabIndex = 15;
|
||||||
|
btnResetPassword.Text = "Reset Password";
|
||||||
|
btnResetPassword.UseVisualStyleBackColor = true;
|
||||||
|
btnResetPassword.Click += btnResetPassword_Click;
|
||||||
|
//
|
||||||
|
// tbConfirmPassword
|
||||||
|
//
|
||||||
|
tbConfirmPassword.Location = new Point(123, 73);
|
||||||
|
tbConfirmPassword.Name = "tbConfirmPassword";
|
||||||
|
tbConfirmPassword.PasswordChar = '*';
|
||||||
|
tbConfirmPassword.Size = new Size(424, 23);
|
||||||
|
tbConfirmPassword.TabIndex = 14;
|
||||||
|
//
|
||||||
|
// lblConfirmPassword
|
||||||
|
//
|
||||||
|
lblConfirmPassword.AutoSize = true;
|
||||||
|
lblConfirmPassword.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblConfirmPassword.ForeColor = SystemColors.ControlLight;
|
||||||
|
lblConfirmPassword.Location = new Point(20, 76);
|
||||||
|
lblConfirmPassword.Name = "lblConfirmPassword";
|
||||||
|
lblConfirmPassword.Size = new Size(97, 15);
|
||||||
|
lblConfirmPassword.TabIndex = 13;
|
||||||
|
lblConfirmPassword.Text = "Confirm Password";
|
||||||
|
//
|
||||||
|
// tbNewPassword
|
||||||
|
//
|
||||||
|
tbNewPassword.Location = new Point(123, 44);
|
||||||
|
tbNewPassword.Name = "tbNewPassword";
|
||||||
|
tbNewPassword.PasswordChar = '*';
|
||||||
|
tbNewPassword.Size = new Size(424, 23);
|
||||||
|
tbNewPassword.TabIndex = 12;
|
||||||
|
//
|
||||||
|
// lblNewPassword
|
||||||
|
//
|
||||||
|
lblNewPassword.AutoSize = true;
|
||||||
|
lblNewPassword.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblNewPassword.ForeColor = SystemColors.ControlLight;
|
||||||
|
lblNewPassword.Location = new Point(36, 47);
|
||||||
|
lblNewPassword.Name = "lblNewPassword";
|
||||||
|
lblNewPassword.Size = new Size(81, 15);
|
||||||
|
lblNewPassword.TabIndex = 11;
|
||||||
|
lblNewPassword.Text = "New Password";
|
||||||
|
//
|
||||||
|
// tbToken
|
||||||
|
//
|
||||||
|
tbToken.Location = new Point(123, 15);
|
||||||
|
tbToken.Name = "tbToken";
|
||||||
|
tbToken.Size = new Size(424, 23);
|
||||||
|
tbToken.TabIndex = 10;
|
||||||
|
//
|
||||||
|
// lblToken
|
||||||
|
//
|
||||||
|
lblToken.AutoSize = true;
|
||||||
|
lblToken.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblToken.ForeColor = SystemColors.ControlLight;
|
||||||
|
lblToken.Location = new Point(82, 18);
|
||||||
|
lblToken.Name = "lblToken";
|
||||||
|
lblToken.Size = new Size(35, 15);
|
||||||
|
lblToken.TabIndex = 9;
|
||||||
|
lblToken.Text = "Token";
|
||||||
|
//
|
||||||
|
// pbLoginBanner
|
||||||
|
//
|
||||||
|
pbLoginBanner.Image = Properties.Resources.LoginBanner;
|
||||||
|
pbLoginBanner.Location = new Point(-3, -1);
|
||||||
|
pbLoginBanner.Name = "pbLoginBanner";
|
||||||
|
pbLoginBanner.Size = new Size(521, 99);
|
||||||
|
pbLoginBanner.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
pbLoginBanner.TabIndex = 2;
|
||||||
|
pbLoginBanner.TabStop = false;
|
||||||
|
//
|
||||||
|
// ResetPassword
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
BackColor = Color.DodgerBlue;
|
||||||
|
ClientSize = new Size(622, 256);
|
||||||
|
Controls.Add(pEmailBox);
|
||||||
|
Controls.Add(pResetPasswordBox);
|
||||||
|
Controls.Add(pbLoginBanner);
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
Name = "ResetPassword";
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
Text = "QtC.NET Client - Reset Password";
|
||||||
|
pEmailBox.ResumeLayout(false);
|
||||||
|
pEmailBox.PerformLayout();
|
||||||
|
pResetPasswordBox.ResumeLayout(false);
|
||||||
|
pResetPasswordBox.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbLoginBanner).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Panel pEmailBox;
|
||||||
|
private Button btnSend;
|
||||||
|
private Label lblHeader;
|
||||||
|
private TextBox tbEmail;
|
||||||
|
private Panel pResetPasswordBox;
|
||||||
|
private TextBox tbConfirmPassword;
|
||||||
|
private Label lblConfirmPassword;
|
||||||
|
private TextBox tbNewPassword;
|
||||||
|
private Label lblNewPassword;
|
||||||
|
private TextBox tbToken;
|
||||||
|
private Label lblToken;
|
||||||
|
private Button btnResetPassword;
|
||||||
|
private PictureBox pbLoginBanner;
|
||||||
|
}
|
||||||
|
}
|
68
qtc-net-client-2/Forms/ResetPassword.cs
Normal file
68
qtc-net-client-2/Forms/ResetPassword.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using QtCNETAPI.Services.ApiService;
|
||||||
|
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 qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
public partial class ResetPassword : Form
|
||||||
|
{
|
||||||
|
private IApiService _apiService;
|
||||||
|
public ResetPassword(IApiService apiService)
|
||||||
|
{
|
||||||
|
_apiService = apiService;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnSend_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(tbEmail.Text))
|
||||||
|
{
|
||||||
|
tbEmail.Enabled = false;
|
||||||
|
btnSend.Enabled = false;
|
||||||
|
|
||||||
|
var result = await _apiService.SendPasswordResetEmail(tbEmail.Text);
|
||||||
|
if (result != null && result.Success && result.Data)
|
||||||
|
{
|
||||||
|
pEmailBox.Visible = false;
|
||||||
|
pResetPasswordBox.Visible = true;
|
||||||
|
|
||||||
|
MessageBox.Show("Got It! You should receive an email shortly.\nIf you do not receive an email, check your spam.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Sorry, This Server Doesn't Have Email Features Enabled Or Something Went Wrong.\nIf you cannot login, you may need to contact the server admin.", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnResetPassword_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(!string.IsNullOrEmpty(tbToken.Text) && !string.IsNullOrEmpty(tbNewPassword.Text) && !string.IsNullOrEmpty(tbConfirmPassword.Text))
|
||||||
|
{
|
||||||
|
tbToken.Enabled = false;
|
||||||
|
tbNewPassword.Enabled = false;
|
||||||
|
tbConfirmPassword.Enabled = false;
|
||||||
|
btnResetPassword.Enabled = false;
|
||||||
|
|
||||||
|
var result = await _apiService.ResetPassword(new QtCNETAPI.Dtos.User.UserPasswordResetDto { Token = tbToken.Text, Password = tbNewPassword.Text });
|
||||||
|
if(result != null && result.Success && result.Data)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Your Password Has Been Reset. You may now login with the new password.", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
Close();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
MessageBox.Show(result?.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
qtc-net-client-2/Forms/ResetPassword.resx
Normal file
120
qtc-net-client-2/Forms/ResetPassword.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
12
qtc-net-client-2/Forms/StockMarketGame.Designer.cs
generated
12
qtc-net-client-2/Forms/StockMarketGame.Designer.cs
generated
@ -52,7 +52,7 @@
|
|||||||
pStockManagement.Controls.Add(btnSell);
|
pStockManagement.Controls.Add(btnSell);
|
||||||
pStockManagement.Controls.Add(btnBuy);
|
pStockManagement.Controls.Add(btnBuy);
|
||||||
pStockManagement.Controls.Add(lblStockCount);
|
pStockManagement.Controls.Add(lblStockCount);
|
||||||
pStockManagement.Location = new Point(242, 134);
|
pStockManagement.Location = new Point(230, 138);
|
||||||
pStockManagement.Name = "pStockManagement";
|
pStockManagement.Name = "pStockManagement";
|
||||||
pStockManagement.Size = new Size(135, 81);
|
pStockManagement.Size = new Size(135, 81);
|
||||||
pStockManagement.TabIndex = 3;
|
pStockManagement.TabIndex = 3;
|
||||||
@ -106,7 +106,7 @@
|
|||||||
pMarketStatus.Controls.Add(lblMarketStatus);
|
pMarketStatus.Controls.Add(lblMarketStatus);
|
||||||
pMarketStatus.Controls.Add(pbDollarSignRight);
|
pMarketStatus.Controls.Add(pbDollarSignRight);
|
||||||
pMarketStatus.Controls.Add(pbDollarSignLeft);
|
pMarketStatus.Controls.Add(pbDollarSignLeft);
|
||||||
pMarketStatus.Location = new Point(9, 7);
|
pMarketStatus.Location = new Point(3, 7);
|
||||||
pMarketStatus.Name = "pMarketStatus";
|
pMarketStatus.Name = "pMarketStatus";
|
||||||
pMarketStatus.Size = new Size(586, 100);
|
pMarketStatus.Size = new Size(586, 100);
|
||||||
pMarketStatus.TabIndex = 4;
|
pMarketStatus.TabIndex = 4;
|
||||||
@ -135,7 +135,7 @@
|
|||||||
// pbDollarSignRight
|
// pbDollarSignRight
|
||||||
//
|
//
|
||||||
pbDollarSignRight.Image = Properties.Resources.dollar_money;
|
pbDollarSignRight.Image = Properties.Resources.dollar_money;
|
||||||
pbDollarSignRight.Location = new Point(498, 3);
|
pbDollarSignRight.Location = new Point(500, 3);
|
||||||
pbDollarSignRight.Name = "pbDollarSignRight";
|
pbDollarSignRight.Name = "pbDollarSignRight";
|
||||||
pbDollarSignRight.Size = new Size(83, 94);
|
pbDollarSignRight.Size = new Size(83, 94);
|
||||||
pbDollarSignRight.SizeMode = PictureBoxSizeMode.Zoom;
|
pbDollarSignRight.SizeMode = PictureBoxSizeMode.Zoom;
|
||||||
@ -145,7 +145,7 @@
|
|||||||
// pbDollarSignLeft
|
// pbDollarSignLeft
|
||||||
//
|
//
|
||||||
pbDollarSignLeft.Image = Properties.Resources.dollar_money;
|
pbDollarSignLeft.Image = Properties.Resources.dollar_money;
|
||||||
pbDollarSignLeft.Location = new Point(6, 3);
|
pbDollarSignLeft.Location = new Point(3, 3);
|
||||||
pbDollarSignLeft.Name = "pbDollarSignLeft";
|
pbDollarSignLeft.Name = "pbDollarSignLeft";
|
||||||
pbDollarSignLeft.Size = new Size(83, 94);
|
pbDollarSignLeft.Size = new Size(83, 94);
|
||||||
pbDollarSignLeft.SizeMode = PictureBoxSizeMode.Zoom;
|
pbDollarSignLeft.SizeMode = PictureBoxSizeMode.Zoom;
|
||||||
@ -156,7 +156,7 @@
|
|||||||
//
|
//
|
||||||
btnRefresh.Enabled = false;
|
btnRefresh.Enabled = false;
|
||||||
btnRefresh.ForeColor = Color.Black;
|
btnRefresh.ForeColor = Color.Black;
|
||||||
btnRefresh.Location = new Point(282, 109);
|
btnRefresh.Location = new Point(270, 113);
|
||||||
btnRefresh.Name = "btnRefresh";
|
btnRefresh.Name = "btnRefresh";
|
||||||
btnRefresh.Size = new Size(56, 23);
|
btnRefresh.Size = new Size(56, 23);
|
||||||
btnRefresh.TabIndex = 10;
|
btnRefresh.TabIndex = 10;
|
||||||
@ -169,7 +169,7 @@
|
|||||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
AutoScaleMode = AutoScaleMode.Font;
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
BackColor = Color.DodgerBlue;
|
BackColor = Color.DodgerBlue;
|
||||||
ClientSize = new Size(606, 227);
|
ClientSize = new Size(595, 227);
|
||||||
Controls.Add(btnRefresh);
|
Controls.Add(btnRefresh);
|
||||||
Controls.Add(pMarketStatus);
|
Controls.Add(pMarketStatus);
|
||||||
Controls.Add(pStockManagement);
|
Controls.Add(pStockManagement);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using qtc_net_client_2.Services;
|
using QtCNETAPI.Dtos.User;
|
||||||
using QtCNETAPI.Dtos.User;
|
|
||||||
using QtCNETAPI.Schema;
|
using QtCNETAPI.Schema;
|
||||||
|
using QtCNETAPI.Services;
|
||||||
using QtCNETAPI.Services.ApiService;
|
using QtCNETAPI.Services.ApiService;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using qtc_net_client_2.ClientModel;
|
using qtc_net_client_2.ClientModel;
|
||||||
using qtc_net_client_2.Services;
|
using qtc_net_client_2.Services;
|
||||||
|
using QtCNETAPI.Services;
|
||||||
using QtCNETAPI.Services.ApiService;
|
using QtCNETAPI.Services.ApiService;
|
||||||
using QtCNETAPI.Services.GatewayService;
|
using QtCNETAPI.Services.GatewayService;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@ -52,8 +53,8 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
// instantiate new ApiService and GatewayService for this session
|
// instantiate new ApiService and GatewayService for this session
|
||||||
// this will keep the gateway thread in the main thread (i think)
|
// this will keep the gateway thread in the main thread (i think)
|
||||||
IApiService api = new ApiService($"{clientConfig.ServerUrl}/api");
|
IApiService api = new ApiService($"{clientConfig.ServerUrl}/api", loggingService);
|
||||||
IGatewayService gateway = new GatewayService($"{clientConfig.ServerUrl}/chat", api);
|
IGatewayService gateway = new GatewayService($"{clientConfig.ServerUrl}/chat", api, loggingService);
|
||||||
|
|
||||||
// ping api
|
// ping api
|
||||||
var pingResult = await api.PingServerAsync();
|
var pingResult = await api.PingServerAsync();
|
||||||
|
@ -81,7 +81,7 @@ namespace qtc_net_client_2.Properties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to 6.1.
|
/// Looks up a localized string similar to 6.3.4.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string AssemblyVersion {
|
internal static string AssemblyVersion {
|
||||||
get {
|
get {
|
||||||
|
@ -118,9 +118,6 @@
|
|||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
<data name="AddContactIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
|
||||||
<value>..\Icons\AddContactIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
|
||||||
</data>
|
|
||||||
<data name="right-horn-animated" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="right-horn-animated" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Anims\right-horn-animated.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Anims\right-horn-animated.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
@ -157,8 +154,8 @@
|
|||||||
<data name="CurrencyIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="CurrencyIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Icons\CurrencyIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Icons\CurrencyIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DefaultPfp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="AddContactIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\DefaultPfp.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Icons\AddContactIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RequestSentIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="RequestSentIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Icons\RequestSentIcon.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>..\Icons\RequestSentIcon.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
@ -176,7 +173,10 @@
|
|||||||
<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.1</value>
|
<value>6.3.4</value>
|
||||||
|
</data>
|
||||||
|
<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>
|
||||||
</data>
|
</data>
|
||||||
<data name="LoginBanner" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="LoginBanner" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\LoginBanner.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Resources\LoginBanner.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
@ -190,7 +190,7 @@
|
|||||||
<data name="AcceptContactIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="AcceptContactIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Icons\AcceptContactIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Icons\AcceptContactIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="cobalt_sittingatputer" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="DefaultPfp" 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\DefaultPfp.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
Binary file not shown.
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 13 KiB |
Loading…
x
Reference in New Issue
Block a user