👽 Integrate Craftmine API

pull/3/head
Alexis Drai 2 years ago
parent 9753fa16e5
commit 911ed0e57f

@ -0,0 +1,453 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CraftingController.cs" company="UCA Clermont-Ferrand">
// Copyright (c) UCA Clermont-Ferrand All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Minecraft.Crafting.Api.Controllers
{
using Microsoft.AspNetCore.Mvc;
using Minecraft.Crafting.Api.Models;
using System.Text.Json;
using System.Text.Json.Serialization;
/// <summary>
/// The crafting controller.
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class CraftingController : ControllerBase
{
/// <summary>
/// The json serializer options.
/// </summary>
private readonly JsonSerializerOptions _jsonSerializerOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};
/// <summary>
/// Adds the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>The async task.</returns>
[HttpPost]
[Route("")]
public Task Add(Item item)
{
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the items.");
}
// Simulate the Id
item.Id = data.Max(s => s.Id) + 1;
data.Add(item);
System.IO.File.WriteAllText("Data/items.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
return Task.CompletedTask;
}
/// <summary>
/// Get all items.
/// </summary>
/// <returns>All items.</returns>
[HttpGet]
[Route("all")]
public Task<List<Item>> All()
{
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the items.");
}
return Task.FromResult(data.ToList());
}
/// <summary>
/// Count the number of items.
/// </summary>
/// <returns>The number of items.</returns>
[HttpGet]
[Route("count")]
public Task<int> Count()
{
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the items.");
}
return Task.FromResult(data.Count);
}
/// <summary>
/// Deletes the specified identifier.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>The async task.</returns>
[HttpDelete]
[Route("{id}")]
public Task Delete(int id)
{
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the items.");
}
var item = data.FirstOrDefault(w => w.Id == id);
if (item == null)
{
throw new Exception($"Unable to found the item with ID: {id}");
}
data.Remove(item);
System.IO.File.WriteAllText("Data/items.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
return Task.CompletedTask;
}
/// <summary>
/// Gets the item by identifier.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>The item.</returns>
[HttpGet]
[Route("{id}")]
public Task<Item> GetById(int id)
{
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the items.");
}
var item = data.FirstOrDefault(w => w.Id == id);
if (item == null)
{
throw new Exception($"Unable to found the item with ID: {id}");
}
return Task.FromResult(item);
}
/// <summary>
/// Gets the item by name.
/// </summary>
/// <param name="name">The name.</param>
/// <returns>
/// The item.
/// </returns>
[HttpGet]
[Route("by-name/{name}")]
public Task<Item> GetByName(string name)
{
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the items.");
}
var item = data.FirstOrDefault(w => w.Name.ToLowerInvariant() == name.ToLowerInvariant());
if (item == null)
{
throw new Exception($"Unable to found the item with name: {name}");
}
return Task.FromResult(item);
}
/// <summary>
/// Gets the recipes.
/// </summary>
/// <returns>The recipes.</returns>
[HttpGet]
[Route("recipe")]
public Task<List<Recipe>> GetRecipe()
{
if (!System.IO.File.Exists("Data/convert-recipes.json"))
{
ResetRecipes();
}
var data = JsonSerializer.Deserialize<List<Recipe>>(System.IO.File.ReadAllText("Data/convert-recipes.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the recipes.");
}
return Task.FromResult(data);
}
/// <summary>
/// Get the items with pagination.
/// </summary>
/// <param name="currentPage">The current page.</param>
/// <param name="pageSize">Size of the page.</param>
/// <returns>The items.</returns>
[HttpGet]
[Route("")]
public Task<List<Item>> List(int currentPage, int pageSize)
{
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the items.");
}
return Task.FromResult(data.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList());
}
/// <summary>
/// Resets the items.
/// </summary>
/// <returns>The async task.</returns>
[HttpGet]
[Route("reset-items")]
public Task ResetItems()
{
if (!System.IO.File.Exists("Data/items.json"))
{
System.IO.File.Delete("Data/items.json");
}
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items-original.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the items.");
}
var defaultImage = Convert.ToBase64String(System.IO.File.ReadAllBytes("Images/default.png"));
var imageTranslation = new Dictionary<string, string>
{
{ "stone_slab", "smooth_stone_slab_side" },
{ "sticky_piston", "piston_top_sticky" },
{ "mob_spawner", "spawner" },
{ "chest", "chest_minecart" },
{ "stone_stairs", "stairs" },
};
foreach (var item in data)
{
var imageFilepath = defaultImage;
if (System.IO.File.Exists($"Images/{item.Name}.png"))
{
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/{item.Name}.png"));
}
if (imageFilepath == defaultImage && System.IO.File.Exists($"Images/{item.Name}_top.png"))
{
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/{item.Name}_top.png"));
}
if (imageFilepath == defaultImage && System.IO.File.Exists($"Images/{item.Name}_front.png"))
{
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/{item.Name}_front.png"));
}
if (imageFilepath == defaultImage && System.IO.File.Exists($"Images/white_{item.Name}.png"))
{
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/white_{item.Name}.png"));
}
if (imageFilepath == defaultImage && System.IO.File.Exists($"Images/oak_{item.Name}.png"))
{
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/oak_{item.Name}.png"));
}
if (imageFilepath == defaultImage && System.IO.File.Exists($"Images/{item.DisplayName.ToLower().Replace(" ", "_")}.png"))
{
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/{item.DisplayName.ToLower().Replace(" ", "_")}.png"));
}
if (imageFilepath == defaultImage && imageTranslation.ContainsKey(item.Name))
{
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/{imageTranslation[item.Name]}.png"));
}
item.ImageBase64 = imageFilepath;
}
System.IO.File.WriteAllText("Data/items.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
return Task.FromResult(data);
}
/// <summary>
/// Resets the recipes.
/// </summary>
/// <returns>The async task.</returns>
[HttpGet]
[Route("reset-recipes")]
public Task ResetRecipes()
{
if (!System.IO.File.Exists("Data/convert-recipes.json"))
{
System.IO.File.Delete("Data/convert-recipes.json");
}
ConvertRecipes();
return Task.CompletedTask;
}
/// <summary>
/// Updates the specified identifier.
/// </summary>
/// <param name="id">The identifier.</param>
/// <param name="item">The item.</param>
/// <returns>The async task.</returns>
[HttpPut]
[Route("{id}")]
public Task Update(int id, Item item)
{
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
var itemOriginal = data?.FirstOrDefault(w => w.Id == id);
if (itemOriginal == null)
{
throw new Exception($"Unable to found the item with ID: {id}");
}
itemOriginal.Id = item.Id;
itemOriginal.Name = item.Name;
itemOriginal.CreatedDate = item.CreatedDate;
itemOriginal.DisplayName = item.DisplayName;
itemOriginal.EnchantCategories = item.EnchantCategories;
itemOriginal.MaxDurability = item.MaxDurability;
itemOriginal.RepairWith = item.RepairWith;
itemOriginal.StackSize = item.StackSize;
itemOriginal.UpdatedDate = item.UpdatedDate;
itemOriginal.ImageBase64 = item.ImageBase64;
System.IO.File.WriteAllText("Data/items.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
return Task.CompletedTask;
}
/// <summary>
/// Gets the name of the item.
/// </summary>
/// <param name="items">The items.</param>
/// <param name="inShape">The in shape.</param>
/// <param name="line">The line.</param>
/// <param name="row">The row.</param>
/// <returns>The name of the item.</returns>
private static string GetItemName(List<Item> items, InShape[][] inShape, int line, int row)
{
if (inShape.Length < line + 1)
{
return null;
}
if (inShape[line].Length < row + 1)
{
return null;
}
var id = inShape[line][row].Integer ?? inShape[line][row].IngredientClass?.Id;
if (id == null)
{
return null;
}
return GetItemName(items, id.Value);
}
/// <summary>
/// Gets the name of the item.
/// </summary>
/// <param name="items">The items.</param>
/// <param name="id">The identifier.</param>
/// <returns>The name of the item.</returns>
private static string GetItemName(List<Item> items, long id)
{
var item = items.FirstOrDefault(w => w.Id == id);
return item?.Name;
}
/// <summary>
/// Converts the recipes.
/// </summary>
private void ConvertRecipes()
{
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
if (data == null)
{
return;
}
var recipes = Recipes.FromJson(System.IO.File.ReadAllText("Data/recipes.json"));
var items = new List<Recipe>();
foreach (var recipe in recipes.SelectMany(s => s.Value))
{
if (recipe.InShape == null)
{
continue;
}
var giveItem = data.FirstOrDefault(w => w.Id == recipe.Result.Id);
if (giveItem == null)
{
continue;
}
items.Add(new Recipe
{
Give = giveItem,
Have = new List<List<string>>
{
new()
{
GetItemName(data, recipe.InShape, 0, 0),
GetItemName(data, recipe.InShape, 0, 1),
GetItemName(data, recipe.InShape, 0, 2)
},
new()
{
GetItemName(data, recipe.InShape, 1, 0),
GetItemName(data, recipe.InShape, 1, 1),
GetItemName(data, recipe.InShape, 1, 2)
},
new()
{
GetItemName(data, recipe.InShape, 2, 0),
GetItemName(data, recipe.InShape, 2, 1),
GetItemName(data, recipe.InShape, 2, 2)
}
}
});
}
System.IO.File.WriteAllText("Data/convert-recipes.json", JsonSerializer.Serialize(items, _jsonSerializerOptions));
}
}
}

