Compare commits
61 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 | |||
fca34d5479 | |||
932ee5fe62 | |||
34f478213e | |||
ffa44ff036 | |||
217e3f301a | |||
28358f44f8 | |||
eb9fd6c8cf | |||
a325a622a5 | |||
0c76a206f7 | |||
502dda6436 | |||
868f6fa067 | |||
003d01fe4e | |||
0d93557959 | |||
9fecd1fb74 | |||
074b68c698 | |||
922528c61c | |||
846a477587 | |||
ad5345512a | |||
37a7807008 | |||
53fab11f88 | |||
042671da91 | |||
7b599863d8 | |||
ee79d53aab | |||
a008c7c942 | |||
43c0b8fd24 | |||
e73b7d8704 | |||
e6238fcc9a | |||
315be1d4ad | |||
98111778db | |||
9055e6524d | |||
54a0c0d963 | |||
eac4631e12 | |||
82c66aad44 | |||
fb15211f23 | |||
68def5ac1f |
@ -11,5 +11,6 @@
|
|||||||
public DateTime CreatedAt { get; set; } = new DateTime();
|
public DateTime CreatedAt { get; set; } = new DateTime();
|
||||||
public int Status { get; set; } = 0;
|
public int Status { get; set; } = 0;
|
||||||
public int CurrencyAmount { get; set; } = 0;
|
public int CurrencyAmount { get; set; } = 0;
|
||||||
|
public int ProfileCosmeticId { get; set; } = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
8
QtCNETAPI/Dtos/User/UserStockActionResultDto.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace QtCNETAPI.Dtos.User
|
||||||
|
{
|
||||||
|
public class UserStockActionResultDto
|
||||||
|
{
|
||||||
|
public int StockAmount { get; set; }
|
||||||
|
public int CurrencyAmount { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -6,5 +6,6 @@
|
|||||||
public string Username { get; set; } = string.Empty;
|
public string Username { get; set; } = string.Empty;
|
||||||
public string Bio { get; set; } = string.Empty;
|
public string Bio { get; set; } = string.Empty;
|
||||||
public DateTime DateOfBirth { get; set; } = new DateTime();
|
public DateTime DateOfBirth { get; set; } = new DateTime();
|
||||||
|
public int ProfileCosmeticId { get; set; } = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
QtCNETAPI/Enums/GameStatus.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace QtCNETAPI.Enums
|
||||||
|
{
|
||||||
|
public enum GameStatus
|
||||||
|
{
|
||||||
|
WaitingForPlayer,
|
||||||
|
SelectingSymbol,
|
||||||
|
Ongoing,
|
||||||
|
P1Win,
|
||||||
|
P2Win,
|
||||||
|
NoWin,
|
||||||
|
PlayerDisconnected
|
||||||
|
}
|
||||||
|
}
|
16
QtCNETAPI/Enums/NumberGuessResult.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Enums
|
||||||
|
{
|
||||||
|
public enum NumberGuessResult
|
||||||
|
{
|
||||||
|
Higher,
|
||||||
|
Lower,
|
||||||
|
Correct,
|
||||||
|
Incorrect
|
||||||
|
}
|
||||||
|
}
|
8
QtCNETAPI/Enums/StoreItemType.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace QtCNETAPI.Enums
|
||||||
|
{
|
||||||
|
public enum StoreItemType
|
||||||
|
{
|
||||||
|
ProfileCosmetic = 1,
|
||||||
|
ClientCosmetic = 2
|
||||||
|
}
|
||||||
|
}
|
9
QtCNETAPI/Enums/TicTacToeSymbol.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace QtCNETAPI.Enums
|
||||||
|
{
|
||||||
|
public enum TicTacToeSymbol
|
||||||
|
{
|
||||||
|
X,
|
||||||
|
O,
|
||||||
|
Blank
|
||||||
|
}
|
||||||
|
}
|
13
QtCNETAPI/Events/GuestUserJoinEventArgs.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Events
|
||||||
|
{
|
||||||
|
public class GuestUserJoinEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public required string Username { get; set; }
|
||||||
|
}
|
||||||
|
}
|
14
QtCNETAPI/Events/RoomListEventArgs.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using QtCNETAPI.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Events
|
||||||
|
{
|
||||||
|
public class RoomListEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public required List<User> UserList { get; set; }
|
||||||
|
}
|
||||||
|
}
|
14
QtCNETAPI/Models/OwnedStoreItem.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Models
|
||||||
|
{
|
||||||
|
public class OwnedStoreItem
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string UserId { get; set; } = string.Empty;
|
||||||
|
public int StoreItemId { get; set; }
|
||||||
|
|
||||||
|
public virtual User? User { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -13,10 +13,13 @@
|
|||||||
public DateTime CreatedAt { get; set; }
|
public DateTime CreatedAt { get; set; }
|
||||||
public int Status { get; set; } = 0;
|
public int Status { get; set; } = 0;
|
||||||
public int CurrencyAmount { get; set; } = 0;
|
public int CurrencyAmount { get; set; } = 0;
|
||||||
|
public int StockAmount { get; set; } = 0;
|
||||||
public DateTime LastCurrencySpin { get; set; }
|
public DateTime LastCurrencySpin { get; set; }
|
||||||
|
public int ActiveProfileCosmetic { get; set; } = 0;
|
||||||
|
|
||||||
public virtual IEnumerable<RefreshToken>? RefreshTokens { get; }
|
public virtual IEnumerable<RefreshToken>? RefreshTokens { get; }
|
||||||
public virtual IEnumerable<Contact>? ContactsMade { get; }
|
public virtual IEnumerable<Contact>? ContactsMade { get; }
|
||||||
public virtual IEnumerable<Contact>? ContactsList { get; }
|
public virtual IEnumerable<Contact>? ContactsList { get; }
|
||||||
|
public virtual IEnumerable<OwnedStoreItem>? OwnedStoreItems { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
16
QtCNETAPI/Schema/GameRoom.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using QtCNETAPI.Enums;
|
||||||
|
using QtCNETAPI.Models;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Schema
|
||||||
|
{
|
||||||
|
public class GameRoom
|
||||||
|
{
|
||||||
|
public string Id { get; set; } = string.Empty;
|
||||||
|
public GameStatus Status { get; set; }
|
||||||
|
public TicTacToeBoard Board { get; set; } = new();
|
||||||
|
public User? Player1 { get; set; }
|
||||||
|
public TicTacToeSymbol P1Symbol { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
public User? Player2 { get; set; }
|
||||||
|
public TicTacToeSymbol P2Symbol { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
}
|
||||||
|
}
|
23
QtCNETAPI/Schema/StoreItem.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using QtCNETAPI.Enums;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Schema
|
||||||
|
{
|
||||||
|
public class StoreItem
|
||||||
|
{
|
||||||
|
[JsonPropertyName("Id")]
|
||||||
|
public int Id { get; set; }
|
||||||
|
[JsonPropertyName("Type")]
|
||||||
|
public StoreItemType Type { get; set; }
|
||||||
|
[JsonPropertyName("Price")]
|
||||||
|
public int Price { get; set; }
|
||||||
|
[JsonPropertyName("Name")]
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
[JsonPropertyName("Description")]
|
||||||
|
public string Description { get; set; } = string.Empty;
|
||||||
|
[JsonPropertyName("AssetUrl")]
|
||||||
|
public string AssetUrl { get; set; } = string.Empty;
|
||||||
|
[JsonPropertyName("ThumbnailUrl")]
|
||||||
|
public string ThumbnailUrl { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
17
QtCNETAPI/Schema/TicTacToeBoard.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using QtCNETAPI.Enums;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Schema
|
||||||
|
{
|
||||||
|
public class TicTacToeBoard
|
||||||
|
{
|
||||||
|
public TicTacToeSymbol Square1 { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
public TicTacToeSymbol Square2 { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
public TicTacToeSymbol Square3 { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
public TicTacToeSymbol Square4 { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
public TicTacToeSymbol Square5 { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
public TicTacToeSymbol Square6 { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
public TicTacToeSymbol Square7 { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
public TicTacToeSymbol Square8 { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
public TicTacToeSymbol Square9 { get; set; } = TicTacToeSymbol.Blank;
|
||||||
|
}
|
||||||
|
}
|
10
QtCNETAPI/Schema/TicTacToeMove.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using QtCNETAPI.Models;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Schema
|
||||||
|
{
|
||||||
|
public class TicTacToeMove
|
||||||
|
{
|
||||||
|
public User User { get; set; } = new();
|
||||||
|
public int Point { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
using QtCNETAPI.Dtos.Room;
|
using QtCNETAPI.Dtos.Room;
|
||||||
using QtCNETAPI.Dtos.User;
|
using QtCNETAPI.Dtos.User;
|
||||||
|
using QtCNETAPI.Enums;
|
||||||
using QtCNETAPI.Models;
|
using QtCNETAPI.Models;
|
||||||
|
using QtCNETAPI.Schema;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@ -11,10 +13,15 @@ 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;
|
||||||
|
|
||||||
|
public event EventHandler? OnCurrentUserUpdate;
|
||||||
|
|
||||||
public string? SessionToken
|
public string? SessionToken
|
||||||
{
|
{
|
||||||
get { return sessionToken; }
|
get { return sessionToken; }
|
||||||
@ -26,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +64,32 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
return serviceResponse;
|
return serviceResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<List<UserInformationDto>>> GetAllUsersAsync()
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<List<UserInformationDto>>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var request = new RestRequest("users/all")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}");
|
||||||
|
var response = await _client.GetAsync<ServiceResponse<List<UserInformationDto>>>(request);
|
||||||
|
|
||||||
|
if (response != null || response!.Data != null)
|
||||||
|
{
|
||||||
|
serviceResponse.Success = true;
|
||||||
|
serviceResponse.Data = response.Data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serviceResponse.Success = false;
|
||||||
|
serviceResponse.Message = "API didn't respond with users.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<ServiceResponse<List<UserInformationDto>>> GetOnlineUsersAsync()
|
public async Task<ServiceResponse<List<UserInformationDto>>> GetOnlineUsersAsync()
|
||||||
{
|
{
|
||||||
await RefreshSessionIfInvalid();
|
await RefreshSessionIfInvalid();
|
||||||
@ -123,10 +157,9 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
serviceResponse.Success = true;
|
serviceResponse.Success = true;
|
||||||
serviceResponse.Data = response.Data;
|
serviceResponse.Data = response.Data;
|
||||||
|
|
||||||
// update currentuser model
|
// anything that changes the user should tell the api service to set it again
|
||||||
CurrentUser!.Username = response.Data!.Username;
|
await SetCurrentUser();
|
||||||
CurrentUser.Bio = response.Data.Bio;
|
OnCurrentUserUpdate?.Invoke(this, EventArgs.Empty);
|
||||||
CurrentUser.DateOfBirth = response.Data.DateOfBirth;
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
serviceResponse.Success = false;
|
serviceResponse.Success = false;
|
||||||
@ -152,6 +185,10 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
{
|
{
|
||||||
serviceResponse.Success = true;
|
serviceResponse.Success = true;
|
||||||
serviceResponse.Data = response.Data;
|
serviceResponse.Data = response.Data;
|
||||||
|
|
||||||
|
// anything that changes the user should tell the api service to set it again
|
||||||
|
await SetCurrentUser();
|
||||||
|
OnCurrentUserUpdate?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -200,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
|
||||||
{
|
{
|
||||||
@ -222,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
|
||||||
{
|
{
|
||||||
@ -245,16 +280,85 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
return serviceResponse;
|
return serviceResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<User> SetCurrentUser()
|
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()
|
||||||
{
|
{
|
||||||
var userRequest = new RestRequest("users/user-authorized")
|
var userRequest = new RestRequest("users/user-authorized")
|
||||||
.AddHeader("Authorization", $"Bearer {SessionToken}");
|
.AddHeader("Authorization", $"Bearer {SessionToken}");
|
||||||
var userResponse = await _client.GetAsync<ServiceResponse<User>>(userRequest);
|
var userResponse = await _client.GetAsync<ServiceResponse<User>>(userRequest);
|
||||||
|
|
||||||
if (userResponse != null || userResponse!.Data != null)
|
if (userResponse != null && userResponse.Success && userResponse.Data != null)
|
||||||
{
|
{
|
||||||
user = userResponse.Data;
|
user = userResponse.Data;
|
||||||
return userResponse.Data!;
|
|
||||||
|
_loggingService.LogString($"Current User's Status Is {userResponse.Data.Status}");
|
||||||
|
|
||||||
|
return userResponse.Data;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
throw new NullReferenceException("Current User could not be set.");
|
throw new NullReferenceException("Current User could not be set.");
|
||||||
@ -309,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 };
|
||||||
}
|
}
|
||||||
@ -558,6 +664,283 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
|
|
||||||
if (response == null) { serviceResponse.Success = false; serviceResponse.Message = "API did not respond."; return serviceResponse; }
|
if (response == null) { serviceResponse.Success = false; serviceResponse.Message = "API did not respond."; return serviceResponse; }
|
||||||
|
|
||||||
|
if (response.Success)
|
||||||
|
{
|
||||||
|
serviceResponse.Success = true;
|
||||||
|
serviceResponse.Data = response.Data;
|
||||||
|
|
||||||
|
// anything that changes the user should tell the api service to set it again
|
||||||
|
await SetCurrentUser();
|
||||||
|
OnCurrentUserUpdate?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<int>> GetCurrentStockPrice()
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<int>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("games/stock-market/current-price")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}");
|
||||||
|
var response = await _client.GetAsync<ServiceResponse<int>>(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<UserStockActionResultDto>> BuyStock(int amount)
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<UserStockActionResultDto>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("games/stock-market/buy-stock")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}")
|
||||||
|
.AddQueryParameter("amount", amount);
|
||||||
|
var response = await _client.PostAsync<ServiceResponse<UserStockActionResultDto>>(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;
|
||||||
|
|
||||||
|
// anything that changes the user should tell the api service to set it again
|
||||||
|
await SetCurrentUser();
|
||||||
|
OnCurrentUserUpdate?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<UserStockActionResultDto>> SellStock(int amount)
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<UserStockActionResultDto>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("games/stock-market/sell-stock")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}")
|
||||||
|
.AddQueryParameter("amount", amount);
|
||||||
|
var response = await _client.PostAsync<ServiceResponse<UserStockActionResultDto>>(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;
|
||||||
|
|
||||||
|
// anything that changes the user should tell the api service to set it again
|
||||||
|
await SetCurrentUser();
|
||||||
|
OnCurrentUserUpdate?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<int>> GetRandomNumber()
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<int>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("games/number-guess/get-number")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}");
|
||||||
|
var response = await _client.GetAsync<ServiceResponse<int>>(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<NumberGuessResult>> GuessRandomNumber(int original, int guess)
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<NumberGuessResult>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("games/number-guess/guess-number")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}")
|
||||||
|
.AddQueryParameter("original", original)
|
||||||
|
.AddQueryParameter("guess", guess);
|
||||||
|
var response = await _client.GetAsync<ServiceResponse<NumberGuessResult>>(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<List<StoreItem>>> GetStoreItems()
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<List<StoreItem>>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("store/all-items")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}");
|
||||||
|
var response = await _client.GetAsync<ServiceResponse<List<StoreItem>>>(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<StoreItem>> GetStoreItem(int id)
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<StoreItem>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("store/item")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}")
|
||||||
|
.AddQueryParameter("id", id);
|
||||||
|
var response = await _client.GetAsync<ServiceResponse<StoreItem>>(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<bool>> BuyStoreItem(int id)
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<bool>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("store/buy-item")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}")
|
||||||
|
.AddQueryParameter("id", id);
|
||||||
|
var response = await _client.PostAsync<ServiceResponse<bool>>(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;
|
||||||
|
|
||||||
|
// anything that changes the user should tell the api service to set it again
|
||||||
|
await SetCurrentUser();
|
||||||
|
OnCurrentUserUpdate?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<List<OwnedStoreItem>>> GetOwnedStoreItems()
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<List<OwnedStoreItem>>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("store/bought-items")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}");
|
||||||
|
var response = await _client.GetAsync<ServiceResponse<List<OwnedStoreItem>>>(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceResponse<OwnedStoreItem>> GetOwnedStoreItem(int id)
|
||||||
|
{
|
||||||
|
await RefreshSessionIfInvalid();
|
||||||
|
|
||||||
|
var serviceResponse = new ServiceResponse<OwnedStoreItem>();
|
||||||
|
|
||||||
|
if (SessionToken == null) throw new NullReferenceException("Function Was Called Before A Session Was Made.");
|
||||||
|
|
||||||
|
var restRequest = new RestRequest("store/bought-item")
|
||||||
|
.AddHeader("Authorization", $"Bearer {SessionToken}")
|
||||||
|
.AddQueryParameter("id", id);
|
||||||
|
var response = await _client.GetAsync<ServiceResponse<OwnedStoreItem>>(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
if (response.Success)
|
||||||
{
|
{
|
||||||
serviceResponse.Success = true;
|
serviceResponse.Success = true;
|
||||||
|
@ -7,6 +7,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using QtCNETAPI.Enums;
|
||||||
|
using QtCNETAPI.Schema;
|
||||||
|
|
||||||
namespace QtCNETAPI.Services.ApiService
|
namespace QtCNETAPI.Services.ApiService
|
||||||
{
|
{
|
||||||
@ -15,11 +17,19 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
public string? SessionToken { get; set; }
|
public string? SessionToken { get; set; }
|
||||||
public User CurrentUser { get; }
|
public User CurrentUser { get; }
|
||||||
|
|
||||||
|
public event EventHandler? OnCurrentUserUpdate;
|
||||||
|
|
||||||
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<User>> LoginAsync(UserLoginDto userLoginDto);
|
public Task<ServiceResponse<List<UserInformationDto>>> GetAllUsersAsync();
|
||||||
|
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<ServiceResponse<User>> RegisterAsync(UserDto userDto);
|
public Task<ServiceResponse<User>> RegisterAsync(UserDto userDto);
|
||||||
public Task<ServiceResponse<UserInformationDto>> GetUserInformationAsync(string id);
|
public Task<ServiceResponse<UserInformationDto>> GetUserInformationAsync(string id);
|
||||||
public Task<ServiceResponse<UserInformationDto>> UpdateUserInformationAsync(UserUpdateInformationDto request);
|
public Task<ServiceResponse<UserInformationDto>> UpdateUserInformationAsync(UserUpdateInformationDto request);
|
||||||
@ -33,5 +43,15 @@ namespace QtCNETAPI.Services.ApiService
|
|||||||
public Task<ServiceResponse<bool>> AcceptContactRequest(string userId);
|
public Task<ServiceResponse<bool>> AcceptContactRequest(string userId);
|
||||||
public Task<ServiceResponse<Contact>> RemoveContactFromCurrentUser(string userId);
|
public Task<ServiceResponse<Contact>> RemoveContactFromCurrentUser(string userId);
|
||||||
public Task<ServiceResponse<int>> AddCurrencyToCurrentUser(int amount, bool isSpinClaim);
|
public Task<ServiceResponse<int>> AddCurrencyToCurrentUser(int amount, bool isSpinClaim);
|
||||||
|
public Task<ServiceResponse<int>> GetCurrentStockPrice();
|
||||||
|
public Task<ServiceResponse<UserStockActionResultDto>> BuyStock(int amount);
|
||||||
|
public Task<ServiceResponse<UserStockActionResultDto>> SellStock(int amount);
|
||||||
|
public Task<ServiceResponse<int>> GetRandomNumber();
|
||||||
|
public Task<ServiceResponse<NumberGuessResult>> GuessRandomNumber(int original, int guess);
|
||||||
|
public Task<ServiceResponse<List<StoreItem>>> GetStoreItems();
|
||||||
|
public Task<ServiceResponse<StoreItem>> GetStoreItem(int id);
|
||||||
|
public Task<ServiceResponse<bool>> BuyStoreItem(int id);
|
||||||
|
public Task<ServiceResponse<List<OwnedStoreItem>>> GetOwnedStoreItems();
|
||||||
|
public Task<ServiceResponse<OwnedStoreItem>> GetOwnedStoreItem(int id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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,60 +7,87 @@ using QtCNETAPI.Services.ApiService;
|
|||||||
|
|
||||||
namespace QtCNETAPI.Services.GatewayService
|
namespace QtCNETAPI.Services.GatewayService
|
||||||
{
|
{
|
||||||
public class GatewayService : IGatewayService
|
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 OnServerMessageReceived;
|
public event EventHandler? OnRoomMessageReceived;
|
||||||
public event EventHandler OnClientFunctionReceived;
|
public event EventHandler? OnRoomUserListReceived;
|
||||||
public event EventHandler OnDirectMessageReceived;
|
public event EventHandler? OnGuestUserJoin;
|
||||||
public event EventHandler OnServerConfigReceived;
|
public event EventHandler? OnRefreshUserListsReceived;
|
||||||
public event EventHandler OnServerDisconnect;
|
public event EventHandler? OnRefreshRoomListReceived;
|
||||||
public event EventHandler OnServerReconnecting;
|
public event EventHandler? OnRoomDeleted;
|
||||||
public event EventHandler OnServerReconnected;
|
public event EventHandler? OnRefreshContactsListReceived;
|
||||||
|
public event EventHandler? OnClientFunctionReceived;
|
||||||
|
public event EventHandler? OnDirectMessageReceived;
|
||||||
|
public event EventHandler? OnServerConfigReceived;
|
||||||
|
public event EventHandler? OnServerDisconnect;
|
||||||
|
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();
|
||||||
|
|
||||||
// start connection
|
|
||||||
await HubConnection.StartAsync();
|
|
||||||
|
|
||||||
// register events
|
// register events
|
||||||
HubConnection.On<string>("rm", (serverMessage) => OnServerMessageReceived?.Invoke(this, new ServerMessageEventArgs{Message = serverMessage}));
|
HubConnection.On<string>("RoomMessage", (serverMessage) => OnRoomMessageReceived?.Invoke(this, new ServerMessageEventArgs { Message = serverMessage }));
|
||||||
HubConnection.On<string>("cf", (function) => OnClientFunctionReceived?.Invoke(this, new ClientFunctionEventArgs{Function = function}));
|
HubConnection.On<string>("cf", (function) => OnClientFunctionReceived?.Invoke(this, new ClientFunctionEventArgs { Function = function }));
|
||||||
HubConnection.On<Message, UserInformationDto>("rdm", (message, user) => OnDirectMessageReceived?.Invoke(this, new DirectMessageEventArgs { Message = message, User = user }));
|
HubConnection.On<Message, UserInformationDto>("ReceiveDirectMessage", (message, user) => OnDirectMessageReceived?.Invoke(this, new DirectMessageEventArgs { Message = message, User = user }));
|
||||||
HubConnection.On<ServerConfig>("rc", (serverConfig) => OnServerConfigReceived?.Invoke(this, new ServerConfigEventArgs{ServerConfig = serverConfig}));
|
HubConnection.On("RefreshUserLists", () => OnRefreshUserListsReceived?.Invoke(this, EventArgs.Empty));
|
||||||
|
HubConnection.On("RefreshRoomList", () => OnRefreshRoomListReceived?.Invoke(this, EventArgs.Empty));
|
||||||
|
HubConnection.On("RefreshContactsList", () => OnRefreshContactsListReceived?.Invoke(this, EventArgs.Empty));
|
||||||
|
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<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;
|
||||||
|
|
||||||
if (HubConnection != null && HubConnection.State == HubConnectionState.Connected)
|
// start connection
|
||||||
await HubConnection.SendAsync("l", _apiService.CurrentUser);
|
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()
|
||||||
@ -70,6 +98,17 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async ValueTask IAsyncDisposable.DisposeAsync()
|
||||||
|
{
|
||||||
|
if (HubConnection != null && HubConnection.State == HubConnectionState.Disconnected)
|
||||||
|
{
|
||||||
|
await HubConnection.DisposeAsync();
|
||||||
|
|
||||||
|
HubConnection = null;
|
||||||
|
CurrentRoom = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task DisposeAsync()
|
public async Task DisposeAsync()
|
||||||
{
|
{
|
||||||
if (HubConnection != null && HubConnection.State == HubConnectionState.Disconnected)
|
if (HubConnection != null && HubConnection.State == HubConnectionState.Disconnected)
|
||||||
@ -83,69 +122,52 @@ 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("jl", _apiService.CurrentUser);
|
await HubConnection.SendAsync("JoinLobby", _apiService.CurrentUser);
|
||||||
InLobby = true;
|
InLobby = true;
|
||||||
CurrentRoom = null;
|
CurrentRoom = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
await HubConnection.SendAsync("ll", _apiService.CurrentUser);
|
await HubConnection.SendAsync("LeaveLobby", _apiService.CurrentUser);
|
||||||
InLobby = false;
|
InLobby = false;
|
||||||
}
|
}
|
||||||
else if (CurrentRoom != null)
|
else if (CurrentRoom != null)
|
||||||
{
|
{
|
||||||
await HubConnection.SendAsync("lr", _apiService.CurrentUser, CurrentRoom);
|
await HubConnection.SendAsync("LeaveRoom", _apiService.CurrentUser, CurrentRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
await HubConnection.SendAsync("jr", _apiService.CurrentUser, room);
|
await HubConnection.SendAsync("JoinRoom", _apiService.CurrentUser, room);
|
||||||
CurrentRoom = room;
|
CurrentRoom = room;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
await HubConnection.SendAsync("ll", _apiService.CurrentUser);
|
await HubConnection.SendAsync("LeaveLobby", _apiService.CurrentUser);
|
||||||
InLobby = false;
|
InLobby = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await HubConnection.SendAsync("lr", _apiService.CurrentUser, CurrentRoom);
|
await HubConnection.SendAsync("LeaveRoom", _apiService.CurrentUser, CurrentRoom);
|
||||||
CurrentRoom = null;
|
CurrentRoom = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RefreshContactsForUser(UserInformationDto user)
|
|
||||||
{
|
|
||||||
await _apiService.RefreshSessionIfInvalid();
|
|
||||||
|
|
||||||
if (HubConnection == null || HubConnection.State != HubConnectionState.Connected) throw new InvalidOperationException("Function was called before connection was made.");
|
|
||||||
|
|
||||||
await HubConnection.SendAsync("rcl", user, _apiService.CurrentUser);
|
|
||||||
}
|
|
||||||
|
|
||||||
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("s", _apiService.CurrentUser, message, InLobby, CurrentRoom);
|
await HubConnection.SendAsync("SendMessage", _apiService.CurrentUser, message, InLobby, CurrentRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendDirectMessageAsync(UserInformationDto user, Message message)
|
public async Task SendDirectMessageAsync(UserInformationDto user, Message message)
|
||||||
@ -154,16 +176,17 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
|
|
||||||
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("sdm", _apiService.CurrentUser, user, message);
|
await HubConnection.SendAsync("SendDirectMessage", _apiService.CurrentUser, user, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
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("us", _apiService.CurrentUser, status);
|
await HubConnection.SendAsync("UpdateStatus", _apiService.CurrentUser, status);
|
||||||
|
|
||||||
|
// anything that changes the user should tell the api service to set it again
|
||||||
|
await _apiService.SetCurrentUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,14 +85,6 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task SendDirectMessageAsync(UserInformationDto user, Message message);
|
public Task SendDirectMessageAsync(UserInformationDto user, Message message);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Refreshes Contacts List For A Specified User
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The User You Wish To Refresh</param>
|
|
||||||
/// <param name="currentUser">Yourself</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public Task RefreshContactsForUser(UserInformationDto user);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates The Status For The Current User
|
/// Updates The Status For The Current User
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -103,9 +95,24 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
// EVENTS
|
// EVENTS
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When A Server Message Is Received, This Event Fires
|
/// When A Room Message Is Received, This Event Fires
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler OnServerMessageReceived;
|
public event EventHandler OnRoomMessageReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires When The User List For A Room Is Received
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler OnRoomUserListReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires When The Room The User Is In Gets Deleted By An Admin
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler OnRoomDeleted;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires When A Guest User Joins Your Room
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler OnGuestUserJoin;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When A Client Function/Event Is Received, This Event Fires
|
/// When A Client Function/Event Is Received, This Event Fires
|
||||||
@ -117,6 +124,21 @@ namespace QtCNETAPI.Services.GatewayService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler OnDirectMessageReceived;
|
public event EventHandler OnDirectMessageReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires When The Client Receives The Request To Refresh Its User List
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler OnRefreshUserListsReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires When The Client Receives The Request To Refresh Its Room List
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler OnRefreshRoomListReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires When The Client Receives The Request To Refresh Its Contacts List
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler OnRefreshContactsListReceived;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When The Server Config Is Received, This Event Fires
|
/// When The Server Config Is Received, This Event Fires
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -136,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
93
QtCNETAPI/Services/LoggingService.cs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.IdentityModel.Abstractions;
|
||||||
|
|
||||||
|
namespace QtCNETAPI.Services
|
||||||
|
{
|
||||||
|
public class LoggingService : IDisposable, ILogger
|
||||||
|
{
|
||||||
|
private DateTime LogDate { get; set; }
|
||||||
|
private string LogFilePath { get; set; }
|
||||||
|
private StreamWriter LogFile { get; set; }
|
||||||
|
public LoggingService()
|
||||||
|
{
|
||||||
|
LogDate = DateTime.Now;
|
||||||
|
LogFilePath = $"./Logs/QtCClientLog_{LogDate:ddMMyyy-hhmm}.log";
|
||||||
|
|
||||||
|
// create log file
|
||||||
|
|
||||||
|
if (!Directory.Exists("./Logs")) Directory.CreateDirectory("./Logs");
|
||||||
|
LogFile = new StreamWriter(File.Create(LogFilePath));
|
||||||
|
|
||||||
|
Debug.WriteLine($"Log File Created At {LogFilePath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogString(string message)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"({DateTime.Now.ToLocalTime():hh:mm}) {message}");
|
||||||
|
LogFile.WriteLine($"({DateTime.Now.ToLocalTime():hh:mm}) {message}");
|
||||||
|
} catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogModel<T>(T model)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// serialize the model as json
|
||||||
|
string modelSerialized = JsonSerializer.Serialize(model, options: new JsonSerializerOptions { WriteIndented = true });
|
||||||
|
|
||||||
|
// log it
|
||||||
|
Debug.WriteLine($"({DateTime.Now.ToLocalTime():hh:mm}) {modelSerialized}");
|
||||||
|
LogFile.WriteLine($"({DateTime.Now.ToLocalTime():hh:mm}) {modelSerialized}");
|
||||||
|
} catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
LogFile.WriteLine("--- END OF LOG ---");
|
||||||
|
LogFile.Close();
|
||||||
|
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() { }
|
||||||
|
}
|
||||||
|
}
|
BIN
qtc-net-client-2/Anims/dollar-money.gif
Normal file
After Width: | Height: | Size: 68 KiB |
25
qtc-net-client-2/ClientModel/ClientUpdateInfo.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace qtc_net_client_2.ClientModel
|
||||||
|
{
|
||||||
|
public class ClientUpdateInfo
|
||||||
|
{
|
||||||
|
[JsonPropertyName("clientFileName")]
|
||||||
|
[JsonRequired]
|
||||||
|
public string ClientFileName { get; set; } = "QtCNetChat.exe";
|
||||||
|
[JsonPropertyName("version")]
|
||||||
|
[JsonRequired]
|
||||||
|
public string Version { get; set; } = string.Empty;
|
||||||
|
[JsonPropertyName("downloadUri")]
|
||||||
|
[JsonRequired]
|
||||||
|
public string DownloadUrl { get; set; } = string.Empty;
|
||||||
|
[JsonPropertyName("updateMandatory")]
|
||||||
|
[JsonRequired]
|
||||||
|
public bool IsUpdateMandatory { get; set; } = false;
|
||||||
|
}
|
||||||
|
}
|
19
qtc-net-client-2/ClientModel/ComboBoxItem.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace qtc_net_client_2.ClientModel
|
||||||
|
{
|
||||||
|
public class ComboBoxItem
|
||||||
|
{
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public object? Value { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Name ?? string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,9 +9,18 @@ namespace qtc_net_client_2.ClientModel
|
|||||||
{
|
{
|
||||||
public class Config
|
public class Config
|
||||||
{
|
{
|
||||||
[JsonPropertyName("apiEndpoint")]
|
[JsonPropertyName("startMinimized")]
|
||||||
public string ApiEndpoint { get; set; } = "https://qtc.alanmoon.net/api";
|
[JsonRequired]
|
||||||
[JsonPropertyName("gatewayEndpoint")]
|
public bool StartMinimized { get; set; } = false;
|
||||||
public string GatewayEndpoint { get; set; } = "https://qtc.alanmoon.net/chat";
|
[JsonPropertyName("minimizeToTray")]
|
||||||
|
[JsonRequired]
|
||||||
|
public bool MinimizeToTray { get; set; } = true;
|
||||||
|
[JsonPropertyName("enableDebugLogs")]
|
||||||
|
[JsonRequired]
|
||||||
|
public bool EnableDebugLogs { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonPropertyName("serverUrl")]
|
||||||
|
[JsonRequired]
|
||||||
|
public string ServerUrl { get; set; } = "https://qtc.alanmoon.net";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
using qtc_net_client_2.Services;
|
|
||||||
using QtCNETAPI.Events;
|
|
||||||
using QtCNETAPI.Models;
|
|
||||||
using QtCNETAPI.Services.ApiService;
|
|
||||||
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
|
|
||||||
{
|
|
||||||
public partial class Chat : Form
|
|
||||||
{
|
|
||||||
IGatewayService _gatewayService;
|
|
||||||
IApiService _apiService;
|
|
||||||
AudioService AudioService = new();
|
|
||||||
public Chat(IGatewayService gatewayService, IApiService apiService)
|
|
||||||
{
|
|
||||||
_gatewayService = gatewayService;
|
|
||||||
_apiService = apiService;
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void frmChat_Load(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
// subscribe to server message event
|
|
||||||
_gatewayService.OnServerMessageReceived += _gatewayService_OnServerMessageReceived;
|
|
||||||
|
|
||||||
if (_gatewayService.CurrentRoom != null) Text = $"QtC.NET Client - Chat Room - {_gatewayService.CurrentRoom.Name}";
|
|
||||||
else if (_gatewayService.InLobby) Text = $"QtC.NET Client - Chat Room - Lobby";
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void frmChat_FormClosing(object sender, FormClosingEventArgs e)
|
|
||||||
{
|
|
||||||
// unsubscribe from server message event
|
|
||||||
_gatewayService.OnServerMessageReceived -= _gatewayService_OnServerMessageReceived;
|
|
||||||
|
|
||||||
if (_gatewayService.CurrentRoom != null || _gatewayService.InLobby)
|
|
||||||
{
|
|
||||||
// leave any room user is in
|
|
||||||
await _gatewayService.LeaveRoomAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void btnSend_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(rtxtChatbox.Text))
|
|
||||||
{
|
|
||||||
// construct message
|
|
||||||
QtCNETAPI.Models.Message message = new() { Content = rtxtChatbox.Text };
|
|
||||||
|
|
||||||
// send it and clear text box
|
|
||||||
await _gatewayService.PostMessageAsync(message);
|
|
||||||
rtxtChatbox.Clear();
|
|
||||||
AudioService.PlaySoundEffect("sndSendClick");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void rtxtChatbox_KeyDown(object sender, KeyEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.KeyCode == Keys.Enter)
|
|
||||||
btnSend_Click(sender, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _gatewayService_OnServerMessageReceived(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
var msgEventArgs = (ServerMessageEventArgs)e;
|
|
||||||
|
|
||||||
AddMessage(msgEventArgs.Message);
|
|
||||||
if (!msgEventArgs.Message.Contains(_apiService.CurrentUser.Username)) AudioService.PlaySoundEffect("sndMessage");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddMessage(string message)
|
|
||||||
{
|
|
||||||
if (InvokeRequired)
|
|
||||||
Invoke(delegate { rtxtChat.AppendText(message + Environment.NewLine); });
|
|
||||||
else rtxtChat.AppendText(message + Environment.NewLine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
namespace qtc_net_client_2.Forms
|
namespace qtc_net_client_2.Forms
|
||||||
{
|
{
|
||||||
partial class Chat
|
partial class ChatRoom
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required designer variable.
|
/// Required designer variable.
|
||||||
@ -28,10 +28,14 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Chat));
|
components = new System.ComponentModel.Container();
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ChatRoom));
|
||||||
rtxtChatbox = new RichTextBox();
|
rtxtChatbox = new RichTextBox();
|
||||||
btnSend = new Button();
|
btnSend = new Button();
|
||||||
rtxtChat = new RichTextBox();
|
rtxtChat = new RichTextBox();
|
||||||
|
lblRoomName = new Label();
|
||||||
|
lvUserList = new ListView();
|
||||||
|
ilStatusIcons = new ImageList(components);
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// rtxtChatbox
|
// rtxtChatbox
|
||||||
@ -57,37 +61,79 @@
|
|||||||
//
|
//
|
||||||
// rtxtChat
|
// rtxtChat
|
||||||
//
|
//
|
||||||
|
rtxtChat.Font = new Font("Segoe UI", 10F);
|
||||||
rtxtChat.HideSelection = false;
|
rtxtChat.HideSelection = false;
|
||||||
rtxtChat.Location = new Point(12, 12);
|
rtxtChat.Location = new Point(142, 43);
|
||||||
rtxtChat.Name = "rtxtChat";
|
rtxtChat.Name = "rtxtChat";
|
||||||
rtxtChat.ReadOnly = true;
|
rtxtChat.ReadOnly = true;
|
||||||
rtxtChat.Size = new Size(593, 250);
|
rtxtChat.Size = new Size(463, 219);
|
||||||
rtxtChat.TabIndex = 3;
|
rtxtChat.TabIndex = 3;
|
||||||
rtxtChat.Text = "";
|
rtxtChat.Text = "";
|
||||||
//
|
//
|
||||||
// Chat
|
// lblRoomName
|
||||||
|
//
|
||||||
|
lblRoomName.AutoSize = true;
|
||||||
|
lblRoomName.Font = new Font("Segoe UI", 25F, FontStyle.Bold | FontStyle.Italic);
|
||||||
|
lblRoomName.ForeColor = Color.White;
|
||||||
|
lblRoomName.Location = new Point(6, -4);
|
||||||
|
lblRoomName.Margin = new Padding(4, 0, 4, 0);
|
||||||
|
lblRoomName.Name = "lblRoomName";
|
||||||
|
lblRoomName.Size = new Size(113, 46);
|
||||||
|
lblRoomName.TabIndex = 8;
|
||||||
|
lblRoomName.Text = "Room";
|
||||||
|
//
|
||||||
|
// lvUserList
|
||||||
|
//
|
||||||
|
lvUserList.Alignment = ListViewAlignment.Left;
|
||||||
|
lvUserList.Location = new Point(12, 43);
|
||||||
|
lvUserList.MultiSelect = false;
|
||||||
|
lvUserList.Name = "lvUserList";
|
||||||
|
lvUserList.Size = new Size(124, 219);
|
||||||
|
lvUserList.SmallImageList = ilStatusIcons;
|
||||||
|
lvUserList.TabIndex = 9;
|
||||||
|
lvUserList.UseCompatibleStateImageBehavior = false;
|
||||||
|
lvUserList.View = View.SmallIcon;
|
||||||
|
lvUserList.DoubleClick += lvUserList_DoubleClick;
|
||||||
|
//
|
||||||
|
// ilStatusIcons
|
||||||
|
//
|
||||||
|
ilStatusIcons.ColorDepth = ColorDepth.Depth32Bit;
|
||||||
|
ilStatusIcons.ImageStream = (ImageListStreamer)resources.GetObject("ilStatusIcons.ImageStream");
|
||||||
|
ilStatusIcons.TransparentColor = Color.Transparent;
|
||||||
|
ilStatusIcons.Images.SetKeyName(0, "Offline");
|
||||||
|
ilStatusIcons.Images.SetKeyName(1, "Online");
|
||||||
|
ilStatusIcons.Images.SetKeyName(2, "Away");
|
||||||
|
ilStatusIcons.Images.SetKeyName(3, "DND");
|
||||||
|
//
|
||||||
|
// ChatRoom
|
||||||
//
|
//
|
||||||
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(617, 334);
|
ClientSize = new Size(617, 334);
|
||||||
|
Controls.Add(lvUserList);
|
||||||
|
Controls.Add(lblRoomName);
|
||||||
Controls.Add(rtxtChat);
|
Controls.Add(rtxtChat);
|
||||||
Controls.Add(btnSend);
|
Controls.Add(btnSend);
|
||||||
Controls.Add(rtxtChatbox);
|
Controls.Add(rtxtChatbox);
|
||||||
FormBorderStyle = FormBorderStyle.FixedSingle;
|
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||||
MaximizeBox = false;
|
MaximizeBox = false;
|
||||||
Name = "Chat";
|
Name = "ChatRoom";
|
||||||
StartPosition = FormStartPosition.CenterScreen;
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
Text = "QtC.NET Client - Chat Room";
|
Text = "QtC.NET Client - Chat Room";
|
||||||
FormClosing += frmChat_FormClosing;
|
FormClosing += frmChat_FormClosing;
|
||||||
Load += frmChat_Load;
|
Load += frmChat_Load;
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
private RichTextBox rtxtChatbox;
|
private RichTextBox rtxtChatbox;
|
||||||
private Button btnSend;
|
private Button btnSend;
|
||||||
private RichTextBox rtxtChat;
|
private RichTextBox rtxtChat;
|
||||||
|
private Label lblRoomName;
|
||||||
|
private ListView lvUserList;
|
||||||
|
private ImageList ilStatusIcons;
|
||||||
}
|
}
|
||||||
}
|
}
|
162
qtc-net-client-2/Forms/ChatRoom.cs
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
using qtc_net_client_2.Services;
|
||||||
|
using QtCNETAPI.Events;
|
||||||
|
using QtCNETAPI.Services.ApiService;
|
||||||
|
using QtCNETAPI.Services.GatewayService;
|
||||||
|
|
||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
public partial class ChatRoom : Form
|
||||||
|
{
|
||||||
|
IGatewayService _gatewayService;
|
||||||
|
IApiService _apiService;
|
||||||
|
AudioService AudioService = new();
|
||||||
|
|
||||||
|
public ChatRoom(IGatewayService gatewayService, IApiService apiService)
|
||||||
|
{
|
||||||
|
_gatewayService = gatewayService;
|
||||||
|
_apiService = apiService;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void frmChat_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// subscribe to server message event
|
||||||
|
_gatewayService.OnRoomMessageReceived += _gatewayService_OnServerMessageReceived;
|
||||||
|
_gatewayService.OnRoomUserListReceived += _gatewayService_OnRoomUserListReceived;
|
||||||
|
_gatewayService.OnRoomDeleted += _gatewayService_OnRoomDeleted;
|
||||||
|
_gatewayService.OnGuestUserJoin += _gatewayService_OnGuestUserJoin;
|
||||||
|
|
||||||
|
if (_gatewayService.CurrentRoom != null) { Text = $"QtC.NET Client - Chat Room - {_gatewayService.CurrentRoom.Name}"; lblRoomName.Text = _gatewayService.CurrentRoom.Name; }
|
||||||
|
else if (_gatewayService.InLobby) { Text = $"QtC.NET Client - Chat Room - Lobby"; lblRoomName.Text = "Lobby"; }
|
||||||
|
|
||||||
|
lvUserList.Clear();
|
||||||
|
|
||||||
|
// always add current user to list i guess
|
||||||
|
lvUserList.Items.Add(_apiService.CurrentUser.Username, _apiService.CurrentUser.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void frmChat_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
// unsubscribe from server message event
|
||||||
|
_gatewayService.OnRoomMessageReceived -= _gatewayService_OnServerMessageReceived;
|
||||||
|
_gatewayService.OnRoomUserListReceived -= _gatewayService_OnRoomUserListReceived;
|
||||||
|
|
||||||
|
if (_gatewayService.CurrentRoom != null || _gatewayService.InLobby)
|
||||||
|
{
|
||||||
|
// leave any room user is in
|
||||||
|
await _gatewayService.LeaveRoomAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnSend_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(rtxtChatbox.Text))
|
||||||
|
{
|
||||||
|
// construct message
|
||||||
|
QtCNETAPI.Models.Message message = new() { Content = rtxtChatbox.Text };
|
||||||
|
|
||||||
|
// send it and clear text box
|
||||||
|
await _gatewayService.PostMessageAsync(message);
|
||||||
|
rtxtChatbox.Clear();
|
||||||
|
AudioService.PlaySoundEffect("sndSendClick");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rtxtChatbox_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.KeyCode == Keys.Enter)
|
||||||
|
btnSend_Click(sender, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void lvUserList_DoubleClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lvUserList.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
string? selectedUser = (string?)lvUserList.SelectedItems[lvUserList.SelectedItems.Count - 1].Text;
|
||||||
|
|
||||||
|
if (selectedUser != null)
|
||||||
|
{
|
||||||
|
// split from [ if it exists
|
||||||
|
if (selectedUser.Contains('[')) selectedUser = selectedUser.Split('[', options: StringSplitOptions.TrimEntries)[0];
|
||||||
|
|
||||||
|
// in this context, we need to find the main form to get the current user directory
|
||||||
|
Main? mainForm = (Main?)Application.OpenForms[0];
|
||||||
|
if (mainForm != null)
|
||||||
|
{
|
||||||
|
// get user info and open profile dialog
|
||||||
|
var user = mainForm.UserDirectory.FirstOrDefault(e => e.Username == selectedUser);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
var res = await _apiService.GetUserInformationAsync(user.Id);
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _gatewayService_OnServerMessageReceived(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var msgEventArgs = (ServerMessageEventArgs)e;
|
||||||
|
|
||||||
|
AddMessage(msgEventArgs.Message);
|
||||||
|
if (!msgEventArgs.Message.Contains(_apiService.CurrentUser.Username)) AudioService.PlaySoundEffect("sndMessage");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _gatewayService_OnRoomUserListReceived(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var args = (RoomListEventArgs)e;
|
||||||
|
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
var args = (GuestUserJoinEventArgs)e;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if(IsHandleCreated && !IsDisposed)
|
||||||
|
{
|
||||||
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
rtxtChat.AppendText(message + Environment.NewLine);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
244
qtc-net-client-2/Forms/ChatRoom.resx
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
<?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>
|
||||||
|
<metadata name="ilStatusIcons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>12, 12</value>
|
||||||
|
</metadata>
|
||||||
|
<data name="ilStatusIcons.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA+hMAAAJNU0Z0AUkBTAIBAQQB
|
||||||
|
AAHAAQABwAEAARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABIAYAASD/
|
||||||
|
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AC4AAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B
|
||||||
|
0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYB
|
||||||
|
BwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekD
|
||||||
|
YAHoA10B0QNQAZ8DMQFNAwUBBhQAAyABLQNUAasDWwHkA1UB9QMkAfsDPAH+AzwB/gMkAfsDUwH0A2IB
|
||||||
|
4QNRAaEDHgEqEAADIAEtA1QBqwNbAeQBSwFaAUsB9QEhAVgBIQH7ARgBWAEYAf4BGAFYARgB/gEhAVgB
|
||||||
|
IQH7A1MB9ANiAeEDUQGhAx4BKhAAAyABLQNUAasDWwHkAUsCWgH1ASECWAH7ARgCWAH+ARgCWAH+ASEC
|
||||||
|
WAH7A1MB9ANiAeEDUQGhAx4BKhAAAyABLQNUAasDWwHkAksBWgH1AiEBWAH7AhgBWAH+AhgBWAH+AiEB
|
||||||
|
WAH7A1MB9ANiAeEDUQGhAx4BKgwAAxsBJQNYAb0DWgHyA0AB/gMwAf8DOQH/AzwB/wM2Af8DKgH/AyQB
|
||||||
|
/wNAAf0DXgHwA1YBsgMaASMIAAMbASUDWAG9A1oB8gEYAWABGAH+AQABVwEAAf8BAAFnAQAB/wEAAWwB
|
||||||
|
AAH/AQABYQEAAf8BAAFMAQAB/wEAAUABAAH/ATABQAEwAf0BWgFeAVoB8ANWAbIBGQEaARkBIwgAAxsB
|
||||||
|
JQNYAb0DWgHyARgCYAH+AQACVwH/AQACZwH/AQACbAH/AQACYQH/AQACTAH/AQACQAH/ATACQAH9AVoC
|
||||||
|
XgHwA1YBsgEZAhoBIwgAAxsBJQNYAb0DWgHyAhgBYAH+AgABVwH/AgABZwH/AgABbAH/AgABYQH/AgAB
|
||||||
|
TAH/AgABQAH/AjABQAH9AloBXgHwA1YBsgIZARoBIwQAAwMBBANSAaUDYAHzA0kB/wNVAf8DZQH/A3EB
|
||||||
|
/wN1Af8DcQH/A2QB/wNMAf8DMQH/AzwB/gNiAe4DUAGaAwMBBAMDAQQBUgFTAVIBpQFWAW8BVgHzAQAB
|
||||||
|
ggEAAf8BAAGZAQAB/wEAAbYBAAH/AQABzAEAAf8BAAHTAQAB/wEAAcsBAAH/AQABswEAAf8BAAGIAQAB
|
||||||
|
/wEAAVcBAAH/ARgBWAEYAf4BXwFiAV8B7gNQAZoDAwEEAwMBBAFSAlMBpQFWAm8B8wEAAoIB/wEAApkB
|
||||||
|
/wEAArYB/wEAAswB/wEAAtMB/wEAAssB/wEAArMB/wEAAogB/wEAAlcB/wEYAlgB/gFfAmIB7gNQAZoD
|
||||||
|
AwEEAwMBBAJSAVMBpQJWAW8B8wIAAYIB/wIAAZkB/wIAAbYB/wIAAcwB/wIAAdMB/wIAAcsB/wIAAbMB
|
||||||
|
/wIAAYgB/wIAAVcB/wIYAVgB/gJfAWIB7gNQAZoDAwEEAy0BRANgAegDewH+A24B/wN7Af8DhQH/A4oB
|
||||||
|
/wOMAf8DigH/A4UB/wN2Af8DVwH/AzIB/wNAAf0DXgHdAyoBPwMtAUQBYAFpAWAB6AEYAYQBGAH+AQAB
|
||||||
|
xgEAAf8BAAHcAQAB/wEAAe4BAAH/AQAB+AEAAf8BAAH7AQAB/wEAAfkBAAH/AQAB7wEAAf8BAAHUAQAB
|
||||||
|
/wEAAZwBAAH/AQABWgEAAf8BMAFAATAB/QNeAd0DKgE/Ay0BRAFgAmkB6AEYAoQB/gEAAsYB/wEAAtwB
|
||||||
|
/wEAAu4B/wEAAvgB/wEAAvsB/wEAAvkB/wEAAu8B/wEAAtQB/wEAApwB/wEAAloB/wEwAkAB/QNeAd0D
|
||||||
|
KgE/Ay0BRAJgAWkB6AIYAYQB/gIAAcYB/wIAAdwB/wIAAe4B/wIAAfgB/wIAAfsB/wIAAfkB/wIAAe8B
|
||||||
|
/wIAAdQB/wIAAZwB/wIAAVoB/wIwAUAB/QNeAd0DKgE/A04BlQN3AfgDfwH/A4UB/wOKAf8DjQH/A44B
|
||||||
|
/wOOAf8DjgH/A40B/wOJAf8DdwH/A00B/wMlAf8DWgHyA0oBiwNOAZUBQgGBAUIB+AEAAeUBAAH/AQAB
|
||||||
|
7wEAAf8BAAH4AQAB/wEAAf0BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/gEAAf8BAAH2AQAB
|
||||||
|
/wEAAdUBAAH/AQABiwEAAf8BAAFBAQAB/wNaAfIDSgGLA04BlQFCAoEB+AEAAuUB/wEAAu8B/wEAAvgB
|
||||||
|
/wEAAv0B/wEAA/8BAAP/AQAD/wEAAv4B/wEAAvYB/wEAAtUB/wEAAosB/wEAAkEB/wNaAfIDSgGLA04B
|
||||||
|
lQJCAYEB+AIAAeUB/wIAAe8B/wIAAfgB/wIAAf0B/wIAAv8CAAL/AgAC/wIAAf4B/wIAAfYB/wIAAdUB
|
||||||
|
/wIAAYsB/wIAAUEB/wNaAfIDSgGLA18B0wN+AfwDkwH/A44B/wONAf8DjgH/A44B/wOOAf8DjgH/A44B
|
||||||
|
/wONAf8DhQH/A2cB/wM0Af8DQQH5A1oBxAFbAV8BWwHTASsBsAErAfwBDgH7AQ4B/wEDAf0BAwH/AQAB
|
||||||
|
/gEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/QEAAf8BAAHvAQAB
|
||||||
|
/wEAAbkBAAH/AQABXQEAAf8DQQH5A1oBxAFbAl8B0wErArAB/AEOAvsB/wEDAv0B/wEAAv4B/wEAA/8B
|
||||||
|
AAP/AQAD/wEAA/8BAAP/AQAC/QH/AQAC7wH/AQACuQH/AQACXQH/A0EB+QNaAcQCWwFfAdMCKwGwAfwC
|
||||||
|
DgH7Af8CAwH9Af8CAAH+Af8CAAL/AgAC/wIAAv8CAAL/AgAC/wIAAf0B/wIAAe8B/wIAAbkB/wIAAV0B
|
||||||
|
/wNBAfkDWgHEA24B9QOAAf4DnwH/A5MB/wOPAf8DjgH/A44B/wOOAf8DjgH/A44B/wOOAf8DiwH/A3cB
|
||||||
|
/wNIAf8DQAH9A2IB4QFTAXYBUwH1ATwBzwE8Af4BJwH/AScB/wELAf8BCwH/AQEB/wEBAf8BAAH/AQAB
|
||||||
|
/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH5AQAB/wEAAdYBAAH/AQAB
|
||||||
|
gQEAAf8BMAFAATAB/QNiAeEBUwJ2AfUBPALPAf4BJwP/AQsD/wEBA/8BAAP/AQAD/wEAA/8BAAP/AQAD
|
||||||
|
/wEAA/8BAAL5Af8BAALWAf8BAAKBAf8BMAJAAf0DYgHhAlMBdgH1AjwBzwH+AicC/wILAv8CAQL/AgAC
|
||||||
|
/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAB+QH/AgAB1gH/AgABgQH/AjABQAH9A2IB4QNtAfYDgAH+A6sB
|
||||||
|
/wOZAf8DkAH/A44B/wOOAf8DjgH/A44B/wOOAf8DjgH/A40B/wN/Af8DVQH/A0AB/QNeAeIBSAF6AUgB
|
||||||
|
9gFfAc8BXwH+AUIB/wFCAf8BGQH/ARkB/wEEAf8BBAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
|
/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/QEAAf8BAAHkAQAB/wEAAZgBAAH/ATABQAEwAf0DXgHiAUgC
|
||||||
|
egH2AV8CzwH+AUID/wEZA/8BBAP/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAP/AQAC/QH/AQAC5AH/AQAC
|
||||||
|
mAH/ATACQAH9A14B4gJIAXoB9gJfAc8B/gJCAv8CGQL/AgQC/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAC
|
||||||
|
/wIAAf0B/wIAAeQB/wIAAZgB/wIwAUAB/QNeAeIDYQHWA34B/AO4Af8DowH/A5MB/wOOAf8DjgH/A44B
|
||||||
|
/wOOAf8DjgH/A44B/wONAf8DggH/A1wB/wNNAfoDWgHHAVwBYQFcAdYBZAG0AWQB/AFfAf8BXwH/AS8B
|
||||||
|
/wEvAf8BDAH/AQwB/wEBAf8BAQH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
|
/wEAAf4BAAH/AQAB6gEAAf8BAAGlAQAB/wEsAU0BLAH6A1oBxwFcAmEB1gFkArQB/AFfA/8BLwP/AQwD
|
||||||
|
/wEBA/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAAv4B/wEAAuoB/wEAAqUB/wEsAk0B+gNaAccCXAFhAdYC
|
||||||
|
ZAG0AfwCXwL/Ai8C/wIMAv8CAQL/AgAC/wIAAv8CAAL/AgAC/wIAAv8CAAH+Af8CAAHqAf8CAAGlAf8C
|
||||||
|
LAFNAfoDWgHHA1ABmgOIAfkDxQH/A7IB/wOcAf8DkQH/A44B/wOOAf8DjgH/A44B/wOPAf8DjgH/A4MB
|
||||||
|
/wNgAf8DWgHyA0wBkANQAZoBagGRAWoB+QF8Af8BfAH/AVEB/wFRAf8BHwH/AR8B/wEHAf8BBwH/AQEB
|
||||||
|
/wEBAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAgH/AQIB/wECAf4BAgH/AQAB6wEAAf8BAAGtAQAB
|
||||||
|
/wFaAWsBWgHyA0wBkANQAZoBagKRAfkBfAP/AVED/wEfA/8BBwP/AQED/wEAA/8BAAP/AQAD/wECA/8B
|
||||||
|
AgL+Af8BAALrAf8BAAKtAf8BWgJrAfIDTAGQA1ABmgJqAZEB+QJ8Av8CUQL/Ah8C/wIHAv8CAQL/AgAC
|
||||||
|
/wIAAv8CAAL/AgIC/wICAf4B/wIAAesB/wIAAa0B/wJaAWsB8gNMAZADLwFJA2wB6wOgAf4DxgH/A64B
|
||||||
|
/wOcAf8DkwH/A5AB/wOPAf8DkAH/A5MB/wOTAf8DhQH/A04B/QNgAeADLQFFAy8BSQNsAesBgAHPAYAB
|
||||||
|
/gF/Af8BfwH/AUkB/wFJAf8BHwH/AR8B/wEMAf8BDAH/AQUB/wEFAf8BAwH/AQMB/wEFAf8BBQH/AQoB
|
||||||
|
/wEKAf8BCgH+AQoB/wEBAe0BAQH/ATABtgEwAf0BYAFmAWAB4AMtAUUDLwFJA2wB6wGAAs8B/gF/A/8B
|
||||||
|
SQP/AR8D/wEMA/8BBQP/AQMD/wEFA/8BCgP/AQoC/gH/AQEC7QH/ATACtgH9AWACZgHgAy0BRQMvAUkD
|
||||||
|
bAHrAoABzwH+An8C/wJJAv8CHwL/AgwC/wIFAv8CAwL/AgUC/wIKAv8CCgH+Af8CAQHtAf8CMAG2Af0C
|
||||||
|
YAFmAeADLQFFAwMBBANWAa4DcAH1A9kB/wPLAf8DtwH/A6cB/wOdAf8DmgH/A5wB/wOfAf8DmwH/A4kB
|
||||||
|
/wNoAfADUgGjAwMBBAMDAQQDVgGuAW4BdgFuAfUBqAH/AagB/wGJAf8BiQH/AVwB/wFcAf8BNwH/ATcB
|
||||||
|
/wEiAf8BIgH/ARsB/wEbAf8BHwH/AR8B/wEmAf8BJgH/AR0B/wEdAf8BBQHzAQUB/wFaAWgBWgHwA1IB
|
||||||
|
owMDAQQDAwEEA1YBrgFuAnYB9QGoA/8BiQP/AVwD/wE3A/8BIgP/ARsD/wEfA/8BJgP/AR0D/wEFAvMB
|
||||||
|
/wFaAmgB8ANSAaMDAwEEAwMBBANWAa4CbgF2AfUCqAL/AokC/wJcAv8CNwL/AiIC/wIbAv8CHwL/AiYC
|
||||||
|
/wIdAv8CBQHzAf8CWgFoAfADUgGjAwMBBAQAAxwBJwNdAccDdwH2A68B/gPXAf8DzAH/A8IB/wO7Af8D
|
||||||
|
twH/A7EB/wOAAf4DaAH0A1kBvAMbASYIAAMcAScDXQHHAXIBegFyAfYBhwHPAYcB/gGlAf8BpQH/AYsB
|
||||||
|
/wGLAf8BdAH/AXQB/wFmAf8BZgH/AVwB/wFcAf8BTgH/AU4B/wFIAc8BSAH+AVMBdwFTAfQBVwFZAVcB
|
||||||
|
vAMbASYIAAMcAScDXQHHAXICegH2AYcCzwH+AaUD/wGLA/8BdAP/AWYD/wFcA/8BTgP/AUgCzwH+AVMC
|
||||||
|
dwH0AVcCWQG8AxsBJggAAxwBJwNdAccCcgF6AfYChwHPAf4CpQL/AosC/wJ0Av8CZgL/AlwC/wJOAv8C
|
||||||
|
SAHPAf4CUwF3AfQCVwFZAbwDGwEmDAADIQEwA1kBtgNnAe4DkwH6A74B/QPUAf8DzAH/A74B/QOEAfkD
|
||||||
|
bAHrA1UBrAMfASwQAAMhATADWQG2AWUBaQFlAe4BfQGfAX0B+gGuAb4BrgH9AZ8B/wGfAf8BjAH/AYwB
|
||||||
|
/wFeAb4BXgH9AWgBkQFoAfkBYQFsAWEB6wNVAawDHwEsEAADIQEwA1kBtgFlAmkB7gF9Ap8B+gGuAr4B
|
||||||
|
/QGfA/8BjAP/AV4CvgH9AWgCkQH5AWECbAHrA1UBrAMfASwQAAMhATADWQG2AmUBaQHuAn0BnwH6Aq4B
|
||||||
|
vgH9Ap8C/wKMAv8CXgG+Af0CaAGRAfkCYQFsAesDVQGsAx8BLBQAAwYBBwM2AVgDVQGsA2YB5QOgAfwD
|
||||||
|
kwH7A2UB4gNTAacDMwFRAwYBBxgAAwYBBwM2AVgDVQGsA2YB5QF+AbQBfgH8AW0BngFtAfsDZQHiA1MB
|
||||||
|
pwMzAVEDBgEHGAADBgEHAzYBWANVAawDZgHlAX4CtAH8AW0CngH7A2UB4gNTAacDMwFRAwYBBxgAAwYB
|
||||||
|
BwM2AVgDVQGsA2YB5QJ+AbQB/AJtAZ4B+wNlAeIDUwGnAzMBUQMGAQcMAAFCAU0BPgcAAT4DAAEoAwAB
|
||||||
|
QAMAASADAAEBAQABAQYAAQEWAAP/gQAB4AEHAeABBwHgAQcB4AEHAcABAwHAAQMBwAEDAcABAwGAAQEB
|
||||||
|
gAEBAYABAQGAAQFQAAGAAQEBgAEBAYABAQGAAQEBwAEDAcABAwHAAQMBwAEDAeABBwHgAQcB4AEHAeAB
|
||||||
|
Bws=
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
AAABAAEAEA8AAAEACABDBQAAFgAAACgAAAAQAAAAHgAAAAEACAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAA9dN/APXTgAD00XoA9M5wAPPLZwDzyF8A8sZZAPLEVADywk4A8L9FAPC8PAD104AA9dF6APTL
|
||||||
|
aQD0z3UA9dSDAPC9PwDvtisA7rIeAPTOcgD0zW8A8sRVAPC7OgDsqgkA4J8AAPPJYwDxwUkA4KIMAM2S
|
||||||
|
AADxwUoAtYEAAO+3LQCbbgAA7K0PAOuoBACneQYAfloAANubAADYmQAAgVsAAGRHAADMkQAAuIMAALqF
|
||||||
|
AAB2VAAAWT8AAF5CAACpeAAAmm4AAJhsAACfcQAAfFgAAG9VFgCjlncAxr6sAI9mAACCXQAAfVkAAHdU
|
||||||
|
AABxUAAAa0wAAGRHAABcQgAAVTwAAN3a0QDt7e0A3t7eAOnp6QDi4uIA+fn5APPz8wD09PQA4uLiAM7O
|
||||||
|
zgD///8A/Pz8APPz8wDc3NwA+OOtAPzy2QD9+e4A/fblAPrpwAD22I8A6+fcAN3d3QDZ2dkA19fXAL6+
|
||||||
|
vgD+/foA+uvEAPTMawD++/QAoqKiAF9fXwBdXV0AW1tbAFRUVAD///8A+vr6AOPPnADusyIA+eSyAP7+
|
||||||
|
/gDk5OQA4uLiAN7e3gDo6OgA4+PjALOvpQDLmR4A7awPAPnmuAD9/f0A9/f3AEFBQQA9PT0ANTU1AIiI
|
||||||
|
iAC9vb0Afnx1ALWHFgDrxGUA39/dAKurqwCjo6MAlpaWAHl5eQDExMQAdHR0AGhbOgDgogkAw6dkAGlp
|
||||||
|
aABGRkYATExMAEVFRQA6OjoAXFxcAFRMOACgdg0AzJIDALuQJQCJdkgAaGFSAFZVUwBTUEgAXFI2AH9k
|
||||||
|
IgChdAUAq3oDAKx8BQCoegYAoXQGAJJpAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAABNTgAAAAAAAAAAAAAAAAAAS0wAAAAAAAAAAAAAAABISUoAAAAAAAAA
|
||||||
|
AAAAAABERUZHAAAAODk6Ozw9Pj9AQUJDAAAAMDEyM5eYmZqbNDU2NwAAKissjo+QkZKTlJWWLS4vACYn
|
||||||
|
hIWGh4iIiYqLjI0oKQAiI3t8WX1+Xn+AgYKDJCUAIHBxcnN0dXV1dnd4eXohAB5mZ2NoaWpqamtsbW5v
|
||||||
|
HwAaG1xdXl9gYGFiY2RlHB0AFBUWVFVWV1dYWVpbFxgZAAAMDQ4PT1BRUlMQERITAAAAAAECAwQFBgcI
|
||||||
|
CQoLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
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;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
namespace qtc_net_client_2.Forms
|
namespace qtc_net_client_2.Forms
|
||||||
{
|
{
|
||||||
partial class TokenJackpotSpinner
|
partial class CurrencyJackpotSpinner
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required designer variable.
|
/// Required designer variable.
|
||||||
@ -44,7 +44,7 @@
|
|||||||
lblTokensWon.Name = "lblTokensWon";
|
lblTokensWon.Name = "lblTokensWon";
|
||||||
lblTokensWon.Size = new Size(129, 25);
|
lblTokensWon.Size = new Size(129, 25);
|
||||||
lblTokensWon.TabIndex = 0;
|
lblTokensWon.TabIndex = 0;
|
||||||
lblTokensWon.Text = "300 Q's Won";
|
lblTokensWon.Text = "999 Q's Won";
|
||||||
lblTokensWon.TextAlign = ContentAlignment.MiddleCenter;
|
lblTokensWon.TextAlign = ContentAlignment.MiddleCenter;
|
||||||
//
|
//
|
||||||
// btnClaim
|
// btnClaim
|
||||||
@ -97,7 +97,7 @@
|
|||||||
MinimizeBox = false;
|
MinimizeBox = false;
|
||||||
Name = "TokenJackpotSpinner";
|
Name = "TokenJackpotSpinner";
|
||||||
StartPosition = FormStartPosition.CenterScreen;
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
Text = "QtC.NET Client - Daily Jackpot Spin";
|
Text = "QtC.NET Client - Jackpot Spin";
|
||||||
FormClosing += TokenJackpotSpinner_FormClosing;
|
FormClosing += TokenJackpotSpinner_FormClosing;
|
||||||
FormClosed += TokenJackpotSpinner_FormClosed;
|
FormClosed += TokenJackpotSpinner_FormClosed;
|
||||||
Load += TokenJackpotSpinner_Load;
|
Load += TokenJackpotSpinner_Load;
|
@ -11,13 +11,13 @@ using System.Windows.Forms;
|
|||||||
|
|
||||||
namespace qtc_net_client_2.Forms
|
namespace qtc_net_client_2.Forms
|
||||||
{
|
{
|
||||||
public partial class TokenJackpotSpinner : Form
|
public partial class CurrencyJackpotSpinner : Form
|
||||||
{
|
{
|
||||||
public int TokensWon { get; private set; }
|
public int TokensWon { get; private set; }
|
||||||
|
|
||||||
private bool AllowClose = false;
|
private bool AllowClose = false;
|
||||||
private AudioService _audioService = new();
|
private AudioService _audioService = new();
|
||||||
public TokenJackpotSpinner()
|
public CurrencyJackpotSpinner()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
@ -61,19 +61,21 @@ namespace qtc_net_client_2.Forms
|
|||||||
|
|
||||||
public async Task StartSpinAnimation(Label label)
|
public async Task StartSpinAnimation(Label label)
|
||||||
{
|
{
|
||||||
if (label.IsHandleCreated)
|
if (IsHandleCreated && label.IsHandleCreated)
|
||||||
{
|
{
|
||||||
Random rnd = new Random();
|
Random rnd = new Random();
|
||||||
_audioService.PlaySoundEffect("sndTokenSpinLoop");
|
_audioService.PlaySoundEffect("sndTokenSpinLoop");
|
||||||
|
|
||||||
while (_audioService.OutputDevice?.PlaybackState == NAudio.Wave.PlaybackState.Playing)
|
while (_audioService.OutputDevice?.PlaybackState == NAudio.Wave.PlaybackState.Playing)
|
||||||
{
|
{
|
||||||
|
if (!IsHandleCreated) return;
|
||||||
label.BeginInvoke(delegate () { label.Text = $"{rnd.Next(0, 300)} Q's Won"; });
|
label.BeginInvoke(delegate () { label.Text = $"{rnd.Next(0, 300)} Q's Won"; });
|
||||||
await Task.Delay(10);
|
await Task.Delay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
var win = rnd.Next(0, 300);
|
var win = rnd.Next(0, 300);
|
||||||
|
|
||||||
|
if (!IsHandleCreated) return;
|
||||||
label.BeginInvoke(delegate ()
|
label.BeginInvoke(delegate ()
|
||||||
{
|
{
|
||||||
label.Text = $"{win} Q's Won";
|
label.Text = $"{win} Q's Won";
|
8
qtc-net-client-2/Forms/DirectMessage.Designer.cs
generated
@ -38,11 +38,11 @@
|
|||||||
// rtxtChat
|
// rtxtChat
|
||||||
//
|
//
|
||||||
rtxtChat.HideSelection = false;
|
rtxtChat.HideSelection = false;
|
||||||
rtxtChat.Location = new Point(12, 56);
|
rtxtChat.Location = new Point(12, 48);
|
||||||
rtxtChat.Margin = new Padding(4, 3, 4, 3);
|
rtxtChat.Margin = new Padding(4, 3, 4, 3);
|
||||||
rtxtChat.Name = "rtxtChat";
|
rtxtChat.Name = "rtxtChat";
|
||||||
rtxtChat.ReadOnly = true;
|
rtxtChat.ReadOnly = true;
|
||||||
rtxtChat.Size = new Size(593, 317);
|
rtxtChat.Size = new Size(593, 325);
|
||||||
rtxtChat.TabIndex = 6;
|
rtxtChat.TabIndex = 6;
|
||||||
rtxtChat.Text = "";
|
rtxtChat.Text = "";
|
||||||
//
|
//
|
||||||
@ -74,7 +74,7 @@
|
|||||||
//
|
//
|
||||||
lblUsername.AutoSize = true;
|
lblUsername.AutoSize = true;
|
||||||
lblUsername.Font = new Font("Segoe UI", 25F, FontStyle.Bold | FontStyle.Italic);
|
lblUsername.Font = new Font("Segoe UI", 25F, FontStyle.Bold | FontStyle.Italic);
|
||||||
lblUsername.Location = new Point(6, 7);
|
lblUsername.Location = new Point(6, 0);
|
||||||
lblUsername.Margin = new Padding(4, 0, 4, 0);
|
lblUsername.Margin = new Padding(4, 0, 4, 0);
|
||||||
lblUsername.Name = "lblUsername";
|
lblUsername.Name = "lblUsername";
|
||||||
lblUsername.Size = new Size(181, 46);
|
lblUsername.Size = new Size(181, 46);
|
||||||
@ -86,7 +86,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(618, 450);
|
ClientSize = new Size(618, 443);
|
||||||
Controls.Add(lblUsername);
|
Controls.Add(lblUsername);
|
||||||
Controls.Add(rtxtChat);
|
Controls.Add(rtxtChat);
|
||||||
Controls.Add(btnSend);
|
Controls.Add(btnSend);
|
||||||
|
@ -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");
|
||||||
@ -51,9 +56,9 @@ namespace qtc_net_client_2.Forms
|
|||||||
|
|
||||||
private async void btnSend_Click(object sender, EventArgs e)
|
private async void btnSend_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (InvokeRequired)
|
if (rtxtChatbox.InvokeRequired)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await rtxtChatbox.Invoke(async delegate ()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(rtxtChatbox.Text))
|
if (!string.IsNullOrEmpty(rtxtChatbox.Text))
|
||||||
{
|
{
|
||||||
@ -69,8 +74,8 @@ 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 });
|
||||||
BeginInvoke(delegate () { Messages.Add($"[{_apiService.CurrentUser.Username}] {rtxtChatbox.Text}\n"); });
|
Messages.Add($"[{_apiService.CurrentUser.Username}] {rtxtChatbox.Text}\n");
|
||||||
BeginInvoke(delegate () { rtxtChatbox.Clear(); });
|
rtxtChatbox.Clear();
|
||||||
AudioService.PlaySoundEffect("sndSendClick");
|
AudioService.PlaySoundEffect("sndSendClick");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
112
qtc-net-client-2/Forms/DonationWindow.Designer.cs
generated
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
partial class DonationWindow
|
||||||
|
{
|
||||||
|
/// <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()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DonationWindow));
|
||||||
|
lblHi = new Label();
|
||||||
|
lblInfo = new Label();
|
||||||
|
pbKofi = new PictureBox();
|
||||||
|
pbCobaltPuter = new PictureBox();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbKofi).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbCobaltPuter).BeginInit();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblHi
|
||||||
|
//
|
||||||
|
lblHi.AutoSize = true;
|
||||||
|
lblHi.Font = new Font("Segoe UI", 30F, FontStyle.Bold | FontStyle.Italic);
|
||||||
|
lblHi.Location = new Point(231, 7);
|
||||||
|
lblHi.Name = "lblHi";
|
||||||
|
lblHi.Size = new Size(81, 54);
|
||||||
|
lblHi.TabIndex = 0;
|
||||||
|
lblHi.Text = "Hi!";
|
||||||
|
//
|
||||||
|
// lblInfo
|
||||||
|
//
|
||||||
|
lblInfo.Font = new Font("Segoe UI", 7F, FontStyle.Bold);
|
||||||
|
lblInfo.Location = new Point(12, 51);
|
||||||
|
lblInfo.Name = "lblInfo";
|
||||||
|
lblInfo.Size = new Size(290, 177);
|
||||||
|
lblInfo.TabIndex = 1;
|
||||||
|
lblInfo.Text = resources.GetString("lblInfo.Text");
|
||||||
|
lblInfo.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// pbKofi
|
||||||
|
//
|
||||||
|
pbKofi.Cursor = Cursors.Hand;
|
||||||
|
pbKofi.Image = Properties.Resources.support_me_on_kofi_badge_blue;
|
||||||
|
pbKofi.Location = new Point(89, 239);
|
||||||
|
pbKofi.Name = "pbKofi";
|
||||||
|
pbKofi.Size = new Size(149, 78);
|
||||||
|
pbKofi.SizeMode = PictureBoxSizeMode.Zoom;
|
||||||
|
pbKofi.TabIndex = 2;
|
||||||
|
pbKofi.TabStop = false;
|
||||||
|
pbKofi.Click += pbKofi_Click;
|
||||||
|
//
|
||||||
|
// pbCobaltPuter
|
||||||
|
//
|
||||||
|
pbCobaltPuter.Image = Properties.Resources.cobalt_sittingatputer;
|
||||||
|
pbCobaltPuter.Location = new Point(316, 29);
|
||||||
|
pbCobaltPuter.Name = "pbCobaltPuter";
|
||||||
|
pbCobaltPuter.Size = new Size(339, 270);
|
||||||
|
pbCobaltPuter.SizeMode = PictureBoxSizeMode.Zoom;
|
||||||
|
pbCobaltPuter.TabIndex = 3;
|
||||||
|
pbCobaltPuter.TabStop = false;
|
||||||
|
//
|
||||||
|
// DonationWindow
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
BackColor = Color.DodgerBlue;
|
||||||
|
ClientSize = new Size(667, 328);
|
||||||
|
Controls.Add(pbCobaltPuter);
|
||||||
|
Controls.Add(pbKofi);
|
||||||
|
Controls.Add(lblInfo);
|
||||||
|
Controls.Add(lblHi);
|
||||||
|
ForeColor = Color.White;
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
Name = "DonationWindow";
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
Text = "QtC.NET Client - Donate!";
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbKofi).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbCobaltPuter).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Label lblHi;
|
||||||
|
private Label lblInfo;
|
||||||
|
private PictureBox pbKofi;
|
||||||
|
private PictureBox pbCobaltPuter;
|
||||||
|
}
|
||||||
|
}
|
51
qtc-net-client-2/Forms/DonationWindow.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Policy;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
public partial class DonationWindow : Form
|
||||||
|
{
|
||||||
|
public DonationWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pbKofi_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var url = "https://ko-fi.com/moonbase__";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.Start(url);
|
||||||
|
} catch
|
||||||
|
{
|
||||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
|
{
|
||||||
|
url = url.Replace("&", "^&");
|
||||||
|
Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true });
|
||||||
|
}
|
||||||
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||||
|
{
|
||||||
|
Process.Start("xdg-open", url);
|
||||||
|
}
|
||||||
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||||
|
{
|
||||||
|
Process.Start("open", url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -117,32 +117,20 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<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.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
<data name="lblInfo.Text" xml:space="preserve">
|
||||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<value>I'm Moonbase, Thanks For Using QtC.NET!
|
||||||
<value>
|
|
||||||
AAABAAEAEA8AAAEACABDBQAAFgAAACgAAAAQAAAAHgAAAAEACAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAA
|
If you wish, you can send a few bucks to my KoFi
|
||||||
AAAAAAAA9dN/APXTgAD00XoA9M5wAPPLZwDzyF8A8sZZAPLEVADywk4A8L9FAPC8PAD104AA9dF6APTL
|
linked below. It will help imensely in improving the
|
||||||
aQD0z3UA9dSDAPC9PwDvtisA7rIeAPTOcgD0zW8A8sRVAPC7OgDsqgkA4J8AAPPJYwDxwUkA4KIMAM2S
|
performance of the platform by upgrading the VPS
|
||||||
AADxwUoAtYEAAO+3LQCbbgAA7K0PAOuoBACneQYAfloAANubAADYmQAAgVsAAGRHAADMkQAAuIMAALqF
|
this is currently being hosted on.
|
||||||
AAB2VAAAWT8AAF5CAACpeAAAmm4AAJhsAACfcQAAfFgAAG9VFgCjlncAxr6sAI9mAACCXQAAfVkAAHdU
|
|
||||||
AABxUAAAa0wAAGRHAABcQgAAVTwAAN3a0QDt7e0A3t7eAOnp6QDi4uIA+fn5APPz8wD09PQA4uLiAM7O
|
This project is and always will be mostly just a passion
|
||||||
zgD///8A/Pz8APPz8wDc3NwA+OOtAPzy2QD9+e4A/fblAPrpwAD22I8A6+fcAN3d3QDZ2dkA19fXAL6+
|
project, similar to the likes of SillyPost. The protocol
|
||||||
vgD+/foA+uvEAPTMawD++/QAoqKiAF9fXwBdXV0AW1tbAFRUVAD///8A+vr6AOPPnADusyIA+eSyAP7+
|
has existed for a bit now, however
|
||||||
/gDk5OQA4uLiAN7e3gDo6OgA4+PjALOvpQDLmR4A7awPAPnmuAD9/f0A9/f3AEFBQQA9PT0ANTU1AIiI
|
this is the most I've worked
|
||||||
iAC9vb0Afnx1ALWHFgDrxGUA39/dAKurqwCjo6MAlpaWAHl5eQDExMQAdHR0AGhbOgDgogkAw6dkAGlp
|
on it.
|
||||||
aABGRkYATExMAEVFRQA6OjoAXFxcAFRMOACgdg0AzJIDALuQJQCJdkgAaGFSAFZVUwBTUEgAXFI2AH9k
|
|
||||||
IgChdAUAq3oDAKx8BQCoegYAoXQGAJJpAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
Thanks again for your interest!</value>
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAABNTgAAAAAAAAAAAAAAAAAAS0wAAAAAAAAAAAAAAABISUoAAAAAAAAA
|
|
||||||
AAAAAABERUZHAAAAODk6Ozw9Pj9AQUJDAAAAMDEyM5eYmZqbNDU2NwAAKissjo+QkZKTlJWWLS4vACYn
|
|
||||||
hIWGh4iIiYqLjI0oKQAiI3t8WX1+Xn+AgYKDJCUAIHBxcnN0dXV1dnd4eXohAB5mZ2NoaWpqamtsbW5v
|
|
||||||
HwAaG1xdXl9gYGFiY2RlHB0AFBUWVFVWV1dYWVpbFxgZAAAMDQ4PT1BRUlMQERITAAAAAAECAwQFBgcI
|
|
||||||
CQoLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
|
||||||
</value>
|
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
135
qtc-net-client-2/Forms/GuessTheNumber.Designer.cs
generated
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
partial class GuessTheNumber
|
||||||
|
{
|
||||||
|
/// <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()
|
||||||
|
{
|
||||||
|
lblHeader = new Label();
|
||||||
|
nudNumberGuess = new NumericUpDown();
|
||||||
|
btnGuess = new Button();
|
||||||
|
lblPrizeInfo = new Label();
|
||||||
|
lblResult = new Label();
|
||||||
|
btnClaimPrize = new Button();
|
||||||
|
((System.ComponentModel.ISupportInitialize)nudNumberGuess).BeginInit();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblHeader
|
||||||
|
//
|
||||||
|
lblHeader.Font = new Font("Segoe UI", 15F, FontStyle.Bold);
|
||||||
|
lblHeader.Location = new Point(12, 9);
|
||||||
|
lblHeader.Name = "lblHeader";
|
||||||
|
lblHeader.Size = new Size(486, 62);
|
||||||
|
lblHeader.TabIndex = 0;
|
||||||
|
lblHeader.Text = "Please Wait, Getting Number...";
|
||||||
|
lblHeader.TextAlign = ContentAlignment.MiddleCenter;
|
||||||
|
//
|
||||||
|
// nudNumberGuess
|
||||||
|
//
|
||||||
|
nudNumberGuess.Location = new Point(190, 127);
|
||||||
|
nudNumberGuess.Maximum = new decimal(new int[] { 500, 0, 0, 0 });
|
||||||
|
nudNumberGuess.Name = "nudNumberGuess";
|
||||||
|
nudNumberGuess.Size = new Size(120, 23);
|
||||||
|
nudNumberGuess.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// btnGuess
|
||||||
|
//
|
||||||
|
btnGuess.ForeColor = Color.Black;
|
||||||
|
btnGuess.Location = new Point(225, 156);
|
||||||
|
btnGuess.Name = "btnGuess";
|
||||||
|
btnGuess.Size = new Size(46, 23);
|
||||||
|
btnGuess.TabIndex = 2;
|
||||||
|
btnGuess.Text = "Guess";
|
||||||
|
btnGuess.UseVisualStyleBackColor = true;
|
||||||
|
btnGuess.Click += btnGuess_Click;
|
||||||
|
//
|
||||||
|
// lblPrizeInfo
|
||||||
|
//
|
||||||
|
lblPrizeInfo.Font = new Font("Segoe UI", 9F, FontStyle.Bold);
|
||||||
|
lblPrizeInfo.ForeColor = Color.Black;
|
||||||
|
lblPrizeInfo.Location = new Point(142, 180);
|
||||||
|
lblPrizeInfo.Name = "lblPrizeInfo";
|
||||||
|
lblPrizeInfo.Size = new Size(212, 63);
|
||||||
|
lblPrizeInfo.TabIndex = 3;
|
||||||
|
lblPrizeInfo.Text = "Prize Possibilities:\r\nGuess Is Higher By 10 - Jackpot Spin\r\nGuess Is Lower By 10 - 200 Q's\r\nGuess Is Equal - Jackpot";
|
||||||
|
lblPrizeInfo.TextAlign = ContentAlignment.TopCenter;
|
||||||
|
//
|
||||||
|
// lblResult
|
||||||
|
//
|
||||||
|
lblResult.Font = new Font("Segoe UI", 9F, FontStyle.Bold);
|
||||||
|
lblResult.Location = new Point(12, 81);
|
||||||
|
lblResult.Name = "lblResult";
|
||||||
|
lblResult.Size = new Size(477, 15);
|
||||||
|
lblResult.TabIndex = 4;
|
||||||
|
lblResult.Text = "lblResult";
|
||||||
|
lblResult.TextAlign = ContentAlignment.MiddleCenter;
|
||||||
|
lblResult.Visible = false;
|
||||||
|
//
|
||||||
|
// btnClaimPrize
|
||||||
|
//
|
||||||
|
btnClaimPrize.ForeColor = Color.Black;
|
||||||
|
btnClaimPrize.Location = new Point(200, 100);
|
||||||
|
btnClaimPrize.Name = "btnClaimPrize";
|
||||||
|
btnClaimPrize.Size = new Size(99, 23);
|
||||||
|
btnClaimPrize.TabIndex = 5;
|
||||||
|
btnClaimPrize.Text = "PRIZE_CLAIM";
|
||||||
|
btnClaimPrize.UseVisualStyleBackColor = true;
|
||||||
|
btnClaimPrize.Visible = false;
|
||||||
|
//
|
||||||
|
// GuessTheNumber
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
BackColor = Color.DodgerBlue;
|
||||||
|
ClientSize = new Size(511, 253);
|
||||||
|
Controls.Add(btnClaimPrize);
|
||||||
|
Controls.Add(lblResult);
|
||||||
|
Controls.Add(lblPrizeInfo);
|
||||||
|
Controls.Add(btnGuess);
|
||||||
|
Controls.Add(nudNumberGuess);
|
||||||
|
Controls.Add(lblHeader);
|
||||||
|
ForeColor = Color.White;
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
Name = "GuessTheNumber";
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
Text = "QtC.NET qGame - Guess The Number";
|
||||||
|
Load += GuessTheNumber_Load;
|
||||||
|
((System.ComponentModel.ISupportInitialize)nudNumberGuess).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Label lblHeader;
|
||||||
|
private NumericUpDown nudNumberGuess;
|
||||||
|
private Button btnGuess;
|
||||||
|
private Label lblPrizeInfo;
|
||||||
|
private Label lblResult;
|
||||||
|
private Button btnClaimPrize;
|
||||||
|
}
|
||||||
|
}
|
125
qtc-net-client-2/Forms/GuessTheNumber.cs
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
using QtCNETAPI.Services.ApiService;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
public partial class GuessTheNumber : Form
|
||||||
|
{
|
||||||
|
private IApiService _apiService;
|
||||||
|
private int _number;
|
||||||
|
private int _guesses;
|
||||||
|
public GuessTheNumber(IApiService apiService)
|
||||||
|
{
|
||||||
|
_apiService = apiService;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void GuessTheNumber_Load(object sender, EventArgs e) => await InitializeGTNGame();
|
||||||
|
|
||||||
|
private async void btnGuess_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(nudNumberGuess.Value > 0)
|
||||||
|
{
|
||||||
|
btnGuess.Enabled = false;
|
||||||
|
|
||||||
|
int guess = int.Parse(nudNumberGuess.Value.ToString());
|
||||||
|
var result = await _apiService.GuessRandomNumber(_number, guess);
|
||||||
|
|
||||||
|
if(result != null && result.Success)
|
||||||
|
{
|
||||||
|
switch(result.Data)
|
||||||
|
{
|
||||||
|
case QtCNETAPI.Enums.NumberGuessResult.Higher:
|
||||||
|
lblResult.Text = "Your Guess Was Higher By 10! You've Earned A Jackpot Spin!";
|
||||||
|
btnClaimPrize.Text = "Spin";
|
||||||
|
btnClaimPrize.Click += BtnClaimPrize_Click_JackpotSpin;
|
||||||
|
|
||||||
|
lblResult.Visible = true;
|
||||||
|
btnClaimPrize.Visible = true;
|
||||||
|
break;
|
||||||
|
case QtCNETAPI.Enums.NumberGuessResult.Lower:
|
||||||
|
lblResult.Text = "Your Guess Was Lower By 10! You've Earned 200 Q's!";
|
||||||
|
btnClaimPrize.Text = "Claim";
|
||||||
|
btnClaimPrize.Click += BtnClaimPrize_Click_QClaim;
|
||||||
|
|
||||||
|
lblResult.Visible = true;
|
||||||
|
btnClaimPrize.Visible = true;
|
||||||
|
break;
|
||||||
|
case QtCNETAPI.Enums.NumberGuessResult.Correct:
|
||||||
|
lblResult.Text = "Your Correct! You've Earned The Jackpot!";
|
||||||
|
btnClaimPrize.Text = "Claim";
|
||||||
|
btnClaimPrize.Click += BtnClaimPrize_Click_QClaimJackpot;
|
||||||
|
|
||||||
|
lblResult.Visible = true;
|
||||||
|
btnClaimPrize.Visible = true;
|
||||||
|
break;
|
||||||
|
case QtCNETAPI.Enums.NumberGuessResult.Incorrect:
|
||||||
|
if (_guesses >= 2)
|
||||||
|
{
|
||||||
|
lblResult.Text = "Unfortunately you've used up all your guesses for this round.";
|
||||||
|
lblResult.Visible = true;
|
||||||
|
btnGuess.Visible = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else _guesses++;
|
||||||
|
|
||||||
|
lblResult.Text = $"Incorrect. You Get Three Chances. You Guessed {_guesses} Time(s)";
|
||||||
|
lblResult.Visible = true;
|
||||||
|
btnGuess.Enabled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnClaimPrize_Click_QClaimJackpot(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("need to figure out how to do this, sorry :)");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void BtnClaimPrize_Click_QClaim(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var result = await _apiService.AddCurrencyToCurrentUser(200, false);
|
||||||
|
if (result != null && result.Success) Close();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("We Weren't Able To Claim Your Prize. You Can Try Again.", "Uh Oh...", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void BtnClaimPrize_Click_JackpotSpin(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
CurrencyJackpotSpinner tokenJackpotSpinner = new CurrencyJackpotSpinner();
|
||||||
|
var formResult = tokenJackpotSpinner.ShowDialog();
|
||||||
|
if (formResult == DialogResult.OK)
|
||||||
|
{
|
||||||
|
var result = await _apiService.AddCurrencyToCurrentUser(tokenJackpotSpinner.TokensWon, false);
|
||||||
|
if (result != null && result.Success) Close();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("We Weren't Able To Claim Your Prize. You Can Try Again.", "Uh Oh...", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task InitializeGTNGame()
|
||||||
|
{
|
||||||
|
var result = await _apiService.GetRandomNumber();
|
||||||
|
|
||||||
|
if (result != null && result.Success)
|
||||||
|
{
|
||||||
|
_number = result.Data;
|
||||||
|
lblHeader.Text = "I've picked a number between 1 and 500.\nWhat Is It?";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
qtc-net-client-2/Forms/GuessTheNumber.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>
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
619
qtc-net-client-2/Forms/Main.Designer.cs
generated
@ -23,59 +23,97 @@
|
|||||||
#region Windows Form Designer generated code
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required method for Designer support - do not modify
|
/// Required method for Designer support - do not modify
|
||||||
/// the contents of this method with the code editor.
|
/// the contents of this method with the code editor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
components = new System.ComponentModel.Container();
|
components = new System.ComponentModel.Container();
|
||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main));
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main));
|
||||||
|
ListViewItem listViewItem1 = new ListViewItem("Stock Market", 0);
|
||||||
|
ListViewItem listViewItem2 = new ListViewItem("Guess The Number", 1);
|
||||||
|
ListViewItem listViewItem3 = new ListViewItem("Tic-Tac-Toe (Multiplayer)", "Tic-tac-toe.png");
|
||||||
tbcMain = new TabControl();
|
tbcMain = new TabControl();
|
||||||
tbpContacts = new TabPage();
|
tbpContacts = new TabPage();
|
||||||
lvContacts = new ListView();
|
lvContacts = new ListView();
|
||||||
|
ctxmRefresh = new ContextMenuStrip(components);
|
||||||
|
refreshToolStripMenuItem = new ToolStripMenuItem();
|
||||||
ilProfilePics = new ImageList(components);
|
ilProfilePics = new ImageList(components);
|
||||||
tbpRooms = new TabPage();
|
tbpRooms = new TabPage();
|
||||||
lbRooms = new ListBox();
|
lbRooms = new ListBox();
|
||||||
tbpOnlineUsers = new TabPage();
|
tbpUsers = new TabPage();
|
||||||
lbOnlineUsers = new ListBox();
|
lvUserDirectory = new ListView();
|
||||||
|
ilStatusIcons = new ImageList(components);
|
||||||
|
tbpGames = new TabPage();
|
||||||
|
lvGames = new ListView();
|
||||||
|
ilGames = new ImageList(components);
|
||||||
|
tbpStore = new TabPage();
|
||||||
|
lvStoreItems = new ListView();
|
||||||
|
ilStoreThumbnails = new ImageList(components);
|
||||||
ilTabIcons = new ImageList(components);
|
ilTabIcons = new ImageList(components);
|
||||||
pbUserPfp = new PictureBox();
|
|
||||||
ctxmChangeStatus = new ContextMenuStrip(components);
|
ctxmChangeStatus = new ContextMenuStrip(components);
|
||||||
onlineToolStripMenuItem = new ToolStripMenuItem();
|
onlineToolStripMenuItem = new ToolStripMenuItem();
|
||||||
awayToolStripMenuItem = new ToolStripMenuItem();
|
awayToolStripMenuItem = new ToolStripMenuItem();
|
||||||
doNotDisturbToolStripMenuItem = new ToolStripMenuItem();
|
doNotDisturbToolStripMenuItem = new ToolStripMenuItem();
|
||||||
invisibleToolStripMenuItem = new ToolStripMenuItem();
|
invisibleToolStripMenuItem = new ToolStripMenuItem();
|
||||||
lblWelcome = new Label();
|
|
||||||
llblSignIn = new LinkLabel();
|
|
||||||
llblSignOut = new LinkLabel();
|
|
||||||
llblEditProfile = new LinkLabel();
|
|
||||||
lblRequestNotif = new Label();
|
lblRequestNotif = new Label();
|
||||||
niMain = new NotifyIcon(components);
|
niMain = new NotifyIcon(components);
|
||||||
btnAddRoom = new Button();
|
llblClaimSpin = new LinkLabel();
|
||||||
|
pCurrencyArea = new Panel();
|
||||||
pbCurrencyIcon = new PictureBox();
|
pbCurrencyIcon = new PictureBox();
|
||||||
lblCurrencyAmount = new Label();
|
lblCurrencyAmount = new Label();
|
||||||
llblClaimSpin = new LinkLabel();
|
pCurrentUser = new Panel();
|
||||||
|
llblEditProfile = new LinkLabel();
|
||||||
|
llblSignOut = new LinkLabel();
|
||||||
|
llblSignIn = new LinkLabel();
|
||||||
|
lblWelcome = new Label();
|
||||||
|
pbUserPfp = 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();
|
||||||
tbpRooms.SuspendLayout();
|
tbpRooms.SuspendLayout();
|
||||||
tbpOnlineUsers.SuspendLayout();
|
tbpUsers.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)pbUserPfp).BeginInit();
|
tbpGames.SuspendLayout();
|
||||||
|
tbpStore.SuspendLayout();
|
||||||
ctxmChangeStatus.SuspendLayout();
|
ctxmChangeStatus.SuspendLayout();
|
||||||
|
pCurrencyArea.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)pbCurrencyIcon).BeginInit();
|
((System.ComponentModel.ISupportInitialize)pbCurrencyIcon).BeginInit();
|
||||||
|
pCurrentUser.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbUserPfp).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbDonate).BeginInit();
|
||||||
|
ctxmAdminUserList.SuspendLayout();
|
||||||
|
ctxmAdminRoomList.SuspendLayout();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// tbcMain
|
// tbcMain
|
||||||
//
|
//
|
||||||
|
tbcMain.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
tbcMain.Controls.Add(tbpContacts);
|
tbcMain.Controls.Add(tbpContacts);
|
||||||
tbcMain.Controls.Add(tbpRooms);
|
tbcMain.Controls.Add(tbpRooms);
|
||||||
tbcMain.Controls.Add(tbpOnlineUsers);
|
tbcMain.Controls.Add(tbpUsers);
|
||||||
|
tbcMain.Controls.Add(tbpGames);
|
||||||
|
tbcMain.Controls.Add(tbpStore);
|
||||||
tbcMain.Enabled = false;
|
tbcMain.Enabled = false;
|
||||||
tbcMain.ImageList = ilTabIcons;
|
tbcMain.ImageList = ilTabIcons;
|
||||||
tbcMain.Location = new Point(12, 66);
|
tbcMain.Location = new Point(12, 83);
|
||||||
tbcMain.Name = "tbcMain";
|
tbcMain.Name = "tbcMain";
|
||||||
tbcMain.SelectedIndex = 0;
|
tbcMain.SelectedIndex = 0;
|
||||||
tbcMain.Size = new Size(258, 535);
|
tbcMain.Size = new Size(352, 499);
|
||||||
tbcMain.TabIndex = 0;
|
tbcMain.TabIndex = 0;
|
||||||
|
tbcMain.SelectedIndexChanged += tbcMain_SelectedIndexChanged;
|
||||||
//
|
//
|
||||||
// tbpContacts
|
// tbpContacts
|
||||||
//
|
//
|
||||||
@ -84,29 +122,46 @@
|
|||||||
tbpContacts.Location = new Point(4, 24);
|
tbpContacts.Location = new Point(4, 24);
|
||||||
tbpContacts.Name = "tbpContacts";
|
tbpContacts.Name = "tbpContacts";
|
||||||
tbpContacts.Padding = new Padding(3);
|
tbpContacts.Padding = new Padding(3);
|
||||||
tbpContacts.Size = new Size(250, 507);
|
tbpContacts.Size = new Size(344, 471);
|
||||||
tbpContacts.TabIndex = 0;
|
tbpContacts.TabIndex = 0;
|
||||||
tbpContacts.Text = "Contacts";
|
tbpContacts.Text = "Contacts";
|
||||||
tbpContacts.UseVisualStyleBackColor = true;
|
tbpContacts.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// lvContacts
|
// lvContacts
|
||||||
//
|
//
|
||||||
|
lvContacts.Alignment = ListViewAlignment.Left;
|
||||||
|
lvContacts.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
lvContacts.ContextMenuStrip = ctxmRefresh;
|
||||||
lvContacts.LargeImageList = ilProfilePics;
|
lvContacts.LargeImageList = ilProfilePics;
|
||||||
lvContacts.Location = new Point(0, 0);
|
lvContacts.Location = new Point(0, 0);
|
||||||
lvContacts.MultiSelect = false;
|
lvContacts.MultiSelect = false;
|
||||||
lvContacts.Name = "lvContacts";
|
lvContacts.Name = "lvContacts";
|
||||||
lvContacts.Size = new Size(250, 507);
|
lvContacts.Size = new Size(344, 478);
|
||||||
lvContacts.SmallImageList = ilProfilePics;
|
lvContacts.SmallImageList = ilProfilePics;
|
||||||
lvContacts.TabIndex = 1;
|
lvContacts.TabIndex = 1;
|
||||||
lvContacts.UseCompatibleStateImageBehavior = false;
|
lvContacts.UseCompatibleStateImageBehavior = false;
|
||||||
lvContacts.View = View.SmallIcon;
|
lvContacts.View = View.SmallIcon;
|
||||||
lvContacts.DoubleClick += lvContacts_DoubleClick;
|
lvContacts.DoubleClick += lvContacts_DoubleClick;
|
||||||
//
|
//
|
||||||
|
// ctxmRefresh
|
||||||
|
//
|
||||||
|
ctxmRefresh.Items.AddRange(new ToolStripItem[] { refreshToolStripMenuItem });
|
||||||
|
ctxmRefresh.Name = "ctxmRefresh";
|
||||||
|
ctxmRefresh.Size = new Size(114, 26);
|
||||||
|
//
|
||||||
|
// refreshToolStripMenuItem
|
||||||
|
//
|
||||||
|
refreshToolStripMenuItem.Name = "refreshToolStripMenuItem";
|
||||||
|
refreshToolStripMenuItem.Size = new Size(113, 22);
|
||||||
|
refreshToolStripMenuItem.Text = "Refresh";
|
||||||
|
refreshToolStripMenuItem.Click += refreshToolStripMenuItem_Click;
|
||||||
|
//
|
||||||
// ilProfilePics
|
// ilProfilePics
|
||||||
//
|
//
|
||||||
ilProfilePics.ColorDepth = ColorDepth.Depth32Bit;
|
ilProfilePics.ColorDepth = ColorDepth.Depth32Bit;
|
||||||
ilProfilePics.ImageSize = new Size(32, 32);
|
ilProfilePics.ImageStream = (ImageListStreamer)resources.GetObject("ilProfilePics.ImageStream");
|
||||||
ilProfilePics.TransparentColor = Color.Transparent;
|
ilProfilePics.TransparentColor = Color.Transparent;
|
||||||
|
ilProfilePics.Images.SetKeyName(0, "DEFAULT");
|
||||||
//
|
//
|
||||||
// tbpRooms
|
// tbpRooms
|
||||||
//
|
//
|
||||||
@ -115,42 +170,125 @@
|
|||||||
tbpRooms.Location = new Point(4, 24);
|
tbpRooms.Location = new Point(4, 24);
|
||||||
tbpRooms.Name = "tbpRooms";
|
tbpRooms.Name = "tbpRooms";
|
||||||
tbpRooms.Padding = new Padding(3);
|
tbpRooms.Padding = new Padding(3);
|
||||||
tbpRooms.Size = new Size(250, 507);
|
tbpRooms.Size = new Size(344, 471);
|
||||||
tbpRooms.TabIndex = 1;
|
tbpRooms.TabIndex = 1;
|
||||||
tbpRooms.Text = "Rooms";
|
tbpRooms.Text = "Rooms";
|
||||||
tbpRooms.UseVisualStyleBackColor = true;
|
tbpRooms.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// lbRooms
|
// lbRooms
|
||||||
//
|
//
|
||||||
|
lbRooms.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
lbRooms.ContextMenuStrip = ctxmRefresh;
|
||||||
lbRooms.FormattingEnabled = true;
|
lbRooms.FormattingEnabled = true;
|
||||||
lbRooms.ItemHeight = 15;
|
lbRooms.ItemHeight = 15;
|
||||||
lbRooms.Location = new Point(0, 0);
|
lbRooms.Location = new Point(0, 0);
|
||||||
lbRooms.Name = "lbRooms";
|
lbRooms.Name = "lbRooms";
|
||||||
lbRooms.Size = new Size(250, 514);
|
lbRooms.Size = new Size(344, 484);
|
||||||
lbRooms.TabIndex = 0;
|
lbRooms.TabIndex = 0;
|
||||||
lbRooms.DoubleClick += lbRooms_DoubleClick;
|
lbRooms.DoubleClick += lbRooms_DoubleClick;
|
||||||
//
|
//
|
||||||
// tbpOnlineUsers
|
// tbpUsers
|
||||||
//
|
//
|
||||||
tbpOnlineUsers.Controls.Add(lbOnlineUsers);
|
tbpUsers.Controls.Add(lvUserDirectory);
|
||||||
tbpOnlineUsers.ImageIndex = 0;
|
tbpUsers.ImageIndex = 1;
|
||||||
tbpOnlineUsers.Location = new Point(4, 24);
|
tbpUsers.Location = new Point(4, 24);
|
||||||
tbpOnlineUsers.Name = "tbpOnlineUsers";
|
tbpUsers.Name = "tbpUsers";
|
||||||
tbpOnlineUsers.Padding = new Padding(3);
|
tbpUsers.Size = new Size(344, 471);
|
||||||
tbpOnlineUsers.Size = new Size(250, 507);
|
tbpUsers.TabIndex = 3;
|
||||||
tbpOnlineUsers.TabIndex = 2;
|
tbpUsers.Text = "Users";
|
||||||
tbpOnlineUsers.Text = "Online Users";
|
tbpUsers.UseVisualStyleBackColor = true;
|
||||||
tbpOnlineUsers.UseVisualStyleBackColor = true;
|
|
||||||
//
|
//
|
||||||
// lbOnlineUsers
|
// lvUserDirectory
|
||||||
//
|
//
|
||||||
lbOnlineUsers.FormattingEnabled = true;
|
lvUserDirectory.Alignment = ListViewAlignment.Left;
|
||||||
lbOnlineUsers.ItemHeight = 15;
|
lvUserDirectory.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
lbOnlineUsers.Location = new Point(0, 0);
|
lvUserDirectory.ContextMenuStrip = ctxmRefresh;
|
||||||
lbOnlineUsers.Name = "lbOnlineUsers";
|
lvUserDirectory.Location = new Point(0, 0);
|
||||||
lbOnlineUsers.Size = new Size(250, 514);
|
lvUserDirectory.MultiSelect = false;
|
||||||
lbOnlineUsers.TabIndex = 0;
|
lvUserDirectory.Name = "lvUserDirectory";
|
||||||
lbOnlineUsers.DoubleClick += lbOnlineUsers_DoubleClick;
|
lvUserDirectory.RightToLeft = RightToLeft.Yes;
|
||||||
|
lvUserDirectory.Size = new Size(344, 484);
|
||||||
|
lvUserDirectory.SmallImageList = ilStatusIcons;
|
||||||
|
lvUserDirectory.TabIndex = 0;
|
||||||
|
lvUserDirectory.UseCompatibleStateImageBehavior = false;
|
||||||
|
lvUserDirectory.View = View.SmallIcon;
|
||||||
|
lvUserDirectory.DoubleClick += lbUserDirectory_DoubleClick;
|
||||||
|
//
|
||||||
|
// ilStatusIcons
|
||||||
|
//
|
||||||
|
ilStatusIcons.ColorDepth = ColorDepth.Depth32Bit;
|
||||||
|
ilStatusIcons.ImageStream = (ImageListStreamer)resources.GetObject("ilStatusIcons.ImageStream");
|
||||||
|
ilStatusIcons.TransparentColor = Color.Transparent;
|
||||||
|
ilStatusIcons.Images.SetKeyName(0, "Offline");
|
||||||
|
ilStatusIcons.Images.SetKeyName(1, "Online");
|
||||||
|
ilStatusIcons.Images.SetKeyName(2, "Away");
|
||||||
|
ilStatusIcons.Images.SetKeyName(3, "DND");
|
||||||
|
//
|
||||||
|
// tbpGames
|
||||||
|
//
|
||||||
|
tbpGames.Controls.Add(lvGames);
|
||||||
|
tbpGames.ImageIndex = 3;
|
||||||
|
tbpGames.Location = new Point(4, 24);
|
||||||
|
tbpGames.Name = "tbpGames";
|
||||||
|
tbpGames.Size = new Size(344, 471);
|
||||||
|
tbpGames.TabIndex = 4;
|
||||||
|
tbpGames.Text = "Games";
|
||||||
|
tbpGames.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// lvGames
|
||||||
|
//
|
||||||
|
lvGames.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
listViewItem1.Tag = "StockMarketGame";
|
||||||
|
listViewItem2.Tag = "GuessTheNumberGame";
|
||||||
|
listViewItem3.Tag = "TicTacToeGame";
|
||||||
|
lvGames.Items.AddRange(new ListViewItem[] { listViewItem1, listViewItem2, listViewItem3 });
|
||||||
|
lvGames.LargeImageList = ilGames;
|
||||||
|
lvGames.Location = new Point(0, 0);
|
||||||
|
lvGames.MultiSelect = false;
|
||||||
|
lvGames.Name = "lvGames";
|
||||||
|
lvGames.Size = new Size(344, 484);
|
||||||
|
lvGames.SmallImageList = ilGames;
|
||||||
|
lvGames.TabIndex = 2;
|
||||||
|
lvGames.UseCompatibleStateImageBehavior = false;
|
||||||
|
lvGames.DoubleClick += lvGames_DoubleClick;
|
||||||
|
//
|
||||||
|
// ilGames
|
||||||
|
//
|
||||||
|
ilGames.ColorDepth = ColorDepth.Depth32Bit;
|
||||||
|
ilGames.ImageStream = (ImageListStreamer)resources.GetObject("ilGames.ImageStream");
|
||||||
|
ilGames.TransparentColor = Color.Transparent;
|
||||||
|
ilGames.Images.SetKeyName(0, "dollar-money.gif");
|
||||||
|
ilGames.Images.SetKeyName(1, "NumberGuessGameIcon.png");
|
||||||
|
ilGames.Images.SetKeyName(2, "Tic-tac-toe.png");
|
||||||
|
//
|
||||||
|
// tbpStore
|
||||||
|
//
|
||||||
|
tbpStore.Controls.Add(lvStoreItems);
|
||||||
|
tbpStore.ImageIndex = 3;
|
||||||
|
tbpStore.Location = new Point(4, 24);
|
||||||
|
tbpStore.Name = "tbpStore";
|
||||||
|
tbpStore.Padding = new Padding(3);
|
||||||
|
tbpStore.Size = new Size(344, 471);
|
||||||
|
tbpStore.TabIndex = 5;
|
||||||
|
tbpStore.Text = "Store";
|
||||||
|
tbpStore.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// lvStoreItems
|
||||||
|
//
|
||||||
|
lvStoreItems.LargeImageList = ilStoreThumbnails;
|
||||||
|
lvStoreItems.Location = new Point(0, 0);
|
||||||
|
lvStoreItems.Name = "lvStoreItems";
|
||||||
|
lvStoreItems.Size = new Size(344, 484);
|
||||||
|
lvStoreItems.SmallImageList = ilStoreThumbnails;
|
||||||
|
lvStoreItems.TabIndex = 0;
|
||||||
|
lvStoreItems.UseCompatibleStateImageBehavior = false;
|
||||||
|
lvStoreItems.DoubleClick += lvStoreItems_DoubleClick;
|
||||||
|
//
|
||||||
|
// ilStoreThumbnails
|
||||||
|
//
|
||||||
|
ilStoreThumbnails.ColorDepth = ColorDepth.Depth32Bit;
|
||||||
|
ilStoreThumbnails.ImageSize = new Size(64, 64);
|
||||||
|
ilStoreThumbnails.TransparentColor = Color.Transparent;
|
||||||
//
|
//
|
||||||
// ilTabIcons
|
// ilTabIcons
|
||||||
//
|
//
|
||||||
@ -158,20 +296,9 @@
|
|||||||
ilTabIcons.ImageStream = (ImageListStreamer)resources.GetObject("ilTabIcons.ImageStream");
|
ilTabIcons.ImageStream = (ImageListStreamer)resources.GetObject("ilTabIcons.ImageStream");
|
||||||
ilTabIcons.TransparentColor = Color.Transparent;
|
ilTabIcons.TransparentColor = Color.Transparent;
|
||||||
ilTabIcons.Images.SetKeyName(0, "ContactsIcon.png");
|
ilTabIcons.Images.SetKeyName(0, "ContactsIcon.png");
|
||||||
ilTabIcons.Images.SetKeyName(1, "RoomsChatIcon.png");
|
ilTabIcons.Images.SetKeyName(1, "UserIcon.png");
|
||||||
//
|
ilTabIcons.Images.SetKeyName(2, "RoomsChatIcon.png");
|
||||||
// pbUserPfp
|
ilTabIcons.Images.SetKeyName(3, "CurrencyIcon.png");
|
||||||
//
|
|
||||||
pbUserPfp.BorderStyle = BorderStyle.FixedSingle;
|
|
||||||
pbUserPfp.ContextMenuStrip = ctxmChangeStatus;
|
|
||||||
pbUserPfp.Image = Properties.Resources.DefaultPfp;
|
|
||||||
pbUserPfp.Location = new Point(12, 10);
|
|
||||||
pbUserPfp.Name = "pbUserPfp";
|
|
||||||
pbUserPfp.Size = new Size(51, 50);
|
|
||||||
pbUserPfp.SizeMode = PictureBoxSizeMode.StretchImage;
|
|
||||||
pbUserPfp.TabIndex = 1;
|
|
||||||
pbUserPfp.TabStop = false;
|
|
||||||
pbUserPfp.Click += pbUserPfp_Click;
|
|
||||||
//
|
//
|
||||||
// ctxmChangeStatus
|
// ctxmChangeStatus
|
||||||
//
|
//
|
||||||
@ -208,118 +335,29 @@
|
|||||||
invisibleToolStripMenuItem.Size = new Size(153, 22);
|
invisibleToolStripMenuItem.Size = new Size(153, 22);
|
||||||
invisibleToolStripMenuItem.Text = "Invisible";
|
invisibleToolStripMenuItem.Text = "Invisible";
|
||||||
//
|
//
|
||||||
// lblWelcome
|
|
||||||
//
|
|
||||||
lblWelcome.AutoSize = true;
|
|
||||||
lblWelcome.Font = new Font("Segoe UI Light", 9F);
|
|
||||||
lblWelcome.ForeColor = SystemColors.ControlLightLight;
|
|
||||||
lblWelcome.Location = new Point(65, 17);
|
|
||||||
lblWelcome.Name = "lblWelcome";
|
|
||||||
lblWelcome.Size = new Size(60, 15);
|
|
||||||
lblWelcome.TabIndex = 2;
|
|
||||||
lblWelcome.Text = "Welcome, ";
|
|
||||||
//
|
|
||||||
// llblSignIn
|
|
||||||
//
|
|
||||||
llblSignIn.AutoSize = true;
|
|
||||||
llblSignIn.Font = new Font("Segoe UI Light", 9F);
|
|
||||||
llblSignIn.LinkColor = Color.White;
|
|
||||||
llblSignIn.Location = new Point(118, 17);
|
|
||||||
llblSignIn.Name = "llblSignIn";
|
|
||||||
llblSignIn.Size = new Size(40, 15);
|
|
||||||
llblSignIn.TabIndex = 3;
|
|
||||||
llblSignIn.TabStop = true;
|
|
||||||
llblSignIn.Text = "Sign In";
|
|
||||||
llblSignIn.LinkClicked += llblSignIn_LinkClicked;
|
|
||||||
//
|
|
||||||
// llblSignOut
|
|
||||||
//
|
|
||||||
llblSignOut.AutoSize = true;
|
|
||||||
llblSignOut.Font = new Font("Segoe UI Light", 9F);
|
|
||||||
llblSignOut.LinkColor = Color.White;
|
|
||||||
llblSignOut.Location = new Point(65, 35);
|
|
||||||
llblSignOut.Name = "llblSignOut";
|
|
||||||
llblSignOut.Size = new Size(50, 15);
|
|
||||||
llblSignOut.TabIndex = 4;
|
|
||||||
llblSignOut.TabStop = true;
|
|
||||||
llblSignOut.Text = "Sign Out";
|
|
||||||
llblSignOut.Visible = false;
|
|
||||||
llblSignOut.LinkClicked += llblSignOut_LinkClicked;
|
|
||||||
//
|
|
||||||
// llblEditProfile
|
|
||||||
//
|
|
||||||
llblEditProfile.AutoSize = true;
|
|
||||||
llblEditProfile.Font = new Font("Segoe UI Light", 9F);
|
|
||||||
llblEditProfile.LinkColor = Color.White;
|
|
||||||
llblEditProfile.Location = new Point(113, 35);
|
|
||||||
llblEditProfile.Name = "llblEditProfile";
|
|
||||||
llblEditProfile.Size = new Size(60, 15);
|
|
||||||
llblEditProfile.TabIndex = 5;
|
|
||||||
llblEditProfile.TabStop = true;
|
|
||||||
llblEditProfile.Text = "Edit Profile";
|
|
||||||
llblEditProfile.Visible = false;
|
|
||||||
llblEditProfile.LinkClicked += llblEditProfile_LinkClicked;
|
|
||||||
//
|
|
||||||
// lblRequestNotif
|
// lblRequestNotif
|
||||||
//
|
//
|
||||||
|
lblRequestNotif.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
lblRequestNotif.AutoSize = true;
|
lblRequestNotif.AutoSize = true;
|
||||||
lblRequestNotif.Font = new Font("Segoe UI", 7F, FontStyle.Bold);
|
lblRequestNotif.Font = new Font("Segoe UI", 6F, FontStyle.Bold);
|
||||||
lblRequestNotif.Location = new Point(128, 54);
|
lblRequestNotif.Location = new Point(12, 67);
|
||||||
lblRequestNotif.Name = "lblRequestNotif";
|
lblRequestNotif.Name = "lblRequestNotif";
|
||||||
lblRequestNotif.Size = new Size(138, 12);
|
lblRequestNotif.Size = new Size(109, 11);
|
||||||
lblRequestNotif.TabIndex = 6;
|
lblRequestNotif.TabIndex = 6;
|
||||||
lblRequestNotif.Text = "You Have Contacts Requests!";
|
lblRequestNotif.Text = "You Have Contact Requests!";
|
||||||
lblRequestNotif.Visible = false;
|
lblRequestNotif.Visible = false;
|
||||||
//
|
//
|
||||||
// niMain
|
// niMain
|
||||||
//
|
//
|
||||||
niMain.Icon = (Icon)resources.GetObject("niMain.Icon");
|
niMain.Icon = (Icon)resources.GetObject("niMain.Icon");
|
||||||
niMain.Text = "QtC.NET Client";
|
niMain.Text = "QtC.NET Client";
|
||||||
niMain.Visible = true;
|
|
||||||
niMain.DoubleClick += niMain_DoubleClick;
|
niMain.DoubleClick += niMain_DoubleClick;
|
||||||
//
|
//
|
||||||
// btnAddRoom
|
|
||||||
//
|
|
||||||
btnAddRoom.FlatAppearance.BorderSize = 0;
|
|
||||||
btnAddRoom.FlatStyle = FlatStyle.Flat;
|
|
||||||
btnAddRoom.Location = new Point(260, 1);
|
|
||||||
btnAddRoom.Name = "btnAddRoom";
|
|
||||||
btnAddRoom.Size = new Size(20, 22);
|
|
||||||
btnAddRoom.TabIndex = 7;
|
|
||||||
btnAddRoom.UseVisualStyleBackColor = true;
|
|
||||||
btnAddRoom.Click += btnAddRoom_Click;
|
|
||||||
//
|
|
||||||
// pbCurrencyIcon
|
|
||||||
//
|
|
||||||
pbCurrencyIcon.Image = Properties.Resources.CurrencyIcon;
|
|
||||||
pbCurrencyIcon.Location = new Point(223, 5);
|
|
||||||
pbCurrencyIcon.Name = "pbCurrencyIcon";
|
|
||||||
pbCurrencyIcon.Size = new Size(15, 14);
|
|
||||||
pbCurrencyIcon.SizeMode = PictureBoxSizeMode.StretchImage;
|
|
||||||
pbCurrencyIcon.TabIndex = 9;
|
|
||||||
pbCurrencyIcon.TabStop = false;
|
|
||||||
pbCurrencyIcon.Visible = false;
|
|
||||||
//
|
|
||||||
// lblCurrencyAmount
|
|
||||||
//
|
|
||||||
lblCurrencyAmount.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
|
||||||
lblCurrencyAmount.AutoSize = true;
|
|
||||||
lblCurrencyAmount.BackColor = Color.Transparent;
|
|
||||||
lblCurrencyAmount.Font = new Font("Segoe UI", 9F, FontStyle.Bold);
|
|
||||||
lblCurrencyAmount.ForeColor = Color.White;
|
|
||||||
lblCurrencyAmount.Location = new Point(239, 5);
|
|
||||||
lblCurrencyAmount.Name = "lblCurrencyAmount";
|
|
||||||
lblCurrencyAmount.Size = new Size(14, 15);
|
|
||||||
lblCurrencyAmount.TabIndex = 10;
|
|
||||||
lblCurrencyAmount.Text = "0";
|
|
||||||
lblCurrencyAmount.TextAlign = ContentAlignment.MiddleCenter;
|
|
||||||
lblCurrencyAmount.Visible = false;
|
|
||||||
//
|
|
||||||
// llblClaimSpin
|
// llblClaimSpin
|
||||||
//
|
//
|
||||||
llblClaimSpin.AutoSize = true;
|
llblClaimSpin.AutoSize = true;
|
||||||
llblClaimSpin.Font = new Font("Segoe UI", 9F, FontStyle.Bold);
|
llblClaimSpin.Font = new Font("Segoe UI", 9F, FontStyle.Bold);
|
||||||
llblClaimSpin.Location = new Point(185, 35);
|
llblClaimSpin.Location = new Point(1, 25);
|
||||||
llblClaimSpin.Name = "llblClaimSpin";
|
llblClaimSpin.Name = "llblClaimSpin";
|
||||||
llblClaimSpin.Size = new Size(94, 15);
|
llblClaimSpin.Size = new Size(94, 15);
|
||||||
llblClaimSpin.TabIndex = 11;
|
llblClaimSpin.TabIndex = 11;
|
||||||
@ -328,23 +366,231 @@
|
|||||||
llblClaimSpin.Visible = false;
|
llblClaimSpin.Visible = false;
|
||||||
llblClaimSpin.LinkClicked += llblClaimSpin_LinkClicked;
|
llblClaimSpin.LinkClicked += llblClaimSpin_LinkClicked;
|
||||||
//
|
//
|
||||||
|
// pCurrencyArea
|
||||||
|
//
|
||||||
|
pCurrencyArea.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
||||||
|
pCurrencyArea.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
pCurrencyArea.Controls.Add(llblClaimSpin);
|
||||||
|
pCurrencyArea.Controls.Add(pbCurrencyIcon);
|
||||||
|
pCurrencyArea.Controls.Add(lblCurrencyAmount);
|
||||||
|
pCurrencyArea.Location = new Point(270, 5);
|
||||||
|
pCurrencyArea.Name = "pCurrencyArea";
|
||||||
|
pCurrencyArea.Size = new Size(95, 46);
|
||||||
|
pCurrencyArea.TabIndex = 12;
|
||||||
|
//
|
||||||
|
// pbCurrencyIcon
|
||||||
|
//
|
||||||
|
pbCurrencyIcon.Image = Properties.Resources.CurrencyIcon;
|
||||||
|
pbCurrencyIcon.Location = new Point(20, 6);
|
||||||
|
pbCurrencyIcon.Name = "pbCurrencyIcon";
|
||||||
|
pbCurrencyIcon.Size = new Size(15, 14);
|
||||||
|
pbCurrencyIcon.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
pbCurrencyIcon.TabIndex = 18;
|
||||||
|
pbCurrencyIcon.TabStop = false;
|
||||||
|
pbCurrencyIcon.Visible = false;
|
||||||
|
//
|
||||||
|
// lblCurrencyAmount
|
||||||
|
//
|
||||||
|
lblCurrencyAmount.BackColor = Color.Transparent;
|
||||||
|
lblCurrencyAmount.Font = new Font("Segoe UI", 9F, FontStyle.Bold);
|
||||||
|
lblCurrencyAmount.ForeColor = Color.White;
|
||||||
|
lblCurrencyAmount.Location = new Point(35, 3);
|
||||||
|
lblCurrencyAmount.Name = "lblCurrencyAmount";
|
||||||
|
lblCurrencyAmount.Size = new Size(69, 20);
|
||||||
|
lblCurrencyAmount.TabIndex = 19;
|
||||||
|
lblCurrencyAmount.Text = "99999";
|
||||||
|
lblCurrencyAmount.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
|
lblCurrencyAmount.Visible = false;
|
||||||
|
//
|
||||||
|
// pCurrentUser
|
||||||
|
//
|
||||||
|
pCurrentUser.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
pCurrentUser.Controls.Add(llblEditProfile);
|
||||||
|
pCurrentUser.Controls.Add(llblSignOut);
|
||||||
|
pCurrentUser.Controls.Add(llblSignIn);
|
||||||
|
pCurrentUser.Controls.Add(lblWelcome);
|
||||||
|
pCurrentUser.Controls.Add(pbUserPfp);
|
||||||
|
pCurrentUser.Location = new Point(5, 4);
|
||||||
|
pCurrentUser.Name = "pCurrentUser";
|
||||||
|
pCurrentUser.Size = new Size(204, 59);
|
||||||
|
pCurrentUser.TabIndex = 13;
|
||||||
|
//
|
||||||
|
// llblEditProfile
|
||||||
|
//
|
||||||
|
llblEditProfile.AutoSize = true;
|
||||||
|
llblEditProfile.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
llblEditProfile.LinkColor = Color.White;
|
||||||
|
llblEditProfile.Location = new Point(104, 29);
|
||||||
|
llblEditProfile.Name = "llblEditProfile";
|
||||||
|
llblEditProfile.Size = new Size(60, 15);
|
||||||
|
llblEditProfile.TabIndex = 10;
|
||||||
|
llblEditProfile.TabStop = true;
|
||||||
|
llblEditProfile.Text = "Edit Profile";
|
||||||
|
llblEditProfile.Visible = false;
|
||||||
|
llblEditProfile.LinkClicked += llblEditProfile_LinkClicked;
|
||||||
|
//
|
||||||
|
// llblSignOut
|
||||||
|
//
|
||||||
|
llblSignOut.AutoSize = true;
|
||||||
|
llblSignOut.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
llblSignOut.LinkColor = Color.White;
|
||||||
|
llblSignOut.Location = new Point(56, 29);
|
||||||
|
llblSignOut.Name = "llblSignOut";
|
||||||
|
llblSignOut.Size = new Size(50, 15);
|
||||||
|
llblSignOut.TabIndex = 9;
|
||||||
|
llblSignOut.TabStop = true;
|
||||||
|
llblSignOut.Text = "Sign Out";
|
||||||
|
llblSignOut.Visible = false;
|
||||||
|
llblSignOut.LinkClicked += llblSignOut_LinkClicked;
|
||||||
|
//
|
||||||
|
// llblSignIn
|
||||||
|
//
|
||||||
|
llblSignIn.AutoSize = true;
|
||||||
|
llblSignIn.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
llblSignIn.LinkColor = Color.White;
|
||||||
|
llblSignIn.Location = new Point(109, 11);
|
||||||
|
llblSignIn.Name = "llblSignIn";
|
||||||
|
llblSignIn.Size = new Size(40, 15);
|
||||||
|
llblSignIn.TabIndex = 8;
|
||||||
|
llblSignIn.TabStop = true;
|
||||||
|
llblSignIn.Text = "Sign In";
|
||||||
|
llblSignIn.LinkClicked += llblSignIn_LinkClicked;
|
||||||
|
//
|
||||||
|
// lblWelcome
|
||||||
|
//
|
||||||
|
lblWelcome.AutoEllipsis = true;
|
||||||
|
lblWelcome.Font = new Font("Segoe UI Light", 9F);
|
||||||
|
lblWelcome.ForeColor = SystemColors.ControlLightLight;
|
||||||
|
lblWelcome.Location = new Point(56, 11);
|
||||||
|
lblWelcome.Name = "lblWelcome";
|
||||||
|
lblWelcome.Size = new Size(143, 15);
|
||||||
|
lblWelcome.TabIndex = 7;
|
||||||
|
lblWelcome.Text = "Welcome, ";
|
||||||
|
//
|
||||||
|
// pbUserPfp
|
||||||
|
//
|
||||||
|
pbUserPfp.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
pbUserPfp.ContextMenuStrip = ctxmChangeStatus;
|
||||||
|
pbUserPfp.Cursor = Cursors.Hand;
|
||||||
|
pbUserPfp.Image = Properties.Resources.DefaultPfp;
|
||||||
|
pbUserPfp.Location = new Point(3, 4);
|
||||||
|
pbUserPfp.Name = "pbUserPfp";
|
||||||
|
pbUserPfp.Size = new Size(51, 50);
|
||||||
|
pbUserPfp.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
pbUserPfp.TabIndex = 6;
|
||||||
|
pbUserPfp.TabStop = false;
|
||||||
|
pbUserPfp.Click += pbUserPfp_Click;
|
||||||
|
//
|
||||||
|
// pbDonate
|
||||||
|
//
|
||||||
|
pbDonate.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
||||||
|
pbDonate.Cursor = Cursors.Hand;
|
||||||
|
pbDonate.Image = Properties.Resources.donatebtn;
|
||||||
|
pbDonate.Location = new Point(288, 56);
|
||||||
|
pbDonate.Name = "pbDonate";
|
||||||
|
pbDonate.Size = new Size(77, 22);
|
||||||
|
pbDonate.SizeMode = PictureBoxSizeMode.Zoom;
|
||||||
|
pbDonate.TabIndex = 14;
|
||||||
|
pbDonate.TabStop = false;
|
||||||
|
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);
|
||||||
AutoScaleMode = AutoScaleMode.Font;
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
BackColor = Color.DodgerBlue;
|
BackColor = Color.DodgerBlue;
|
||||||
ClientSize = new Size(282, 613);
|
ClientSize = new Size(376, 594);
|
||||||
Controls.Add(llblClaimSpin);
|
Controls.Add(pbDonate);
|
||||||
Controls.Add(pbCurrencyIcon);
|
Controls.Add(pCurrentUser);
|
||||||
Controls.Add(lblCurrencyAmount);
|
Controls.Add(pCurrencyArea);
|
||||||
Controls.Add(btnAddRoom);
|
|
||||||
Controls.Add(lblRequestNotif);
|
Controls.Add(lblRequestNotif);
|
||||||
Controls.Add(llblEditProfile);
|
|
||||||
Controls.Add(llblSignOut);
|
|
||||||
Controls.Add(llblSignIn);
|
|
||||||
Controls.Add(lblWelcome);
|
|
||||||
Controls.Add(pbUserPfp);
|
|
||||||
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;
|
||||||
@ -356,11 +602,21 @@
|
|||||||
Resize += frmMain_Resize;
|
Resize += frmMain_Resize;
|
||||||
tbcMain.ResumeLayout(false);
|
tbcMain.ResumeLayout(false);
|
||||||
tbpContacts.ResumeLayout(false);
|
tbpContacts.ResumeLayout(false);
|
||||||
|
ctxmRefresh.ResumeLayout(false);
|
||||||
tbpRooms.ResumeLayout(false);
|
tbpRooms.ResumeLayout(false);
|
||||||
tbpOnlineUsers.ResumeLayout(false);
|
tbpUsers.ResumeLayout(false);
|
||||||
((System.ComponentModel.ISupportInitialize)pbUserPfp).EndInit();
|
tbpGames.ResumeLayout(false);
|
||||||
|
tbpStore.ResumeLayout(false);
|
||||||
ctxmChangeStatus.ResumeLayout(false);
|
ctxmChangeStatus.ResumeLayout(false);
|
||||||
|
pCurrencyArea.ResumeLayout(false);
|
||||||
|
pCurrencyArea.PerformLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)pbCurrencyIcon).EndInit();
|
((System.ComponentModel.ISupportInitialize)pbCurrencyIcon).EndInit();
|
||||||
|
pCurrentUser.ResumeLayout(false);
|
||||||
|
pCurrentUser.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbUserPfp).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbDonate).EndInit();
|
||||||
|
ctxmAdminUserList.ResumeLayout(false);
|
||||||
|
ctxmAdminRoomList.ResumeLayout(false);
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
PerformLayout();
|
PerformLayout();
|
||||||
}
|
}
|
||||||
@ -371,16 +627,9 @@
|
|||||||
private TabPage tbpContacts;
|
private TabPage tbpContacts;
|
||||||
private TabPage tbpRooms;
|
private TabPage tbpRooms;
|
||||||
private ListBox lbRooms;
|
private ListBox lbRooms;
|
||||||
private PictureBox pbUserPfp;
|
|
||||||
private Label lblWelcome;
|
|
||||||
private LinkLabel llblSignIn;
|
|
||||||
private LinkLabel llblSignOut;
|
|
||||||
private TabPage tbpOnlineUsers;
|
|
||||||
private ListBox lbOnlineUsers;
|
|
||||||
private LinkLabel llblEditProfile;
|
|
||||||
private Label lblRequestNotif;
|
private Label lblRequestNotif;
|
||||||
private ListView lvContacts;
|
private ListView lvContacts;
|
||||||
private ImageList ilProfilePics;
|
private System.Windows.Forms.ImageList ilProfilePics;
|
||||||
private NotifyIcon niMain;
|
private NotifyIcon niMain;
|
||||||
private ImageList ilTabIcons;
|
private ImageList ilTabIcons;
|
||||||
private ContextMenuStrip ctxmChangeStatus;
|
private ContextMenuStrip ctxmChangeStatus;
|
||||||
@ -388,9 +637,39 @@
|
|||||||
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 Panel pCurrencyArea;
|
||||||
|
private Panel pCurrentUser;
|
||||||
|
private LinkLabel llblEditProfile;
|
||||||
|
private LinkLabel llblSignOut;
|
||||||
|
private LinkLabel llblSignIn;
|
||||||
|
private Label lblWelcome;
|
||||||
|
private PictureBox pbUserPfp;
|
||||||
|
private TabPage tbpGames;
|
||||||
|
private ListView lvGames;
|
||||||
|
private ImageList ilGames;
|
||||||
private PictureBox pbCurrencyIcon;
|
private PictureBox pbCurrencyIcon;
|
||||||
private Label lblCurrencyAmount;
|
private Label lblCurrencyAmount;
|
||||||
private LinkLabel llblClaimSpin;
|
private ContextMenuStrip ctxmRefresh;
|
||||||
|
private ToolStripMenuItem refreshToolStripMenuItem;
|
||||||
|
private ImageList ilStatusIcons;
|
||||||
|
private TabPage tbpUsers;
|
||||||
|
private ListView lvUserDirectory;
|
||||||
|
private PictureBox pbDonate;
|
||||||
|
private TabPage tbpStore;
|
||||||
|
private ListView lvStoreItems;
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,9 @@ using QtCNETAPI.Models;
|
|||||||
using qtc_net_client_2.Forms;
|
using qtc_net_client_2.Forms;
|
||||||
using qtc_net_client_2.Services;
|
using qtc_net_client_2.Services;
|
||||||
using qtc_net_client_2.ClientModel;
|
using qtc_net_client_2.ClientModel;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using QtCNETAPI.Schema;
|
||||||
|
using QtCNETAPI.Services;
|
||||||
|
|
||||||
namespace qtc_net_client_2
|
namespace qtc_net_client_2
|
||||||
{
|
{
|
||||||
@ -13,21 +16,31 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
private IApiService _apiService;
|
private IApiService _apiService;
|
||||||
private IGatewayService _gatewayService;
|
private IGatewayService _gatewayService;
|
||||||
private AudioService AudioService = new();
|
|
||||||
|
|
||||||
private List<Room> RoomList = [];
|
private Config _config;
|
||||||
private List<UserInformationDto> OnlineUsers = [];
|
private ServerConfig _serverConfig;
|
||||||
private List<UserInformationDto> Contacts = [];
|
private AudioService AudioService = new();
|
||||||
public Main(IApiService apiService, IGatewayService gatewayService)
|
private LoggingService LoggingService;
|
||||||
|
|
||||||
|
public List<Room> RoomList = [];
|
||||||
|
public List<UserInformationDto> UserDirectory = [];
|
||||||
|
public List<Contact> Contacts = [];
|
||||||
|
|
||||||
|
private bool FirstMinimize = true;
|
||||||
|
public Main(IApiService apiService, IGatewayService gatewayService, Config config, LoggingService loggingService)
|
||||||
{
|
{
|
||||||
_apiService = apiService;
|
_apiService = apiService;
|
||||||
_gatewayService = gatewayService;
|
_gatewayService = gatewayService;
|
||||||
|
_config = config;
|
||||||
|
LoggingService = loggingService;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void frmMain_Load(object sender, EventArgs e)
|
private async void frmMain_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString("Main Form Loaded");
|
||||||
|
|
||||||
// start request notif blink task
|
// start request notif blink task
|
||||||
Thread blinkThread = new Thread(async () => await StartRequestNotifBlankLoop(lblRequestNotif));
|
Thread blinkThread = new Thread(async () => await StartRequestNotifBlankLoop(lblRequestNotif));
|
||||||
blinkThread.Start();
|
blinkThread.Start();
|
||||||
@ -66,8 +79,10 @@ namespace qtc_net_client_2
|
|||||||
// join lobby
|
// join lobby
|
||||||
if (!_gatewayService.InLobby) await _gatewayService.JoinLobbyAsync();
|
if (!_gatewayService.InLobby) await _gatewayService.JoinLobbyAsync();
|
||||||
|
|
||||||
Chat frmChat = new Chat(_gatewayService, _apiService);
|
ChatRoom frmChat = new ChatRoom(_gatewayService, _apiService);
|
||||||
frmChat.Show();
|
frmChat.Show();
|
||||||
|
|
||||||
|
LoggingService.LogString("User Has Joined Lobby Room");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +92,10 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
if (_gatewayService.CurrentRoom != room) await _gatewayService.JoinRoomAsync(room);
|
if (_gatewayService.CurrentRoom != room) await _gatewayService.JoinRoomAsync(room);
|
||||||
|
|
||||||
Chat frmChat = new Chat(_gatewayService, _apiService);
|
ChatRoom frmChat = new ChatRoom(_gatewayService, _apiService);
|
||||||
frmChat.Show();
|
frmChat.Show();
|
||||||
|
|
||||||
|
LoggingService.LogString($"User Has Joined {room.Name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,6 +131,7 @@ namespace qtc_net_client_2
|
|||||||
ms.Dispose();
|
ms.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,36 +150,10 @@ namespace qtc_net_client_2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void lbOnlineUsers_DoubleClick(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (lbOnlineUsers.SelectedItems.Count > 0)
|
|
||||||
{
|
|
||||||
string? selectedUser = (string?)lbOnlineUsers.SelectedItems[lbOnlineUsers.SelectedItems.Count - 1];
|
|
||||||
|
|
||||||
if (selectedUser != null)
|
|
||||||
{
|
|
||||||
// get user info and open profile dialog
|
|
||||||
var user = OnlineUsers.FirstOrDefault(e => e.Username == selectedUser);
|
|
||||||
var res = await _apiService.GetUserInformationAsync(user!.Id);
|
|
||||||
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
|
|
||||||
|
|
||||||
if (res.Data != null && res.Success)
|
|
||||||
{
|
|
||||||
Profile frmProfile = new Profile(res.Data, pfpRes, _apiService, _gatewayService);
|
|
||||||
frmProfile.ShowDialog();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void llblEditProfile_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
private void llblEditProfile_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
{
|
{
|
||||||
ProfileEdit frmProfileEdit = new ProfileEdit(_apiService);
|
ProfileEdit frmProfileEdit = new ProfileEdit(_apiService);
|
||||||
var dialogResult = frmProfileEdit.ShowDialog();
|
frmProfileEdit.ShowDialog();
|
||||||
if (dialogResult == DialogResult.OK)
|
|
||||||
{
|
|
||||||
MessageBox.Show("If you updated your username, hit the refresh button to see it update on your lists.\nThe top username will not update until you restart your client.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void lvContacts_DoubleClick(object sender, EventArgs e)
|
private async void lvContacts_DoubleClick(object sender, EventArgs e)
|
||||||
@ -176,36 +168,61 @@ namespace qtc_net_client_2
|
|||||||
if (selectedUser.Contains('[')) selectedUser = selectedUser.Split('[', options: StringSplitOptions.TrimEntries)[0];
|
if (selectedUser.Contains('[')) selectedUser = selectedUser.Split('[', options: StringSplitOptions.TrimEntries)[0];
|
||||||
|
|
||||||
// get user info and open profile dialog
|
// get user info and open profile dialog
|
||||||
var user = Contacts.FirstOrDefault(e => e.Username == selectedUser);
|
var user = UserDirectory.FirstOrDefault(e => e.Username == selectedUser);
|
||||||
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 (res.Data != null && res.Success)
|
if (res.Data != null && res.Success)
|
||||||
{
|
{
|
||||||
Profile frmProfile = new Profile(res.Data, pfpRes, _apiService, _gatewayService);
|
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
|
||||||
frmProfile.ShowDialog();
|
Profile frmProfile = new Profile(res.Data, pfpRes, Contacts, _apiService, _gatewayService, cosmeticData);
|
||||||
|
frmProfile.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void btnRefresh_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
// refresh all
|
|
||||||
await RefreshContactsList();
|
|
||||||
await RefreshRoomsList();
|
|
||||||
await RefreshOnlineUsersList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void frmMain_Resize(object sender, EventArgs e)
|
private void frmMain_Resize(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (WindowState == FormWindowState.Minimized) Hide();
|
if (WindowState == FormWindowState.Minimized && _config.MinimizeToTray)
|
||||||
|
{
|
||||||
|
Hide();
|
||||||
|
niMain.Visible = true;
|
||||||
|
if (FirstMinimize)
|
||||||
|
{
|
||||||
|
niMain.ShowBalloonTip(10,
|
||||||
|
"I'm over here!",
|
||||||
|
"QtC.NET Mimimizes To Tray By Default. To Change This Behaviour, Refer To config.json",
|
||||||
|
ToolTipIcon.Info);
|
||||||
|
FirstMinimize = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void niMain_DoubleClick(object sender, EventArgs e)
|
private void niMain_DoubleClick(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Show();
|
Show();
|
||||||
WindowState = FormWindowState.Normal;
|
WindowState = FormWindowState.Normal;
|
||||||
|
niMain.Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void frmMain_FormClosed(object sender, FormClosedEventArgs e)
|
private async void frmMain_FormClosed(object sender, FormClosedEventArgs e)
|
||||||
@ -267,7 +284,7 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
private async void llblClaimSpin_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
private async void llblClaimSpin_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
{
|
{
|
||||||
TokenJackpotSpinner tokenJackpotSpinner = new TokenJackpotSpinner();
|
CurrencyJackpotSpinner tokenJackpotSpinner = new CurrencyJackpotSpinner();
|
||||||
var frmResult = tokenJackpotSpinner.ShowDialog();
|
var frmResult = tokenJackpotSpinner.ShowDialog();
|
||||||
|
|
||||||
if (frmResult == DialogResult.OK && tokenJackpotSpinner.TokensWon > 0)
|
if (frmResult == DialogResult.OK && tokenJackpotSpinner.TokensWon > 0)
|
||||||
@ -276,18 +293,286 @@ namespace qtc_net_client_2
|
|||||||
var result = await _apiService.AddCurrencyToCurrentUser(tokenJackpotSpinner.TokensWon, true);
|
var result = await _apiService.AddCurrencyToCurrentUser(tokenJackpotSpinner.TokensWon, true);
|
||||||
if (result.Success)
|
if (result.Success)
|
||||||
{
|
{
|
||||||
lblCurrencyAmount.Text = (_apiService.CurrentUser.CurrencyAmount + tokenJackpotSpinner.TokensWon).ToString();
|
lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString("N0");
|
||||||
llblClaimSpin.Visible = false;
|
llblClaimSpin.Visible = false;
|
||||||
}
|
}
|
||||||
else MessageBox.Show("We Were Unable To Claim Your Prize At This Time. Please Try Again Later.", "Uh Oh.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
else MessageBox.Show("We Were Unable To Claim Your Prize At This Time. Please Try Again Later.", "Uh Oh.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void lbUserDirectory_DoubleClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lvUserDirectory.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
string? selectedUser = (string?)lvUserDirectory.SelectedItems[lvUserDirectory.SelectedItems.Count - 1].Text;
|
||||||
|
|
||||||
|
if (selectedUser != null)
|
||||||
|
{
|
||||||
|
// get user info and open profile dialog
|
||||||
|
var user = UserDirectory.FirstOrDefault(e => e.Username == selectedUser);
|
||||||
|
var res = await _apiService.GetUserInformationAsync(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 (res.Data != null && res.Success)
|
||||||
|
{
|
||||||
|
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
|
||||||
|
Profile frmProfile = new Profile(res.Data, pfpRes, Contacts, _apiService, _gatewayService, cosmeticData);
|
||||||
|
frmProfile.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lvGames_DoubleClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lvGames.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
string? gameSelected = (string?)lvGames.SelectedItems[lvGames.SelectedItems.Count - 1].Tag;
|
||||||
|
|
||||||
|
switch (gameSelected)
|
||||||
|
{
|
||||||
|
case "StockMarketGame":
|
||||||
|
StockMarketGame stockMarketGame = new StockMarketGame(_apiService);
|
||||||
|
stockMarketGame.Show();
|
||||||
|
break;
|
||||||
|
case "GuessTheNumberGame":
|
||||||
|
GuessTheNumber guessTheNumber = new GuessTheNumber(_apiService);
|
||||||
|
guessTheNumber.Show();
|
||||||
|
break;
|
||||||
|
case "TicTacToeGame":
|
||||||
|
TicTacToeGame ticTacToeGame = new TicTacToeGame(_apiService, _config);
|
||||||
|
ticTacToeGame.Show();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void refreshToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (tbcMain.SelectedIndex == 0) await RefreshContactsList();
|
||||||
|
if (tbcMain.SelectedIndex == 1) await RefreshRoomsList();
|
||||||
|
if (tbcMain.SelectedIndex == 2) await RefreshUsers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pbDonate_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
DonationWindow donationWindow = new DonationWindow();
|
||||||
|
donationWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void tbcMain_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (tbcMain.SelectedIndex == 4)
|
||||||
|
{
|
||||||
|
// get store items
|
||||||
|
var storeItems = await _apiService.GetStoreItems();
|
||||||
|
if (storeItems != null && storeItems.Success && storeItems.Data != null)
|
||||||
|
{
|
||||||
|
if (lvStoreItems.Items.Count == storeItems.Data.Count) return;
|
||||||
|
|
||||||
|
ilStoreThumbnails.Images.Clear();
|
||||||
|
foreach (var item in storeItems.Data)
|
||||||
|
{
|
||||||
|
await GetAndAddStoreThumbnail(item);
|
||||||
|
var lvitem = lvStoreItems.Items.Add(new ListViewItem { Text = item.Name, Name = item.Id.ToString() });
|
||||||
|
lvitem.ImageKey = item.Id.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void lvStoreItems_DoubleClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lvStoreItems.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
string? itemSelected = (string?)lvStoreItems.SelectedItems[lvStoreItems.SelectedItems.Count - 1].Name;
|
||||||
|
if (itemSelected != null)
|
||||||
|
{
|
||||||
|
// get item
|
||||||
|
var item = await _apiService.GetStoreItem(int.Parse(itemSelected));
|
||||||
|
if (item != null && item.Success && item.Data != null)
|
||||||
|
{
|
||||||
|
StoreItemDisplay storeItemDisplay = new StoreItemDisplay(item.Data, LoggingService, _apiService);
|
||||||
|
storeItemDisplay.ShowDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
if (_apiService.CurrentUser != null && _apiService.SessionToken != null)
|
if (_apiService.CurrentUser != null && _apiService.SessionToken != null)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString($"Logged In As '{_apiService.CurrentUser.Username}'");
|
||||||
|
LoggingService.LogString("Starting SignalR Connection...");
|
||||||
|
|
||||||
// start gateway connection
|
// start gateway connection
|
||||||
await _gatewayService.StartAsync();
|
await _gatewayService.StartAsync();
|
||||||
|
|
||||||
@ -295,18 +580,26 @@ namespace qtc_net_client_2
|
|||||||
_gatewayService.OnServerReconnecting += _gatewayService_OnServerReconnecting;
|
_gatewayService.OnServerReconnecting += _gatewayService_OnServerReconnecting;
|
||||||
_gatewayService.OnServerReconnected += _gatewayService_OnServerReconnected;
|
_gatewayService.OnServerReconnected += _gatewayService_OnServerReconnected;
|
||||||
_gatewayService.OnServerDisconnect += _gatewayService_OnServerDisconnect;
|
_gatewayService.OnServerDisconnect += _gatewayService_OnServerDisconnect;
|
||||||
_gatewayService.OnClientFunctionReceived += _gatewayService_OnClientFunctionReceived;
|
|
||||||
_gatewayService.OnDirectMessageReceived += _gatewayService_OnDirectMessageReceived;
|
_gatewayService.OnDirectMessageReceived += _gatewayService_OnDirectMessageReceived;
|
||||||
|
_gatewayService.OnRefreshUserListsReceived += _gatewayService_OnRefreshUserListReceived;
|
||||||
|
_gatewayService.OnRefreshRoomListReceived += _gatewayService_OnRefreshRoomListReceived;
|
||||||
|
_gatewayService.OnRefreshContactsListReceived += _gatewayService_OnRefreshContactsListReceived;
|
||||||
_gatewayService.OnServerConfigReceived += _gatewayService_OnServerConfigReceived;
|
_gatewayService.OnServerConfigReceived += _gatewayService_OnServerConfigReceived;
|
||||||
|
_gatewayService.OnUserForceLogout += _gatewayService_OnUserForceLogout;
|
||||||
|
|
||||||
|
_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("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;
|
||||||
lblWelcome.Text = $"Welcome, {_apiService.CurrentUser.Username}";
|
lblWelcome.Text = $"Welcome, {_apiService.CurrentUser.Username}";
|
||||||
lblCurrencyAmount.Visible = true;
|
lblCurrencyAmount.Visible = true;
|
||||||
pbCurrencyIcon.Visible = true;
|
pbCurrencyIcon.Visible = true;
|
||||||
lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString();
|
lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString("N0");
|
||||||
llblSignOut.Visible = true;
|
llblSignOut.Visible = true;
|
||||||
llblEditProfile.Visible = true;
|
llblEditProfile.Visible = true;
|
||||||
tbcMain.Enabled = true;
|
tbcMain.Enabled = true;
|
||||||
@ -321,14 +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();
|
||||||
await RefreshOnlineUsersList();
|
|
||||||
|
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
@ -358,52 +651,60 @@ 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 (_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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshOnlineUsersList()
|
private async Task RefreshUsers()
|
||||||
{
|
{
|
||||||
if (InvokeRequired)
|
LoggingService.LogString("Refreshing All Users List...");
|
||||||
|
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
{
|
{
|
||||||
lbOnlineUsers.Items.Clear();
|
// get all users on server
|
||||||
var usersOnlineRes = await _apiService.GetOnlineUsersAsync();
|
var userList = await _apiService.GetAllUsersAsync();
|
||||||
if (usersOnlineRes.Success && usersOnlineRes.Data != null)
|
|
||||||
|
if (userList != null && userList.Success && userList.Data != null)
|
||||||
{
|
{
|
||||||
foreach (var user in usersOnlineRes.Data)
|
// clear the list
|
||||||
|
lvUserDirectory.Items.Clear();
|
||||||
|
UserDirectory.Clear();
|
||||||
|
|
||||||
|
// populate list
|
||||||
|
foreach (var user in userList.Data)
|
||||||
{
|
{
|
||||||
lbOnlineUsers.Items.Add(user.Username);
|
lvUserDirectory.Items.Add(user.Username, user.Status);
|
||||||
|
UserDirectory.Add(user);
|
||||||
}
|
}
|
||||||
OnlineUsers = usersOnlineRes.Data;
|
|
||||||
|
if (System.Diagnostics.Debugger.IsAttached || _config.EnableDebugLogs)
|
||||||
|
LoggingService.LogModel(userList.Data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lbOnlineUsers.Items.Clear();
|
|
||||||
var usersOnlineRes = await _apiService.GetOnlineUsersAsync();
|
|
||||||
if (usersOnlineRes.Success && usersOnlineRes.Data != null)
|
|
||||||
{
|
|
||||||
lbOnlineUsers.Items.Clear();
|
|
||||||
foreach (var user in usersOnlineRes.Data)
|
|
||||||
{
|
|
||||||
lbOnlineUsers.Items.Add(user.Username);
|
|
||||||
}
|
|
||||||
OnlineUsers = usersOnlineRes.Data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshRoomsList()
|
private async Task RefreshRoomsList()
|
||||||
{
|
{
|
||||||
if (InvokeRequired)
|
LoggingService.LogString("Refreshing Rooms List...");
|
||||||
|
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
{
|
{
|
||||||
@ -416,33 +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()
|
||||||
{
|
{
|
||||||
if (InvokeRequired)
|
LoggingService.LogString("Refreshing Contacts List...");
|
||||||
|
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
{
|
{
|
||||||
@ -467,7 +756,7 @@ namespace qtc_net_client_2
|
|||||||
|
|
||||||
if (user.Data != null)
|
if (user.Data != null)
|
||||||
{
|
{
|
||||||
Contacts.Add(user.Data);
|
Contacts.Add(contact);
|
||||||
if (contact.OwnerId == _apiService.CurrentUser!.Id)
|
if (contact.OwnerId == _apiService.CurrentUser!.Id)
|
||||||
{
|
{
|
||||||
switch (contact.OwnerStatus)
|
switch (contact.OwnerStatus)
|
||||||
@ -475,12 +764,16 @@ namespace qtc_net_client_2
|
|||||||
case Contact.ContactStatus.AwaitingApprovalFromOther:
|
case Contact.ContactStatus.AwaitingApprovalFromOther:
|
||||||
var lvi = lvContacts.Items.Add($"{user.Data.Username} [Request Sent]");
|
var lvi = lvContacts.Items.Add($"{user.Data.Username} [Request Sent]");
|
||||||
await AddProfilePicToList(user.Data.Id);
|
await AddProfilePicToList(user.Data.Id);
|
||||||
lvi.ImageKey = user.Data.Id;
|
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
|
||||||
|
lvi.ImageKey = user.Data.Id;
|
||||||
|
else lvi.ImageKey = "DEFAULT";
|
||||||
break;
|
break;
|
||||||
case Contact.ContactStatus.Accepted:
|
case Contact.ContactStatus.Accepted:
|
||||||
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
|
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
|
||||||
await AddProfilePicToList(user.Data.Id);
|
await AddProfilePicToList(user.Data.Id);
|
||||||
lvi2.ImageKey = user.Data.Id;
|
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
|
||||||
|
lvi2.ImageKey = user.Data.Id;
|
||||||
|
else lvi2.ImageKey = "DEFAULT";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -491,80 +784,27 @@ namespace qtc_net_client_2
|
|||||||
case Contact.ContactStatus.AwaitingApprovalFromSelf:
|
case Contact.ContactStatus.AwaitingApprovalFromSelf:
|
||||||
var lvi = lvContacts.Items.Add($"{user.Data.Username} [Contact Request]");
|
var lvi = lvContacts.Items.Add($"{user.Data.Username} [Contact Request]");
|
||||||
await AddProfilePicToList(user.Data.Id);
|
await AddProfilePicToList(user.Data.Id);
|
||||||
lvi.ImageKey = user.Data.Id;
|
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
|
||||||
|
lvi.ImageKey = user.Data.Id;
|
||||||
|
else lvi.ImageKey = "DEFAULT";
|
||||||
AudioService.PlaySoundEffect("sndContactRequest");
|
AudioService.PlaySoundEffect("sndContactRequest");
|
||||||
break;
|
break;
|
||||||
case Contact.ContactStatus.Accepted:
|
case Contact.ContactStatus.Accepted:
|
||||||
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
|
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
|
||||||
await AddProfilePicToList(user.Data.Id);
|
await AddProfilePicToList(user.Data.Id);
|
||||||
lvi2.ImageKey = user.Data.Id;
|
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
|
||||||
|
lvi2.ImageKey = user.Data.Id;
|
||||||
|
else lvi2.ImageKey = "DEFAULT";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(user.Data);
|
|
||||||
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);
|
|
||||||
lvi.ImageKey = user.Data.Id;
|
|
||||||
break;
|
|
||||||
case Contact.ContactStatus.Accepted:
|
|
||||||
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
|
|
||||||
await AddProfilePicToList(user.Data.Id);
|
|
||||||
lvi2.ImageKey = user.Data.Id;
|
|
||||||
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);
|
|
||||||
lvi.ImageKey = user.Data.Id;
|
|
||||||
AudioService.PlaySoundEffect("sndContactRequest");
|
|
||||||
break;
|
|
||||||
case Contact.ContactStatus.Accepted:
|
|
||||||
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
|
|
||||||
await AddProfilePicToList(user.Data.Id);
|
|
||||||
lvi2.ImageKey = user.Data.Id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,7 +812,7 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (InvokeRequired && label.IsHandleCreated)
|
if(IsHandleCreated && !IsDisposed)
|
||||||
{
|
{
|
||||||
await Invoke(async delegate ()
|
await Invoke(async delegate ()
|
||||||
{
|
{
|
||||||
@ -582,13 +822,6 @@ namespace qtc_net_client_2
|
|||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (label.IsHandleCreated)
|
|
||||||
{
|
|
||||||
label.ForeColor = Color.Red;
|
|
||||||
await Task.Delay(500);
|
|
||||||
label.ForeColor = Color.Blue;
|
|
||||||
await Task.Delay(500);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,24 +836,58 @@ namespace qtc_net_client_2
|
|||||||
ms.Dispose();
|
ms.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (result != null) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{result.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task GetAndAddStoreThumbnail(StoreItem item)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using HttpClient client = new();
|
||||||
|
var response = await client.GetAsync(item.ThumbnailUrl);
|
||||||
|
if (response != null && response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
using var stream = await response.Content.ReadAsStreamAsync();
|
||||||
|
Image image = Image.FromStream(stream);
|
||||||
|
stream.Dispose();
|
||||||
|
ilStoreThumbnails.Images.Add(item.Id.ToString(), image);
|
||||||
|
}
|
||||||
|
else if (response != null) LoggingService.LogString($"Store Item Thumbnail Could Not Be Loaded Due To Status Code {response.StatusCode}");
|
||||||
|
else LoggingService.LogString("Store Item Thumbnail Could Not Be Loaded");
|
||||||
|
client.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LoggingService.LogString("Store Item Thumbnail Could Not Be Loaded\n" + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshCurrencyCounter()
|
||||||
|
{
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
|
{
|
||||||
|
Invoke(delegate () { lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString("N0"); });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void _gatewayService_OnServerDisconnect(object? sender, EventArgs e)
|
private async void _gatewayService_OnServerDisconnect(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
LoggingService.LogString("Disconnected From SignalR");
|
||||||
|
|
||||||
if (DialogResult == DialogResult.OK) return;
|
if (DialogResult == DialogResult.OK) return;
|
||||||
|
|
||||||
var args = (ServerConnectionClosedEventArgs)e;
|
var args = (ServerConnectionClosedEventArgs)e;
|
||||||
string? error = string.Empty;
|
string? error = string.Empty;
|
||||||
if (args.Error != null) error = args.Error.Message;
|
if (args.Error != null) { error = args.Error.Message; LoggingService.LogString($"{args.Error.Message}\n{args.Error.StackTrace}"); }
|
||||||
|
|
||||||
// disconnect can sometimes be caused by an expired JWT token, attempt connection restart
|
// disconnect can sometimes be caused by an expired JWT token, attempt connection restart
|
||||||
await _gatewayService.StopAsync();
|
await _gatewayService.StopAsync();
|
||||||
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)
|
||||||
@ -629,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);
|
||||||
}
|
}
|
||||||
@ -649,24 +917,45 @@ 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; });
|
|
||||||
|
|
||||||
private async void _gatewayService_OnClientFunctionReceived(object? sender, EventArgs e)
|
|
||||||
{
|
{
|
||||||
var args = (ClientFunctionEventArgs)e;
|
var args = (ServerConnectionReconnectingEventArgs)e;
|
||||||
|
|
||||||
switch (args.Function)
|
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)
|
||||||
{
|
{
|
||||||
case "rul":
|
Invoke(delegate ()
|
||||||
await RefreshOnlineUsersList();
|
{
|
||||||
break;
|
tbcMain.Enabled = false;
|
||||||
case "rr":
|
lblConnectionLost.Visible = true;
|
||||||
await RefreshRoomsList();
|
});
|
||||||
break;
|
}
|
||||||
case "rcl":
|
}
|
||||||
await RefreshContactsList();
|
|
||||||
break;
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -674,10 +963,17 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
var args = (ServerConfigEventArgs)e;
|
var args = (ServerConfigEventArgs)e;
|
||||||
|
|
||||||
|
LoggingService.LogString($"Server Config Received");
|
||||||
|
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");
|
||||||
MessageBox.Show($"Sorry, This Server Is Currently Down.\nMessage: {args.ServerConfig.IsDownMessage}\n\nPlease Try Again Later");
|
MessageBox.Show($"Sorry, This Server Is Currently Down.\nMessage: {args.ServerConfig.IsDownMessage}\n\nPlease Try Again Later");
|
||||||
|
|
||||||
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)
|
||||||
@ -687,8 +983,6 @@ namespace qtc_net_client_2
|
|||||||
}
|
}
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BeginInvoke(delegate () { Text = $"QtC.NET Client = Connected To {args.ServerConfig.Name}"; });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,6 +990,8 @@ namespace qtc_net_client_2
|
|||||||
{
|
{
|
||||||
var args = (DirectMessageEventArgs)e;
|
var args = (DirectMessageEventArgs)e;
|
||||||
|
|
||||||
|
LoggingService.LogString($"Direct Message Received From '{args.User.Username}'");
|
||||||
|
|
||||||
DirectMessage? existingForm = (DirectMessage?)Application.OpenForms.Cast<Form>().FirstOrDefault(e => e.Name == "DirectMessage");
|
DirectMessage? existingForm = (DirectMessage?)Application.OpenForms.Cast<Form>().FirstOrDefault(e => e.Name == "DirectMessage");
|
||||||
if (existingForm != null && existingForm.User.Id == args.User.Id)
|
if (existingForm != null && existingForm.User.Id == args.User.Id)
|
||||||
{
|
{
|
||||||
@ -709,5 +1005,26 @@ namespace qtc_net_client_2
|
|||||||
Task.Run(frmDirectMessage.ShowDialog);
|
Task.Run(frmDirectMessage.ShowDialog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
lblWelcome.Text = $"Welcome, {_apiService.CurrentUser.Username}";
|
||||||
|
RefreshCurrencyCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void _gatewayService_OnRefreshContactsListReceived(object? sender, EventArgs e) => await RefreshContactsList();
|
||||||
|
private async void _gatewayService_OnRefreshRoomListReceived(object? sender, EventArgs e) => await RefreshRoomsList();
|
||||||
|
private async void _gatewayService_OnRefreshUserListReceived(object? sender, EventArgs e) => await RefreshUsers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,67 +112,444 @@
|
|||||||
<value>2.0</value>
|
<value>2.0</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<resheader name="reader">
|
<resheader name="reader">
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<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=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<metadata name="ctxmRefresh.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>356, 21</value>
|
||||||
|
</metadata>
|
||||||
<metadata name="ilProfilePics.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="ilProfilePics.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>17, 17</value>
|
<value>17, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
<data name="ilProfilePics.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA0A0AAAJNU0Z0AUkBTAMBAQAB
|
||||||
|
mAEBAZgBAQEgAQABIAEABP8BIQEACP8BQgFNATYHAAE2AwABKAMAAYADAAEgAwABAQEAASAGAAFAEgAD
|
||||||
|
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
|
||||||
|
/g3/A/0B/wP9Ef8D/AH/A/4N/wPaAf8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af//AIEAA6IB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A9oN/wP8Af8D/iX/A/wN/wPaAf8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af//
|
||||||
|
AIEAA6UB/wO6Af8DugH/A7oB/wO6Af8DugH/A9kR/wP+Ff8D/R3/A9oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB//8AgQADpAH/A7kB/wO6Af8DugH/A7oB/wO6Af8D2QH/A/wV/wP+Df8D/QH/A/0R/wP+Af8D
|
||||||
|
/gH/A9oB/wO6Af8DugH/A7kB/wO6Af8DugH/A7oB//8AgQADoQH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
2gH/A/4B/wP9Ef8D/AH/A/4N/wP9Af8D/RH/A/wB/wPZAf8DugH/A7oB/wO6Af8DuQH/A7oB/wO6Af//
|
||||||
|
AIEAA58B/wO6Af8DugH/A7oB/wO6Af8DugH/A9oF/wP9Af8D/RH/A/0B/wP+Df8D/QH/A/0R/wPZAf8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7kB/wO6Af//AIEAA7EB/wO6Af8DugH/A7oB/wO6Af8DugH/A9MJ/wP+Ff8D
|
||||||
|
/AH/A/4h/wPTAf8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af//AIEAA7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
uQH/A8AB/wP9Df8D/hH/A/4V/wP9Bf8D/QH/A8AB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQAD
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A9oN/wP+Af8D/RX/A/4N/wP9Af8D/AH/A9oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af//AIEAA7oB/wO5Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
3Q3/A/0B/wP9Ef8D/QH/A/4N/wPcAf8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQAD
|
||||||
|
ugH/A7oB/wO5Af8DuQH/A7oB/wO6Af8DugH/A7oB/wO5Af8DyQH/A+wB/wP+Bf8D/gH/A/wR/wP9Af8D
|
||||||
|
/QH/A+wB/wPKAf8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af//AIEAA7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7kB/wO6Af8DwQH/A9IB/wPfAf8D5gH/A+oB/wPrAf8D
|
||||||
|
5wH/A98B/wPSAf8DwAH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af//
|
||||||
|
AIEAA7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
vQH/A8cB/wPGAf8DvQH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af//AIEAA7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A8IB/wPnAf8D/QX/A/4B/wP6Af8D5gH/A8IB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB//8AgQADugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wPIAf8D+QH/A/0N/wP9Af8D/QH/A/oB/wPIAf8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO5Af8DugH/A7oB//8AgQADugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A74B/wP4Bf8D/AH/A/4N/wP9Af8D/AH/A/gB/wO+Af8DugH/A7oB/wO6Af8DuQH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO5Af8DugH//wCBAAO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7kB/wO6Af8D
|
||||||
|
2w3/A/0B/wP9Df8D/QH/A/4B/wPbAf8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH//wCBAAO6Af8DugH/A7oB/wO6Af8DugH/A7kB/wO6Af8DugH/A7oB/wO6Af8D8BH/A/wB/wP+Ef8D
|
||||||
|
8AH/A7oB/wO6Af8DugH/A7oB/wO5Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQADugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A/gB/wP9Jf8D+AH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB//8AgQADugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A/QB/wP9Af8D/BH/A/4B/wP+Cf8D9QH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB//8AgQADugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A+UF/wP+Af8D
|
||||||
|
/BH/A/wB/wP9Bf8D5QH/A7oB/wO5Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQAD
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DuQH/A8gB/wP+Bf8D/gH/A/wR/wP9Af8D
|
||||||
|
/QH/A8gB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7kB/wO6Af//AIEAA7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D3Qn/A/4V/wPcAf8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQADugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D2QH/A/wJ/wP+Bf8D/AH/A9kB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQADugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A8AB/wPWAf8D4gH/A+EB/wPVAf8DwAH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQADugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7kB/wO6Af8DugH/A7oB/wO6Af8DugH/A7kB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQAD
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO5Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO5Af8D
|
||||||
|
uQH/A7oB//8AgQADugH/A7oB/wO6Af8DuQH/A7oB/wO6Af8DugH/A7oB/wO5Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO5Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB//8AgQADugH/A7oB/wO6Af8DugH/A7kB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DuQH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQADugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQADugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8D
|
||||||
|
ugH/A7oB/wO6Af8DugH/A7kB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB/wO6Af8DugH/A7oB//8AgQAB
|
||||||
|
QgFNAT4HAAE+AwABKAMAAYADAAEgAwABAQEAAQEGAAECFgAD//8A/wADAAs=
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<metadata name="ilStatusIcons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>13, 101</value>
|
||||||
|
</metadata>
|
||||||
|
<data name="ilStatusIcons.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAohMAAAJNU0Z0AUkBTAIBAQQB
|
||||||
|
AAFQAQEBUAEBARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABIAYAASD/
|
||||||
|
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AC4AAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B
|
||||||
|
0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYB
|
||||||
|
BwM0AVQDUQGiA14B0gNaAekDYAHoA10B0QNQAZ8DMQFNAwUBBhgAAwYBBwM0AVQDUQGiA14B0gNaAekD
|
||||||
|
YAHoA10B0QNQAZ8DMQFNAwUBBhQAAyABLQNUAasDWwHkA1oB9QMkAfsDTgH+A04B/gMkAfsDUwH0A2IB
|
||||||
|
4QNRAaEDHgEqEAADIAEtA1QBqwNbAeQDWgH1ASEBXgEhAfsBKgFqASoB/gEqAWoBKgH+ASEBXgEhAfsD
|
||||||
|
UwH0A2IB4QNRAaEDHgEqEAADIAEtA1QBqwNbAeQDWgH1ASECXgH7ASoCagH+ASoCagH+ASECXgH7A1MB
|
||||||
|
9ANiAeEDUQGhAx4BKhAAAyABLQNUAasDWwHkA1oB9QIhAV4B+wIqAWoB/gIqAWoB/gIhAV4B+wNTAfQD
|
||||||
|
YgHhA1EBoQMeASoMAAMbASUDWAG9A1oB8gNSAf4DMAH/AzkB/wM8Af8DNgH/AyoB/wMkAf8DQAH9A14B
|
||||||
|
8ANWAbIDGgEjCAADGwElA1gBvQNaAfIBKgFyASoB/gEAAVcBAAH/AQABZwEAAf8BAAFsAQAB/wEAAWEB
|
||||||
|
AAH/AQABTAEAAf8BAAFAAQAB/wNAAf0DXgHwA1YBsgEZARoBGQEjCAADGwElA1gBvQNaAfIBKgJyAf4B
|
||||||
|
AAJXAf8BAAJnAf8BAAJsAf8BAAJhAf8BAAJMAf8BAAJAAf8DQAH9A14B8ANWAbIBGQIaASMIAAMbASUD
|
||||||
|
WAG9A1oB8gIqAXIB/gIAAVcB/wIAAWcB/wIAAWwB/wIAAWEB/wIAAUwB/wIAAUAB/wNAAf0DXgHwA1YB
|
||||||
|
sgIZARoBIwQAAwMBBANSAaUDYAHzA0kB/wNVAf8DZQH/A3EB/wN1Af8DcQH/A2QB/wNMAf8DMQH/A04B
|
||||||
|
/gNiAe4DUAGaAwMBBAMDAQQBUgFTAVIBpQFgAW8BYAHzAQABggEAAf8BAAGZAQAB/wEAAbYBAAH/AQAB
|
||||||
|
zAEAAf8BAAHTAQAB/wEAAcsBAAH/AQABswEAAf8BAAGIAQAB/wEAAVcBAAH/ASoBagEqAf4DYgHuA1AB
|
||||||
|
mgMDAQQDAwEEAVICUwGlAWACbwHzAQACggH/AQACmQH/AQACtgH/AQACzAH/AQAC0wH/AQACywH/AQAC
|
||||||
|
swH/AQACiAH/AQACVwH/ASoCagH+A2IB7gNQAZoDAwEEAwMBBAJSAVMBpQJgAW8B8wIAAYIB/wIAAZkB
|
||||||
|
/wIAAbYB/wIAAcwB/wIAAdMB/wIAAcsB/wIAAbMB/wIAAYgB/wIAAVcB/wIqAWoB/gNiAe4DUAGaAwMB
|
||||||
|
BAMtAUQDYAHoA4AB/gNuAf8DewH/A4UB/wOKAf8DjAH/A4oB/wOFAf8DdgH/A1cB/wMyAf8DQAH9A14B
|
||||||
|
3QMqAT8DLQFEAWABaQFgAegBKgGAASoB/gEAAcYBAAH/AQAB3AEAAf8BAAHuAQAB/wEAAfgBAAH/AQAB
|
||||||
|
+wEAAf8BAAH5AQAB/wEAAe8BAAH/AQAB1AEAAf8BAAGcAQAB/wEAAVoBAAH/A0AB/QNeAd0DKgE/Ay0B
|
||||||
|
RAFgAmkB6AEqAoAB/gEAAsYB/wEAAtwB/wEAAu4B/wEAAvgB/wEAAvsB/wEAAvkB/wEAAu8B/wEAAtQB
|
||||||
|
/wEAApwB/wEAAloB/wNAAf0DXgHdAyoBPwMtAUQCYAFpAegCKgGAAf4CAAHGAf8CAAHcAf8CAAHuAf8C
|
||||||
|
AAH4Af8CAAH7Af8CAAH5Af8CAAHvAf8CAAHUAf8CAAGcAf8CAAFaAf8DQAH9A14B3QMqAT8DTgGVA3cB
|
||||||
|
+AN/Af8DhQH/A4oB/wONAf8DjgH/A44B/wOOAf8DjQH/A4kB/wN3Af8DTQH/AyUB/wNaAfIDSgGLA04B
|
||||||
|
lQFcAXwBXAH4AQAB5QEAAf8BAAHvAQAB/wEAAfgBAAH/AQAB/QEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
|
/wEAAf8BAAH+AQAB/wEAAfYBAAH/AQAB1QEAAf8BAAGLAQAB/wEAAUEBAAH/A1oB8gNKAYsDTgGVAVwC
|
||||||
|
fAH4AQAC5QH/AQAC7wH/AQAC+AH/AQAC/QH/AQAD/wEAA/8BAAP/AQAC/gH/AQAC9gH/AQAC1QH/AQAC
|
||||||
|
iwH/AQACQQH/A1oB8gNKAYsDTgGVAlwBfAH4AgAB5QH/AgAB7wH/AgAB+AH/AgAB/QH/AgAC/wIAAv8C
|
||||||
|
AAL/AgAB/gH/AgAB9gH/AgAB1QH/AgABiwH/AgABQQH/A1oB8gNKAYsDXwHTA34B/AOTAf8DjgH/A40B
|
||||||
|
/wOOAf8DjgH/A44B/wOOAf8DjgH/A40B/wOFAf8DZwH/AzQB/wNBAfkDWgHEAVsBXwFbAdMBKwF+ASsB
|
||||||
|
/AEOAfsBDgH/AQMB/QEDAf8BAAH+AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
|
/wEAAf8BAAH9AQAB/wEAAe8BAAH/AQABuQEAAf8BAAFdAQAB/wNBAfkDWgHEAVsCXwHTASsCfgH8AQ4C
|
||||||
|
+wH/AQMC/QH/AQAC/gH/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAL9Af8BAALvAf8BAAK5Af8BAAJdAf8D
|
||||||
|
QQH5A1oBxAJbAV8B0wIrAX4B/AIOAfsB/wIDAf0B/wIAAf4B/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAB
|
||||||
|
/QH/AgAB7wH/AgABuQH/AgABXQH/A0EB+QNaAcQDbgH1A4AB/gOfAf8DkwH/A48B/wOOAf8DjgH/A44B
|
||||||
|
/wOOAf8DjgH/A44B/wOLAf8DdwH/A0gB/wNAAf0DYgHhAVoBbgFaAfUBTgGrAU4B/gEnAf8BJwH/AQsB
|
||||||
|
/wELAf8BAQH/AQEB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
|
/wEAAfkBAAH/AQAB1gEAAf8BAAGBAQAB/wNAAf0DYgHhAVoCbgH1AU4CqwH+AScD/wELA/8BAQP/AQAD
|
||||||
|
/wEAA/8BAAP/AQAD/wEAA/8BAAP/AQAC+QH/AQAC1gH/AQACgQH/A0AB/QNiAeECWgFuAfUCTgGrAf4C
|
||||||
|
JwL/AgsC/wIBAv8CAAL/AgAC/wIAAv8CAAL/AgAC/wIAAv8CAAH5Af8CAAHWAf8CAAGBAf8DQAH9A2IB
|
||||||
|
4QNjAfYDgAH+A6sB/wOZAf8DkAH/A44B/wOOAf8DjgH/A44B/wOOAf8DjgH/A40B/wN/Af8DVQH/A0AB
|
||||||
|
/QNeAeIBSAFjAUgB9gFxAasBcQH+AUIB/wFCAf8BGQH/ARkB/wEEAf8BBAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
|
/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/QEAAf8BAAHkAQAB/wEAAZgBAAH/A0AB
|
||||||
|
/QNeAeIBSAJjAfYBcQKrAf4BQgP/ARkD/wEEA/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAL9Af8B
|
||||||
|
AALkAf8BAAKYAf8DQAH9A14B4gJIAWMB9gJxAasB/gJCAv8CGQL/AgQC/wIAAv8CAAL/AgAC/wIAAv8C
|
||||||
|
AAL/AgAC/wIAAf0B/wIAAeQB/wIAAZgB/wNAAf0DXgHiA2EB1gN+AfwDuAH/A6MB/wOTAf8DjgH/A44B
|
||||||
|
/wOOAf8DjgH/A44B/wOOAf8DjQH/A4IB/wNcAf8DTQH6A1oBxwFcAWEBXAHWAWQBgwFkAfwBXwH/AV8B
|
||||||
|
/wEvAf8BLwH/AQwB/wEMAf8BAQH/AQEB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQAB
|
||||||
|
/wEAAf8BAAH+AQAB/wEAAeoBAAH/AQABpQEAAf8BSAFNAUgB+gNaAccBXAJhAdYBZAKDAfwBXwP/AS8D
|
||||||
|
/wEMA/8BAQP/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAL+Af8BAALqAf8BAAKlAf8BSAJNAfoDWgHHAlwB
|
||||||
|
YQHWAmQBgwH8Al8C/wIvAv8CDAL/AgEC/wIAAv8CAAL/AgAC/wIAAv8CAAL/AgAB/gH/AgAB6gH/AgAB
|
||||||
|
pQH/AkgBTQH6A1oBxwNQAZoDbQH5A8UB/wOyAf8DnAH/A5EB/wOOAf8DjgH/A44B/wOOAf8DjwH/A44B
|
||||||
|
/wODAf8DYAH/A1oB8gNMAZADUAGaAWoBfwFqAfkBfAH/AXwB/wFRAf8BUQH/AR8B/wEfAf8BBwH/AQcB
|
||||||
|
/wEBAf8BAQH/AQAB/wEAAf8BAAH/AQAB/wEAAf8BAAH/AQIB/wECAf8BAgH+AQIB/wEAAesBAAH/AQAB
|
||||||
|
rQEAAf8BWgFrAVoB8gNMAZADUAGaAWoCfwH5AXwD/wFRA/8BHwP/AQcD/wEBA/8BAAP/AQAD/wEAA/8B
|
||||||
|
AgP/AQIC/gH/AQAC6wH/AQACrQH/AVoCawHyA0wBkANQAZoCagF/AfkCfAL/AlEC/wIfAv8CBwL/AgEC
|
||||||
|
/wIAAv8CAAL/AgAC/wICAv8CAgH+Af8CAAHrAf8CAAGtAf8CWgFrAfIDTAGQAy8BSQNsAesDgAH+A8YB
|
||||||
|
/wOuAf8DnAH/A5MB/wOQAf8DjwH/A5AB/wOTAf8DkwH/A4UB/wNAAf0DYAHgAy0BRQMvAUkDbAHrAYAB
|
||||||
|
qwGAAf4BfwH/AX8B/wFJAf8BSQH/AR8B/wEfAf8BDAH/AQwB/wEFAf8BBQH/AQMB/wEDAf8BBQH/AQUB
|
||||||
|
/wEKAf8BCgH/AQoB/gEKAf8BAQHtAQEB/wFAAbYBQAH9AWABZgFgAeADLQFFAy8BSQNsAesBgAKrAf4B
|
||||||
|
fwP/AUkD/wEfA/8BDAP/AQUD/wEDA/8BBQP/AQoD/wEKAv4B/wEBAu0B/wFAArYB/QFgAmYB4AMtAUUD
|
||||||
|
LwFJA2wB6wKAAasB/gJ/Av8CSQL/Ah8C/wIMAv8CBQL/AgMC/wIFAv8CCgL/AgoB/gH/AgEB7QH/AkAB
|
||||||
|
tgH9AmABZgHgAy0BRQMDAQQDVgGuA24B9QPZAf8DywH/A7cB/wOnAf8DnQH/A5oB/wOcAf8DnwH/A5sB
|
||||||
|
/wOJAf8DaAHwA1IBowMDAQQDAwEEA1YBrgNuAfUBqAH/AagB/wGJAf8BiQH/AVwB/wFcAf8BNwH/ATcB
|
||||||
|
/wEiAf8BIgH/ARsB/wEbAf8BHwH/AR8B/wEmAf8BJgH/AR0B/wEdAf8BBQHzAQUB/wFeAWgBXgHwA1IB
|
||||||
|
owMDAQQDAwEEA1YBrgNuAfUBqAP/AYkD/wFcA/8BNwP/ASID/wEbA/8BHwP/ASYD/wEdA/8BBQLzAf8B
|
||||||
|
XgJoAfADUgGjAwMBBAMDAQQDVgGuA24B9QKoAv8CiQL/AlwC/wI3Av8CIgL/AhsC/wIfAv8CJgL/Ah0C
|
||||||
|
/wIFAfMB/wJeAWgB8ANSAaMDAwEEBAADHAEnA10BxwNjAfYDiwH+A9cB/wPMAf8DwgH/A7sB/wO3Af8D
|
||||||
|
sQH/A4AB/gNoAfQDWQG8AxsBJggAAxwBJwNdAccDYwH2AYABqwGAAf4BpQH/AaUB/wGLAf8BiwH/AXQB
|
||||||
|
/wF0Af8BZgH/AWYB/wFcAf8BXAH/AU4B/wFOAf8BWgGrAVoB/gFTAWgBUwH0AVcBWQFXAbwDGwEmCAAD
|
||||||
|
HAEnA10BxwNjAfYBgAKrAf4BpQP/AYsD/wF0A/8BZgP/AVwD/wFOA/8BWgKrAf4BUwJoAfQBVwJZAbwD
|
||||||
|
GwEmCAADHAEnA10BxwNjAfYCgAGrAf4CpQL/AosC/wJ0Av8CZgL/AlwC/wJOAv8CWgGrAf4CUwFoAfQC
|
||||||
|
VwFZAbwDGwEmDAADIQEwA1kBtgNiAe4DfQH6A74B/QPUAf8DzAH/A74B/QNqAfkDbAHrA1UBrAMfASwQ
|
||||||
|
AAMhATADWQG2A2IB7gN9AfoBrgG+Aa4B/QGfAf8BnwH/AYwB/wGMAf8BTAG+AUwB/QFoAX8BaAH5AWEB
|
||||||
|
bAFhAesDVQGsAx8BLBAAAyEBMANZAbYDYgHuA30B+gGuAr4B/QGfA/8BjAP/AUwCvgH9AWgCfwH5AWEC
|
||||||
|
bAHrA1UBrAMfASwQAAMhATADWQG2A2IB7gN9AfoCrgG+Af0CnwL/AowC/wJMAb4B/QJoAX8B+QJhAWwB
|
||||||
|
6wNVAawDHwEsFAADBgEHAzYBWANVAawDZgHlA34B/AOBAfsDZQHiA1MBpwMzAVEDBgEHGAADBgEHAzYB
|
||||||
|
WANVAawDZgHlAX4BgwF+AfwBXwGMAV8B+wNlAeIDUwGnAzMBUQMGAQcYAAMGAQcDNgFYA1UBrANmAeUB
|
||||||
|
fgKDAfwBXwKMAfsDZQHiA1MBpwMzAVEDBgEHGAADBgEHAzYBWANVAawDZgHlAn4BgwH8Al8BjAH7A2UB
|
||||||
|
4gNTAacDMwFRAwYBBwwAAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/+BAAHgAQcB
|
||||||
|
4AEHAeABBwHgAQcBwAEDAcABAwHAAQMBwAEDAYABAQGAAQEBgAEBAYABAVAAAYABAQGAAQEBgAEBAYAB
|
||||||
|
AQHAAQMBwAEDAcABAwHAAQMB4AEHAeABBwHgAQcB4AEHCw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<metadata name="ilGames.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>24, 73</value>
|
||||||
|
</metadata>
|
||||||
|
<data name="ilGames.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAKCUAAAJNU0Z0AUkBTAIBAQMB
|
||||||
|
AAEQAQIBEAECASABAAEgAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABgAMAASADAAEBAQABIAYAAUB6
|
||||||
|
AANcAecBCAEKAQAB/wMqAUAMAAMqAUADNgFXAz8BbAM/AWwDPwFsAz8BbAM/AWwDPwFsAz8BbAM/AWwD
|
||||||
|
PwFsAz8BbAM/AWwDPwFsAz8BbAM/AWwDPwFsAz8BbAI7AToBYgMzAVEDGAEhVAADUwGiA1sBwCAAA1QB
|
||||||
|
pgNZAbzwAAMhATADRgGAFAABFQEfAQQB/wENARUBAAH/AQgBCgEAAf8BCAEKAQAB/wwAA0QBegNTAacC
|
||||||
|
YQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8C
|
||||||
|
YQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYQFdAc8CYAFdAc4DWQG7AlABTwGbAyoBQFQAA18B0ANiAe4g
|
||||||
|
AANhAdQDYwHp5AADWgG/AQgBCgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoB
|
||||||
|
AAH/AQgBCgEAAf8DWgG/A1oBvwFDAXQBBwH/AUcBdwEMAf8BJQFHAQAB/wEOARkBAAH/DAACSwFKAYoC
|
||||||
|
WgFYAb0CZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoC
|
||||||
|
ZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCZwFdAeoCYwFaAekCXwFbAdMDVQGvAy4BSFQAA18B
|
||||||
|
0ANiAe4gAANhAdQDYwHp4AABCAEKAQAB/wEQAR4BAAH/ASEBQQEAAf8BJwFLAQAB/wEmAUoBAAH/ASEB
|
||||||
|
QQEAAf8BEAEeAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEpAU4BAAH/AVoBlgEQAf8BWgGcARAB
|
||||||
|
/wFzAbYBJgH/ARgBLgEAAf8MAANJAYYCWgFYAbcCZQFgAeMCZQFgAeMCZQFgAeMCZQFgAeMCagFhAeYC
|
||||||
|
agFeAe0CaAFTAfQBfgF3ASsB/AH/AXgBAAL/AXgBAAH/Am4BWgH1AmoBYQHmAmUBYAHjAmUBYAHjAmUB
|
||||||
|
YAHjAmUBXgHiAl4BWwHNAlUBUwGqAi4BLQFGVAADXwHQA2IB7iAAA2EB1ANjAencAAEIAQoBAAH/AT0B
|
||||||
|
cQECAf8BTAGGAQcB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BTAF/AQ8B
|
||||||
|
/wE7AWcBCAH/ASEBNAEIAf8BUwGOAQsB/wFaAZwBEAH/AXIBswEnAf8BUwGBARsB/xAAAysBQQM2AVkC
|
||||||
|
QAE/AW4CQAE/AW4CQAE/AW4CQAE/AW4DRAF7AlEBUAGfAl0BWwHFA2IB7gH/AXgBAAL/AXgBAAH/Al8B
|
||||||
|
XQHJA0UBfAJAAT8BbgJAAT8BbgJAAT8BbgM/AW0DOwFjAzMBUgMZASJUAANfAdADYgHuIAADYQHUA2MB
|
||||||
|
6dgAARUBKQEAAf8BSgGEAQQB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
||||||
|
UgGMARAB/wFSAYwBEAH/AVIBjAEQAf8BWgGUARAB/wFWAZABDAH/AVoBmgEQAf8BWgGcARAB/wFyAakB
|
||||||
|
MAH/AQgBCgEAAf8BCAEKAQAB/wwAAwwBEAMRARYDFQEcAxUBHAMVARwDFQEcAyEBMAI+AT0BaQJTAVIB
|
||||||
|
pQJmAV8B5QH/AXgBAAL/AXgBAAH/AlUBUwGqAyIBMQMVARwDFQEcAxUBHAMUARsDEwEZAxABFQMHAQlU
|
||||||
|
AANfAdADYgHuIAADYQHUA2MB6dQAARYBJwECAf8BSQGAAQcB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB
|
||||||
|
/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQsB/wFSAYwBEAH/AVIBjAEQAf8BWAGSARAB/wFaAZQBEAH/AVoB
|
||||||
|
mwEQAf8BWgGcARAB/wFcAZ4BEgH/ATsBbQEDAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8IAAMFBAYE
|
||||||
|
CAEKAwgBCgMIAQoDCAEKAxcBHwI5ATgBXQNRAZ4CZQFgAeMB/wF4AQAC/wF4AQAB/wNSAaMDGAEhAwgB
|
||||||
|
CgMIAQoDCAEKAwgBCgMHAQkDBgEHAwIBA1QAA18B0ANiAe4gAANhAdQDYwHp0AADXQHfAUcBgAEDAf8B
|
||||||
|
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMARAB/wFSAYwB
|
||||||
|
EAH/AVIBjAEQAf8BWgGUARAB/wFaAZQBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAEQAf8B
|
||||||
|
WgGYARAB/wEWASoBAAH/AQgBCgEAAf8BCAEKAQAB/xwAAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgB
|
||||||
|
AAH/AlEBUAGfAxIBGHAAA18B0ANiAe4gAANhAdQDYwHp0AABLAFQAQAB/wFKAYwBAAH/AVIBjAEIAf8B
|
||||||
|
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBDgH/AVUBkgEQAf8BWgGcARAB/wFaAZwB
|
||||||
|
EAH/AVoBlAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBlAEYAf8B
|
||||||
|
WAGSARYB/wEQAR4BAAH/AQgBCgEAAf8cAAMSARcDNQFWA1ABmgNiAeEB/wF4AQAC/wF4AQAB/wJRAVAB
|
||||||
|
nwMSARhwAANfAdADYgHuIAADYQHUA2MB6dQAA0sBjwEzAV4BAAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwB
|
||||||
|
CAH/AVIBjAEQAf8BfwHAATMB/wFfAZ4BFwH/ASABPwEAAf8BCAEKAQAB/wFSAYwBEAH/AVoBnAEQAf8B
|
||||||
|
WgGcARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGVARcB/wFaAZQBGAH/AVoBlAEYAf8BWgGUARgB/wEIAQoB
|
||||||
|
AAH/AQgBCgEAAf8YAAMSARcDNQFWA1ABmgNiAeEB/wF4AQAC/wF4AQAB/wJRAVABnwMSARgUAAQBAwMB
|
||||||
|
BAMGBAcBCQMHAQkDBAEFBAIEARQAAxEBFgMhAS8DIQEvAyEBLwMhAS8DIQEvAyEBLwMhAS8DIQEvAyEB
|
||||||
|
LwNhAdkDcAHxAyEBLwMhAS8DIQEvAyEBLwMhAS8DIQEvAyEBLwMhAS8DYgHcA2oB7QMhAS8DIQEvAyEB
|
||||||
|
LwMhAS8DIQEvAyEBLwMhAS8DIQEvAyEBLwMNARG4AAFCAXsBAAH/AVIBjAEIAf8BewHGASkB/wMzAVAE
|
||||||
|
AAMMARABOQFrAQAB/wFaAZwBEAH/AVoBnAEQAf8BXQGXARMB/wFWAZQBDAH/AVoBnAEQAf8BWgGUARgB
|
||||||
|
/wFaAZQBGAH/AWMBnAEYAf8BYwGlARcB/wEpAVABAAH/AQgBCgEAAf8YAAMSARcDNQFWA1ABmgNiAeEB
|
||||||
|
/wF4AQAC/wF4AQAB/wJRAVABnwMSARgUAAQCAwkBDAMPARQDEwEaAxIBGAMKAQ0DBAEFBAEUAANpAegD
|
||||||
|
fwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8D
|
||||||
|
fwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8D
|
||||||
|
YQHPvAABCAEKAQAB/wwAARMBIwEAAf8BWgGUARAB/wFaAZwBEAH/AZQB1gFKAf8BDQERAQIB/wExAVoB
|
||||||
|
AAH/AVoBlAESAf8BWgGUARgB/wFaAZQBGAH/AWMBnAEYAf8BYwGlARcB/wFrAaUBIQH/ARABHgEAAf8Y
|
||||||
|
AAMSARcDNQFWA1ABmgNiAeEB/wF4AQAC/wF4AQAB/wJRAVABnwMSARgUAAMFAQYDHQEpAzABSgI7ATwB
|
||||||
|
ZQI7ATwBZAMoATwCFQEWAR0DBgEIFAADPAFkA0wBjwNMAY8DTAGPA0wBjwNMAY8DTAGPA0wBjwNMAY8D
|
||||||
|
TAGPA2cB6gN8AfgDTAGPA0wBjwNMAY8DTAGPA0wBjwNMAY8DTAGPA0wBjwNlAewDbgH1A0wBjwNMAY8D
|
||||||
|
TAGPA0wBjwNMAY8DTAGPA0wBjwNMAY8DTAGPAzUBVqgAA10B3wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB
|
||||||
|
/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wMzAVADOgFgAUsBhQEHAf8BWgGUARAB/wFaAZwBEAH/ATkB
|
||||||
|
awEAAf8DCQEMARABHgEAAf8BVAGOARIB/wFaAZQBGAH/AWMBnAEYAf8BYwGcARgB/wFjAaUBFwH/AXMB
|
||||||
|
tAEpAf8BEAEeAQAB/xgAAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwkB
|
||||||
|
DAMzAVACTAFNAZECXQFfAckCWwFdAcoDRAF6AykBPQMMARA8AANfAdADYgHuIAADYQHUA2MB6cwAAQgB
|
||||||
|
CgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB
|
||||||
|
/wEIAQoBAAH/ATMBXwECAf8BWgGUARAB/wFaAZwBEAH/Aa0B5wFjAf8BEAEeAQAB/wEIAQoBAAH/ARQB
|
||||||
|
JgEAAf8BVAGOARIB/wFiAZsBGAH/AWMBnAEYAf8BYwGlARcB/wFjAaUBFwH/AWMBnAEhAf8BGAEuAQAB
|
||||||
|
/xgAAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwkBCwMuAUcDSAGEAlkB
|
||||||
|
XAHDAlwBXwHLA0kBhQMuAUcDDwETPAADXwHQA2IB7iAAA2EB1ANjAenIAAEIAQoBAAH/ASsBUgEAAf8B
|
||||||
|
QQFyAQUB/wFKAYQBBgH/AUoBhAEGAf8BSgGEAQYB/wFCAXMBBgH/ASkBUAEAAf8BEAEeAQAB/wEfAToB
|
||||||
|
AAH/AVUBjwELAf8BWgGVARAB/wFaAZwBEAH/AdYB/wGMAf8BEAEeAQAB/wEYAS4BAAH/AUIBeAEDAf8B
|
||||||
|
WgGUARgB/wFiAZsBGAH/AWMBnAEYAf8BYwGlARcB/wFjAaUBFwH/AXMBtAEpAf8BEAEeAQAB/xgAAxIB
|
||||||
|
FwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwYBCAMkATQDPAFmA1MBpwNYAbgC
|
||||||
|
RwFIAYMDMQFNAw8BFDwAA18B0ANiAe4gAANhAdQDYwHpxAABKAFNAQAB/wFOAYgBBwH/AVIBjAEIAf8B
|
||||||
|
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFSAYwB
|
||||||
|
EAH/AVoBlAEQAf8BWgGcARAB/wFjAaUBFwH/AUIBewEAAf8BSgGEAQYB/wFSAYwBCAH/AVoBmAEUAf8B
|
||||||
|
WgGUARgB/wFjAZwBGAH/AWMBpQEXAf8BYwGlARcB/wFjAaUBFwH/AZQByQFNAf8EAAMQARUDGgEkAyEB
|
||||||
|
LwMRARYEAgQBAxIBFwM1AVYDUAGaA2IB4QH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBQAAwMBBAMTARkD
|
||||||
|
JQE2AjsBPAFkAkEBQgFyAzMBUQMhAS8DCQEMPAADXwHQA2IB7iAAA2EB1ANjAenAAAEpAU4BAgH/AVIB
|
||||||
|
jAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMARAB
|
||||||
|
/wFSAYwBEAH/AVIBjAEQAf8BWgGUARAB/wFaAZUBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoB
|
||||||
|
nAEQAf8BWgGUARgB/wFaAZQBGAH/AWMBnAEYAf8BYwGcARgB/wFjAaUBFwH/AWMBpQEXAf8BYwGlARcB
|
||||||
|
/wFlAaABIQH/BAADHgErAjEBMAFMAzsBYwMiATEDBwEJAwQBBQMSARgDNgFXA1ABmgNiAeEB/wF4AQAC
|
||||||
|
/wF4AQAB/wJRAVABnwMSARgcAAMHAQkDHAEnAyMBMgIZARoBIwMPARQDBAEFPAADXwHQA2IB7iAAA2EB
|
||||||
|
1ANjAem8AANGAYABTgGIAQcB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
||||||
|
UgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFSAYwBEAH/AVoBlAEQAf8BWgGXARAB/wFaAZwB
|
||||||
|
EAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBlAEYAf8BWgGUARgB/wFjAZwBGAH/AWMBoQEYAf8B
|
||||||
|
YwGlARcB/wFjAaUBFwH/AXgBugEsAf8BCAEKAQAB/wQAAyQBNANFAXwCWgFYAbcDTgGUAz8BbQMoATsD
|
||||||
|
HwEsAzkBXgNQAZoDYgHhAf8BeAEAAv8BeAEAAf8CUQFQAZ8DEgEYHAADEgEXAzwBZgNKAYkDQAFvAy4B
|
||||||
|
RwMOARI8AANfAdADYgHuIAADYQHUA2MB6bwAATUBXgEHAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
||||||
|
UgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFaAZQB
|
||||||
|
EAH/AVoBlAEQAf8BWgGbARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZYBFgH/AVoBlAEYAf8B
|
||||||
|
XQGXARgB/wFjAZwBGAH/AWMBpQEXAf8BYwGlARcB/wFwAbMBIAH/ASsBUAEEAf8IAAMnAToCUwFRAaIB
|
||||||
|
gwFfASEB+wJlAVwB5wJcAVoBxAJDAUIBdQMxAU0CQAE/AW4CUQFQAZ8CZQFgAeMB/wF4AQAC/wF4AQAB
|
||||||
|
/wJRAVABnwMSARgcAAMZASIDTgGVAlsBXgHNAlYBVwGyA0QBegMdASkDBgEIBAIEATAAA18B0ANiAe4g
|
||||||
|
AANhAdQDYwHpvAABSgGEAQYB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
||||||
|
ZwGpARcB/wFSAYwBCAH/AUoBhAEGAf8BSgGEAQYB/wFSAYwBEAH/AVoBlAEQAf8BWgGXARAB/wFaAZwB
|
||||||
|
EAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBlAEYAf8BWgGUARgB/wFfAZgBGAH/AWMBngEYAf8B
|
||||||
|
YwGlARcB/wFrAakBHQH/ASkBUAEAAf8MAAMiATEDTgGYAm8BYAHzAmgBXgHwAmoBYQHmAloBVwHCAlUB
|
||||||
|
UwGqA1MBpwJZAVcBvAJsAWEB6wH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBwAAxQBGwJDAUQBdwJWAVkB
|
||||||
|
tgJbAV4BzQJWAVgBswM/AWwDJgE4AwwBDwMCAQMIAAMCAQMDDQERAw0BEQMNAREDDQERAw0BEQMNARED
|
||||||
|
DQERAw0BEQMNAREDXwHTA2cB7wMNAREDDQERAw0BEQMNAREDDQERAw0BEQMNAREDDQERA2IB1wNnAeoD
|
||||||
|
DQERAw0BEQMNAREDDQERAw0BEQMNAREDDQERAw0BEQMNAREDBAEFlAABSgGEAQYB/wFSAYwBCAH/AVIB
|
||||||
|
jAEIAf8BUgGMAQgB/wFSAYwBCAH/AWkBpAEeAf8BLAFQAQMB/wEIAQoBAAH/ATcBYQEHAf8BUgGMAQ4B
|
||||||
|
/wFSAYwBEAH/AX8BwQEyAf8BWwFeAVsB0wNaAb8BLwFZAQAB/wFEAXoBBQH/AVABigEIAf8BWgGcAQ4B
|
||||||
|
/wFaAZwBEAH/AVoBnAEQAf8BTwGGARAB/wFEAXQBDAH/A1oBvxAAAhoBGQEjA0QBewJdAVsBygJjAV8B
|
||||||
|
2gJpAWAB6AJnAVkB7wJlAV0B7AJhAVwB1gJfAVsB2AJoAVMB9AH/AXgBAAL/AXgBAAH/AlEBUAGfAxIB
|
||||||
|
GBwAAw8BEwM0AVMDTQGSAl0BYQHPAl0BYQHUAlIBVAGoAkEBQgFyAyYBOAMUARsDBgEIAwIBAwNaAcID
|
||||||
|
fwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8D
|
||||||
|
fwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8DfwH/A38B/wN/Af8D
|
||||||
|
YgHclAABSgGMAQAB/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AWcBnQEnAf8BCAEKAQAB
|
||||||
|
/wEKAQ8BAAH/AUIBdwEDAf8BUgGMARAB/wFaAZwBEAH/ASUBQQEFAf8EAAM6AWABCAEKAQAB/wEIAQoB
|
||||||
|
AAH/BAADRgGAA0YBgANGAYAcAAMKAQ0DIgExAzQBVANEAXgCUQFQAZ8CYQFdAc8CagFeAe0CZQFdAewC
|
||||||
|
aAFeAfABgwFfASEB+wH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGBwAAwYBCAMYASEDMQFNAkwBTQGRAlgB
|
||||||
|
WgG9Al0BYQHRAlkBXAHDAlEBUwGiAz0BZwIZARoBIwMMAQ8DQAFvA1UBrQNVAa0DVQGtA1UBrQNVAa0D
|
||||||
|
VQGtA1UBrQNVAa0DVQGtA2gB8AN9AfoDVQGtA1UBrQNVAa0DVQGtA1UBrQNVAa0DVQGtA1UBrQNwAfED
|
||||||
|
fAH4A1UBrQNVAa0DVQGtA1UBrQNVAa0DVQGtA1UBrQNVAa0DVQGtA0cBgZQAATsBbQECAf8BUgGMAQgB
|
||||||
|
/wFSAYwBCAH/AVIBjAEIAf8BUgGMAQgB/wFTAY4BEAH/AQ8BGwEAAf8BIwFDAQAB/wFSAYwBEAH/AVIB
|
||||||
|
jAEQAf8BewG9ATAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoBAAH/AQgBCgEAAf8BCAEKAQAB
|
||||||
|
/wEIAQoBAAH/KAADAwEEAwkBCwMiATEDOAFbAk8BTgGXAl8BXAHIAmYBXwHlAm8BUQH3Ab4BRQFAAf0B
|
||||||
|
/wF4AQAC/wF4AQAB/wJRAVABnwMSARgcAAQBAwIBAwMVARwDNQFWAksBTAGPAlwBXwHIAl0BYwHfAmAB
|
||||||
|
ZQHjAlIBUwGlAzQBUwMcAScoAANfAdADYgHuIAADYQHUA2MB6bwAAQgBCgEAAf8BUgGMAQgB/wFSAYwB
|
||||||
|
CAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AU4BggEPAf8BSgGEAQYB/wFSAYwBEAH/AWMBpQEXAf8B
|
||||||
|
CAEKAQAB/wEIAQoBAAH/ARMBIwEAAf8BQgFzAQYB/wEgAT8BAAH/AQgBCgEAAf8BCAEKAQAB/wEIAQoB
|
||||||
|
AAH/AQgBCgEAAf8BCAEKAQAB/yAABAEDAwEEAwwBEAMYASADKQE9Az4BagJXAVYBtQJmAV8B5QJvAVEB
|
||||||
|
9wH/AXgBAAL/AXgBAAH/AlEBUAGfAxIBGCAABAEDBwEJAxQBGwMqAUADQwF2A1UBrwJaAWMB6QJbAV8B
|
||||||
|
0AJQAVEBnwMzAVEoAANfAdADYgHuIAADYQHUA2MB6cAAAUIBcwEGAf8BUgGMAQgB/wFSAYwBCAH/AVIB
|
||||||
|
jAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFKAYQBBgH/ARABHgEAAf8BMQFaAQAB
|
||||||
|
/wFNAYQBDQH/AVoBnAEQAf8BWgGcARAB/wFSAYwBCAH/ARABHgEAAf8BCAEKAQAB/wEIAQoBAAH/A0YB
|
||||||
|
gCwAAwIBAwMLAQ4DIAEuA0MBdgJXAVUBsQJmAWAB4AJjAUgB9gFtAWoBQQH5AlEBUAGcAxIBFwwABAED
|
||||||
|
DAEQAxcBHwMdASgDHQEoAwwBDwgAAw8BFAImAScBOQJHAUgBgwNiAeECXAFlAecDXgHSAj8BQAFuKAAD
|
||||||
|
XwHQA2IB7iAAA2EB1ANjAenEAAFJAYkBAAH/AVIBjAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEIAf8B
|
||||||
|
UgGMARAB/wFSAYwBEAH/AVIBjAEQAf8BUgGMARAB/wFaAZQBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwB
|
||||||
|
EAH/AVoBnAEQAf8BWgGUARgB/wFCAXMBBgH/AQoBDgEAAf8wAAQBAwMBBAMMAQ8DHgEqAzoBYQJZAVcB
|
||||||
|
uQJjAVsB5ANiAe4CTwFOAZcDEgEXDAADAgEDAyEBLwM2AVkCQgFDAXUCQQFCAXMDHgErCAADBAEFAwwB
|
||||||
|
DwM4AVwCXQFgAc4CXQFlAewCWQFnAe8DRgF/KAADXwHQA2IB7iAAA2EB1ANjAenIAAE6AWsBAAH/AVIB
|
||||||
|
jAEIAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFaAZQBEAH/AVoBlAEQAf8BWgGcARAB
|
||||||
|
/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZQBGAH/AVoBlAEYAf8BYwGlARcB/wEZASwBAwH/OAAD
|
||||||
|
AgEDAwgBCgMgAS0CQQFAAXECTQFMAZEDUAGaAjsBOgFiAwwBDwwAAwMBBAMrAUEDRAF6A1MBpwNVAa0D
|
||||||
|
NwFaAxgBIAMJAQsDBgEHAw0BEQM5AV8CXQFhAdECWQFnAe8CYAFvAfMCRgFHAYEoAANfAdADYgHuIAAD
|
||||||
|
YQHUA2MB6cwAASwBVQEAAf8BUgGMAQgB/wFSAYwBCAH/AVIBjAEQAf8BUgGMARAB/wFaAZQBEAH/AVoB
|
||||||
|
lAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZQBGAH/AVoBlAEYAf8BIQFBAQAB
|
||||||
|
/0AABAIDBwEJAxAEFQEcAhYBFQEdAw8BEwMCAQMMAAMDAQQDMANLAUwBjwJbAV0BygJbAWEB3gNOAZQD
|
||||||
|
NAFTAxUBHAMNAREDHgErAkMBRAF3Al0BYwHfAmUBcAHxAloBYwHpA0QBeygAA18B0ANiAe4gAANhAdQD
|
||||||
|
YwHpyAABEgEiAQAB/wFMAYYBBgH/AVIBjAEIAf8BWgGcARAB/wFQAYoBCAH/AVIBjAEQAf8BWgGUARAB
|
||||||
|
/wFaAZwBEAH/AVoBnAEQAf8BWgGcARAB/wFaAZwBEAH/AVoBnAERAf8BaQGrAR8B/wEIAQoBAAH/bAAD
|
||||||
|
AgEDAyEBLwM6AWEDVQGtAl8BYwHaA1oBvwJQAVEBnwNEAXoCQQFCAXIDSQGFAlYBVwGyAl4BagHtAmAB
|
||||||
|
ZAHbAlUBVwGxAzgBWygAA18B0ANiAe4gAANhAdQDYwHpyAABEAEeAQAB/wFIAX0BBwH/AVkBkwETAf8B
|
||||||
|
VQGIARgB/wgAASEBQQEAAf8BQgF7AQAB/wFSAYwBCAH/AVUBkQEIAf8BOQFmAQQB/wNZAe94AAMGAQgD
|
||||||
|
FwEfA0QBewJZAVwBxgJbAWMB5AJTAWgB9ANiAe4DYgHuAmUBcAHxAkgBYwH2AisBfgH8AlkBXAG+Az4B
|
||||||
|
awMkATQoAANfAdADYgHuIAADYQHUA2MB6dAAAR4BOgEAAf+cAAQCAwkBDAMqAz8BQAFuA04BlgJWAVgB
|
||||||
|
swJZAVwBwQJaAV0BxwJaAV0BxwJXAVkBuQJRAVIBpAJAAUEBcQMlATYDEwEZKAADXwHQA2IB7iAAA2EB
|
||||||
|
1ANjAen/AHkABAEDCwEOAyYBOAM5AV4DRgF9AkoBSwGLA0oBiQM+AWsDKgE/AxcBHwMCAQMsAANTAaID
|
||||||
|
WgG/IAADVAGmA1kBu6gAAUIBTQE+BwABPgMAASgDAAGAAwABIAMAAQEBAAEBBgABAhYAA/8BAAP/AccC
|
||||||
|
AAEHAv8BzwHzAf8EAAL/Ac8BhwIAAQcC/wHPAfMB/wQAAf8B/gEAAQcCAAEHAv8BzwHzAf8EAAH/AfwB
|
||||||
|
AAEHAgABBwL/Ac8B8wH/BAAB/wH4AQABDwIAAQcC/wHPAfMB/wQAAf8B8AEAAQcCAAEHAv8BzwHzAf8E
|
||||||
|
AAH/AeABAAEDAgABBwL/Ac8B8wH/BAAB/wHAAQABAQH8AQMD/wHPAfMB/wQAAf8BwAEAAQEB/AEDA/8B
|
||||||
|
zwHzAf8EAAH/AeACAAH8AQMB4AEfCAAB/wH8ASABAAH8AQMB4AEfCAAB/wH+AeABAAH8AQMB4AEfCAAB
|
||||||
|
/wHAAgAB/AEDAeABHwH/Ac8B8wH/BAAB/wGAAgAB/AEDAeABHwH/Ac8B8wH/BAAB/wMAAfwBAwHgAR8B
|
||||||
|
/wHPAfMB/wQAAf4CAAEBAQABAwHgAR8B/wHPAfMB/wQAAfwCAAEBAQABAwH4AR8B/wHPAfMB/wQAAfgC
|
||||||
|
AAEBAQABAwH4AR8B/wHPAfMB/wQAAfgCAAEDAQABAwH4AQMB/wHPAfMB/wQAAfgCAAEHAQABAwH4AQMI
|
||||||
|
AAH4AgABDwEAAQMB+AkAAfgBAAFEAX8BAAEDAfgJAAH4AQABAQH/AYABAwH4AQAB/wHPAfMB/wQAAfgC
|
||||||
|
AAF/AYABAwH8AQAB/wHPAfMB/wQAAfwCAAF/AfABAwGBAYAB/wHPAfMB/wQAAf4CAAH/AfABAwGBAYAB
|
||||||
|
/wHPAfMB/wQAAf8CAAH/AfwBAwGAAQAB/wHPAfMB/wQAAf8BgAEBAf8B/gEDAYABAAH/Ac8B8wH/BAAB
|
||||||
|
/wEAAQMD/wGAAQAB/wHPAfMB/wQAAf8BDAEPA/8BwAEAAf8BzwHzAf8EAAH/Ad8E/wHAAQAB/wHPAfMB
|
||||||
|
/wQABv8B8AEBAf8BzwHzAf8EAAs=
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<metadata name="ilStoreThumbnails.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>12, 128</value>
|
||||||
|
</metadata>
|
||||||
<metadata name="ilTabIcons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="ilTabIcons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>122, 19</value>
|
<value>20, 44</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
<data name="ilTabIcons.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
<data name="ilTabIcons.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
<value>
|
<value>
|
||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA5ggAAAJNU0Z0AUkBTAIBAQIB
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAshIAAAJNU0Z0AUkBTAIBAQQB
|
||||||
AAGoAQABqAEAARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAARADAAEBAQABIAYAARAS
|
AAEQAQMBEAEDARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABIAYAASD/
|
||||||
AANnAe8CZwFZAe8BZwFdAVkB7wFnAVsBWQHvAWcBWwFZAe8BZwJZAe8BZwFkAVkB7wNnAe8DZwHvA2cB
|
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ACIAA2cB7wJnAVkB7wFnAV0BWQHvAWcBWwFZAe8B
|
||||||
7wNnAe8DZwHvA2cB7wNnAe8DZwHvA2cB7zgAAzMBUQN8AfWAAAP4Af8BuQGVATwB/wGDAX0BbgH/AYQB
|
ZwFbAVkB7wFnAlkB7wFnAWQBWQHvA2cB7wNnAe8DZwHvA2cB7wNnAe8DZwHvA2cB7wNnAe8DZwHvAwcB
|
||||||
fQFsAf8BqgGEAScB/wGsAXsBAAH/AcwBvAGUAf8DfgH/A34B/wN+Af8DfgH/A34B/wN+Af8DfgH/A34B
|
CQMqAT8DRQF8A1kBuwNjAd8DaAH0A4AB/gOBAf8DgQH/A4EB/wOAAf4DaAH0A2MB3wNaAboDRAF6AycB
|
||||||
/wOOAf84AAMSARgDPwFtgAAE/wGXAYsBbQH/AoEBgAH/AYIBgQGAAf8BmAGIAWAB/wHKAZABAAH/Ad0B
|
OjgAAzMBUQNuAfUIAAM3AVoDWAG4A2MB3wJjAV0B3wFiAl0B3wNdAd8DXQHfAWECXQHfA2MB3wNjAd8D
|
||||||
zAGfAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOTAf80AANfAdMDPQFnhAAE/wGGAYQB
|
VQGsAzABSwgAA/gB/wG5AZUBPAH/AYMBfQFuAf8BhAF9AWwB/wGqAYQBJwH/AawBewEAAf8BzAG8AZQB
|
||||||
fQH/A4EB/wOBAf8BhwGDAXoB/wHPAZQBAAH/Ad4BzAGfAf8D4AH/A+AB/wPgAf8D4AH/A+AB/wPgAf8D
|
/wN+Af8DfgH/A34B/wN+Af8DfgH/A34B/wN+Af8DfgH/A44B/wNDAXUDXQHMA3wB+AOBAf8DgQH/A4EB
|
||||||
4AH/A+AB/wO8Af80AANaAcIDNAFThAAE/wGLAYYBegH/A4EB/wOBAf8BjgGGAXEB/wHPAZQBAAH/Ad4B
|
/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A3wB+ANUAag4AAMSARgDPwFtBAADOwFiA10B
|
||||||
zAGfIf8DygH/EAADDQERAz8BbANTAacBXAJZAb4BWAJWAbMBSAJHAYMDIQEwBAADdgHzAzoBYIgABP8B
|
xQNoAfQBnwFlATEB/wGXAVMBFwH/AZYBSwEJAf8BkwFGAQEB/wGMAUMBAwH/AX0BQAELAf8BawFAARoB
|
||||||
rAGWAWAB/wGDAYIBfwH/AYUBggF9Af8BswGTAUQB/wHPAZQBAAH/Ad4BzAGfAf8DsAH/A7AB/wOwAf8D
|
/wFuAVABNgH/A2gB8ANaAbcDNAFUBAAE/wGXAYsBbQH/AoEBgAH/AYIBgQGAAf8BmAGIAWAB/wHKAZAB
|
||||||
sAH/A7AB/wOwAf8DsAH/A7AB/wOoAf8IAAMaASQDUgGgAWkBYwFIAfYBogFzAQAB/wGuAXwBAAH/AbAB
|
AAH/Ad0BzAGfAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOTAf8DagHtA30B+gOBAf8D
|
||||||
fQEAAf8BqAF4AQAB/wGVAWoBAAH/AYABaQEVAf4BXAJZAcYDVwG1AxYBHogABP8B2QGqATcB/wG+AZgB
|
gQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DVQGvNAADXwHTAz0B
|
||||||
OAH/AcABmAE2Af8B3AGiARQB/wHPAZQBAAH/Ad4BzAGfAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8D
|
ZwQAAzUBVQNdAccCbgFaAfUBuAFlARsB/wG5AVgBAgH/AckBXwEAAf8B2AFlAQAB/wHcAWcBAAH/AdYB
|
||||||
gQH/A4EB/wOTAf8EAAMgAS0CYwFaAekBvwGIAQAB/wHNAZUBCgH/AbABiAEnAf8BcwFkAT8B/wFNAUsB
|
ZAEAAf8BwwFcAQAB/wGiAUwBAAH/AXwBOwEDAf8BbgFGASMB/wNoAfADWgG3AzABSgT/AYYBhAF9Af8D
|
||||||
RwH/AU4BSwFCAf8BZgFXATEB/wGaAXQBFwH/AaQBdgEDAf8BcAFPAQAB/wNDAXYEAYQABP8B4QGuATEB
|
gQH/A4EB/wGHAYMBegH/Ac8BlAEAAf8B3gHMAZ8B/wPgAf8D4AH/A+AB/wPgAf8D4AH/A+AB/wPgAf8D
|
||||||
/wG9AZcBOwH/AcABmAE1Af8B4wGlAQoB/wHPAZQBAAH/Ad4BzAGfAf8DwAH/A8AB/wPAAf8DwAH/A8AB
|
4AH/A7wB/wNjAd8DbgH1A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8D
|
||||||
/wPAAf8DwAH/A8AB/wOvAf8EAAJjAVoB6QHZAZoBAAH/AdoBowEcAf8CjgGMAf8DigH/A5cB/wObAf8D
|
gQH/A4EB/wNVAa80AANaAcIDNAFTBAADXAHEAnwBXAH4AdQBcQEYAf8B1wFlAQAB/wHlAWwBAAH/AfIB
|
||||||
kQH/A3QB/wNIAf8BQwFCAT8B/wG1AYMBBwH/AXoBVwEAAf8DNgFYhAAE/wG7AZ0BUwH/AYgBhAF5Af8B
|
cgEAAf8B+gF1AQAB/wH8AXYBAAH/AfoBdgEAAf8B8wFyAQAB/wHiAWsBAAH/Ab0BWQEAAf8BhwFAAQAB
|
||||||
jAGFAXQB/wHEAZkBMAH/Ac8BlAEAAf8B3gHMAZ8h/wPKAf8DQwF2AekBpwECAf8B6QGrARIB/wHQAcoB
|
/wFxAUgBIwH/A2gB8ANWAasE/wGLAYYBegH/A4EB/wOBAf8BjgGGAXEB/wHPAZQBAAH/Ad4BzAGfIf8D
|
||||||
uwH/A6wB/wNdAf8DTAH/A0sB/wNEAf8DDwH/A7MB/wNmAf8BVAFMAToB/wGuAX0BBAH/A10BzIQABP8B
|
ygH/AzYBWANbAcADbgH1A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8D
|
||||||
lAGKAXMB/wOBAf8DgQH/AZoBigFjAf8BzwGUAQAB/wHeAcwBnwH/A9AB/wPQAf8D0AH/A9AB/wPQAf8D
|
aAH0A1IBpBAAAw0BEQM/AWwDUwGnAVwCWQG+AVgCVgGzAUgCRwGDAyEBMAQAA28B8wM6AWAIAAH+Ad0B
|
||||||
0AH/A9AB/wPQAf8DtQH/AmoBYQHmAe0BrQEQAf8B9AHQAXYB/wP6Af8D+gH/A30B/wN/Af8DgAH/A4AB
|
wQH/Ae0BgAEgAf8B7QFxAQIB/wHzAXMBAAH/AfoBdgEAAf8B/gF4AQAC/wF7AQgC/wGIAScC/wGiAVMB
|
||||||
/wN+Af8DhAH/A7sB/wNqAf8BqAGAARwB/wFrAWMBSAH2hAAE/wGGAYMBfgH/A4EB/wOBAf8BhgGDAXsB
|
/wH+AYEBFwH/AfwBeAEEAf8B7AFvAQAB/wHBAVsBAAH/AYYBQQEDAf8BeAFWATYB/wNjAd8E/wGsAZYB
|
||||||
/wHPAZQBAAH/Ad4BzAGfAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOTAf8BawFoAWIB
|
YAH/AYMBggF/Af8BhQGCAX0B/wGzAZMBRAH/Ac8BlAEAAf8B3gHMAZ8B/wOwAf8DsAH/A7AB/wOwAf8D
|
||||||
7gHvAbQBIQH/AfcB3AGXCf8DkQH/A4gB/wOHAf8DhwH/A4EB/wNXAf8D5gH/A6MB/wG2AZEBNgH/AYYB
|
sAH/A7AB/wOwAf8DsAH/A6gB/wMCAQMDGgEjAzgBXANUAagDYgHXA3AB8QOAAf4DgQH/A4EB/wOBAf8D
|
||||||
agE+AfmEAAT/AYsBhgF5Af8DgQH/A4EB/wGOAYYBcQH/Ac8BlAEAAf8B3gHMAZ8B/wOhAf8DoQH/A6EB
|
gQH9A2gB8ANhAdQDUwGlAzYBWQMYASAIAAMaASQDUgGgAmMBSAH2AaIBcwEAAf8BrgF8AQAB/wGwAX0B
|
||||||
/wOhAf8DoQH/A6EB/wOhAf8DoQH/A6EB/wNLAY0B8AG+AT8B/wH0Ac0BbCH/A/sB/wPQAf8B1wGnATEB
|
AAH/AagBeAEAAf8BlQFqAQAB/wKAAWIB/gFcAlkBxgNXAbUDFgEeCAAB/wGyAW8B/wH9AYABEQH/AfwB
|
||||||
/wJhAV0B0YQABP8BpwGUAWcB/wGDAYIBfwH/AYUBgwF+Af8BsAGUAU4B/wHTAZcBAgH/AeABzgGfAf8D
|
dwEBAf8B/QF3AQAC/wF4AQAC/wF/AQ8C/wGSATsC/wGzAYMC/wHqAeAC/wGQAT0C/wF7AQoB/wH8AXcB
|
||||||
5wH/A+cB/wPnAf8D5wH/A+cB/wPnAf8D5wH/A+cB/wPAAf8DBwEJAWsBaQFiAe4B8QG8ATsB/wH6AeoB
|
AAH/AeUBbAEAAf8BsQFUAQAB/wGEAUsBGgH/A2MB3wT/AdkBqgE3Af8BvgGYATgB/wHAAZgBNgH/AdwB
|
||||||
wgH/A9wB/wN3Af8DaAH/A2gB/wNoAf8DMgn/AfIB3QGpAf8B6gGpAQgB/wM+AWqEAAT/AdcBsQFSAf8B
|
ogEUAf8BzwGUAQAB/wHeAcwBnwH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DkwH/RAAD
|
||||||
mgGPAXQB/wGgAZIBbQH/AeABrwE3Af8B5wGpARAB/wHrAdUBoAH/A4EB/wOBAf8DgQH/A4EB/wOBAf8D
|
IAEtAmMBWgHpAb8BiAEAAf8BzQGVAQoB/wGwAYgBJwH/AXMBZAE/Af8BTQFLAUcB/wFOAUsBQgH/AWYB
|
||||||
gQH/A4EB/wOBAf8DkwH/BAADMwFRAWsBaQFoAfAB8wHGAVgB/wH6AecBuBb/Af4B+wH/AfkB4gGqAf8B
|
VwExAf8BmgF0ARcB/wGkAXYBAwH/AXABTwEAAf8DQwF2BAEEAAH/AZoBQgL/AYMBFQH/Af4BegEEAv8B
|
||||||
7wG4AS0B/wNOAZYEAoQABP8B9AHNAWwB/wH0AcsBZgH/AfQBywFlAf8B9AHLAWUB/wHxAcEBSQH/AfkB
|
eAEAAv8BeAEAAv8BlQE/Av8BygGuAv8B2gHGAv8B7QHlAv8BlgFJAv8BfAENAf8B/gF4AQAB/wH0AXMB
|
||||||
4wGsAf8DiQH/A4kB/wOJAf8DiQH/A4kB/wOJAf8DiQH/A4kB/wOaAf8IAAMiATEDXwHJAaIBjQFnAfoB
|
AAH/AdABYgEAAf8BmgFOAQoB/wFjAl0B3wT/AeEBrgExAf8BvQGXATsB/wHAAZgBNQH/AeMBpQEKAf8B
|
||||||
8wHKAWUB/wH5AeEBpgH/AfsB7QHMAf8B+wHsAcgB/wH4Ad0BmwH/AcgBmgFmAf4CZQFeAeIDPQFoBAGI
|
zwGUAQAB/wHeAcwBnwH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DrwH/CAADAgEDAwgB
|
||||||
AED/EAADDwETA0cBggNkAdsBtgGhAW8B/ANnAeoDVAGoAygBO5QAAUIBTQE+BwABPgMAASgDAAFAAwAB
|
CgMhAS8DMQFOAz0BaANDAXYDRAF6A0MBdQM9AWcDMQFNAyABLgMHAQkEAggAAmMBWgHpAdkBmgEAAf8B
|
||||||
EAMAAQEBAAEBBQABgBcAA/8DAAH/AfwGAAH/AfwGAAH/AfkGAAH/AfkGAAHwARMGAAHAAQMGAAGAAQEG
|
2gGjARwB/wKOAYwB/wOKAf8DlwH/A5sB/wORAf8DdAH/A0gB/wFDAUIBPwH/AbUBgwEHAf8BegFXAQAB
|
||||||
AAGAAQEHAAEBBwABAQcAAQEHAAEBBwABAQYAAYABAQYAAcABAwYAAfABHwQACw==
|
/wM2AVgEAAH/AZUBNwL/AYkBHwL/AX0BCAL/AXgBAAL/AXgBAAL/AagBXAL/AeABzQL/AaEBZgL/AdgB
|
||||||
|
xQL/AbkBlAL/AYcBIwL/AXgBAAH/AfsBdgEAAf8B4gFqAQAB/wGvAVQBAwH/AWMCXQHfBP8BuwGdAVMB
|
||||||
|
/wGIAYQBeQH/AYwBhQF0Af8BxAGZATAB/wHPAZQBAAH/Ad4BzAGfIf8DygH/BAADEwEaAzkBXQNZAbwD
|
||||||
|
ZAHbA2oB7QNjAfYDXwH7A4EB/QNfAfsDYwH2A2UB7ANjAdoDWgG6AzgBXAMTARoDQwF2AekBpwECAf8B
|
||||||
|
6QGrARIB/wHQAcoBuwH/A6wB/wNdAf8DTAH/A0sB/wNEAf8DDwH/A7MB/wNmAf8BVAFMAToB/wGuAX0B
|
||||||
|
BAH/A10BzAQAAf8BoAFJAv8BkgExAv8BgQERAv8BeQEDAv8BeAEAAv8BqAFcAv8B4AHNAv8BoQFmAv8B
|
||||||
|
2AHFAv8BwAGfAv8BiQEnAv8BeAEAAf8B/gF4AQAB/wHsAW8BAAH/Ab8BWgECAf8BYwJdAd8E/wGUAYoB
|
||||||
|
cwH/A4EB/wOBAf8BmgGKAWMB/wHPAZQBAAH/Ad4BzAGfAf8D0AH/A9AB/wPQAf8D0AH/A9AB/wPQAf8D
|
||||||
|
0AH/A9AB/wO1Af8DGgEkA1YBrgNoAfQDgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8D
|
||||||
|
gQH/A4EB/wNrAfIDUgGhAmoBYQHmAe0BrQEQAf8B9AHQAXYB/wP6Af8D+gH/A30B/wN/Af8DgAH/A4AB
|
||||||
|
/wN+Af8DhAH/A7sB/wNqAf8BqAGAARwB/wJjAUgB9gQAAf8BswFvAv8BngFIAv8BiAEeAv8BfAEHAv8B
|
||||||
|
eAEAAv8BmAFDAv8BzgG0Av8B1wHAAv8B6gHgAv8BnQFXAv8BfgERAv8BeAEAAv8BeAEAAf8B8AFxAQAB
|
||||||
|
/wHLAWQBCQH/AWMBYQFdAd8E/wGGAYMBfgH/A4EB/wOBAf8BhgGDAXsB/wHPAZQBAAH/Ad4BzAGfAf8D
|
||||||
|
gQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOTAf8DVwGyA2UB5wOBAf8DgQH/A4EB/wOBAf8D
|
||||||
|
gQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DVQGvA2IB7gHvAbQBIQH/AfcB3AGXCf8D
|
||||||
|
kQH/A4gB/wOHAf8DhwH/A4EB/wNXAf8D5gH/A6MB/wG2AZEBNgH/AmoBQQH5BAAB/wHMAZ8C/wGsAWMC
|
||||||
|
/wGTATMC/wGBAREC/wF5AQIC/wGCARYC/wGaAUsC/wGuAXgC/wGlAVcC/wGBARcC/wF5AQQC/wF4AQAC
|
||||||
|
/wF4AQAB/wHwAXEBAAH/AdUBcQEXAf8CYwFdAd8E/wGLAYYBeQH/A4EB/wOBAf8BjgGGAXEB/wHPAZQB
|
||||||
|
AAH/Ad4BzAGfAf8DoQH/A6EB/wOhAf8DoQH/A6EB/wOhAf8DoQH/A6EB/wOhAf8DbwHzA18B+wOBAf8D
|
||||||
|
gQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DVQGvA0sBjQHwAb4B
|
||||||
|
PwH/AfQBzQFsIf8D+wH/A9AB/wHXAacBMQH/AmEBXQHRBAAB/wHpAdUC/wG8AYEC/wGkAVQC/wGOASoC
|
||||||
|
/wF/AQ0C/wF5AQIC/wF7AQkC/wGCAR0C/wF4AQAC/wF4AQAC/wF4AQEC/wF6AQQC/wF6AQMB/wHzAXQB
|
||||||
|
AwH/AeIBhAEyAf8DYwHfBP8BpwGUAWcB/wGDAYIBfwH/AYUBgwF+Af8BsAGUAU4B/wHTAZcBAgH/AeAB
|
||||||
|
zgGfAf8D5wH/A+cB/wPnAf8D5wH/A+cB/wPnAf8D5wH/A+cB/wPAAf8DZAHbA2gB9AOBAf8DgQH/A4EB
|
||||||
|
/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DVQGvAwcBCQNiAe4B8QG8ATsB
|
||||||
|
/wH6AeoBwgH/A9wB/wN3Af8DaAH/A2gB/wNoAf8DMgn/AfIB3QGpAf8B6gGpAQgB/wM+AWoEAANeAdID
|
||||||
|
agH5Af8BuwF9Av8BowFSAv8BkAEsAv8BggETAv8BfQEIAv8BegEEAv8BeQECAv8BegEEAv8BfQEJAv8B
|
||||||
|
gAEPAv8BfwENAf8B+AGGASAB/wNoAfQDWAG4BP8B1wGxAVIB/wGaAY8BdAH/AaABkgFtAf8B4AGvATcB
|
||||||
|
/wHnAakBEAH/AesB1QGgAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOTAf8DPAFkA18B
|
||||||
|
yQN9AfoDgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wN9AfoDVQGqBAAD
|
||||||
|
MwFRA2gB8AHzAcYBWAH/AfoB5wG4Fv8B/gH7Af8B+QHiAaoB/wHvAbgBLQH/A04BlgQCBAADPAFmA2MB
|
||||||
|
1QN8AfgB/wG+AYUC/wGqAV8C/wGZAT4C/wGNAScC/wGGARoC/wGDARUC/wGFARkC/wGKASIC/wGNASgC
|
||||||
|
/wGTATMB/wJuAWgB9QNdAcUDNgFZBP8B9AHNAWwB/wH0AcsBZgH/AfQBywFlAf8B9AHLAWUB/wHxAcEB
|
||||||
|
SQH/AfkB4wGsAf8DiQH/A4kB/wOJAf8DiQH/A4kB/wOJAf8DiQH/A4kB/wOaAf8DBgEIAzEBTANQAZsD
|
||||||
|
ZQHsA30B+gOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DfQH6A2oB7QNQAZsDLwFJCAADIgExA18B
|
||||||
|
yQJ9AWcB+gHzAcoBZQH/AfkB4QGmAf8B+wHtAcwB/wH7AewByAH/AfgB3QGbAf8DgAH+AmUBXgHiAz0B
|
||||||
|
aAQBDAADQgFyA2MB1QNqAfkB/wHJAZkC/wG8AX8C/wGuAWYC/wGkAVMC/wGfAUoC/wGfAUsC/wGjAVEC
|
||||||
|
/wGnAVgB/wN8AfgDXQHHAzsBYgQAQP8IAAMFAQYDEgEXAzoBYANRAZ8DXwHTA2cB7wNjAfYDYgHuA14B
|
||||||
|
0gNRAZ4DOQFfAxEBFgMFAQYUAAMPARMDRwGCA2QB2wJ+AW8B/ANnAeoDVAGoAygBOxwAAzwBZQNeAdIB
|
||||||
|
/wHvAeAC/wHcAbwC/wHNAZ8C/wHBAYoC/wG7AX8C/wG/AYYC/wHNAaEC/wHpAdYB/wNcAcQDNQFVCAAB
|
||||||
|
QgFNAT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEBFgAD/4UAAf8B/AHAAQMEAAH/AfwBgAEBBAAB
|
||||||
|
/wH5BgAB/wH5BgAB8AETBgABwAEDBAAC/wGAAQEEAAHAAQEBgAEBBAABgAIAAQEHAAEBBwABAQcAAQEH
|
||||||
|
AAEBBgABgAEBBgABwAEDAYABAQIAAcABAQHwAR8BwAEDCw==
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="ctxmChangeStatus.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="ctxmChangeStatus.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>297, 21</value>
|
<value>205, 21</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
<metadata name="niMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="niMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>216, 21</value>
|
<value>125, 19</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
<data name="niMain.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="niMain.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
@ -251,8 +628,14 @@
|
|||||||
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>55</value>
|
<value>90</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
|
52
qtc-net-client-2/Forms/Profile.Designer.cs
generated
@ -37,25 +37,22 @@
|
|||||||
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();
|
||||||
panel1 = 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();
|
||||||
panel1.SuspendLayout();
|
pCurrency.SuspendLayout();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// pbUserPfp
|
// pbUserPfp
|
||||||
//
|
//
|
||||||
pbUserPfp.BorderStyle = BorderStyle.FixedSingle;
|
|
||||||
pbUserPfp.Image = Properties.Resources.DefaultPfp;
|
pbUserPfp.Image = Properties.Resources.DefaultPfp;
|
||||||
pbUserPfp.Location = new Point(12, 12);
|
pbUserPfp.Location = new Point(9, 5);
|
||||||
pbUserPfp.Name = "pbUserPfp";
|
pbUserPfp.Name = "pbUserPfp";
|
||||||
pbUserPfp.Size = new Size(128, 126);
|
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;
|
||||||
@ -64,7 +61,7 @@
|
|||||||
//
|
//
|
||||||
lblUsername.AutoSize = true;
|
lblUsername.AutoSize = true;
|
||||||
lblUsername.Font = new Font("Segoe UI Light", 15F, FontStyle.Bold);
|
lblUsername.Font = new Font("Segoe UI Light", 15F, FontStyle.Bold);
|
||||||
lblUsername.ForeColor = SystemColors.ControlLight;
|
lblUsername.ForeColor = Color.White;
|
||||||
lblUsername.Location = new Point(3, 0);
|
lblUsername.Location = new Point(3, 0);
|
||||||
lblUsername.Name = "lblUsername";
|
lblUsername.Name = "lblUsername";
|
||||||
lblUsername.Size = new Size(105, 28);
|
lblUsername.Size = new Size(105, 28);
|
||||||
@ -149,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;
|
||||||
@ -188,21 +174,21 @@
|
|||||||
//
|
//
|
||||||
flpUsernameCurrency.BackColor = Color.Transparent;
|
flpUsernameCurrency.BackColor = Color.Transparent;
|
||||||
flpUsernameCurrency.Controls.Add(lblUsername);
|
flpUsernameCurrency.Controls.Add(lblUsername);
|
||||||
flpUsernameCurrency.Controls.Add(panel1);
|
flpUsernameCurrency.Controls.Add(pCurrency);
|
||||||
flpUsernameCurrency.Location = new Point(152, 8);
|
flpUsernameCurrency.Location = new Point(152, 8);
|
||||||
flpUsernameCurrency.Name = "flpUsernameCurrency";
|
flpUsernameCurrency.Name = "flpUsernameCurrency";
|
||||||
flpUsernameCurrency.Size = new Size(246, 33);
|
flpUsernameCurrency.Size = new Size(246, 33);
|
||||||
flpUsernameCurrency.TabIndex = 13;
|
flpUsernameCurrency.TabIndex = 13;
|
||||||
flpUsernameCurrency.WrapContents = false;
|
flpUsernameCurrency.WrapContents = false;
|
||||||
//
|
//
|
||||||
// panel1
|
// pCurrency
|
||||||
//
|
//
|
||||||
panel1.Controls.Add(pbCurrencyIcon);
|
pCurrency.Controls.Add(pbCurrencyIcon);
|
||||||
panel1.Controls.Add(lblCurrencyAmount);
|
pCurrency.Controls.Add(lblCurrencyAmount);
|
||||||
panel1.Location = new Point(114, 3);
|
pCurrency.Location = new Point(114, 3);
|
||||||
panel1.Name = "panel1";
|
pCurrency.Name = "pCurrency";
|
||||||
panel1.Size = new Size(73, 24);
|
pCurrency.Size = new Size(73, 24);
|
||||||
panel1.TabIndex = 14;
|
pCurrency.TabIndex = 14;
|
||||||
//
|
//
|
||||||
// Profile
|
// Profile
|
||||||
//
|
//
|
||||||
@ -214,28 +200,27 @@
|
|||||||
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);
|
||||||
Controls.Add(btnMessage);
|
Controls.Add(btnMessage);
|
||||||
Font = new Font("Segoe UI Light", 9F);
|
Font = new Font("Segoe UI Light", 9F);
|
||||||
|
ForeColor = Color.White;
|
||||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||||
MaximizeBox = false;
|
MaximizeBox = false;
|
||||||
MinimizeBox = false;
|
MinimizeBox = false;
|
||||||
Name = "Profile";
|
Name = "Profile";
|
||||||
StartPosition = FormStartPosition.CenterParent;
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
Text = "QtC.NET Client - User Profile";
|
Text = "QtC.NET Client - User Profile";
|
||||||
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();
|
||||||
panel1.ResumeLayout(false);
|
pCurrency.ResumeLayout(false);
|
||||||
panel1.PerformLayout();
|
pCurrency.PerformLayout();
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,10 +234,9 @@
|
|||||||
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;
|
||||||
private Panel panel1;
|
private Panel pCurrency;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,72 +1,95 @@
|
|||||||
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;
|
|
||||||
|
|
||||||
namespace qtc_net_client_2.Forms
|
namespace qtc_net_client_2.Forms
|
||||||
{
|
{
|
||||||
public partial class Profile : Form
|
public partial class Profile : Form
|
||||||
{
|
{
|
||||||
UserInformationDto _userInformationDto;
|
private UserInformationDto _userInformationDto;
|
||||||
IApiService _apiService;
|
private IApiService _apiService;
|
||||||
IGatewayService _gatewayService;
|
private IGatewayService _gatewayService;
|
||||||
|
|
||||||
ServiceResponse<byte[]>? pfpRes;
|
private ServiceResponse<byte[]>? pfpRes;
|
||||||
public Profile(UserInformationDto userInfo, ServiceResponse<byte[]>? pfp, IApiService apiService, IGatewayService gatewayService)
|
byte[]? cosmeticRes;
|
||||||
|
|
||||||
|
private List<Contact> contactsList;
|
||||||
|
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;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void frmProfile_Load(object sender, EventArgs e)
|
private async void frmProfile_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var contactsList = await _apiService.GetCurrentUserContacts();
|
|
||||||
|
|
||||||
lblUsername.Text = _userInformationDto.Username;
|
lblUsername.Text = _userInformationDto.Username;
|
||||||
lblCurrencyAmount.Text = _userInformationDto.CurrencyAmount.ToString();
|
lblCurrencyAmount.Text = _userInformationDto.CurrencyAmount.ToString("N0");
|
||||||
rtxtBio.Text = _userInformationDto.Bio;
|
rtxtBio.Text = _userInformationDto.Bio;
|
||||||
|
|
||||||
|
Bitmap? pfp = null;
|
||||||
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 = Image.FromStream(ms);
|
pfp = new Bitmap(ms);
|
||||||
ms.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bitmap? cosmetic = null;
|
||||||
|
if(cosmeticRes != null)
|
||||||
|
{
|
||||||
|
using var ms = new MemoryStream(cosmeticRes);
|
||||||
|
cosmetic = new Bitmap(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
@ -75,9 +98,9 @@ namespace qtc_net_client_2.Forms
|
|||||||
}
|
}
|
||||||
else btnAddContact.Visible = true;
|
else btnAddContact.Visible = true;
|
||||||
|
|
||||||
if (contactsList != null && contactsList.Success && contactsList.Data != null)
|
if (contactsList != null)
|
||||||
{
|
{
|
||||||
var contact = contactsList.Data.FirstOrDefault(e => e.UserId == _userInformationDto.Id || e.OwnerId == _userInformationDto.Id);
|
var contact = contactsList.FirstOrDefault(e => e.UserId == _userInformationDto.Id || e.OwnerId == _userInformationDto.Id);
|
||||||
if (contact != null)
|
if (contact != null)
|
||||||
{
|
{
|
||||||
if (contact.OwnerId == _apiService.CurrentUser.Id)
|
if (contact.OwnerId == _apiService.CurrentUser.Id)
|
||||||
@ -153,8 +176,6 @@ namespace qtc_net_client_2.Forms
|
|||||||
btnAddContact.Enabled = false;
|
btnAddContact.Enabled = false;
|
||||||
using (var ms = new MemoryStream(Resources.RequestSentIcon)) { btnAddContact.Image = Image.FromStream(ms); ms.Dispose(); }
|
using (var ms = new MemoryStream(Resources.RequestSentIcon)) { btnAddContact.Image = Image.FromStream(ms); ms.Dispose(); }
|
||||||
btnCancelRequest.Visible = true;
|
btnCancelRequest.Visible = true;
|
||||||
|
|
||||||
await _gatewayService.RefreshContactsForUser(_userInformationDto);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,8 +187,6 @@ namespace qtc_net_client_2.Forms
|
|||||||
btnAddContact.Image = Resources.AddContactIcon;
|
btnAddContact.Image = Resources.AddContactIcon;
|
||||||
btnAddContact.Click += btnAddContact_Click_Add;
|
btnAddContact.Click += btnAddContact_Click_Add;
|
||||||
btnMessage.Visible = false;
|
btnMessage.Visible = false;
|
||||||
|
|
||||||
await _gatewayService.RefreshContactsForUser(_userInformationDto);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,8 +202,6 @@ namespace qtc_net_client_2.Forms
|
|||||||
btnAddContact.Image = Resources.RemoveContactIcon;
|
btnAddContact.Image = Resources.RemoveContactIcon;
|
||||||
btnAddContact.Click += btnAddContact_Click_Remove;
|
btnAddContact.Click += btnAddContact_Click_Remove;
|
||||||
if (_userInformationDto.Status >= 1) btnMessage.Visible = true;
|
if (_userInformationDto.Status >= 1) btnMessage.Visible = true;
|
||||||
|
|
||||||
await _gatewayService.RefreshContactsForUser(_userInformationDto);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,8 +216,6 @@ namespace qtc_net_client_2.Forms
|
|||||||
btnAddContact.Visible = true;
|
btnAddContact.Visible = true;
|
||||||
btnAddContact.Image = Resources.AddContactIcon;
|
btnAddContact.Image = Resources.AddContactIcon;
|
||||||
btnAddContact.Click += btnAddContact_Click_Add;
|
btnAddContact.Click += btnAddContact_Click_Add;
|
||||||
|
|
||||||
await _gatewayService.RefreshContactsForUser(_userInformationDto);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,8 +229,6 @@ namespace qtc_net_client_2.Forms
|
|||||||
btnAddContact.Click += btnAddContact_Click_Add;
|
btnAddContact.Click += btnAddContact_Click_Add;
|
||||||
|
|
||||||
btnCancelRequest.Visible = false;
|
btnCancelRequest.Visible = false;
|
||||||
|
|
||||||
await _gatewayService.RefreshContactsForUser(_userInformationDto);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,5 +238,32 @@ namespace qtc_net_client_2.Forms
|
|||||||
Close();
|
Close();
|
||||||
frmDirectMessage.Show();
|
frmDirectMessage.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CreateProfileImage(Bitmap precenseImage, Bitmap? pfp = null, Bitmap? cosmetic = null)
|
||||||
|
{
|
||||||
|
Bitmap combined = new Bitmap(139, 138);
|
||||||
|
|
||||||
|
using Graphics g = Graphics.FromImage(combined);
|
||||||
|
g.Clear(Color.Transparent);
|
||||||
|
g.CompositingMode = CompositingMode.SourceOver;
|
||||||
|
|
||||||
|
if (pfp != null)
|
||||||
|
{
|
||||||
|
pfp.MakeTransparent();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
precenseImage.MakeTransparent();
|
||||||
|
g.DrawImage(precenseImage, 104, 0, 35, 35);
|
||||||
|
|
||||||
|
pbUserPfp.Image = combined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
qtc-net-client-2/Forms/ProfileEdit.Designer.cs
generated
@ -33,6 +33,8 @@
|
|||||||
rtxtBio = new RichTextBox();
|
rtxtBio = new RichTextBox();
|
||||||
lblBio = new Label();
|
lblBio = new Label();
|
||||||
btnSave = new Button();
|
btnSave = new Button();
|
||||||
|
cbCosmetic = new ComboBox();
|
||||||
|
lblCosmetic = new Label();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// tbUsername
|
// tbUsername
|
||||||
@ -71,7 +73,7 @@
|
|||||||
// btnSave
|
// btnSave
|
||||||
//
|
//
|
||||||
btnSave.ForeColor = Color.Black;
|
btnSave.ForeColor = Color.Black;
|
||||||
btnSave.Location = new Point(76, 148);
|
btnSave.Location = new Point(76, 177);
|
||||||
btnSave.Name = "btnSave";
|
btnSave.Name = "btnSave";
|
||||||
btnSave.Size = new Size(43, 23);
|
btnSave.Size = new Size(43, 23);
|
||||||
btnSave.TabIndex = 4;
|
btnSave.TabIndex = 4;
|
||||||
@ -79,12 +81,32 @@
|
|||||||
btnSave.UseVisualStyleBackColor = true;
|
btnSave.UseVisualStyleBackColor = true;
|
||||||
btnSave.Click += btnSave_Click;
|
btnSave.Click += btnSave_Click;
|
||||||
//
|
//
|
||||||
// frmProfileEdit
|
// cbCosmetic
|
||||||
|
//
|
||||||
|
cbCosmetic.FormattingEnabled = true;
|
||||||
|
cbCosmetic.Items.AddRange(new object[] { "(None)" });
|
||||||
|
cbCosmetic.Location = new Point(76, 148);
|
||||||
|
cbCosmetic.Name = "cbCosmetic";
|
||||||
|
cbCosmetic.Size = new Size(121, 23);
|
||||||
|
cbCosmetic.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// lblCosmetic
|
||||||
|
//
|
||||||
|
lblCosmetic.AutoSize = true;
|
||||||
|
lblCosmetic.Location = new Point(21, 151);
|
||||||
|
lblCosmetic.Name = "lblCosmetic";
|
||||||
|
lblCosmetic.Size = new Size(53, 15);
|
||||||
|
lblCosmetic.TabIndex = 6;
|
||||||
|
lblCosmetic.Text = "Cosmetic";
|
||||||
|
//
|
||||||
|
// ProfileEdit
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(6F, 15F);
|
AutoScaleDimensions = new SizeF(6F, 15F);
|
||||||
AutoScaleMode = AutoScaleMode.Font;
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
BackColor = Color.DodgerBlue;
|
BackColor = Color.DodgerBlue;
|
||||||
ClientSize = new Size(345, 187);
|
ClientSize = new Size(345, 208);
|
||||||
|
Controls.Add(lblCosmetic);
|
||||||
|
Controls.Add(cbCosmetic);
|
||||||
Controls.Add(btnSave);
|
Controls.Add(btnSave);
|
||||||
Controls.Add(lblBio);
|
Controls.Add(lblBio);
|
||||||
Controls.Add(rtxtBio);
|
Controls.Add(rtxtBio);
|
||||||
@ -95,7 +117,7 @@
|
|||||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
MaximizeBox = false;
|
MaximizeBox = false;
|
||||||
MinimizeBox = false;
|
MinimizeBox = false;
|
||||||
Name = "frmProfileEdit";
|
Name = "ProfileEdit";
|
||||||
StartPosition = FormStartPosition.CenterParent;
|
StartPosition = FormStartPosition.CenterParent;
|
||||||
Text = "QtC.NET Client - Edit Profile";
|
Text = "QtC.NET Client - Edit Profile";
|
||||||
Load += frmProfileEdit_Load;
|
Load += frmProfileEdit_Load;
|
||||||
@ -110,5 +132,7 @@
|
|||||||
private RichTextBox rtxtBio;
|
private RichTextBox rtxtBio;
|
||||||
private Label lblBio;
|
private Label lblBio;
|
||||||
private Button btnSave;
|
private Button btnSave;
|
||||||
|
private ComboBox cbCosmetic;
|
||||||
|
private Label lblCosmetic;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,6 @@
|
|||||||
using QtCNETAPI.Dtos.User;
|
using Microsoft.AspNetCore.Mvc.TagHelpers;
|
||||||
|
using qtc_net_client_2.ClientModel;
|
||||||
|
using QtCNETAPI.Dtos.User;
|
||||||
using QtCNETAPI.Services.ApiService;
|
using QtCNETAPI.Services.ApiService;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -21,38 +23,81 @@ namespace qtc_net_client_2.Forms
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void frmProfileEdit_Load(object sender, EventArgs e)
|
private async void frmProfileEdit_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
tbUsername.Text = _apiService.CurrentUser!.Username;
|
tbUsername.Text = _apiService.CurrentUser.Username;
|
||||||
rtxtBio.Text = _apiService.CurrentUser!.Bio;
|
rtxtBio.Text = _apiService.CurrentUser.Bio;
|
||||||
|
|
||||||
|
// get all owned cosmetics
|
||||||
|
var boughtItems = await _apiService.GetOwnedStoreItems();
|
||||||
|
List<ComboBoxItem> items = new List<ComboBoxItem>();
|
||||||
|
|
||||||
|
if(boughtItems != null && boughtItems.Success && boughtItems.Data != null)
|
||||||
|
{
|
||||||
|
items.Add(new ComboBoxItem
|
||||||
|
{
|
||||||
|
Name = "(None)",
|
||||||
|
Value = 0
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in boughtItems.Data)
|
||||||
|
{
|
||||||
|
// get item from the store
|
||||||
|
var storeItem = await _apiService.GetStoreItem(item.StoreItemId);
|
||||||
|
if(storeItem != null && storeItem.Success && storeItem.Data != null)
|
||||||
|
{
|
||||||
|
var cbi = new ComboBoxItem
|
||||||
|
{
|
||||||
|
Name = storeItem.Data.Name,
|
||||||
|
Value = storeItem.Data.Id
|
||||||
|
};
|
||||||
|
items.Add(cbi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
items.Add(new ComboBoxItem
|
||||||
|
{
|
||||||
|
Name = "(None)",
|
||||||
|
Value = 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cbCosmetic.DataSource = items;
|
||||||
|
cbCosmetic.SelectedIndex = cbCosmetic.Items.IndexOf(items.FirstOrDefault(e => (int?)e.Value == _apiService.CurrentUser.ActiveProfileCosmetic));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void btnSave_Click(object sender, EventArgs e)
|
private async void btnSave_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if(!string.IsNullOrEmpty(tbUsername.Text) && (tbUsername.Text != _apiService.CurrentUser!.Username || rtxtBio.Text != _apiService.CurrentUser!.Bio))
|
ComboBoxItem? selectedItem = (ComboBoxItem?)cbCosmetic.SelectedItem;
|
||||||
|
|
||||||
|
// update user info
|
||||||
|
UserUpdateInformationDto userUpdateInformationDto = new UserUpdateInformationDto
|
||||||
{
|
{
|
||||||
// update user info
|
Id = _apiService.CurrentUser.Id,
|
||||||
UserUpdateInformationDto userUpdateInformationDto = new UserUpdateInformationDto
|
Username = tbUsername.Text,
|
||||||
{
|
Bio = rtxtBio.Text,
|
||||||
Id = _apiService.CurrentUser.Id,
|
DateOfBirth = _apiService.CurrentUser.DateOfBirth
|
||||||
Username = tbUsername.Text,
|
};
|
||||||
Bio = rtxtBio.Text,
|
|
||||||
DateOfBirth = _apiService.CurrentUser.DateOfBirth
|
|
||||||
};
|
|
||||||
|
|
||||||
var res = await _apiService.UpdateUserInformationAsync(userUpdateInformationDto);
|
if (selectedItem != null)
|
||||||
|
{
|
||||||
|
int selectedItemId = (int?)selectedItem.Value ?? 0;
|
||||||
|
userUpdateInformationDto.ProfileCosmeticId = selectedItemId;
|
||||||
|
}
|
||||||
|
|
||||||
if (res.Success)
|
var res = await _apiService.UpdateUserInformationAsync(userUpdateInformationDto);
|
||||||
{
|
|
||||||
DialogResult = DialogResult.OK;
|
if (res.Success)
|
||||||
Close();
|
{
|
||||||
}
|
DialogResult = DialogResult.OK;
|
||||||
else
|
Close();
|
||||||
{
|
}
|
||||||
MessageBox.Show(res.Message, "Info Update Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
else
|
||||||
DialogResult = DialogResult.Cancel;
|
{
|
||||||
Close();
|
MessageBox.Show(res.Message, "Info Update Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
DialogResult = DialogResult.Cancel;
|
||||||
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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>
|
206
qtc-net-client-2/Forms/StockMarketGame.Designer.cs
generated
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
partial class StockMarketGame
|
||||||
|
{
|
||||||
|
/// <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()
|
||||||
|
{
|
||||||
|
pStockManagement = new Panel();
|
||||||
|
nudStockBuySellAmount = new NumericUpDown();
|
||||||
|
btnSell = new Button();
|
||||||
|
btnBuy = new Button();
|
||||||
|
lblStockCount = new Label();
|
||||||
|
pMarketStatus = new Panel();
|
||||||
|
lblCurrentStockPrice = new Label();
|
||||||
|
lblMarketStatus = new Label();
|
||||||
|
pbDollarSignRight = new PictureBox();
|
||||||
|
pbDollarSignLeft = new PictureBox();
|
||||||
|
btnRefresh = new Button();
|
||||||
|
pStockManagement.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)nudStockBuySellAmount).BeginInit();
|
||||||
|
pMarketStatus.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbDollarSignRight).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbDollarSignLeft).BeginInit();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// pStockManagement
|
||||||
|
//
|
||||||
|
pStockManagement.Controls.Add(nudStockBuySellAmount);
|
||||||
|
pStockManagement.Controls.Add(btnSell);
|
||||||
|
pStockManagement.Controls.Add(btnBuy);
|
||||||
|
pStockManagement.Controls.Add(lblStockCount);
|
||||||
|
pStockManagement.Location = new Point(230, 138);
|
||||||
|
pStockManagement.Name = "pStockManagement";
|
||||||
|
pStockManagement.Size = new Size(135, 81);
|
||||||
|
pStockManagement.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// nudStockBuySellAmount
|
||||||
|
//
|
||||||
|
nudStockBuySellAmount.Enabled = false;
|
||||||
|
nudStockBuySellAmount.Location = new Point(48, 7);
|
||||||
|
nudStockBuySellAmount.Name = "nudStockBuySellAmount";
|
||||||
|
nudStockBuySellAmount.Size = new Size(42, 23);
|
||||||
|
nudStockBuySellAmount.TabIndex = 9;
|
||||||
|
//
|
||||||
|
// btnSell
|
||||||
|
//
|
||||||
|
btnSell.Enabled = false;
|
||||||
|
btnSell.ForeColor = Color.Black;
|
||||||
|
btnSell.Location = new Point(88, 52);
|
||||||
|
btnSell.Name = "btnSell";
|
||||||
|
btnSell.Size = new Size(39, 23);
|
||||||
|
btnSell.TabIndex = 8;
|
||||||
|
btnSell.Text = "Sell";
|
||||||
|
btnSell.UseVisualStyleBackColor = true;
|
||||||
|
btnSell.Click += btnSell_Click;
|
||||||
|
//
|
||||||
|
// btnBuy
|
||||||
|
//
|
||||||
|
btnBuy.Enabled = false;
|
||||||
|
btnBuy.ForeColor = Color.Black;
|
||||||
|
btnBuy.Location = new Point(9, 52);
|
||||||
|
btnBuy.Name = "btnBuy";
|
||||||
|
btnBuy.Size = new Size(39, 23);
|
||||||
|
btnBuy.TabIndex = 7;
|
||||||
|
btnBuy.Text = "Buy";
|
||||||
|
btnBuy.UseVisualStyleBackColor = true;
|
||||||
|
btnBuy.Click += btnBuy_Click;
|
||||||
|
//
|
||||||
|
// lblStockCount
|
||||||
|
//
|
||||||
|
lblStockCount.Font = new Font("Segoe UI", 7F, FontStyle.Bold);
|
||||||
|
lblStockCount.ImageAlign = ContentAlignment.MiddleRight;
|
||||||
|
lblStockCount.Location = new Point(11, 34);
|
||||||
|
lblStockCount.Name = "lblStockCount";
|
||||||
|
lblStockCount.Size = new Size(115, 12);
|
||||||
|
lblStockCount.TabIndex = 6;
|
||||||
|
lblStockCount.Text = "Your Stock Count - 999";
|
||||||
|
lblStockCount.TextAlign = ContentAlignment.MiddleCenter;
|
||||||
|
//
|
||||||
|
// pMarketStatus
|
||||||
|
//
|
||||||
|
pMarketStatus.Controls.Add(lblCurrentStockPrice);
|
||||||
|
pMarketStatus.Controls.Add(lblMarketStatus);
|
||||||
|
pMarketStatus.Controls.Add(pbDollarSignRight);
|
||||||
|
pMarketStatus.Controls.Add(pbDollarSignLeft);
|
||||||
|
pMarketStatus.Location = new Point(3, 7);
|
||||||
|
pMarketStatus.Name = "pMarketStatus";
|
||||||
|
pMarketStatus.Size = new Size(586, 100);
|
||||||
|
pMarketStatus.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// lblCurrentStockPrice
|
||||||
|
//
|
||||||
|
lblCurrentStockPrice.Font = new Font("Segoe UI", 9F, FontStyle.Bold);
|
||||||
|
lblCurrentStockPrice.ForeColor = Color.Black;
|
||||||
|
lblCurrentStockPrice.Location = new Point(194, 73);
|
||||||
|
lblCurrentStockPrice.Name = "lblCurrentStockPrice";
|
||||||
|
lblCurrentStockPrice.Size = new Size(199, 15);
|
||||||
|
lblCurrentStockPrice.TabIndex = 5;
|
||||||
|
lblCurrentStockPrice.Text = "Current Price Per Stock Is 999 Q's";
|
||||||
|
lblCurrentStockPrice.TextAlign = ContentAlignment.MiddleCenter;
|
||||||
|
//
|
||||||
|
// lblMarketStatus
|
||||||
|
//
|
||||||
|
lblMarketStatus.Font = new Font("Segoe UI", 35F, FontStyle.Bold | FontStyle.Italic);
|
||||||
|
lblMarketStatus.Location = new Point(90, 4);
|
||||||
|
lblMarketStatus.Name = "lblMarketStatus";
|
||||||
|
lblMarketStatus.Size = new Size(408, 62);
|
||||||
|
lblMarketStatus.TabIndex = 5;
|
||||||
|
lblMarketStatus.Text = "MARKET_STATUS";
|
||||||
|
lblMarketStatus.TextAlign = ContentAlignment.MiddleCenter;
|
||||||
|
//
|
||||||
|
// pbDollarSignRight
|
||||||
|
//
|
||||||
|
pbDollarSignRight.Image = Properties.Resources.dollar_money;
|
||||||
|
pbDollarSignRight.Location = new Point(500, 3);
|
||||||
|
pbDollarSignRight.Name = "pbDollarSignRight";
|
||||||
|
pbDollarSignRight.Size = new Size(83, 94);
|
||||||
|
pbDollarSignRight.SizeMode = PictureBoxSizeMode.Zoom;
|
||||||
|
pbDollarSignRight.TabIndex = 4;
|
||||||
|
pbDollarSignRight.TabStop = false;
|
||||||
|
//
|
||||||
|
// pbDollarSignLeft
|
||||||
|
//
|
||||||
|
pbDollarSignLeft.Image = Properties.Resources.dollar_money;
|
||||||
|
pbDollarSignLeft.Location = new Point(3, 3);
|
||||||
|
pbDollarSignLeft.Name = "pbDollarSignLeft";
|
||||||
|
pbDollarSignLeft.Size = new Size(83, 94);
|
||||||
|
pbDollarSignLeft.SizeMode = PictureBoxSizeMode.Zoom;
|
||||||
|
pbDollarSignLeft.TabIndex = 3;
|
||||||
|
pbDollarSignLeft.TabStop = false;
|
||||||
|
//
|
||||||
|
// btnRefresh
|
||||||
|
//
|
||||||
|
btnRefresh.Enabled = false;
|
||||||
|
btnRefresh.ForeColor = Color.Black;
|
||||||
|
btnRefresh.Location = new Point(270, 113);
|
||||||
|
btnRefresh.Name = "btnRefresh";
|
||||||
|
btnRefresh.Size = new Size(56, 23);
|
||||||
|
btnRefresh.TabIndex = 10;
|
||||||
|
btnRefresh.Text = "Refresh";
|
||||||
|
btnRefresh.UseVisualStyleBackColor = true;
|
||||||
|
btnRefresh.Click += btnRefresh_Click;
|
||||||
|
//
|
||||||
|
// StockMarketGame
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
BackColor = Color.DodgerBlue;
|
||||||
|
ClientSize = new Size(595, 227);
|
||||||
|
Controls.Add(btnRefresh);
|
||||||
|
Controls.Add(pMarketStatus);
|
||||||
|
Controls.Add(pStockManagement);
|
||||||
|
ForeColor = Color.White;
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
Name = "StockMarketGame";
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
Text = "QtC.NET qGame - Stock Market";
|
||||||
|
Load += StockMarketGame_Load;
|
||||||
|
pStockManagement.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)nudStockBuySellAmount).EndInit();
|
||||||
|
pMarketStatus.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbDollarSignRight).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbDollarSignLeft).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Panel pStockManagement;
|
||||||
|
private Button btnSell;
|
||||||
|
private Button btnBuy;
|
||||||
|
private Label lblStockCount;
|
||||||
|
private Panel pMarketStatus;
|
||||||
|
private Label lblCurrentStockPrice;
|
||||||
|
private Label lblMarketStatus;
|
||||||
|
private PictureBox pbDollarSignRight;
|
||||||
|
private PictureBox pbDollarSignLeft;
|
||||||
|
private Button btnRefresh;
|
||||||
|
private NumericUpDown nudStockBuySellAmount;
|
||||||
|
}
|
||||||
|
}
|
151
qtc-net-client-2/Forms/StockMarketGame.cs
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
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 StockMarketGame : Form
|
||||||
|
{
|
||||||
|
private IApiService _apiService;
|
||||||
|
private int StockPrice = 0;
|
||||||
|
public StockMarketGame(IApiService apiService)
|
||||||
|
{
|
||||||
|
_apiService = apiService;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void StockMarketGame_Load(object sender, EventArgs e) => await InitializeStockMarketGame();
|
||||||
|
private async void btnRefresh_Click(object sender, EventArgs e) => await InitializeStockMarketGame();
|
||||||
|
|
||||||
|
private async void btnBuy_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (nudStockBuySellAmount.Value > 0)
|
||||||
|
{
|
||||||
|
nudStockBuySellAmount.Enabled = false;
|
||||||
|
btnBuy.Enabled = false;
|
||||||
|
btnSell.Enabled = false;
|
||||||
|
btnRefresh.Enabled = false;
|
||||||
|
|
||||||
|
// buy stock
|
||||||
|
var amountToBuy = int.Parse(nudStockBuySellAmount.Value.ToString());
|
||||||
|
var result = await _apiService.BuyStock(amountToBuy);
|
||||||
|
|
||||||
|
if (result != null && result.Success && result.Data != null)
|
||||||
|
{
|
||||||
|
lblStockCount.Text = $"Your Stock Count - {result.Data.StockAmount}";
|
||||||
|
|
||||||
|
_apiService.CurrentUser.StockAmount = result.Data.StockAmount;
|
||||||
|
_apiService.CurrentUser.CurrencyAmount = result.Data.CurrencyAmount;
|
||||||
|
|
||||||
|
nudStockBuySellAmount.Enabled = true;
|
||||||
|
nudStockBuySellAmount.Value = 0;
|
||||||
|
btnBuy.Enabled = true;
|
||||||
|
btnSell.Enabled = true;
|
||||||
|
btnRefresh.Enabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Buy Failed. Either You Don't Have Enough Q's Or A Server Side Error Occured.", "Oops.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
nudStockBuySellAmount.Enabled = true;
|
||||||
|
nudStockBuySellAmount.Value = 0;
|
||||||
|
btnBuy.Enabled = true;
|
||||||
|
btnSell.Enabled = true;
|
||||||
|
btnRefresh.Enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnSell_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(nudStockBuySellAmount.Value > 0)
|
||||||
|
{
|
||||||
|
nudStockBuySellAmount.Enabled = false;
|
||||||
|
btnBuy.Enabled = false;
|
||||||
|
btnSell.Enabled = false;
|
||||||
|
btnRefresh.Enabled = false;
|
||||||
|
|
||||||
|
// sell stock
|
||||||
|
var amountToSell = int.Parse(nudStockBuySellAmount.Value.ToString());
|
||||||
|
var result = await _apiService.SellStock(amountToSell);
|
||||||
|
|
||||||
|
if (result != null && result.Success && result.Data != null)
|
||||||
|
{
|
||||||
|
lblStockCount.Text = $"Your Stock Count - {result.Data.StockAmount}";
|
||||||
|
|
||||||
|
_apiService.CurrentUser.StockAmount = result.Data.StockAmount;
|
||||||
|
_apiService.CurrentUser.CurrencyAmount = result.Data.CurrencyAmount;
|
||||||
|
|
||||||
|
nudStockBuySellAmount.Enabled = true;
|
||||||
|
nudStockBuySellAmount.Value = 0;
|
||||||
|
btnBuy.Enabled = true;
|
||||||
|
btnSell.Enabled = true;
|
||||||
|
btnRefresh.Enabled = true;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Sell Failed. Either You Don't Have Enough Stock Or A Server Side Error Occured.", "Oops.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
nudStockBuySellAmount.Enabled = true;
|
||||||
|
nudStockBuySellAmount.Value = 0;
|
||||||
|
btnBuy.Enabled = true;
|
||||||
|
btnSell.Enabled = true;
|
||||||
|
btnRefresh.Enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task InitializeStockMarketGame()
|
||||||
|
{
|
||||||
|
var currentStockPriceResult = await _apiService.GetCurrentStockPrice();
|
||||||
|
|
||||||
|
if (currentStockPriceResult != null && currentStockPriceResult.Success)
|
||||||
|
{
|
||||||
|
lblCurrentStockPrice.Text = $"Current Price Per Stock Is {currentStockPriceResult.Data} Q's";
|
||||||
|
lblStockCount.Text = $"Your Stock Count - {_apiService.CurrentUser.StockAmount}";
|
||||||
|
|
||||||
|
switch (currentStockPriceResult.Data)
|
||||||
|
{
|
||||||
|
case < 49:
|
||||||
|
lblMarketStatus.Text = "not good cheif :(";
|
||||||
|
lblMarketStatus.ForeColor = Color.Red;
|
||||||
|
break;
|
||||||
|
case < 99:
|
||||||
|
lblMarketStatus.Text = "its aight :/";
|
||||||
|
lblMarketStatus.ForeColor = Color.DarkGreen;
|
||||||
|
break;
|
||||||
|
case < 149:
|
||||||
|
lblMarketStatus.Text = "its good :)";
|
||||||
|
lblMarketStatus.ForeColor = Color.Green;
|
||||||
|
break;
|
||||||
|
case < 199:
|
||||||
|
lblMarketStatus.Text = "very good :D";
|
||||||
|
lblMarketStatus.ForeColor = Color.Blue;
|
||||||
|
break;
|
||||||
|
case > 200:
|
||||||
|
lblMarketStatus.Text = "$ AWESOME $";
|
||||||
|
lblMarketStatus.ForeColor = Color.LightGreen;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
lblMarketStatus.Text = "Cannot Determine";
|
||||||
|
lblMarketStatus.ForeColor = Color.White;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nudStockBuySellAmount.Enabled = true;
|
||||||
|
btnBuy.Enabled = true;
|
||||||
|
btnSell.Enabled = true;
|
||||||
|
btnRefresh.Enabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("The Stock Market Endpoint Could Not Be Reached. Please Check Your Internet Connection", "Uh Oh.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
qtc-net-client-2/Forms/StockMarketGame.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>
|
135
qtc-net-client-2/Forms/StoreItemDisplay.Designer.cs
generated
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
namespace qtc_net_client_2.Forms
|
||||||
|
{
|
||||||
|
partial class StoreItemDisplay
|
||||||
|
{
|
||||||
|
/// <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()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(StoreItemDisplay));
|
||||||
|
pbItemThumbnail = new PictureBox();
|
||||||
|
lblName = new Label();
|
||||||
|
lblDescription = new Label();
|
||||||
|
btnBuy = new Button();
|
||||||
|
pbCurrencyIcon = new PictureBox();
|
||||||
|
lblPrice = new Label();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbItemThumbnail).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbCurrencyIcon).BeginInit();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// pbItemThumbnail
|
||||||
|
//
|
||||||
|
pbItemThumbnail.Location = new Point(12, 12);
|
||||||
|
pbItemThumbnail.Name = "pbItemThumbnail";
|
||||||
|
pbItemThumbnail.Size = new Size(148, 141);
|
||||||
|
pbItemThumbnail.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
pbItemThumbnail.TabIndex = 0;
|
||||||
|
pbItemThumbnail.TabStop = false;
|
||||||
|
//
|
||||||
|
// lblName
|
||||||
|
//
|
||||||
|
lblName.AutoSize = true;
|
||||||
|
lblName.Font = new Font("Segoe UI", 21.75F, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point, 0);
|
||||||
|
lblName.Location = new Point(165, 7);
|
||||||
|
lblName.Name = "lblName";
|
||||||
|
lblName.Size = new Size(239, 40);
|
||||||
|
lblName.TabIndex = 1;
|
||||||
|
lblName.Text = "Item Name Here";
|
||||||
|
//
|
||||||
|
// lblDescription
|
||||||
|
//
|
||||||
|
lblDescription.Location = new Point(169, 44);
|
||||||
|
lblDescription.Name = "lblDescription";
|
||||||
|
lblDescription.Size = new Size(448, 109);
|
||||||
|
lblDescription.TabIndex = 2;
|
||||||
|
lblDescription.Text = resources.GetString("lblDescription.Text");
|
||||||
|
//
|
||||||
|
// btnBuy
|
||||||
|
//
|
||||||
|
btnBuy.ForeColor = Color.Black;
|
||||||
|
btnBuy.Location = new Point(542, 157);
|
||||||
|
btnBuy.Name = "btnBuy";
|
||||||
|
btnBuy.Size = new Size(75, 23);
|
||||||
|
btnBuy.TabIndex = 3;
|
||||||
|
btnBuy.Text = "Buy";
|
||||||
|
btnBuy.UseVisualStyleBackColor = true;
|
||||||
|
btnBuy.Click += btnBuy_Click;
|
||||||
|
//
|
||||||
|
// pbCurrencyIcon
|
||||||
|
//
|
||||||
|
pbCurrencyIcon.Image = Properties.Resources.CurrencyIcon;
|
||||||
|
pbCurrencyIcon.Location = new Point(48, 161);
|
||||||
|
pbCurrencyIcon.Name = "pbCurrencyIcon";
|
||||||
|
pbCurrencyIcon.Size = new Size(15, 14);
|
||||||
|
pbCurrencyIcon.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
pbCurrencyIcon.TabIndex = 19;
|
||||||
|
pbCurrencyIcon.TabStop = false;
|
||||||
|
//
|
||||||
|
// lblPrice
|
||||||
|
//
|
||||||
|
lblPrice.AutoEllipsis = true;
|
||||||
|
lblPrice.Font = new Font("Segoe UI", 8F, FontStyle.Bold, GraphicsUnit.Point, 0);
|
||||||
|
lblPrice.Location = new Point(64, 162);
|
||||||
|
lblPrice.Name = "lblPrice";
|
||||||
|
lblPrice.Size = new Size(61, 13);
|
||||||
|
lblPrice.TabIndex = 20;
|
||||||
|
lblPrice.Text = "99,999,999";
|
||||||
|
//
|
||||||
|
// StoreItemDisplay
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
BackColor = Color.DodgerBlue;
|
||||||
|
ClientSize = new Size(629, 188);
|
||||||
|
Controls.Add(lblPrice);
|
||||||
|
Controls.Add(pbCurrencyIcon);
|
||||||
|
Controls.Add(btnBuy);
|
||||||
|
Controls.Add(lblDescription);
|
||||||
|
Controls.Add(lblName);
|
||||||
|
Controls.Add(pbItemThumbnail);
|
||||||
|
ForeColor = Color.White;
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
Name = "StoreItemDisplay";
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
Text = "QtC.NET Client - Store Item";
|
||||||
|
Load += StoreItemDisplay_Load;
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbItemThumbnail).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbCurrencyIcon).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private PictureBox pbItemThumbnail;
|
||||||
|
private Label lblName;
|
||||||
|
private Label lblDescription;
|
||||||
|
private Button btnBuy;
|
||||||
|
private PictureBox pbCurrencyIcon;
|
||||||
|
private Label lblPrice;
|
||||||
|
}
|
||||||
|
}
|
97
qtc-net-client-2/Forms/StoreItemDisplay.cs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
using QtCNETAPI.Dtos.User;
|
||||||
|
using QtCNETAPI.Schema;
|
||||||
|
using QtCNETAPI.Services;
|
||||||
|
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 StoreItemDisplay : Form
|
||||||
|
{
|
||||||
|
private StoreItem StoreItem { get; set; }
|
||||||
|
|
||||||
|
private LoggingService _loggingService;
|
||||||
|
private IApiService _apiService;
|
||||||
|
public StoreItemDisplay(StoreItem item, LoggingService loggingService, IApiService apiService)
|
||||||
|
{
|
||||||
|
StoreItem = item;
|
||||||
|
_loggingService = loggingService;
|
||||||
|
_apiService = apiService;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void StoreItemDisplay_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
lblName.Text = StoreItem.Name;
|
||||||
|
lblDescription.Text = StoreItem.Description;
|
||||||
|
lblPrice.Text = StoreItem.Price.ToString("N0");
|
||||||
|
|
||||||
|
// does the user already own this item?
|
||||||
|
var ownedItem = await _apiService.GetOwnedStoreItem(StoreItem.Id);
|
||||||
|
if (ownedItem != null && ownedItem.Success && ownedItem.Data != null)
|
||||||
|
{
|
||||||
|
btnBuy.Enabled = false;
|
||||||
|
btnBuy.Text = "Bought";
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using HttpClient client = new();
|
||||||
|
var response = await client.GetAsync(StoreItem.ThumbnailUrl);
|
||||||
|
if (response != null && response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
using var stream = await response.Content.ReadAsStreamAsync();
|
||||||
|
Image image = Image.FromStream(stream);
|
||||||
|
stream.Dispose();
|
||||||
|
pbItemThumbnail.Image = image;
|
||||||
|
}
|
||||||
|
else if (response != null) _loggingService.LogString($"Store Item Thumbnail Could Not Be Loaded Due To Status Code {response.StatusCode}");
|
||||||
|
else _loggingService.LogString("Store Item Thumbnail Could Not Be Loaded");
|
||||||
|
client.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_loggingService.LogString("Store Item Thumbnail Could Not Be Loaded\n" + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnBuy_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Enabled = false;
|
||||||
|
|
||||||
|
// attempt to buy item
|
||||||
|
var ownedStoreItem = await _apiService.BuyStoreItem(StoreItem.Id);
|
||||||
|
if (ownedStoreItem != null && ownedStoreItem.Success)
|
||||||
|
{
|
||||||
|
Enabled = true;
|
||||||
|
|
||||||
|
var result = MessageBox.Show($"Successfully Bought '{StoreItem.Name}'! Would You Like To Wear It Now?", "Success!", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||||
|
if (result == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
// send an update dto that only updates the current users cosmetic
|
||||||
|
UserUpdateInformationDto updateDto = new UserUpdateInformationDto
|
||||||
|
{
|
||||||
|
Id = _apiService.CurrentUser.Id,
|
||||||
|
Bio = _apiService.CurrentUser.Bio,
|
||||||
|
DateOfBirth = _apiService.CurrentUser.DateOfBirth,
|
||||||
|
Username = _apiService.CurrentUser.Username,
|
||||||
|
ProfileCosmeticId = StoreItem.Id
|
||||||
|
};
|
||||||
|
|
||||||
|
await _apiService.UpdateUserInformationAsync(updateDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else MessageBox.Show("We Weren't Able To Complete Your Purchase.\nYou May Not Have Enough Funds For This Item.", "Oops.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
123
qtc-net-client-2/Forms/StoreItemDisplay.resx
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<?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>
|
||||||
|
<data name="lblDescription.Text" xml:space="preserve">
|
||||||
|
<value>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
457
qtc-net-client-2/Forms/TicTacToeGame.Designer.cs
generated
Normal file
@ -0,0 +1,457 @@
|
|||||||
|
namespace qtc_net_client_2
|
||||||
|
{
|
||||||
|
partial class TicTacToeGame
|
||||||
|
{
|
||||||
|
/// <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()
|
||||||
|
{
|
||||||
|
pBoard = new Panel();
|
||||||
|
btnSquare9 = new Button();
|
||||||
|
btnSquare1 = new Button();
|
||||||
|
btnSquare7 = new Button();
|
||||||
|
btnSquare8 = new Button();
|
||||||
|
btnSquare6 = new Button();
|
||||||
|
btnSquare4 = new Button();
|
||||||
|
btnSquare5 = new Button();
|
||||||
|
btnSquare3 = new Button();
|
||||||
|
btnSquare2 = new Button();
|
||||||
|
pbBoard = new PictureBox();
|
||||||
|
pSymbolSelection = new Panel();
|
||||||
|
btnOSelect = new Button();
|
||||||
|
btnXSelect = new Button();
|
||||||
|
label1 = new Label();
|
||||||
|
pLoading = new Panel();
|
||||||
|
btnPlayAgain = new Button();
|
||||||
|
lblPlayAgain = new Label();
|
||||||
|
lblLoadStatus = new Label();
|
||||||
|
lblPlayerOne = new Label();
|
||||||
|
lblP1Username = new Label();
|
||||||
|
lblP2Username = new Label();
|
||||||
|
lblPlayerTwo = new Label();
|
||||||
|
lvUserlist = new ListView();
|
||||||
|
rtxtChatbox = new RichTextBox();
|
||||||
|
btnSend = new Button();
|
||||||
|
rtxtChat = new RichTextBox();
|
||||||
|
lblJackpotWon = new Label();
|
||||||
|
pBoard.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbBoard).BeginInit();
|
||||||
|
pSymbolSelection.SuspendLayout();
|
||||||
|
pLoading.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// pBoard
|
||||||
|
//
|
||||||
|
pBoard.Controls.Add(btnSquare9);
|
||||||
|
pBoard.Controls.Add(btnSquare1);
|
||||||
|
pBoard.Controls.Add(btnSquare7);
|
||||||
|
pBoard.Controls.Add(btnSquare8);
|
||||||
|
pBoard.Controls.Add(btnSquare6);
|
||||||
|
pBoard.Controls.Add(btnSquare4);
|
||||||
|
pBoard.Controls.Add(btnSquare5);
|
||||||
|
pBoard.Controls.Add(btnSquare3);
|
||||||
|
pBoard.Controls.Add(btnSquare2);
|
||||||
|
pBoard.Controls.Add(pbBoard);
|
||||||
|
pBoard.Enabled = false;
|
||||||
|
pBoard.Location = new Point(30, 18);
|
||||||
|
pBoard.Name = "pBoard";
|
||||||
|
pBoard.Size = new Size(541, 474);
|
||||||
|
pBoard.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// btnSquare9
|
||||||
|
//
|
||||||
|
btnSquare9.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnSquare9.FlatAppearance.BorderSize = 0;
|
||||||
|
btnSquare9.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnSquare9.Location = new Point(374, 341);
|
||||||
|
btnSquare9.Name = "btnSquare9";
|
||||||
|
btnSquare9.Size = new Size(99, 90);
|
||||||
|
btnSquare9.TabIndex = 11;
|
||||||
|
btnSquare9.UseVisualStyleBackColor = true;
|
||||||
|
btnSquare9.Click += btnSquareX_Click;
|
||||||
|
//
|
||||||
|
// btnSquare1
|
||||||
|
//
|
||||||
|
btnSquare1.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnSquare1.FlatAppearance.BorderSize = 0;
|
||||||
|
btnSquare1.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnSquare1.Location = new Point(79, 49);
|
||||||
|
btnSquare1.Name = "btnSquare1";
|
||||||
|
btnSquare1.Size = new Size(99, 90);
|
||||||
|
btnSquare1.TabIndex = 4;
|
||||||
|
btnSquare1.UseVisualStyleBackColor = true;
|
||||||
|
btnSquare1.Click += btnSquareX_Click;
|
||||||
|
//
|
||||||
|
// btnSquare7
|
||||||
|
//
|
||||||
|
btnSquare7.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnSquare7.FlatAppearance.BorderSize = 0;
|
||||||
|
btnSquare7.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnSquare7.Location = new Point(79, 341);
|
||||||
|
btnSquare7.Name = "btnSquare7";
|
||||||
|
btnSquare7.Size = new Size(99, 90);
|
||||||
|
btnSquare7.TabIndex = 10;
|
||||||
|
btnSquare7.UseVisualStyleBackColor = true;
|
||||||
|
btnSquare7.Click += btnSquareX_Click;
|
||||||
|
//
|
||||||
|
// btnSquare8
|
||||||
|
//
|
||||||
|
btnSquare8.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnSquare8.FlatAppearance.BorderSize = 0;
|
||||||
|
btnSquare8.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnSquare8.Location = new Point(229, 341);
|
||||||
|
btnSquare8.Name = "btnSquare8";
|
||||||
|
btnSquare8.Size = new Size(99, 90);
|
||||||
|
btnSquare8.TabIndex = 9;
|
||||||
|
btnSquare8.UseVisualStyleBackColor = true;
|
||||||
|
btnSquare8.Click += btnSquareX_Click;
|
||||||
|
//
|
||||||
|
// btnSquare6
|
||||||
|
//
|
||||||
|
btnSquare6.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnSquare6.FlatAppearance.BorderSize = 0;
|
||||||
|
btnSquare6.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnSquare6.Location = new Point(374, 195);
|
||||||
|
btnSquare6.Name = "btnSquare6";
|
||||||
|
btnSquare6.Size = new Size(99, 90);
|
||||||
|
btnSquare6.TabIndex = 8;
|
||||||
|
btnSquare6.UseVisualStyleBackColor = true;
|
||||||
|
btnSquare6.Click += btnSquareX_Click;
|
||||||
|
//
|
||||||
|
// btnSquare4
|
||||||
|
//
|
||||||
|
btnSquare4.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnSquare4.FlatAppearance.BorderSize = 0;
|
||||||
|
btnSquare4.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnSquare4.Location = new Point(79, 195);
|
||||||
|
btnSquare4.Name = "btnSquare4";
|
||||||
|
btnSquare4.Size = new Size(99, 90);
|
||||||
|
btnSquare4.TabIndex = 7;
|
||||||
|
btnSquare4.UseVisualStyleBackColor = true;
|
||||||
|
btnSquare4.Click += btnSquareX_Click;
|
||||||
|
//
|
||||||
|
// btnSquare5
|
||||||
|
//
|
||||||
|
btnSquare5.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnSquare5.FlatAppearance.BorderSize = 0;
|
||||||
|
btnSquare5.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnSquare5.Location = new Point(229, 195);
|
||||||
|
btnSquare5.Name = "btnSquare5";
|
||||||
|
btnSquare5.Size = new Size(99, 90);
|
||||||
|
btnSquare5.TabIndex = 6;
|
||||||
|
btnSquare5.UseVisualStyleBackColor = true;
|
||||||
|
btnSquare5.Click += btnSquareX_Click;
|
||||||
|
//
|
||||||
|
// btnSquare3
|
||||||
|
//
|
||||||
|
btnSquare3.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnSquare3.FlatAppearance.BorderSize = 0;
|
||||||
|
btnSquare3.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnSquare3.Location = new Point(374, 49);
|
||||||
|
btnSquare3.Name = "btnSquare3";
|
||||||
|
btnSquare3.Size = new Size(99, 90);
|
||||||
|
btnSquare3.TabIndex = 5;
|
||||||
|
btnSquare3.UseVisualStyleBackColor = true;
|
||||||
|
btnSquare3.Click += btnSquareX_Click;
|
||||||
|
//
|
||||||
|
// btnSquare2
|
||||||
|
//
|
||||||
|
btnSquare2.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnSquare2.FlatAppearance.BorderSize = 0;
|
||||||
|
btnSquare2.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnSquare2.Location = new Point(229, 49);
|
||||||
|
btnSquare2.Name = "btnSquare2";
|
||||||
|
btnSquare2.Size = new Size(99, 90);
|
||||||
|
btnSquare2.TabIndex = 3;
|
||||||
|
btnSquare2.UseVisualStyleBackColor = true;
|
||||||
|
btnSquare2.Click += btnSquareX_Click;
|
||||||
|
//
|
||||||
|
// pbBoard
|
||||||
|
//
|
||||||
|
pbBoard.Image = Properties.Resources.Tic_tac_toe;
|
||||||
|
pbBoard.Location = new Point(27, 15);
|
||||||
|
pbBoard.Name = "pbBoard";
|
||||||
|
pbBoard.Size = new Size(501, 444);
|
||||||
|
pbBoard.SizeMode = PictureBoxSizeMode.Zoom;
|
||||||
|
pbBoard.TabIndex = 0;
|
||||||
|
pbBoard.TabStop = false;
|
||||||
|
//
|
||||||
|
// pSymbolSelection
|
||||||
|
//
|
||||||
|
pSymbolSelection.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
pSymbolSelection.Controls.Add(btnOSelect);
|
||||||
|
pSymbolSelection.Controls.Add(btnXSelect);
|
||||||
|
pSymbolSelection.Controls.Add(label1);
|
||||||
|
pSymbolSelection.Location = new Point(161, 109);
|
||||||
|
pSymbolSelection.Name = "pSymbolSelection";
|
||||||
|
pSymbolSelection.Size = new Size(275, 255);
|
||||||
|
pSymbolSelection.TabIndex = 3;
|
||||||
|
pSymbolSelection.Visible = false;
|
||||||
|
//
|
||||||
|
// btnOSelect
|
||||||
|
//
|
||||||
|
btnOSelect.BackgroundImage = Properties.Resources.O;
|
||||||
|
btnOSelect.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnOSelect.FlatAppearance.BorderSize = 0;
|
||||||
|
btnOSelect.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnOSelect.Location = new Point(157, 104);
|
||||||
|
btnOSelect.Name = "btnOSelect";
|
||||||
|
btnOSelect.Size = new Size(91, 89);
|
||||||
|
btnOSelect.TabIndex = 2;
|
||||||
|
btnOSelect.UseVisualStyleBackColor = true;
|
||||||
|
btnOSelect.Click += btnOSelect_Click;
|
||||||
|
//
|
||||||
|
// btnXSelect
|
||||||
|
//
|
||||||
|
btnXSelect.BackgroundImage = Properties.Resources.X;
|
||||||
|
btnXSelect.BackgroundImageLayout = ImageLayout.Stretch;
|
||||||
|
btnXSelect.FlatAppearance.BorderSize = 0;
|
||||||
|
btnXSelect.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnXSelect.Location = new Point(34, 103);
|
||||||
|
btnXSelect.Name = "btnXSelect";
|
||||||
|
btnXSelect.Size = new Size(91, 89);
|
||||||
|
btnXSelect.TabIndex = 1;
|
||||||
|
btnXSelect.UseVisualStyleBackColor = true;
|
||||||
|
btnXSelect.Click += btnXSelect_Click;
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.Font = new Font("Segoe UI", 15F, FontStyle.Bold, GraphicsUnit.Point, 0);
|
||||||
|
label1.ForeColor = Color.White;
|
||||||
|
label1.Location = new Point(11, 14);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(250, 49);
|
||||||
|
label1.TabIndex = 0;
|
||||||
|
label1.Text = "Please Select Symbol";
|
||||||
|
label1.TextAlign = ContentAlignment.MiddleCenter;
|
||||||
|
//
|
||||||
|
// pLoading
|
||||||
|
//
|
||||||
|
pLoading.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
pLoading.Controls.Add(btnPlayAgain);
|
||||||
|
pLoading.Controls.Add(lblPlayAgain);
|
||||||
|
pLoading.Controls.Add(lblLoadStatus);
|
||||||
|
pLoading.Location = new Point(161, 109);
|
||||||
|
pLoading.Name = "pLoading";
|
||||||
|
pLoading.Size = new Size(275, 255);
|
||||||
|
pLoading.TabIndex = 2;
|
||||||
|
pLoading.Visible = false;
|
||||||
|
//
|
||||||
|
// btnPlayAgain
|
||||||
|
//
|
||||||
|
btnPlayAgain.Location = new Point(97, 223);
|
||||||
|
btnPlayAgain.Name = "btnPlayAgain";
|
||||||
|
btnPlayAgain.Size = new Size(75, 23);
|
||||||
|
btnPlayAgain.TabIndex = 2;
|
||||||
|
btnPlayAgain.Text = "Play Again";
|
||||||
|
btnPlayAgain.UseVisualStyleBackColor = true;
|
||||||
|
btnPlayAgain.Visible = false;
|
||||||
|
btnPlayAgain.Click += btnPlayAgain_Click;
|
||||||
|
//
|
||||||
|
// lblPlayAgain
|
||||||
|
//
|
||||||
|
lblPlayAgain.ForeColor = Color.White;
|
||||||
|
lblPlayAgain.Location = new Point(28, 134);
|
||||||
|
lblPlayAgain.Name = "lblPlayAgain";
|
||||||
|
lblPlayAgain.Size = new Size(218, 86);
|
||||||
|
lblPlayAgain.TabIndex = 1;
|
||||||
|
lblPlayAgain.Text = "If you wish to play with a different user, you can close\r\nthis window and match up again. Otherwise click\r\n\"Play Again\"";
|
||||||
|
lblPlayAgain.TextAlign = ContentAlignment.MiddleCenter;
|
||||||
|
lblPlayAgain.Visible = false;
|
||||||
|
//
|
||||||
|
// lblLoadStatus
|
||||||
|
//
|
||||||
|
lblLoadStatus.Font = new Font("Segoe UI", 21.75F, FontStyle.Bold, GraphicsUnit.Point, 0);
|
||||||
|
lblLoadStatus.ForeColor = Color.White;
|
||||||
|
lblLoadStatus.Location = new Point(11, 4);
|
||||||
|
lblLoadStatus.Name = "lblLoadStatus";
|
||||||
|
lblLoadStatus.Size = new Size(250, 130);
|
||||||
|
lblLoadStatus.TabIndex = 0;
|
||||||
|
lblLoadStatus.Text = "Text";
|
||||||
|
lblLoadStatus.TextAlign = ContentAlignment.MiddleCenter;
|
||||||
|
//
|
||||||
|
// lblPlayerOne
|
||||||
|
//
|
||||||
|
lblPlayerOne.Font = new Font("Segoe UI", 12F, FontStyle.Bold | FontStyle.Italic);
|
||||||
|
lblPlayerOne.ForeColor = Color.White;
|
||||||
|
lblPlayerOne.Location = new Point(30, 501);
|
||||||
|
lblPlayerOne.Name = "lblPlayerOne";
|
||||||
|
lblPlayerOne.Size = new Size(29, 23);
|
||||||
|
lblPlayerOne.TabIndex = 2;
|
||||||
|
lblPlayerOne.Text = "P1";
|
||||||
|
//
|
||||||
|
// lblP1Username
|
||||||
|
//
|
||||||
|
lblP1Username.AutoSize = true;
|
||||||
|
lblP1Username.Font = new Font("Segoe UI", 15F, FontStyle.Bold | FontStyle.Italic);
|
||||||
|
lblP1Username.ForeColor = Color.White;
|
||||||
|
lblP1Username.Location = new Point(26, 519);
|
||||||
|
lblP1Username.Name = "lblP1Username";
|
||||||
|
lblP1Username.Size = new Size(105, 28);
|
||||||
|
lblP1Username.TabIndex = 3;
|
||||||
|
lblP1Username.Text = "Username";
|
||||||
|
//
|
||||||
|
// lblP2Username
|
||||||
|
//
|
||||||
|
lblP2Username.AutoSize = true;
|
||||||
|
lblP2Username.Font = new Font("Segoe UI", 15F, FontStyle.Bold | FontStyle.Italic);
|
||||||
|
lblP2Username.ForeColor = Color.White;
|
||||||
|
lblP2Username.Location = new Point(466, 519);
|
||||||
|
lblP2Username.Name = "lblP2Username";
|
||||||
|
lblP2Username.Size = new Size(105, 28);
|
||||||
|
lblP2Username.TabIndex = 5;
|
||||||
|
lblP2Username.Text = "Username";
|
||||||
|
lblP2Username.TextAlign = ContentAlignment.MiddleRight;
|
||||||
|
//
|
||||||
|
// lblPlayerTwo
|
||||||
|
//
|
||||||
|
lblPlayerTwo.Font = new Font("Segoe UI", 12F, FontStyle.Bold | FontStyle.Italic);
|
||||||
|
lblPlayerTwo.ForeColor = Color.White;
|
||||||
|
lblPlayerTwo.Location = new Point(540, 501);
|
||||||
|
lblPlayerTwo.Name = "lblPlayerTwo";
|
||||||
|
lblPlayerTwo.Size = new Size(29, 23);
|
||||||
|
lblPlayerTwo.TabIndex = 4;
|
||||||
|
lblPlayerTwo.Text = "P2";
|
||||||
|
//
|
||||||
|
// lvUserlist
|
||||||
|
//
|
||||||
|
lvUserlist.Alignment = ListViewAlignment.Left;
|
||||||
|
lvUserlist.Location = new Point(577, 48);
|
||||||
|
lvUserlist.MultiSelect = false;
|
||||||
|
lvUserlist.Name = "lvUserlist";
|
||||||
|
lvUserlist.Size = new Size(309, 211);
|
||||||
|
lvUserlist.TabIndex = 6;
|
||||||
|
lvUserlist.UseCompatibleStateImageBehavior = false;
|
||||||
|
lvUserlist.View = View.SmallIcon;
|
||||||
|
//
|
||||||
|
// rtxtChatbox
|
||||||
|
//
|
||||||
|
rtxtChatbox.Location = new Point(577, 497);
|
||||||
|
rtxtChatbox.Name = "rtxtChatbox";
|
||||||
|
rtxtChatbox.Size = new Size(230, 49);
|
||||||
|
rtxtChatbox.TabIndex = 8;
|
||||||
|
rtxtChatbox.Text = "";
|
||||||
|
rtxtChatbox.KeyDown += rtxtChatbox_KeyDown;
|
||||||
|
//
|
||||||
|
// btnSend
|
||||||
|
//
|
||||||
|
btnSend.BackgroundImage = Properties.Resources.SendIcon;
|
||||||
|
btnSend.BackgroundImageLayout = ImageLayout.Zoom;
|
||||||
|
btnSend.FlatAppearance.BorderSize = 0;
|
||||||
|
btnSend.FlatStyle = FlatStyle.Flat;
|
||||||
|
btnSend.Location = new Point(811, 497);
|
||||||
|
btnSend.Name = "btnSend";
|
||||||
|
btnSend.Size = new Size(75, 50);
|
||||||
|
btnSend.TabIndex = 9;
|
||||||
|
btnSend.UseVisualStyleBackColor = true;
|
||||||
|
btnSend.Click += btnSend_Click;
|
||||||
|
//
|
||||||
|
// rtxtChat
|
||||||
|
//
|
||||||
|
rtxtChat.Font = new Font("Segoe UI", 10F);
|
||||||
|
rtxtChat.HideSelection = false;
|
||||||
|
rtxtChat.Location = new Point(577, 265);
|
||||||
|
rtxtChat.Name = "rtxtChat";
|
||||||
|
rtxtChat.ReadOnly = true;
|
||||||
|
rtxtChat.Size = new Size(309, 227);
|
||||||
|
rtxtChat.TabIndex = 10;
|
||||||
|
rtxtChat.Text = "";
|
||||||
|
//
|
||||||
|
// lblJackpotWon
|
||||||
|
//
|
||||||
|
lblJackpotWon.AutoSize = true;
|
||||||
|
lblJackpotWon.Font = new Font("Segoe UI", 12F, FontStyle.Bold | FontStyle.Italic);
|
||||||
|
lblJackpotWon.ForeColor = Color.Blue;
|
||||||
|
lblJackpotWon.Location = new Point(744, 18);
|
||||||
|
lblJackpotWon.Name = "lblJackpotWon";
|
||||||
|
lblJackpotWon.Size = new Size(142, 21);
|
||||||
|
lblJackpotWon.TabIndex = 11;
|
||||||
|
lblJackpotWon.Text = "3 Wins = Jackpot!";
|
||||||
|
//
|
||||||
|
// TicTacToeGame
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
BackColor = Color.DodgerBlue;
|
||||||
|
ClientSize = new Size(898, 558);
|
||||||
|
Controls.Add(lblJackpotWon);
|
||||||
|
Controls.Add(rtxtChat);
|
||||||
|
Controls.Add(btnSend);
|
||||||
|
Controls.Add(rtxtChatbox);
|
||||||
|
Controls.Add(lvUserlist);
|
||||||
|
Controls.Add(lblP2Username);
|
||||||
|
Controls.Add(lblPlayerTwo);
|
||||||
|
Controls.Add(lblP1Username);
|
||||||
|
Controls.Add(lblPlayerOne);
|
||||||
|
Controls.Add(pLoading);
|
||||||
|
Controls.Add(pSymbolSelection);
|
||||||
|
Controls.Add(pBoard);
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
Name = "TicTacToeGame";
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
Text = "QtC.NET qGame - qTic-Tac-Toe";
|
||||||
|
FormClosed += TicTacToeGame_FormClosed;
|
||||||
|
Load += Main_Load;
|
||||||
|
pBoard.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbBoard).EndInit();
|
||||||
|
pSymbolSelection.ResumeLayout(false);
|
||||||
|
pLoading.ResumeLayout(false);
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Panel pBoard;
|
||||||
|
private PictureBox pbBoard;
|
||||||
|
private Button btnSquare9;
|
||||||
|
private Button btnSquare7;
|
||||||
|
private Button btnSquare8;
|
||||||
|
private Button btnSquare6;
|
||||||
|
private Button btnSquare4;
|
||||||
|
private Button btnSquare5;
|
||||||
|
private Button btnSquare3;
|
||||||
|
private Button btnSquare1;
|
||||||
|
private Button btnSquare2;
|
||||||
|
private Panel pLoading;
|
||||||
|
private Label lblLoadStatus;
|
||||||
|
private Label lblPlayerOne;
|
||||||
|
private Label lblP1Username;
|
||||||
|
private Label lblP2Username;
|
||||||
|
private Label lblPlayerTwo;
|
||||||
|
private Panel pSymbolSelection;
|
||||||
|
private Button btnOSelect;
|
||||||
|
private Button btnXSelect;
|
||||||
|
private Label label1;
|
||||||
|
private ListView lvUserlist;
|
||||||
|
private RichTextBox rtxtChatbox;
|
||||||
|
private Button btnSend;
|
||||||
|
private Label lblPlayAgain;
|
||||||
|
private Button btnPlayAgain;
|
||||||
|
private RichTextBox rtxtChat;
|
||||||
|
private Label lblJackpotWon;
|
||||||
|
}
|
||||||
|
}
|
520
qtc-net-client-2/Forms/TicTacToeGame.cs
Normal file
@ -0,0 +1,520 @@
|
|||||||
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
using qtc_net_client_2.Forms;
|
||||||
|
using qtc_net_client_2.Services;
|
||||||
|
using QtCNETAPI.Enums;
|
||||||
|
using QtCNETAPI.Models;
|
||||||
|
using QtCNETAPI.Schema;
|
||||||
|
using QtCNETAPI.Services.ApiService;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using qtc_net_client_2.ClientModel;
|
||||||
|
|
||||||
|
namespace qtc_net_client_2
|
||||||
|
{
|
||||||
|
public partial class TicTacToeGame : Form
|
||||||
|
{
|
||||||
|
private HubConnection? GameHubConnection { get; set; }
|
||||||
|
private GameRoom? CurrentRoom { get; set; }
|
||||||
|
|
||||||
|
private IApiService _apiService;
|
||||||
|
private Config _config;
|
||||||
|
private AudioService _audioService = new();
|
||||||
|
|
||||||
|
private int WinCount { get; set; }
|
||||||
|
private bool JackpotWon { get; set; } = false;
|
||||||
|
public TicTacToeGame(IApiService apiService, Config config)
|
||||||
|
{
|
||||||
|
_apiService = apiService;
|
||||||
|
_config = config;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void Main_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// first, connect to the game hub
|
||||||
|
GameHubConnection = new HubConnectionBuilder()
|
||||||
|
.WithUrl($"{_config.ServerUrl}/tttgame", options =>
|
||||||
|
{
|
||||||
|
options.AccessTokenProvider = () => Task.FromResult(_apiService.SessionToken)!;
|
||||||
|
})
|
||||||
|
.WithAutomaticReconnect()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
pLoading.Visible = true;
|
||||||
|
lblLoadStatus.Text = "Connecting\nTo\nHub...";
|
||||||
|
|
||||||
|
GameHubConnection.On<GameRoom>("WaitingForPlayer", (room) =>
|
||||||
|
{
|
||||||
|
CurrentRoom = room;
|
||||||
|
|
||||||
|
BeginInvoke(delegate ()
|
||||||
|
{
|
||||||
|
if (room.Player1 != null)
|
||||||
|
{
|
||||||
|
lblP1Username.Text = room.Player1.Username;
|
||||||
|
lvUserlist.Items.Add(room.Player1.Id, room.Player1.Username, room.Player1.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
lblLoadStatus.Text = "Waiting\nFor\nPlayer...";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
GameHubConnection.On<GameRoom>("GameStart", (room) =>
|
||||||
|
{
|
||||||
|
CurrentRoom = room;
|
||||||
|
|
||||||
|
BeginInvoke(delegate ()
|
||||||
|
{
|
||||||
|
pLoading.Visible = false;
|
||||||
|
pSymbolSelection.Visible = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
GameHubConnection.On<GameRoom, string?>("GameEnd", (room, usernameDisconnected) =>
|
||||||
|
{
|
||||||
|
CurrentRoom = room;
|
||||||
|
|
||||||
|
BeginInvoke(delegate ()
|
||||||
|
{
|
||||||
|
if (room.Player1 == null) lblP1Username.Text = "Username";
|
||||||
|
if (room.Player2 == null) lblP2Username.Text = "Username";
|
||||||
|
|
||||||
|
ToggleBoardControl(false);
|
||||||
|
|
||||||
|
switch (room.Status)
|
||||||
|
{
|
||||||
|
case GameStatus.P1Win:
|
||||||
|
{
|
||||||
|
if (_apiService.CurrentUser.Id == room.Player1?.Id)
|
||||||
|
{
|
||||||
|
lblLoadStatus.Text = "You Won!";
|
||||||
|
WinCount++;
|
||||||
|
|
||||||
|
if (WinCount >= 3)
|
||||||
|
{
|
||||||
|
JackpotWon = true;
|
||||||
|
lblJackpotWon.Text = "You Won A Spin!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else lblLoadStatus.Text = "You Lost!";
|
||||||
|
lblPlayAgain.Visible = true;
|
||||||
|
btnPlayAgain.Visible = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GameStatus.P2Win:
|
||||||
|
{
|
||||||
|
if (_apiService.CurrentUser.Id == room.Player2?.Id)
|
||||||
|
{
|
||||||
|
lblLoadStatus.Text = "You Won!";
|
||||||
|
WinCount++;
|
||||||
|
|
||||||
|
if (WinCount >= 3)
|
||||||
|
{
|
||||||
|
JackpotWon = true;
|
||||||
|
lblJackpotWon.Text = "You Won A Spin!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else lblLoadStatus.Text = "You Lost!";
|
||||||
|
lblPlayAgain.Visible = true;
|
||||||
|
btnPlayAgain.Visible = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GameStatus.PlayerDisconnected:
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(usernameDisconnected))
|
||||||
|
lblLoadStatus.Text = $"Game Ended.\nUser {usernameDisconnected}\nDisconnected.";
|
||||||
|
lblPlayAgain.Visible = false;
|
||||||
|
btnPlayAgain.Visible = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GameStatus.NoWin:
|
||||||
|
lblLoadStatus.Text = "It's a draw!";
|
||||||
|
lblPlayAgain.Visible = true;
|
||||||
|
btnPlayAgain.Visible = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pLoading.Visible = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
GameHubConnection.On<GameRoom>("RestartGame", (room) =>
|
||||||
|
{
|
||||||
|
CurrentRoom = room;
|
||||||
|
|
||||||
|
BeginInvoke(delegate ()
|
||||||
|
{
|
||||||
|
if (pLoading.Visible) pLoading.Visible = false;
|
||||||
|
});
|
||||||
|
ClearBoard();
|
||||||
|
ToggleBoardControl(true);
|
||||||
|
|
||||||
|
BeginInvoke(delegate ()
|
||||||
|
{
|
||||||
|
List<Button> buttons = [btnSquare1, btnSquare2, btnSquare3, btnSquare4, btnSquare5, btnSquare6, btnSquare7, btnSquare8, btnSquare9];
|
||||||
|
|
||||||
|
foreach (Button button in buttons)
|
||||||
|
{
|
||||||
|
if (button.BackgroundImage == null)
|
||||||
|
button.Enabled = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
GameHubConnection.On<GameRoom>("SelectSymbol", (room) =>
|
||||||
|
{
|
||||||
|
CurrentRoom = room;
|
||||||
|
|
||||||
|
BeginInvoke(delegate ()
|
||||||
|
{
|
||||||
|
if (room.Player1 != null)
|
||||||
|
{
|
||||||
|
lblP1Username.Text = room.Player1.Username;
|
||||||
|
if (!lvUserlist.Items.ContainsKey(room.Player1.Id)) lvUserlist.Items.Add(room.Player1.Id, room.Player1.Username, room.Player1.Status);
|
||||||
|
}
|
||||||
|
if (room.Player2 != null)
|
||||||
|
{
|
||||||
|
lblP2Username.Text = room.Player2.Username;
|
||||||
|
if (!lvUserlist.Items.ContainsKey(room.Player2.Id)) lvUserlist.Items.Add(room.Player2.Id, room.Player2.Username, room.Player2.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLoading.Visible) pLoading.Visible = false;
|
||||||
|
pSymbolSelection.Visible = true;
|
||||||
|
pBoard.Enabled = true;
|
||||||
|
ToggleAllSquareButtons(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
GameHubConnection.On<GameRoom>("SelectingSymbol", (room) =>
|
||||||
|
{
|
||||||
|
CurrentRoom = room;
|
||||||
|
|
||||||
|
BeginInvoke(delegate ()
|
||||||
|
{
|
||||||
|
if (pSymbolSelection.Visible) return;
|
||||||
|
|
||||||
|
if (room.Player1 != null)
|
||||||
|
{
|
||||||
|
lblP1Username.Text = room.Player1.Username;
|
||||||
|
if (!lvUserlist.Items.ContainsKey(room.Player1.Id)) lvUserlist.Items.Add(room.Player1.Id, room.Player1.Username, room.Player1.Status);
|
||||||
|
}
|
||||||
|
if (room.Player2 != null)
|
||||||
|
{
|
||||||
|
lblP2Username.Text = room.Player2.Username;
|
||||||
|
if (!lvUserlist.Items.ContainsKey(room.Player2.Id)) lvUserlist.Items.Add(room.Player2.Id, room.Player2.Username, room.Player2.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
pLoading.Visible = true;
|
||||||
|
lblLoadStatus.Text = $"Player 1\nIs Selecting\nSymbol...";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
GameHubConnection.On<GameRoom, TicTacToeMove>("UpdateBoard", (room, move) =>
|
||||||
|
{
|
||||||
|
CurrentRoom = room;
|
||||||
|
|
||||||
|
UpdateBoardUI(move);
|
||||||
|
});
|
||||||
|
|
||||||
|
GameHubConnection.On<GameRoom>("StartTurn", (room) =>
|
||||||
|
{
|
||||||
|
CurrentRoom = room;
|
||||||
|
ToggleBoardControl(true);
|
||||||
|
AddChatMessage("[SERVER] Your Turn!");
|
||||||
|
});
|
||||||
|
|
||||||
|
GameHubConnection.On<GameRoom>("EndTurn", (room) =>
|
||||||
|
{
|
||||||
|
CurrentRoom = room;
|
||||||
|
ToggleBoardControl(false);
|
||||||
|
AddChatMessage("[SERVER] Other Players Turn");
|
||||||
|
});
|
||||||
|
|
||||||
|
GameHubConnection.On<string>("ReceiveMessage", (msg) =>
|
||||||
|
{
|
||||||
|
AddChatMessage(msg);
|
||||||
|
if (msg.Split('[')[1] != _apiService.CurrentUser.Username)
|
||||||
|
_audioService.PlaySoundEffect("sndMessage");
|
||||||
|
});
|
||||||
|
|
||||||
|
try { await GameHubConnection.StartAsync(); }
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Sorry, We Couldn't Connect To The Game Server Due To An Error. Please Try Again Later.\n\n{ex.Message}", "Oops.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
lblLoadStatus.Text = "Finding\nRoom...";
|
||||||
|
await GameHubConnection.SendAsync("FindRoom");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void TicTacToeGame_FormClosed(object sender, FormClosedEventArgs e)
|
||||||
|
{
|
||||||
|
if (GameHubConnection != null && GameHubConnection.State == HubConnectionState.Connected)
|
||||||
|
{
|
||||||
|
if(JackpotWon)
|
||||||
|
{
|
||||||
|
// start a jackpot spin
|
||||||
|
CurrencyJackpotSpinner currencyJackpotSpinner = new CurrencyJackpotSpinner();
|
||||||
|
var dialogResult = currencyJackpotSpinner.ShowDialog();
|
||||||
|
if (dialogResult == DialogResult.OK)
|
||||||
|
{
|
||||||
|
await _apiService.AddCurrencyToCurrentUser(currencyJackpotSpinner.TokensWon, false);
|
||||||
|
_apiService.CurrentUser.CurrencyAmount += currencyJackpotSpinner.TokensWon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop and dispose connection
|
||||||
|
await GameHubConnection.StopAsync();
|
||||||
|
await GameHubConnection.DisposeAsync();
|
||||||
|
GameHubConnection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnXSelect_Click(object sender, EventArgs e) => await SelectSymbol(TicTacToeSymbol.X);
|
||||||
|
private async void btnOSelect_Click(object sender, EventArgs e) => await SelectSymbol(TicTacToeSymbol.O);
|
||||||
|
|
||||||
|
private async void btnPlayAgain_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (GameHubConnection != null && GameHubConnection.State == HubConnectionState.Connected && CurrentRoom != null)
|
||||||
|
{
|
||||||
|
await GameHubConnection.SendAsync("RestartGame", CurrentRoom.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnSquareX_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// create move
|
||||||
|
TicTacToeMove move = new TicTacToeMove
|
||||||
|
{
|
||||||
|
User = _apiService.CurrentUser
|
||||||
|
};
|
||||||
|
|
||||||
|
if (sender is Button btn)
|
||||||
|
{
|
||||||
|
switch (btn.Name)
|
||||||
|
{
|
||||||
|
case "btnSquare1":
|
||||||
|
move.Point = 1;
|
||||||
|
break;
|
||||||
|
case "btnSquare2":
|
||||||
|
move.Point = 2;
|
||||||
|
break;
|
||||||
|
case "btnSquare3":
|
||||||
|
move.Point = 3;
|
||||||
|
break;
|
||||||
|
case "btnSquare4":
|
||||||
|
move.Point = 4;
|
||||||
|
break;
|
||||||
|
case "btnSquare5":
|
||||||
|
move.Point = 5;
|
||||||
|
break;
|
||||||
|
case "btnSquare6":
|
||||||
|
move.Point = 6;
|
||||||
|
break;
|
||||||
|
case "btnSquare7":
|
||||||
|
move.Point = 7;
|
||||||
|
break;
|
||||||
|
case "btnSquare8":
|
||||||
|
move.Point = 8;
|
||||||
|
break;
|
||||||
|
case "btnSquare9":
|
||||||
|
move.Point = 9;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send move
|
||||||
|
if (GameHubConnection != null && GameHubConnection.State == HubConnectionState.Connected && CurrentRoom != null)
|
||||||
|
await GameHubConnection.SendAsync("MakeMove", CurrentRoom.Id, move);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void btnSend_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if ((GameHubConnection != null && GameHubConnection.State == HubConnectionState.Connected && CurrentRoom != null) &&
|
||||||
|
!string.IsNullOrWhiteSpace(rtxtChatbox.Text))
|
||||||
|
{
|
||||||
|
await GameHubConnection.SendAsync("SendRoomMessage", CurrentRoom.Id, $"[{_apiService.CurrentUser.Username}] {rtxtChatbox.Text}");
|
||||||
|
_audioService.PlaySoundEffect("sndSendClick");
|
||||||
|
rtxtChatbox.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rtxtChatbox_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if(e.KeyCode == Keys.Enter)
|
||||||
|
btnSend_Click(sender, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleBoardControl(bool toggle)
|
||||||
|
{
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
|
{
|
||||||
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
pBoard.Enabled = toggle;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleAllSquareButtons(bool toggle)
|
||||||
|
{
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
|
{
|
||||||
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
List<Button> buttons = [btnSquare1, btnSquare2, btnSquare3, btnSquare4, btnSquare5, btnSquare6, btnSquare7, btnSquare8, btnSquare9];
|
||||||
|
|
||||||
|
foreach (Button button in buttons)
|
||||||
|
button.Enabled = toggle;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SelectSymbol(TicTacToeSymbol symbol)
|
||||||
|
{
|
||||||
|
if (GameHubConnection != null && GameHubConnection.State == HubConnectionState.Connected && CurrentRoom != null)
|
||||||
|
{
|
||||||
|
await GameHubConnection.SendAsync("SetSymbol", CurrentRoom.Id, symbol);
|
||||||
|
ToggleAllSquareButtons(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateBoardUI(TicTacToeMove move)
|
||||||
|
{
|
||||||
|
if (IsHandleCreated && !IsDisposed && CurrentRoom != null)
|
||||||
|
{
|
||||||
|
// play move made sound
|
||||||
|
_audioService.PlaySoundEffect("sndTTTMoveMade");
|
||||||
|
|
||||||
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
switch (CurrentRoom.Board.Square1)
|
||||||
|
{
|
||||||
|
case TicTacToeSymbol.X:
|
||||||
|
btnSquare1.BackgroundImage = Properties.Resources.X;
|
||||||
|
btnSquare1.Enabled = false;
|
||||||
|
break;
|
||||||
|
case TicTacToeSymbol.O:
|
||||||
|
btnSquare1.BackgroundImage = Properties.Resources.O;
|
||||||
|
btnSquare1.Enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (CurrentRoom.Board.Square2)
|
||||||
|
{
|
||||||
|
case TicTacToeSymbol.X:
|
||||||
|
btnSquare2.BackgroundImage = Properties.Resources.X;
|
||||||
|
btnSquare2.Enabled = false;
|
||||||
|
break;
|
||||||
|
case TicTacToeSymbol.O:
|
||||||
|
btnSquare2.BackgroundImage = Properties.Resources.O;
|
||||||
|
btnSquare2.Enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (CurrentRoom.Board.Square3)
|
||||||
|
{
|
||||||
|
case TicTacToeSymbol.X:
|
||||||
|
btnSquare3.BackgroundImage = Properties.Resources.X;
|
||||||
|
btnSquare3.Enabled = false;
|
||||||
|
break;
|
||||||
|
case TicTacToeSymbol.O:
|
||||||
|
btnSquare3.BackgroundImage = Properties.Resources.O;
|
||||||
|
btnSquare3.Enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (CurrentRoom.Board.Square4)
|
||||||
|
{
|
||||||
|
case TicTacToeSymbol.X:
|
||||||
|
btnSquare4.BackgroundImage = Properties.Resources.X;
|
||||||
|
btnSquare4.Enabled = false;
|
||||||
|
break;
|
||||||
|
case TicTacToeSymbol.O:
|
||||||
|
btnSquare4.BackgroundImage = Properties.Resources.O;
|
||||||
|
btnSquare4.Enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (CurrentRoom.Board.Square5)
|
||||||
|
{
|
||||||
|
case TicTacToeSymbol.X:
|
||||||
|
btnSquare5.BackgroundImage = Properties.Resources.X;
|
||||||
|
btnSquare5.Enabled = false;
|
||||||
|
break;
|
||||||
|
case TicTacToeSymbol.O:
|
||||||
|
btnSquare5.BackgroundImage = Properties.Resources.O;
|
||||||
|
btnSquare5.Enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (CurrentRoom.Board.Square6)
|
||||||
|
{
|
||||||
|
case TicTacToeSymbol.X:
|
||||||
|
btnSquare6.BackgroundImage = Properties.Resources.X;
|
||||||
|
btnSquare6.Enabled = false;
|
||||||
|
break;
|
||||||
|
case TicTacToeSymbol.O:
|
||||||
|
btnSquare6.BackgroundImage = Properties.Resources.O;
|
||||||
|
btnSquare6.Enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (CurrentRoom.Board.Square7)
|
||||||
|
{
|
||||||
|
case TicTacToeSymbol.X:
|
||||||
|
btnSquare7.BackgroundImage = Properties.Resources.X;
|
||||||
|
btnSquare7.Enabled = false;
|
||||||
|
break;
|
||||||
|
case TicTacToeSymbol.O:
|
||||||
|
btnSquare7.BackgroundImage = Properties.Resources.O;
|
||||||
|
btnSquare7.Enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (CurrentRoom.Board.Square8)
|
||||||
|
{
|
||||||
|
case TicTacToeSymbol.X:
|
||||||
|
btnSquare8.BackgroundImage = Properties.Resources.X;
|
||||||
|
btnSquare8.Enabled = false;
|
||||||
|
break;
|
||||||
|
case TicTacToeSymbol.O:
|
||||||
|
btnSquare8.BackgroundImage = Properties.Resources.O;
|
||||||
|
btnSquare8.Enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (CurrentRoom.Board.Square9)
|
||||||
|
{
|
||||||
|
case TicTacToeSymbol.X:
|
||||||
|
btnSquare9.BackgroundImage = Properties.Resources.X;
|
||||||
|
btnSquare9.Enabled = false;
|
||||||
|
break;
|
||||||
|
case TicTacToeSymbol.O:
|
||||||
|
btnSquare9.BackgroundImage = Properties.Resources.O;
|
||||||
|
btnSquare9.Enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddChatMessage(string msg)
|
||||||
|
{
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
|
{
|
||||||
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
rtxtChat.AppendText($"{msg}\n");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearBoard()
|
||||||
|
{
|
||||||
|
if (IsHandleCreated && !IsDisposed)
|
||||||
|
{
|
||||||
|
Invoke(delegate ()
|
||||||
|
{
|
||||||
|
List<Button> buttons = [btnSquare1, btnSquare2, btnSquare3, btnSquare4, btnSquare5, btnSquare6, btnSquare7, btnSquare8, btnSquare9];
|
||||||
|
|
||||||
|
foreach (Button button in buttons)
|
||||||
|
button.BackgroundImage = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
qtc-net-client-2/Forms/TicTacToeGame.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>
|
BIN
qtc-net-client-2/Icons/NumberGuessGameIcon.png
Normal file
After Width: | Height: | Size: 435 B |
BIN
qtc-net-client-2/Icons/UserIcon.png
Normal file
After Width: | Height: | Size: 348 B |
@ -1,4 +1,6 @@
|
|||||||
using qtc_net_client_2.ClientModel;
|
using qtc_net_client_2.ClientModel;
|
||||||
|
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;
|
||||||
@ -14,8 +16,17 @@ namespace qtc_net_client_2
|
|||||||
[STAThread]
|
[STAThread]
|
||||||
static async Task Main()
|
static async Task Main()
|
||||||
{
|
{
|
||||||
|
// first thing, create a new log
|
||||||
|
LoggingService loggingService = new();
|
||||||
|
|
||||||
Config clientConfig = new Config();
|
Config clientConfig = new Config();
|
||||||
|
|
||||||
|
if(System.Diagnostics.Debugger.IsAttached)
|
||||||
|
{
|
||||||
|
// use localhost
|
||||||
|
clientConfig.ServerUrl = "http://localhost:5268";
|
||||||
|
}
|
||||||
|
|
||||||
// find config file
|
// find config file
|
||||||
if(!File.Exists("./config.json"))
|
if(!File.Exists("./config.json"))
|
||||||
{
|
{
|
||||||
@ -24,35 +35,50 @@ namespace qtc_net_client_2
|
|||||||
File.WriteAllText("./config.json", configJson);
|
File.WriteAllText("./config.json", configJson);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// use config in file
|
try
|
||||||
Config? fileConfig = JsonSerializer.Deserialize<Config>(File.ReadAllText("./config.json"));
|
{
|
||||||
if(fileConfig != null)
|
// use config in file
|
||||||
clientConfig = fileConfig;
|
Config? fileConfig = JsonSerializer.Deserialize<Config>(File.ReadAllText("./config.json"));
|
||||||
|
if (fileConfig != null)
|
||||||
|
{
|
||||||
|
clientConfig = fileConfig;
|
||||||
|
}
|
||||||
|
} catch (JsonException)
|
||||||
|
{
|
||||||
|
// there was a missing property, reset config to default
|
||||||
|
string configJson = JsonSerializer.Serialize(clientConfig, options: new JsonSerializerOptions { WriteIndented = true });
|
||||||
|
File.WriteAllText("./config.json", configJson);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.ApiEndpoint);
|
IApiService api = new ApiService($"{clientConfig.ServerUrl}/api", loggingService);
|
||||||
IGatewayService gateway = new GatewayService(clientConfig.GatewayEndpoint, api);
|
IGatewayService gateway = new GatewayService($"{clientConfig.ServerUrl}/chat", api, loggingService);
|
||||||
|
|
||||||
// ping api
|
// ping api
|
||||||
var pingResult = api.PingServerAsync().GetAwaiter().GetResult();
|
var pingResult = await api.PingServerAsync();
|
||||||
if (!pingResult.Success)
|
if (!pingResult.Success)
|
||||||
{
|
{
|
||||||
MessageBox.Show("The API Specified In The Config Could Not Be Reached.\nCheck The URL Specified, Otherwise Contact The Server Admin.", "Uh Oh.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
MessageBox.Show("The Server Specified In The Config Could Not Be Reached.\nCheck The URL Specified, Otherwise Contact The Server Admin.", "Uh Oh.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
Environment.Exit(1);
|
Environment.Exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for updates
|
||||||
|
UpdateService updateService = new();
|
||||||
|
await updateService.CheckForUpdatesAsync();
|
||||||
|
|
||||||
// To customize application configuration such as set high DPI settings or default font,
|
// To customize application configuration such as set high DPI settings or default font,
|
||||||
// see https://aka.ms/applicationconfiguration.
|
// see https://aka.ms/applicationconfiguration.
|
||||||
ApplicationConfiguration.Initialize();
|
ApplicationConfiguration.Initialize();
|
||||||
Application.Run(new Main(api, gateway));
|
Application.Run(new Main(api, gateway, clientConfig, loggingService));
|
||||||
|
|
||||||
// if application loop is exited, dispose everything
|
// if application loop is exited, dispose everything
|
||||||
await gateway.DisposeAsync();
|
await gateway.DisposeAsync();
|
||||||
|
loggingService.Dispose();
|
||||||
|
|
||||||
api = null;
|
api = null!; // shut up compiler >:(
|
||||||
gateway = null;
|
gateway = null!;
|
||||||
|
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
|
79
qtc-net-client-2/Properties/Resources.Designer.cs
generated
@ -80,6 +80,15 @@ namespace qtc_net_client_2.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to 6.3.4.
|
||||||
|
/// </summary>
|
||||||
|
internal static string AssemblyVersion {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("AssemblyVersion", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -100,6 +109,16 @@ namespace qtc_net_client_2.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Bitmap cobalt_sittingatputer {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("cobalt_sittingatputer", resourceCulture);
|
||||||
|
return ((System.Drawing.Bitmap)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -140,6 +159,26 @@ namespace qtc_net_client_2.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Bitmap dollar_money {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("dollar-money", resourceCulture);
|
||||||
|
return ((System.Drawing.Bitmap)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Bitmap donatebtn {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("donatebtn", resourceCulture);
|
||||||
|
return ((System.Drawing.Bitmap)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -170,6 +209,16 @@ namespace qtc_net_client_2.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Bitmap O {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("O", resourceCulture);
|
||||||
|
return ((System.Drawing.Bitmap)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -229,5 +278,35 @@ namespace qtc_net_client_2.Properties {
|
|||||||
return ((System.Drawing.Bitmap)(obj));
|
return ((System.Drawing.Bitmap)(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Bitmap support_me_on_kofi_badge_blue {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("support_me_on_kofi_badge_blue", resourceCulture);
|
||||||
|
return ((System.Drawing.Bitmap)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Bitmap Tic_tac_toe {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("Tic-tac-toe", resourceCulture);
|
||||||
|
return ((System.Drawing.Bitmap)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Bitmap X {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("X", resourceCulture);
|
||||||
|
return ((System.Drawing.Bitmap)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,12 +124,21 @@
|
|||||||
<data name="SendIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="SendIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Icons\SendIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Icons\SendIcon.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="X" 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>..\Resources\X.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
|
<data name="left-horn-animated" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Anims\left-horn-animated.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="OfflineIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="OfflineIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Icons\OfflineIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Icons\OfflineIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="dollar-money" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Anims\dollar-money.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
|
<data name="Tic-tac-toe" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\Tic-tac-toe1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
<data name="OnlineIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="OnlineIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Icons\OnlineIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Icons\OnlineIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
@ -151,22 +160,37 @@
|
|||||||
<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>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="support_me_on_kofi_badge_blue" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\support_me_on_kofi_badge_blue.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
|
<data name="O" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\O.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
<data name="RemoveContactIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="RemoveContactIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Icons\RemoveContactIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Icons\RemoveContactIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="MessageIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<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">
|
||||||
|
<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 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>
|
||||||
</data>
|
</data>
|
||||||
<data name="DeclineContactIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="DeclineContactIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Icons\DeclineContactIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Icons\DeclineContactIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="donatebtn" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\donatebtn.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
<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="left-horn-animated" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="DefaultPfp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Anims\left-horn-animated.gif;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>
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 13 KiB |
BIN
qtc-net-client-2/Resources/O.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
qtc-net-client-2/Resources/Tic-tac-toe.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
qtc-net-client-2/Resources/Tic-tac-toe1.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
qtc-net-client-2/Resources/X.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
qtc-net-client-2/Resources/cobalt_sittingatputer.jpg
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
qtc-net-client-2/Resources/donatebtn.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
qtc-net-client-2/Resources/support_me_on_kofi_badge_blue.png
Normal file
After Width: | Height: | Size: 24 KiB |
108
qtc-net-client-2/Services/UpdateService.cs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
using qtc_net_client_2.ClientModel;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using qtc_net_client_2.Properties;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace qtc_net_client_2.Services
|
||||||
|
{
|
||||||
|
public class UpdateService
|
||||||
|
{
|
||||||
|
public async Task CheckForUpdatesAsync()
|
||||||
|
{
|
||||||
|
if (Debugger.IsAttached) return;
|
||||||
|
|
||||||
|
// get client update info
|
||||||
|
HttpClient client = new();
|
||||||
|
client.BaseAddress = new Uri("https://qtcclient.alanmoon.net");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ClientUpdateInfo? updateInfo = await client.GetFromJsonAsync<ClientUpdateInfo>("clientinfo.json");
|
||||||
|
if (updateInfo != null)
|
||||||
|
{
|
||||||
|
if (updateInfo.Version != Resources.AssemblyVersion)
|
||||||
|
{
|
||||||
|
// inform the user an update is available
|
||||||
|
if (!updateInfo.IsUpdateMandatory)
|
||||||
|
{
|
||||||
|
var result = MessageBox.Show(
|
||||||
|
$"An Update For QtC.NET Is Available. You Can View The Changelog At {updateInfo.DownloadUrl}. Do You Want To Update Now?",
|
||||||
|
"Update Available",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Information);
|
||||||
|
if (result == DialogResult.Yes) await UpdateAsync(updateInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var result = MessageBox.Show(
|
||||||
|
"Your QtC.NET Client Is Not Up To Date. Using This Version Of The Client With The Current Version Of The Server Could Lead To Data Loss.\n" +
|
||||||
|
$"You Can View The Changelog At {updateInfo.DownloadUrl}. Do You Want To Update Now?",
|
||||||
|
"Update Required",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Error);
|
||||||
|
if (result == DialogResult.Yes) await UpdateAsync(updateInfo);
|
||||||
|
else Environment.Exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Client Update HTTP Request Failed - " + ex.Message);
|
||||||
|
} catch (JsonException)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Client Update Info From Server Invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateAsync(ClientUpdateInfo updateInfo)
|
||||||
|
{
|
||||||
|
HttpClient client = new();
|
||||||
|
client.BaseAddress = new Uri("https://qtcclient.alanmoon.net");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// if bak file already exists, delete it
|
||||||
|
if (File.Exists($"/{updateInfo.ClientFileName}.bak")) File.Delete($"/{updateInfo.ClientFileName}.bak");
|
||||||
|
|
||||||
|
// move old client to backup file
|
||||||
|
File.Move($"./{updateInfo.ClientFileName}", $"{updateInfo.ClientFileName}.bak");
|
||||||
|
|
||||||
|
// download new client version
|
||||||
|
var clientFileStream = await client.GetStreamAsync(updateInfo.ClientFileName);
|
||||||
|
using(var fs = new FileStream($"./{updateInfo.ClientFileName}", FileMode.Create))
|
||||||
|
{
|
||||||
|
clientFileStream.CopyTo(fs);
|
||||||
|
fs.Dispose();
|
||||||
|
}
|
||||||
|
clientFileStream.Dispose();
|
||||||
|
|
||||||
|
// restart the process
|
||||||
|
Process process = new Process();
|
||||||
|
process.StartInfo = new ProcessStartInfo { FileName = $"./{updateInfo.ClientFileName}", WorkingDirectory = Environment.CurrentDirectory };
|
||||||
|
|
||||||
|
process.Start();
|
||||||
|
Environment.Exit(0);
|
||||||
|
} catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Update Failed. Please Check Your Internet Connection.\n{ex.Message}",
|
||||||
|
"Update Failed",
|
||||||
|
MessageBoxButtons.OK,
|
||||||
|
MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Update Failed. Permissions In Client Folder Are Wrong.\n{ex.Message}",
|
||||||
|
"Update Failed",
|
||||||
|
MessageBoxButtons.OK,
|
||||||
|
MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
qtc-net-client-2/Sounds/sndTTTMoveMade.wav
Normal file
@ -62,6 +62,9 @@
|
|||||||
<None Update="Sounds\sndTokenWin.wav">
|
<None Update="Sounds\sndTokenWin.wav">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Sounds\sndTTTMoveMade.wav">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|