Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial launcher redesign #36

Merged
merged 14 commits into from
Oct 2, 2024
27 changes: 27 additions & 0 deletions Fuyu.Backend.Core/Controllers/AccountGamesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Fuyu.Backend.Core.DTO.Responses;
using Fuyu.Common.Networking;
using Fuyu.Common.Serialization;
using Fuyu.Backend.Core.Services;
using System.Threading.Tasks;

namespace Fuyu.Backend.Core.Controllers
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
{
public class AccountGamesController : HttpController
{
public AccountGamesController() : base("/account/games")
{
}

public override async Task RunAsync(HttpContext context)
{
var sessionId = context.GetSessionId();
var result = AccountService.GetGames(sessionId);
var response = new AccountGamesResponse()
{
Games = result
};

await context.SendJsonAsync(Json.Stringify(response));
}
}
}
20 changes: 20 additions & 0 deletions Fuyu.Backend.Core/Controllers/AccountLogoutController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Fuyu.Common.Networking;
using System.Threading.Tasks;

namespace Fuyu.Backend.Core.Controllers
{
public class AccountLogoutController : HttpController
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
{
public AccountLogoutController() : base("/account/logout")
{
}

public override async Task RunAsync(HttpContext context)
{
var sessionId = context.GetSessionId();
CoreOrm.RemoveSession(sessionId);

await context.SendJsonAsync("{}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,8 @@ public override async Task RunAsync(HttpContext context)
var request = await context.GetJsonAsync<AccountRegisterGameRequest>();
var sessionId = context.GetSessionId();
var result = AccountService.RegisterGame(sessionId, request.Game, request.Edition);
var response = new AccountRegisterGameResponse()
{
Status = result
};

await context.SendJsonAsync(Json.Stringify(response));
await context.SendJsonAsync(Json.Stringify(result));
}
}
}
12 changes: 12 additions & 0 deletions Fuyu.Backend.Core/DTO/Response/AccountGamesResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Fuyu.Backend.Core.DTO.Responses
{
[DataContract]
public class AccountGamesResponse
{
[DataMember]
public Dictionary<string, int?> Games;
}
}
3 changes: 3 additions & 0 deletions Fuyu.Backend.Core/DTO/Response/AccountRegisterGameResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ public class AccountRegisterGameResponse
{
[DataMember]
public ERegisterStatus Status;

[DataMember]
public int AccountId;
}
}
2 changes: 2 additions & 0 deletions Fuyu.Backend.Core/Servers/CoreServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ public CoreServer() : base("core", "http://localhost:8000/")
public void RegisterServices()
{
AddHttpController<AccountLoginController>();
AddHttpController<AccountLogoutController>();
AddHttpController<AccountRegisterController>();
AddHttpController<AccountRegisterGameController>();
AddHttpController<AccountGamesController>();
}
}
}
21 changes: 18 additions & 3 deletions Fuyu.Backend.Core/Services/AccountService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,18 @@ public static ERegisterStatus RegisterAccount(string username, string password)
return ERegisterStatus.Success;
}