@ -0,0 +1,143 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="InventoryController.cs" company="UCA Clermont-Ferrand">
// Copyright (c) UCA Clermont-Ferrand All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Minecraft.Crafting.Api.Controllers
{
using Microsoft.AspNetCore.Mvc;
using Minecraft.Crafting.Api.Models;
using System.Text.Json;
using System.Text.Json.Serialization;
/// <summary>
/// The inventory controller.
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class InventoryController : ControllerBase
{
/// <summary>
/// The json serializer options.
/// </summary>
private readonly JsonSerializerOptions _jsonSerializerOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};
/// <summary>
/// Adds to inventory.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>The async task.</returns>
[HttpPost]
[Route("")]
public Task AddToInventory(InventoryModel item)
{
var data = JsonSerializer.Deserialize<List<InventoryModel>>(System.IO.File.ReadAllText("Data/inventory.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the inventory.");
}
data.Add(item);
System.IO.File.WriteAllText("Data/inventory.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
return Task.CompletedTask;
}
/// <summary>
/// Deletes from inventory.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>The async task.</returns>
[HttpDelete]
[Route("")]
public Task DeleteFromInventory(InventoryModel item)
{
if (!System.IO.File.Exists("Data/inventory.json"))
{
throw new Exception($"Unable to found the item with name: {item.ItemName}");
}
var data = JsonSerializer.Deserialize<List<InventoryModel>>(System.IO.File.ReadAllText("Data/inventory.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the inventory.");
}
var inventoryItem = data.FirstOrDefault(w => w.ItemName == item.ItemName && w.Position == item.Position);
if (inventoryItem == null)
{
throw new Exception($"Unable to found the item with name: {item.ItemName} at position: {item.Position}");
}
data.Remove(inventoryItem);
System.IO.File.WriteAllText("Data/inventory.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
return Task.CompletedTask;
}
/// <summary>
/// Gets the inventory.
/// </summary>
/// <returns>The inventory.</returns>
[HttpGet]
[Route("")]
public Task<List<InventoryModel>> GetInventory()
{
if (!System.IO.File.Exists("Data/inventory.json"))
{
return Task.FromResult(new List<InventoryModel>());
}
var data = JsonSerializer.Deserialize<List<InventoryModel>>(System.IO.File.ReadAllText("Data/inventory.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the inventory.");
}
return Task.FromResult(data);
}
/// <summary>
/// Updates the inventory.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>The async task.</returns>
[HttpPut]
[Route("")]
public Task UpdateInventory(InventoryModel item)
{
var data = JsonSerializer.Deserialize<List<InventoryModel>>(System.IO.File.ReadAllText("Data/inventory.json"), _jsonSerializerOptions);
if (data == null)
{
throw new Exception("Unable to get the inventory.");
}
var inventoryItem = data.FirstOrDefault(w => w.ItemName == item.ItemName && w.Position == item.Position);
if (inventoryItem == null)
{
throw new Exception($"Unable to found the item with name: {item.ItemName} at position: {item.Position}");
}
inventoryItem.ItemName = item.ItemName;
inventoryItem.Position = item.Position;
System.IO.File.WriteAllText("Data/inventory.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
return Task.CompletedTask;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,20 @@
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["src/Minecraft.Crafting.Api/Minecraft.Crafting.Api.csproj", "Minecraft.Crafting.Api/"]
RUN dotnet restore "Minecraft.Crafting.Api/Minecraft.Crafting.Api.csproj"
COPY src/. .
WORKDIR "/src/Minecraft.Crafting.Api"
RUN dotnet build "Minecraft.Crafting.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Minecraft.Crafting.Api.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Minecraft.Crafting.Api.dll"]

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 2
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 20
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,38 @@
{
"animation": {
"frames": [
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15
]
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 2
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 2
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 8
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 3
}
}

@ -0,0 +1,45 @@
{
"animation": {
"frametime": 2,
"frames": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
18,
17,
16,
15,
14,
13,
12,
11,
10,
9,
8,
7,
6,
5,
4,
3,
2,
1
]
}
}

@ -0,0 +1,11 @@
{
"animation": {
"frametime": 8,
"interpolate": true,
"frames": [
0,
1,
2
]
}
}

@ -0,0 +1,30 @@
{
"animation": {
"frametime": 300,
"interpolate": true,
"frames": [
0,
1,
0,
2,
0,
3,
0,
1,
2,
1,
3,
1,
0,
2,
1,
2,
3,
2,
0,
3,
1,
3
]
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,6 @@
{
"animation": {
"frametime": 20,
"interpolate": true
}
}

@ -0,0 +1,6 @@
{
"animation": {
"frametime": 3,
"interpolate": true
}
}

@ -0,0 +1,6 @@
{
"animation": {
"frametime": 6,
"interpolate": true
}
}

@ -0,0 +1,6 @@
{
"animation": {
"frametime": 20,
"interpolate": true
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 5
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 2
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": false,
"frametime": 4
}
}

@ -0,0 +1,6 @@
{
"animation": {
"frametime": 2
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 20
}
}

@ -0,0 +1,38 @@
{
"animation": {
"frames": [
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15
]
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 8
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": false,
"frametime": 1
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 2
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 2
}
}

@ -0,0 +1,6 @@
{
"animation": {
"interpolate": true,
"frametime": 10
}
}

@ -0,0 +1,5 @@
{
"animation": {
"frametime": 2
}
}

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup>
<ItemGroup>
<Content Update="Data\items-original.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Data\recipes.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Images\*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

@ -0,0 +1,29 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="InventoryController.cs" company="UCA Clermont-Ferrand">
// Copyright (c) UCA Clermont-Ferrand All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Minecraft.Crafting.Api.Models
{
/// <summary>
/// The inventory model.
/// </summary>
public class InventoryModel
{
/// <summary>
/// Gets or sets the name of the item.
/// </summary>
public string ItemName { get; set; }
/// <summary>
/// Gets or sets the number item.
/// </summary>
public int NumberItem { get; set; }
/// <summary>
/// Gets or sets the position.
/// </summary>
public int Position { get; set; }
}
}

@ -0,0 +1,73 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="InventoryController.cs" company="UCA Clermont-Ferrand">
// Copyright (c) UCA Clermont-Ferrand All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Minecraft.Crafting.Api.Models
{
/// <summary>
/// The item.
/// </summary>
public class Item
{
/// <summary>
/// Initializes a new instance of the <see cref="Item"/> class.
/// </summary>
public Item()
{
EnchantCategories = new List<string>();
RepairWith = new List<string>();
}
/// <summary>
/// Gets or sets the created date.
/// </summary>
public DateTime CreatedDate { get; set; }
/// <summary>
/// Gets or sets the display name.
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// Gets or sets the enchant categories.
/// </summary>
public List<string> EnchantCategories { get; set; }
/// <summary>
/// Gets or sets the identifier.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Gets or sets the image base64.
/// </summary>
public string ImageBase64 { get; set; }
/// <summary>
/// Gets or sets the maximum durability.
/// </summary>
public int MaxDurability { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Gets or sets the repair with.
/// </summary>
public List<string> RepairWith { get; set; }
/// <summary>
/// Gets or sets the size of the stack.
/// </summary>
public int StackSize { get; set; }
/// <summary>
/// Gets or sets the updated date.
/// </summary>
public DateTime? UpdatedDate { get; set; }
}
}

@ -0,0 +1,26 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="InventoryController.cs" company="UCA Clermont-Ferrand">
// Copyright (c) UCA Clermont-Ferrand All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Minecraft.Crafting.Api
{
using Minecraft.Crafting.Api.Models;
/// <summary>
/// The recipe.
/// </summary>
public class Recipe
{
/// <summary>
/// Gets or sets the give.
/// </summary>
public Item Give { get; set; }
/// <summary>
/// Gets or sets the have.
/// </summary>
public List<List<string>> Have { get; set; }
}
}

@ -0,0 +1,41 @@
namespace Minecraft.Crafting.Api
{
/// <summary>
/// The program.
/// </summary>
public class Program
{
/// <summary>
/// Defines the entry point of the application.
/// </summary>
/// <param name="args">The arguments.</param>
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
}

@ -0,0 +1,38 @@
{
"profiles": {
"Minecraft.Crafting.Api": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:7234;http://localhost:5234"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"publishAllPorts": true,
"useSSL": true
}
},
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:51530",
"sslPort": 44598
}
}
}

@ -0,0 +1,177 @@
namespace Minecraft.Crafting.Api
{
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Globalization;
using JsonConverter = Newtonsoft.Json.JsonConverter;
using JsonSerializer = Newtonsoft.Json.JsonSerializer;
public struct IngredientElement
{
public IngredientClass IngredientClass;
public long? Integer;
public static implicit operator IngredientElement(IngredientClass IngredientClass) => new IngredientElement { IngredientClass = IngredientClass };
public static implicit operator IngredientElement(long Integer) => new IngredientElement { Integer = Integer };
}
public struct InShape
{
public IngredientClass IngredientClass;
public long? Integer;
public bool IsNull => IngredientClass == null && Integer == null;
public static implicit operator InShape(IngredientClass IngredientClass) => new InShape { IngredientClass = IngredientClass };
public static implicit operator InShape(long Integer) => new InShape { Integer = Integer };
}
public static class Serialize
{
public static string ToJson(this Dictionary<string, Recipes[]> self) => JsonConvert.SerializeObject(self, Converter.Settings);
}
public class IngredientClass
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("metadata")]
public long Metadata { get; set; }
}
public partial class Recipes
{
[JsonProperty("ingredients", NullValueHandling = NullValueHandling.Ignore)]
public IngredientElement[] Ingredients { get; set; }
[JsonProperty("inShape", NullValueHandling = NullValueHandling.Ignore)]
public InShape[][] InShape { get; set; }
[JsonProperty("outShape", NullValueHandling = NullValueHandling.Ignore)]
public long?[][] OutShape { get; set; }
[JsonProperty("result")]
public Result Result { get; set; }
}
public partial class Recipes
{
public static Dictionary<string, Recipes[]> FromJson(string json) => JsonConvert.DeserializeObject<Dictionary<string, Recipes[]>>(json, Converter.Settings);
}
public class Result
{
[JsonProperty("count")]
public long Count { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("metadata")]
public long Metadata { get; set; }
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
InShapeConverter.Singleton,
IngredientElementConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class IngredientElementConverter : JsonConverter
{
public static readonly IngredientElementConverter Singleton = new IngredientElementConverter();
public override bool CanConvert(Type t) => t == typeof(IngredientElement) || t == typeof(IngredientElement?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Integer:
var integerValue = serializer.Deserialize<long>(reader);
return new IngredientElement { Integer = integerValue };
case JsonToken.StartObject:
var objectValue = serializer.Deserialize<IngredientClass>(reader);
return new IngredientElement { IngredientClass = objectValue };
}
throw new Exception("Cannot unmarshal type IngredientElement");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
var value = (IngredientElement)untypedValue;
if (value.Integer != null)
{
serializer.Serialize(writer, value.Integer.Value);
return;
}
if (value.IngredientClass != null)
{
serializer.Serialize(writer, value.IngredientClass);
return;
}
throw new Exception("Cannot marshal type IngredientElement");
}
}
internal class InShapeConverter : JsonConverter
{
public static readonly InShapeConverter Singleton = new InShapeConverter();
public override bool CanConvert(Type t) => t == typeof(InShape) || t == typeof(InShape?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Null:
return new InShape { };
case JsonToken.Integer:
var integerValue = serializer.Deserialize<long>(reader);
return new InShape { Integer = integerValue };
case JsonToken.StartObject:
var objectValue = serializer.Deserialize<IngredientClass>(reader);
return new InShape { IngredientClass = objectValue };
}
throw new Exception("Cannot unmarshal type InShape");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
var value = (InShape)untypedValue;
if (value.IsNull)
{
serializer.Serialize(writer, null);
return;
}
if (value.Integer != null)
{
serializer.Serialize(writer, value.Integer.Value);
return;
}
if (value.IngredientClass != null)
{
serializer.Serialize(writer, value.IngredientClass);
return;
}
throw new Exception("Cannot marshal type InShape");
}
}
}

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

@ -5,6 +5,8 @@ VisualStudioVersion = 17.2.32616.157
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "blazor_lab", "blazor_lab\blazor_lab.csproj", "{7B8F9C82-6399-47FC-A996-8140F39484D6}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "blazor_lab", "blazor_lab\blazor_lab.csproj", "{7B8F9C82-6399-47FC-A996-8140F39484D6}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Minecraft.Crafting.Api", "Minecraft.Crafting.Api\Minecraft.Crafting.Api.csproj", "{F89D34E2-0DBC-4E98-BC77-E4CB00A33D19}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -15,6 +17,10 @@ Global
{7B8F9C82-6399-47FC-A996-8140F39484D6}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B8F9C82-6399-47FC-A996-8140F39484D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B8F9C82-6399-47FC-A996-8140F39484D6}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B8F9C82-6399-47FC-A996-8140F39484D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B8F9C82-6399-47FC-A996-8140F39484D6}.Release|Any CPU.Build.0 = Release|Any CPU {7B8F9C82-6399-47FC-A996-8140F39484D6}.Release|Any CPU.Build.0 = Release|Any CPU
{F89D34E2-0DBC-4E98-BC77-E4CB00A33D19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F89D34E2-0DBC-4E98-BC77-E4CB00A33D19}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F89D34E2-0DBC-4E98-BC77-E4CB00A33D19}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F89D34E2-0DBC-4E98-BC77-E4CB00A33D19}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

