Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Server.Application.Port.Output.Transaction;
using Server.Application.UseCase.Character;
using Server.Application.UseCase.Character.Command;
using Server.Infrastructure.Persistence.Model;
using Server.Domain.Entity;
using Server.Infrastructure.StaticData.Model;

namespace Server.Tests.Application.Character;
Expand Down Expand Up @@ -64,11 +64,11 @@ public async Task ExecuteAsync_Should_Create_CharacterData_And_PieceData()

await useCase.ExecuteAsync(command, CancellationToken.None);

_repoMock.Verify(x => x.CreateAsync(It.Is<PlayerCharacterData>(
_repoMock.Verify(x => x.CreateAsync(It.Is<PlayerCharacter>(
p => p.UserId == 1 && p.CharacterId == 10 && p.CharacterLevel == 1 && p.CharacterExp == 0
), It.IsAny<CancellationToken>()), Times.Once);

_repoMock.Verify(x => x.CreatePieceData(It.Is<PlayerCharacterPieceData>(
_repoMock.Verify(x => x.CreatePieceData(It.Is<PlayerCharacter>(
p => p.UserId == 1 && p.CharacterId == 10 && p.PieceAmount == 0
), It.IsAny<CancellationToken>()), Times.Once);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
using Server.Application.Exceptions;
using Server.Application.Port.Output.Persistence;
using Server.Application.UseCase.Character;
using Server.Domain.Entity;
using Server.Infrastructure.Persistence.Model;
using Server.Infrastructure.StaticData.Model;

namespace Server.Tests.Application.Character;

Expand Down Expand Up @@ -31,7 +33,7 @@ public async Task ExecuteAsync_Should_Return_EmptyList_When_No_Characters()
{
int userId = 1;
_repoMock.Setup(x => x.FindAll(userId, It.IsAny<CancellationToken>()))
.ReturnsAsync(Enumerable.Empty<PlayerCharacterData>());
.ReturnsAsync(Enumerable.Empty<PlayerCharacter>());

var useCase = CreateUseCase();

Expand All @@ -44,10 +46,10 @@ public async Task ExecuteAsync_Should_Return_EmptyList_When_No_Characters()
public async Task ExecuteAsync_Should_Return_All_Characters()
{
int userId = 1;
var characters = new List<PlayerCharacterData>
var characters = new List<PlayerCharacter>
{
new PlayerCharacterData(userId, 10),
new PlayerCharacterData(userId, 20)
PlayerCharacter.Create(userId, 10, CharacterRole.Main),
PlayerCharacter.Create(userId, 20, CharacterRole.Main)
};

_repoMock.Setup(x => x.FindAll(userId, It.IsAny<CancellationToken>()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
using Server.Application.Port.Output.Persistence;
using Server.Application.UseCase.Character;
using Server.Application.UseCase.Character.Command;
using Server.Infrastructure.Persistence.Model;
using Server.Domain.Entity;
using Server.Infrastructure.StaticData.Model;

namespace Server.Tests.Application.Character;

Expand All @@ -21,7 +22,7 @@ public async Task ExecuteAsync_Should_Throw_When_PlayerCharacter_Not_Found()
var command = new GetPlayerCharacterCommand(1, 10);

_repoMock.Setup(x => x.FindCharacter(1, 10, It.IsAny<CancellationToken>()))
.ReturnsAsync((PlayerCharacterData?)null);
.ReturnsAsync((PlayerCharacter?)null);

var useCase = CreateUseCase();

Expand All @@ -37,15 +38,7 @@ public async Task ExecuteAsync_Should_Return_PlayerCharacterData_When_Found()
{
var command = new GetPlayerCharacterCommand(1, 10);

var characterData = new PlayerCharacterData(
UserId: 1,
CharacterId: 10,
CharacterLevel: 1,
CharacterExp: 0,
NormalSkillLevel: 1,
UltimateSkillLevel: 1,
SupportSkillLevel: 1
);
var characterData = PlayerCharacter.Create(1, 10, CharacterRole.Main);

_repoMock.Setup(x => x.FindCharacter(1, 10, It.IsAny<CancellationToken>()))
.ReturnsAsync(characterData);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using Server.Infrastructure.Persistence.Model;
using Server.Domain.Entity;
using Server.Infrastructure.Persistence.Model;

namespace Server.Api.Dto.Response.Character;

public class GetAllPlayerCharactersResponse
{
public List<PlayerCharacterData> Characters { get; set; }
public List<PlayerCharacter> Characters { get; set; }

Check warning on line 8 in PaperMania/Server/Api/Dto/Response/Character/GetAllPlayerCharactersResponse.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Non-nullable property 'Characters' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using Server.Infrastructure.Persistence.Model;
using Server.Domain.Entity;
using Server.Infrastructure.Persistence.Model;

namespace Server.Api.Dto.Response.Character;

public class GetCharacterDataResponse
{
public PlayerCharacterData Character { get; set; }
public PlayerCharacter Character { get; set; }

Check warning on line 8 in PaperMania/Server/Api/Dto/Response/Character/GetCharacterDataResponse.cs

View workflow job for this annotation

GitHub Actions / build-and-test

Non-nullable property 'Character' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Server.Infrastructure.Persistence.Model;
using Server.Domain.Entity;

namespace Server.Application.Port.Input.Character;

public interface IGetAllPlayerCharacterDataUseCase
{
Task<List<PlayerCharacterData>> ExecuteAsync(int userId, CancellationToken ct);
Task<List<PlayerCharacter>> ExecuteAsync(int userId, CancellationToken ct);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using Server.Application.UseCase.Character.Command;
using Server.Infrastructure.Persistence.Model;
using Server.Domain.Entity;

namespace Server.Application.Port.Input.Character;

public interface IGetPlayerCharacterUseCase
{
Task<PlayerCharacterData> ExecuteAsync(GetPlayerCharacterCommand request, CancellationToken ct);
Task<PlayerCharacter> ExecuteAsync(GetPlayerCharacterCommand request, CancellationToken ct);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using Server.Domain.Entity;
using Server.Infrastructure.Persistence.Model;

namespace Server.Application.Port.Output.Persistence;

public interface ICharacterRepository
{
Task<IEnumerable<PlayerCharacterData>> FindAll(int userId, CancellationToken ct);
Task<PlayerCharacterData?> FindCharacter(int userId, int characterId, CancellationToken ct);
Task<PlayerCharacterData> UpdateAsync(PlayerCharacterData data, CancellationToken ct);
Task CreateAsync(PlayerCharacterData data, CancellationToken ct);
Task CreatePieceData(PlayerCharacterPieceData data, CancellationToken ct);
Task<IEnumerable<PlayerCharacter>> FindAll(int userId, CancellationToken ct);
Task<PlayerCharacter?> FindCharacter(int userId, int characterId, CancellationToken ct);
Task<PlayerCharacter> UpdateAsync(PlayerCharacter entity, CancellationToken ct);
Task CreateAsync(PlayerCharacter entity, CancellationToken ct);
Task CreatePieceData(PlayerCharacter entity, CancellationToken ct);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using Server.Application.Port.Output.StaticData;
using Server.Application.Port.Output.Transaction;
using Server.Application.UseCase.Character.Command;
using Server.Infrastructure.Persistence.Model;
using Server.Domain.Entity;

namespace Server.Application.UseCase.Character;

Expand All @@ -30,27 +30,18 @@ public async Task ExecuteAsync(CreatePlayerCharacterCommand request, Cancellatio
{
request.Validate();

var character = _store.Get(request.CharacterId)
?? throw new RequestException(
ErrorStatusCode.NotFound,
"CHARACTER_NOT_FOUND"
var characterDef = _store.Get(request.CharacterId)
?? throw new RequestException(
ErrorStatusCode.NotFound,
"CHARACTER_NOT_FOUND"
);

await _transactionScope.ExecuteAsync(async (innerCt) =>
{
var data = new PlayerCharacterData(
request.UserId,
request.CharacterId,
1,
0,
character.NormalSkillId == 0 ? 0 : 1,
character.UltimateSkillId == 0 ? 0 : 1,
character.SupportSkillId == 0 ? 0 : 1
);

await _repository.CreateAsync(data, innerCt);
var character = PlayerCharacter.Create(request.UserId, request.CharacterId, characterDef.Role);

await _repository.CreatePieceData(new PlayerCharacterPieceData(data.UserId, data.CharacterId, 0),innerCt);
await _repository.CreateAsync(character, innerCt);
await _repository.CreatePieceData(character, innerCt);
}, ct);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Server.Application.Exceptions;
using Server.Application.Port.Input.Character;
using Server.Application.Port.Output.Persistence;
using Server.Infrastructure.Persistence.Model;
using Server.Domain.Entity;

namespace Server.Application.UseCase.Character;

Expand All @@ -15,7 +15,7 @@ public GetAllPlayerCharacterDataUseCase(ICharacterRepository repository)
_repository = repository;
}

public async Task<List<PlayerCharacterData>> ExecuteAsync(int userId, CancellationToken ct)
public async Task<List<PlayerCharacter>> ExecuteAsync(int userId, CancellationToken ct)
{
if (userId <= 0)
throw new RequestException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Server.Application.Port.Input.Character;
using Server.Application.Port.Output.Persistence;
using Server.Application.UseCase.Character.Command;
using Server.Infrastructure.Persistence.Model;
using Server.Domain.Entity;

namespace Server.Application.UseCase.Character;

Expand All @@ -16,7 +16,7 @@ public GetPlayerCharacterUseCase(ICharacterRepository repository)
_repository = repository;
}

public async Task<PlayerCharacterData> ExecuteAsync(GetPlayerCharacterCommand request, CancellationToken ct)
public async Task<PlayerCharacter> ExecuteAsync(GetPlayerCharacterCommand request, CancellationToken ct)
{
request.Validate();

Expand Down
96 changes: 96 additions & 0 deletions PaperMania/Server/Domain/Entity/PlayerCharacter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using Server.Infrastructure.StaticData.Model;

namespace Server.Domain.Entity;

public class PlayerCharacter
{
public int UserId { get; set; }
public int CharacterId { get; set; }
public int CharacterLevel { get; set; }
public int CharacterExp { get; set; }
public CharacterRole Role { get; set; }
public int NormalSkillLevel { get; set; }
public int UltimateSkillLevel { get; set; }
public int SupportSkillLevel { get; set; }
public int PieceAmount { get; set; }

public PlayerCharacter(int userId, int characterId, int characterLevel, int characterExp,
int normalSkillLevel, int ultimateSkillLevel, int supportSkillLevel, int pieceAmount)
{
UserId = userId;
CharacterId = characterId;
CharacterLevel = characterLevel;
CharacterExp = characterExp;
NormalSkillLevel = normalSkillLevel;
UltimateSkillLevel = ultimateSkillLevel;
SupportSkillLevel = supportSkillLevel;
PieceAmount = pieceAmount;
}

public static PlayerCharacter Create(int userId, int characterId, CharacterRole role)
{
return role switch
{
CharacterRole.Main => CreateMain(userId, characterId),
CharacterRole.Support => CreateSupport(userId, characterId),
_ => throw new ArgumentException("Invalid character role")
};
}

private static PlayerCharacter CreateMain(int userId, int characterId)
{
return new PlayerCharacter(userId, characterId,
characterLevel: 1, characterExp: 0,
normalSkillLevel: 1, ultimateSkillLevel: 1, supportSkillLevel: 0,
pieceAmount: 0);
}

private static PlayerCharacter CreateSupport(int userId, int characterId)
{
return new PlayerCharacter(userId, characterId,
characterLevel: 1, characterExp: 0,
normalSkillLevel: 1, ultimateSkillLevel: 0, supportSkillLevel: 1,
pieceAmount: 0);
}

public void AddPiece(int amount)
{
if (amount <= 0)
throw new ArgumentException("Piece amount must be positive");

PieceAmount += amount;
}

public void UpgradeNormalSkill(int maxLevel)
{
if (NormalSkillLevel >= maxLevel)
throw new InvalidOperationException("Normal skill is already at max level");

NormalSkillLevel++;
}

public void UpgradeUltimateSkill(int maxLevel)
{
if (UltimateSkillLevel >= maxLevel)
throw new InvalidOperationException("Ultimate skill is already at max level");

UltimateSkillLevel++;
}

public void UpgradeSupportSkill(int maxLevel)
{
if (SupportSkillLevel >= maxLevel)
throw new InvalidOperationException("Support skill is already at max level");

SupportSkillLevel++;
}

public void GainExp(int amount, Action<int> onLevelUp)
{
if (amount <= 0)
throw new ArgumentException("Exp amount must be positive");

CharacterExp += amount;
onLevelUp?.Invoke(CharacterLevel);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
namespace Server.Infrastructure.Persistence.Model;

public record PlayerCharacterData(
int UserId,
int CharacterId,
int CharacterLevel = 1,
int CharacterExp = 0,
int NormalSkillLevel = 1,
int UltimateSkillLevel = 1,
int SupportSkillLevel = 1
);
public class PlayerCharacterData
{
public int UserId { get; set; }
public int CharacterId { get; set; }
public int CharacterLevel { get; set; } = 1;
public int CharacterExp { get; set; } = 0;
public int NormalSkillLevel { get; set; }
public int UltimateSkillLevel { get; set; }
public int SupportSkillLevel { get; set; }
public int PieceAmount { get; set; }

public PlayerCharacterData() { }

public PlayerCharacterData(int userId, int characterId)
{
UserId = userId;
CharacterId = characterId;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
namespace Server.Infrastructure.Persistence.Model;

public record PlayerCharacterPieceData(
int UserId,
int CharacterId,
int PieceAmount
);
public class PlayerCharacterPieceData
{
public int UserId { get; set; }
public int CharacterId { get; set; }
public int PieceAmount { get; set; }
}
Loading
Loading