public static ERegisterStatus RegisterGame(string sessionId, string game, string edition)
public static AccountRegisterGameResponse RegisterGame(string sessionId, string game, string edition)
{
var account = CoreOrm.GetAccount(sessionId);

// find existing game
if (account.Games.ContainsKey(game) && account.Games[game].HasValue)
{
return ERegisterStatus.AlreadyExists;
return new AccountRegisterGameResponse()
{
Status = ERegisterStatus.AlreadyExists,
AccountId = -1
};
}

// register game
Expand All @@ -207,9 +211,20 @@ public static ERegisterStatus RegisterGame(string sessionId, string game, string
CoreOrm.SetOrAddAccount(account);
WriteToDisk(account);

return ERegisterStatus.Success;
return new AccountRegisterGameResponse()
{
Status = ERegisterStatus.Success,
AccountId = accountId
};
}

public static Dictionary<string, int?> GetGames(string sessionId)
{
var account = CoreOrm.GetAccount(sessionId);

TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
return account.Games;
}

public static void WriteToDisk(Account account)
{
VFS.WriteTextFile(
Expand Down
40 changes: 35 additions & 5 deletions Fuyu.Launcher.Core/Services/RequestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
using Fuyu.Backend.Core.DTO.Accounts;
using Fuyu.Backend.Core.DTO.Requests;
using Fuyu.Backend.Core.DTO.Responses;
using System.Collections.Generic;
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
using System.Collections;
using System;

namespace Fuyu.Launcher.Core.Services
{
Expand Down Expand Up @@ -38,6 +41,13 @@ private static T2 HttpPost<T1, T2>(string id, string path, T1 request)
return response;
}

public static void ResetSessions()
{
_httpClients.Set("fuyu", new HttpClient(SettingsService.FuyuAddress, string.Empty));
_httpClients.Set("eft", new HttpClient(SettingsService.EftAddress, string.Empty));
_httpClients.Set("arena", new HttpClient(SettingsService.ArenaAddress, string.Empty));
}

public static void CreateSession(string id, string address, string sessionId)
{
_httpClients.Set(id, new HttpClient(address, sessionId));
Expand All @@ -58,7 +68,7 @@ public static ERegisterStatus RegisterAccount(string username, string password)
return response.Status;
}

public static string LoginAccount(string username, string password)
public static AccountLoginResponse LoginAccount(string username, string password)
{
var hashedPassword = Sha256.Generate(password);
var request = new AccountLoginRequest()
Expand All @@ -71,10 +81,30 @@ public static string LoginAccount(string username, string password)
"/account/login",
request);

return response.SessionId;
return response;
}

public static void LogoutAccount()
{
HttpPost<object, object>(
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
"fuyu",
"/account/logout",
null);

ResetSessions();
}

public static ERegisterStatus RegisterGame(string game, string edition)
public static Dictionary<string, int?> GetGames()
{
var response = HttpPost<object, AccountGamesResponse>(
seionmoya marked this conversation as resolved.
Show resolved Hide resolved
"fuyu",
"/account/games",
null);

return response.Games;
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
}

public static AccountRegisterGameResponse RegisterGame(string game, string edition)
{
var request = new AccountRegisterGameRequest()
{
Expand All @@ -86,10 +116,10 @@ public static ERegisterStatus RegisterGame(string game, string edition)
"/account/register/game",
request);

return response.Status;
return response;
}

public static string LoginGame(string game, int accountId)
public static string LoginGame(string game, int accountId)
{
var request = new FuyuGameLoginRequest()
{
Expand Down
37 changes: 37 additions & 0 deletions Fuyu.Launcher/Components/AboutDialog.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@using System.Diagnostics;

<div>
<MudDialog>
<DialogContent>
<MudStack Class="my-6" AlignItems="AlignItems.Center" Justify="Justify.Center">
<MudAvatar Style="height: 70px; width: 70px;" Rounded="true">
<MudImage Src="../img/icon.png"></MudImage>
</MudAvatar>
<MudText Typo="Typo.h6">冬 Fuyu</MudText>
<MudText Typo="Typo.subtitle2">1.0.0</MudText>
<MudStack Row="true">
<MudTooltip Text="Website" ShowOnHover="true" Arrow="true" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Link" Color="Color.Tertiary" OnClick="@(() => OpenLinkOnDefaultBrowser("https://placeholder.com"))" />
</MudTooltip>
<MudTooltip Text="Discord" ShowOnHover="true" Arrow="true" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Custom.Brands.Discord" Style="color: #5865F2;" OnClick="@(() => OpenLinkOnDefaultBrowser("https://discord.com/invite/placeholder"))" />
</MudTooltip>
<MudTooltip Text="GitHub" ShowOnHover="true" Arrow="true" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Custom.Brands.GitHub" Style="color: #F0F6FC;" OnClick="@(() => OpenLinkOnDefaultBrowser("https://github.com/project-fika/Fuyu"))" />
</MudTooltip>
</MudStack>
<MudText Typo="Typo.body2">Copyright © 2024 seionmoya</MudText>
</MudStack>
</DialogContent>
</MudDialog>
</div>

@code {
[CascadingParameter]
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
private MudDialogInstance MudDialog { get; set; }

private void OpenLinkOnDefaultBrowser(string link)
{
Process.Start(new ProcessStartInfo(link) { UseShellExecute = true });
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
}
}
122 changes: 122 additions & 0 deletions Fuyu.Launcher/Components/AddGameDialog.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
@using Fuyu.Backend.Core.DTO.Accounts

@inherits Fluxor.Blazor.Web.Components.FluxorComponent

@inject IState<GamesState> GamesState
@inject IDispatcher Dispatcher
@inject ISnackbar Snackbar

@if (!GamesState.Value.Games.Values.Contains(null))
{
<MudDialog>
<DialogContent>
<MudText Typo="Typo.h6">No more games left to add.</MudText>
</DialogContent>
<DialogActions>
<MudButton Color="Color.Tertiary" OnClick="Cancel_Clicked">Close</MudButton>
</DialogActions>
</MudDialog>
}
else
{
<MudDialog>
<DialogContent>
<MudStack>
<MudSelect @bind-Value="_game" @bind-Value:after="Game_Changed" Label="Game" HelperText="Choose one of the available games">
@foreach (var (gameId, gameName) in games)
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
{
if (GamesState.Value.Games[gameId] == null)
{
<MudSelectItem Value="@gameId">@gameName</MudSelectItem>
}
}
</MudSelect>
<MudSelect @bind-Value="_edition" Label="Edition" HelperText="Choose one of the game editions" Disabled="@string.IsNullOrWhiteSpace(_game)">
@if (!string.IsNullOrWhiteSpace(_game))
{
@foreach (var (editionId, edtionName) in gameEditions[_game])
{
<MudSelectItem Value="@editionId">@edtionName</MudSelectItem>
}
}
</MudSelect>
</MudStack>
</DialogContent>
<DialogActions>
<MudButton Variant="Variant.Text" OnClick="Cancel_Clicked">Cancel</MudButton>
<MudButton Color="Color.Tertiary" OnClick="Add_Clicked" Disabled="Add_Disabled()">Add</MudButton>
</DialogActions>
</MudDialog>
}


@code {
[CascadingParameter]
private MudDialogInstance MudDialog { get; set; }

private string _game = string.Empty;
private string _username = string.Empty;
private string _edition = string.Empty;

// TODO: Remove both of these Dictionaries, get this from backend or a future localization service
private Dictionary<string, string> games = new()
{
["eft"] = "Escape from Tarkov",
["arena"] = "Escape from Tarkov: Arena"
};

private Dictionary<string, Dictionary<string, string>> gameEditions = new()
{
["eft"] = new()
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
{
["standard"] = "Standard",
["left behind"] = "Left Behind",
["prepare to escape"] = "Prepare to Escape",
["edge of darkness"] = "Edge of Darkness",
["unheard"] = "Unheard"
},
["arena"] = new()
{
["standard"] = "Standard",
["ryhzy"] = "Ryhzy"
}
};

private void Game_Changed()
{
_edition = string.Empty;
}

private bool Add_Disabled()
{
return string.IsNullOrWhiteSpace(_game) || string.IsNullOrWhiteSpace(_edition);
}

private void Cancel_Clicked()
{
MudDialog.Cancel();
}

private void Add_Clicked() {
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
if(Add_Disabled())
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
{
return;
}

var response = RequestService.RegisterGame(_game, _edition);

switch(response.Status)
{
case ERegisterStatus.Success:
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
Dispatcher.Dispatch(new AddGameAction(_game, response.AccountId));

Snackbar.Add("Successfully added game to account!", Severity.Success);

MudDialog.Close(DialogResult.Ok(true));
break;
TheSpartaPT marked this conversation as resolved.
Show resolved Hide resolved
case ERegisterStatus.AlreadyExists:
Snackbar.Add("Game already exists in account!", Severity.Warning);
break;
}
}
}
11 changes: 11 additions & 0 deletions Fuyu.Launcher/Components/Background.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div>
@if (Glass) {
<div class="bg bg-glass"></div>
}
<div class="bg bg-img"></div>
</div>

@code {
[Parameter]
public bool Glass { get; set; } = false;
}
Loading