@ -43,6 +43,8 @@ builder.Services.Configure<RequestLocalizationOptions>(options =>
options.SupportedUICultures = new List<CultureInfo> { new CultureInfo("en-US"), new CultureInfo("fr-FR") }; options.SupportedUICultures = new List<CultureInfo> { new CultureInfo("en-US"), new CultureInfo("fr-FR") };
}); });
builder.Services.AddScoped<IDataService, DataApiService>();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.

@ -0,0 +1,59 @@
using blazor_lab.Components;
using blazor_lab.Factories;
using blazor_lab.Models;
namespace blazor_lab.Services
{
public class DataApiService : IDataService
{
private readonly HttpClient _http;
public DataApiService(
HttpClient http)
{
_http = http;
}
public async Task Add(ItemModel model)
{
// Get the item
var item = ItemFactory.Create(model);
// Save the data
await _http.PostAsJsonAsync("https://localhost:7234/api/Crafting/", item);
}
public async Task<int> Count()
{
return await _http.GetFromJsonAsync<int>("https://localhost:7234/api/Crafting/count");
}
public async Task<List<Item>> List(int currentPage, int pageSize)
{
return await _http.GetFromJsonAsync<List<Item>>($"https://localhost:7234/api/Crafting/?currentPage={currentPage}&pageSize={pageSize}");
}
public async Task<Item> GetById(int id)
{
return await _http.GetFromJsonAsync<Item>($"https://localhost:7234/api/Crafting/{id}");
}
public async Task Update(int id, ItemModel model)
{
// Get the item
var item = ItemFactory.Create(model);
await _http.PutAsJsonAsync($"https://localhost:7234/api/Crafting/{id}", item);
}
public async Task Delete(int id)
{
await _http.DeleteAsync($"https://localhost:7234/api/Crafting/{id}");
}
public async Task<List<CraftingRecipe>> GetRecipes()
{
return await _http.GetFromJsonAsync<List<CraftingRecipe>>("https://localhost:7234/api/Crafting/recipe");
}
}
}

@ -117,7 +117,11 @@ namespace blazor_lab.Services
public async Task Update(int id, ItemModel model) public async Task Update(int id, ItemModel model)
{ {
var currentData = await _localStorageService.GetItemAsync<List<Item>>("data"); var currentData = await _localStorageService.GetItemAsync<List<Item>>("data");
var item = await GetById(id); var item = currentData.FirstOrDefault(w => w.Id == id);
if (item == null)
{
throw new Exception($"Unable to found the item with ID: {id}");
}
ItemFactory.Update(item, model); ItemFactory.Update(item, model);

@ -15,7 +15,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="wwwroot\images\" /> <Folder Include="wwwroot\_content\" />
</ItemGroup> </ItemGroup>
</Project> </Project>

Loading…
Cancel
Save