-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
create ClaimOneTimeGift(action), OneTimeGiftSheet(sheet)
- Loading branch information
1 parent
8f11988
commit 655b8a4
Showing
3 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using Bencodex.Types; | ||
using Libplanet.Action; | ||
using Libplanet.Action.State; | ||
using Libplanet.Crypto; | ||
using Nekoyume.Extensions; | ||
using Nekoyume.Model.Item; | ||
using Nekoyume.Model.State; | ||
using Nekoyume.Module; | ||
using Nekoyume.TableData; | ||
using static Lib9c.SerializeKeys; | ||
|
||
namespace Nekoyume.Action | ||
{ | ||
[ActionType(ActionTypeText)] | ||
public class ClaimOneTimeGift : GameAction | ||
{ | ||
private const string ActionTypeText = "claim_one_time_gift"; | ||
|
||
public Address AvatarAddress; | ||
|
||
public static Address ClaimedGiftIdsAddress(Address avatarAddress) => | ||
avatarAddress.Derive("claimed_gift_ids"); | ||
|
||
public ClaimOneTimeGift(Address avatarAddress) | ||
{ | ||
AvatarAddress = avatarAddress; | ||
} | ||
|
||
public ClaimOneTimeGift() | ||
{ | ||
} | ||
|
||
protected override IImmutableDictionary<string, IValue> PlainValueInternal => | ||
ImmutableDictionary<string, IValue>.Empty | ||
.Add(AvatarAddressKey, AvatarAddress.Serialize()); | ||
|
||
protected override void LoadPlainValueInternal(IImmutableDictionary<string, IValue> plainValue) | ||
{ | ||
AvatarAddress = plainValue[AvatarAddressKey].ToAddress(); | ||
} | ||
|
||
public override IWorld Execute(IActionContext context) | ||
{ | ||
context.UseGas(1); | ||
var states = context.PreviousState; | ||
var random = context.GetRandom(); | ||
var addressesHex = GetSignerAndOtherAddressesHex(context, AvatarAddress); | ||
|
||
var avatarState = states.GetAvatarState(AvatarAddress, | ||
getWorldInformation: false, | ||
getQuestList: false); | ||
if (avatarState is null) | ||
{ | ||
throw new FailedLoadStateException( | ||
ActionTypeText, | ||
addressesHex, | ||
typeof(AvatarState), | ||
AvatarAddress); | ||
} | ||
|
||
var sheetTypes = new [] | ||
{ | ||
typeof(OneTimeGiftSheet), | ||
}; | ||
var sheets = states.GetSheets( | ||
containItemSheet: true, | ||
sheetTypes: sheetTypes); | ||
|
||
var oneTimeGiftSheet = sheets.GetSheet<OneTimeGiftSheet>(); | ||
if (!oneTimeGiftSheet.TryFindRowByBlockIndex(context.BlockIndex, out var giftRow)) | ||
{ | ||
throw new ClaimableGiftDoesNotExistException( | ||
$"[{addressesHex}] Claimable gift does not exist at block index: {context.BlockIndex}" | ||
); | ||
} | ||
|
||
var claimedGiftIdsAddress = ClaimedGiftIdsAddress(AvatarAddress); | ||
var claimedGiftIds = states.TryGetLegacyState(claimedGiftIdsAddress, out List rawIds) | ||
? rawIds.ToList(StateExtensions.ToInteger) | ||
: new List<int>(); | ||
if (claimedGiftIds.Contains(giftRow.Id)) | ||
{ | ||
throw new AlreadyClaimedGiftException( | ||
$"[{addressesHex}] Already claimed gift: {giftRow.Id}" | ||
); | ||
} | ||
|
||
var itemSheet = sheets.GetItemSheet(); | ||
foreach (var (itemId, count) in giftRow.Rewards) | ||
{ | ||
var item = ItemFactory.CreateItem(itemSheet[itemId], random); | ||
if (item is INonFungibleItem) | ||
{ | ||
foreach (var _ in Enumerable.Range(0, count)) | ||
{ | ||
avatarState.inventory.AddItem(item); | ||
} | ||
} | ||
else | ||
{ | ||
avatarState.inventory.AddItem(item, count); | ||
} | ||
} | ||
|
||
claimedGiftIds.Add(giftRow.Id); | ||
|
||
return states | ||
.SetLegacyState(claimedGiftIdsAddress, claimedGiftIds.Aggregate(List.Empty, | ||
(current, giftId) => current.Add(giftId.Serialize()))) | ||
.SetAvatarState(AvatarAddress, avatarState, setWorldInformation: false, setQuestList: false); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using System; | ||
using System.Runtime.Serialization; | ||
|
||
namespace Nekoyume.Action | ||
{ | ||
[Serializable] | ||
public class AlreadyClaimedGiftException : Exception | ||
{ | ||
public AlreadyClaimedGiftException() | ||
{ | ||
} | ||
|
||
public AlreadyClaimedGiftException(string msg) : base(msg) | ||
{ | ||
} | ||
|
||
public AlreadyClaimedGiftException(SerializationInfo info, StreamingContext context) : base(info, context) | ||
{ | ||
} | ||
} | ||
|
||
[Serializable] | ||
public class ClaimableGiftDoesNotExistException : Exception | ||
{ | ||
public ClaimableGiftDoesNotExistException() | ||
{ | ||
} | ||
|
||
public ClaimableGiftDoesNotExistException(string msg) : base(msg) | ||
{ | ||
} | ||
|
||
public ClaimableGiftDoesNotExistException(SerializationInfo info, StreamingContext context) : base(info, context) | ||
{ | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using static Nekoyume.TableData.TableExtensions; | ||
|
||
namespace Nekoyume.TableData | ||
{ | ||
public class OneTimeGiftSheet : Sheet<int, OneTimeGiftSheet.Row> | ||
{ | ||
public class Row : SheetRow<int> | ||
{ | ||
public override int Key => Id; | ||
public int Id; | ||
public long StartedBlockIndex; | ||
public long EndedBlockIndex; | ||
public List<(int itemId, int Count)> Rewards; | ||
|
||
public override void Set(IReadOnlyList<string> fields) | ||
{ | ||
Id = ParseInt(fields[0]); | ||
StartedBlockIndex = ParseLong(fields[1]); | ||
EndedBlockIndex = ParseLong(fields[2]); | ||
|
||
Rewards = new List<(int, int)>(); | ||
for (int i = 0; i < 5; i++) | ||
{ | ||
var offset = i * 2; | ||
if (!TryParseInt(fields[3 + offset], out var materialId) || materialId == 0 || | ||
!TryParseInt(fields[4 + offset], out var count) || count == 0) | ||
{ | ||
continue; | ||
} | ||
|
||
Rewards.Add((materialId, count)); | ||
} | ||
} | ||
} | ||
|
||
public OneTimeGiftSheet() : base(nameof(OneTimeGiftSheet)) | ||
{ | ||
} | ||
|
||
public bool TryFindRowByBlockIndex(long blockIndex, out Row row) | ||
{ | ||
row = OrderedList.FirstOrDefault(r => r.StartedBlockIndex <= blockIndex && blockIndex <= r.EndedBlockIndex); | ||
return row != null; | ||
} | ||
} | ||
} |