Skip to content
This repository was archived by the owner on Feb 7, 2025. It is now read-only.

[SVR-293] [던전] 던전 상세 정보 READ 기능 #147

Merged
merged 5 commits into from
Mar 25, 2024
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
11 changes: 9 additions & 2 deletions backend/app/Savor22b/Constants/Addresses.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ namespace Savor22b.Constants;

public static class Addresses
{
public static readonly Address ShopVaultAddress = new Address("0000000000000000000000000000000000000000");
public static readonly Address UserHouseDataAddress = new Address("0000000000000000000000000000000000000001");
public static readonly Address ShopVaultAddress = new Address(
"0000000000000000000000000000000000000000"
);
public static readonly Address UserHouseDataAddress = new Address(
"0000000000000000000000000000000000000001"
);
public static readonly Address DungeonDataAddress = new Address(
"0000000000000000000000000000000000000002"
);
}
1 change: 0 additions & 1 deletion backend/app/Savor22b/GraphTypes/Query/Query.cs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,6 @@ swarm is null
);

AddField(new CalculateRelocationCostQuery());
AddField(new VillagesQuery(blockChain));
AddField(new ShopQuery());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public Subscription(
_subject = new Subject<Libplanet.Blocks.BlockHash>();

AddField(new UserStateField(_blockChain, _subject));
AddField(new VillageField(_blockChain, _subject));

AddField(
new FieldType()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
namespace Savor22b.GraphTypes.Query;
namespace Savor22b.GraphTypes.Subscription;

using System.Collections.Immutable;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using Bencodex.Types;
using GraphQL;
using GraphQL.Resolvers;
Expand All @@ -12,12 +14,18 @@ namespace Savor22b.GraphTypes.Query;
using Savor22b.Model;
using Savor22b.States;

public class VillagesQuery : FieldType
public class VillageField : FieldType
{
public VillagesQuery(BlockChain blockChain)
private readonly BlockChain _blockChain;
private readonly Subject<Libplanet.Blocks.BlockHash> _subject;

public VillageField(BlockChain blockChain, Subject<Libplanet.Blocks.BlockHash> subject)
: base()
{
Name = "villages";
_blockChain = blockChain;
_subject = subject;

Name = "Village";
Type = typeof(NonNullGraphType<ListGraphType<VillageType>>);
Description = "Get all villages";
Resolver = new FuncFieldResolver<ImmutableList<VillageDetail>>(context =>
Expand All @@ -38,6 +46,25 @@ public VillagesQuery(BlockChain blockChain)
throw new ExecutionError(e.Message);
}
});
StreamResolver = new SourceStreamResolver<ImmutableList<VillageDetail>>(
(context) =>
{
try
{
var villages = CsvDataHelper.GetVillageCSVData().ToArray();

return _subject
.DistinctUntilChanged()
.Select(
_ => GetVillageDetails(villages.ToImmutableList(), context, blockChain)
);
}
catch (Exception e)
{
throw new ExecutionError(e.Message);
}
}
);
}

public static ImmutableList<VillageDetail> GetVillageDetails(
Expand Down
30 changes: 29 additions & 1 deletion backend/app/Savor22b/GraphTypes/Types/DungeonStateType.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
namespace Savor22b.GraphTypes.Types;

using GraphQL.Types;
using Libplanet;
using Libplanet.Blockchain;
using Libplanet.Explorer.GraphTypes;
using Savor22b.Model;

public class DungeonStateType : ObjectGraphType<Dungeon>
{
public DungeonStateType()
public DungeonStateType(BlockChain blockChain)
{
Field<NonNullGraphType<StringGraphType>>(
"name",
Expand Down Expand Up @@ -36,5 +39,30 @@ public DungeonStateType()
description: "던전이 위치하는 마을의 id 입니다.",
resolve: context => context.Source.VillageId
);

Field<NonNullGraphType<ListGraphType<StaticSeedStateType>>>(
"seeds",
description: "던전에서 획득 가능한 씨앗 목록입니다.",
resolve: context =>
{
var seeds = context.Source.RewardSeedIdList.Select(
seedId => CsvDataHelper.GetSeedById(seedId)!
);

return seeds;
}
);

Field<NonNullGraphType<BooleanGraphType>>(
"isConquest",
description: "현재 던전이 점령 되었는지의 여부입니다.",
resolve: context => context.Source.IsConquest(blockChain)
);

Field<AddressType>(
"conquestUserAddress",
description: "현재 던전을 점령하고 있는 유저의 Address입니다.",
resolve: context => context.Source.CurrentConquestUserAddress(blockChain)
);
}
}
26 changes: 26 additions & 0 deletions backend/app/Savor22b/GraphTypes/Types/StaticSeedStateType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using GraphQL.Types;
using Savor22b.Model;

namespace Savor22b.GraphTypes.Types;

public class StaticSeedStateType : ObjectGraphType<Seed>
{
public StaticSeedStateType()
{
Field<IntGraphType>(
name: "seedId",
description: "The ID of the seed.",
resolve: context => context.Source.Id
);

Field<StringGraphType>(
name: "name",
description: "The name of the seed.",
resolve: context =>
{
Seed seed = CsvDataHelper.GetSeedById(context.Source.Id)!;
return seed.Name;
}
);
}
}
34 changes: 34 additions & 0 deletions backend/app/Savor22b/Model/Dungeon.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
using System.Collections.Immutable;
using Bencodex.Types;
using Libplanet;
using Libplanet.Blockchain;
using Savor22b.Constants;
using Savor22b.States;

namespace Savor22b.Model;

public class Dungeon
Expand All @@ -7,4 +14,31 @@ public class Dungeon
public int Y { get; set; }
public int ID { get; set; }
public int VillageId { get; set; }
public ImmutableList<int> RewardSeedIdList { get; set; }

private static GlobalDungeonState GetGlobalDungeonState(BlockChain blockChain)
{
GlobalDungeonState globalDungeonState = blockChain.GetState(Addresses.DungeonDataAddress)
is Dictionary stateEncoded
? new GlobalDungeonState(stateEncoded)
: new GlobalDungeonState();

return globalDungeonState;
}

public bool IsConquest(BlockChain blockChain)
{
GlobalDungeonState globalDungeonState = GetGlobalDungeonState(blockChain);

return globalDungeonState.DungeonStatus.ContainsKey(ID.ToString());
}

public Address? CurrentConquestUserAddress(BlockChain blockChain)
{
GlobalDungeonState globalDungeonState = GetGlobalDungeonState(blockChain);

return globalDungeonState.DungeonStatus.TryGetValue(ID.ToString(), out Address address)
? address
: null;
}
}
53 changes: 53 additions & 0 deletions backend/app/Savor22b/States/DungeonConquestHistoryState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
namespace Savor22b.States;

using Bencodex.Types;
using Libplanet;
using Libplanet.Headless.Extensions;

public class DungeonConquestHistoryState : State
{
public long BlockIndex { get; private set; }
public int DungeonId { get; private set; }
public Address TargetUserAddress { get; private set; }
public int DungeonConquestStatus { get; private set; }

public DungeonConquestHistoryState(
long blockIndex,
int dungeonId,
Address targetUserAddress,
int dungeonConquestStatus
)
{
BlockIndex = blockIndex;
DungeonId = dungeonId;
TargetUserAddress = targetUserAddress;
DungeonConquestStatus = dungeonConquestStatus;
}

public DungeonConquestHistoryState(Dictionary encoded)
{
BlockIndex = encoded[nameof(BlockIndex)].ToLong();
DungeonId = encoded[nameof(DungeonId)].ToInteger();
TargetUserAddress = encoded[nameof(TargetUserAddress)].ToAddress();
DungeonConquestStatus = encoded[nameof(DungeonConquestStatus)].ToInteger();
}

public IValue Serialize()
{
var pairs = new[]
{
new KeyValuePair<IKey, IValue>((Text)nameof(BlockIndex), BlockIndex.Serialize()),
new KeyValuePair<IKey, IValue>((Text)nameof(DungeonId), DungeonId.Serialize()),
new KeyValuePair<IKey, IValue>(
(Text)nameof(TargetUserAddress),
TargetUserAddress.ToBencodex()
),
new KeyValuePair<IKey, IValue>(
(Text)nameof(DungeonConquestStatus),
DungeonConquestStatus.Serialize()
),
};

return new Dictionary(pairs);
}
}
57 changes: 57 additions & 0 deletions backend/app/Savor22b/States/DungeonHistoryState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
namespace Savor22b.States;

using System.Collections.Immutable;
using Bencodex.Types;
using Libplanet.Headless.Extensions;

public class DungeonHistoryState : State
{
public long BlockIndex { get; private set; }
public int DungeonId { get; private set; }
public int DungeonClearStatus { get; private set; }
public ImmutableList<int> DungeonClearRewardSeedIdList { get; private set; }

public DungeonHistoryState(
long blockIndex,
int dungeonId,
int dungeonClearStatus,
ImmutableList<int> dungeonClearRewardSeedIdList
)
{
BlockIndex = blockIndex;
DungeonId = dungeonId;
DungeonClearStatus = dungeonClearStatus;
DungeonClearRewardSeedIdList = dungeonClearRewardSeedIdList;
}

public DungeonHistoryState(Dictionary encoded)
{
BlockIndex = encoded[nameof(BlockIndex)].ToLong();
DungeonId = encoded[nameof(DungeonId)].ToInteger();
DungeonClearStatus = encoded[nameof(DungeonClearStatus)].ToInteger();
DungeonClearRewardSeedIdList = (
(Bencodex.Types.List)encoded[nameof(DungeonClearRewardSeedIdList)]
)
.Select(e => e.ToInteger())
.ToImmutableList();
}

public IValue Serialize()
{
var pairs = new[]
{
new KeyValuePair<IKey, IValue>((Text)nameof(BlockIndex), BlockIndex.Serialize()),
new KeyValuePair<IKey, IValue>((Text)nameof(DungeonId), DungeonId.Serialize()),
new KeyValuePair<IKey, IValue>(
(Text)nameof(DungeonClearStatus),
DungeonClearStatus.Serialize()
),
new KeyValuePair<IKey, IValue>(
(Text)nameof(DungeonClearRewardSeedIdList),
new List(DungeonClearRewardSeedIdList.Select(e => e.Serialize()))
),
};

return new Dictionary(pairs);
}
}
33 changes: 0 additions & 33 deletions backend/app/Savor22b/States/DungeonKeyHistory.cs

This file was deleted.

Loading
Loading