/// <summary> /// TableSheetsState를 기준으로 초기화합니다. /// </summary> /// <param name="tableSheetsState">기준으로 삼을 상태입니다.</param> public void InitializeWithTableSheetsState(TableSheetsState tableSheetsState) { foreach (var pair in tableSheetsState.TableSheets) { SetToSheet(pair.Key, pair.Value); } ItemSheetInitialize(); QuestSheetInitialize(); }
public static TableSheets FromTableSheetsState(TableSheetsState tableSheetsState) { if (Cache.TryGetValue(tableSheetsState, out var cached)) { return(cached); } var tableSheets = new TableSheets(); tableSheets.InitializeWithTableSheetsState(tableSheetsState); Cache.Add(tableSheetsState, tableSheets); return(tableSheets); }
protected override void LoadPlainValueInternal(IImmutableDictionary <string, IValue> plainValue) { RankingState = new RankingState((Bencodex.Types.Dictionary)plainValue["ranking_state"]); ShopState = new ShopState((Bencodex.Types.Dictionary)plainValue["shop_state"]); TableSheetsState = new TableSheetsState((Bencodex.Types.Dictionary)plainValue["table_sheets_state"]); GameConfigState = new GameConfigState((Bencodex.Types.Dictionary)plainValue["game_config_state"]); RedeemCodeState = new RedeemCodeState((Bencodex.Types.Dictionary)plainValue["redeem_code_state"]); AdminAddressState = new AdminState((Bencodex.Types.Dictionary)plainValue["admin_address_state"]); ActivatedAccountsState = new ActivatedAccountsState( (Bencodex.Types.Dictionary)plainValue["activated_accounts_state"] ); GoldCurrencyState = new GoldCurrencyState( (Bencodex.Types.Dictionary)plainValue["gold_currency_state"] ); }
public CombinationConsumableTest() { _agentAddress = default; _avatarAddress = _agentAddress.Derive("avatar"); _slotAddress = _avatarAddress.Derive( string.Format( CultureInfo.InvariantCulture, CombinationSlotState.DeriveFormat, 0 ) ); _tableSheetsState = TableSheetsImporter.ImportTableSheets(); _tableSheets = TableSheets.FromTableSheetsState(_tableSheetsState); _random = new ItemEnhancementTest.TestRandom(); }
public override IAccountStateDelta Execute(IActionContext context) { IActionContext ctx = context; var states = ctx.PreviousStates; var weeklyArenaState = new WeeklyArenaState(0); if (ctx.Rehearsal) { states = states.SetState(RankingState.Address, MarkChanged); states = states.SetState(ShopState.Address, MarkChanged); states = states.SetState(TableSheetsState.Address, MarkChanged); states = states.SetState(weeklyArenaState.address, MarkChanged); states = states.SetState(GameConfigState.Address, MarkChanged); states = states.SetState(RedeemCodeState.Address, MarkChanged); states = states.SetState(AdminState.Address, MarkChanged); states = states.SetState(ActivatedAccountsState.Address, MarkChanged); states = states.SetState(GoldCurrencyState.Address, MarkChanged); states = states.SetState(Addresses.GoldDistribution, MarkChanged); return(states); } if (ctx.BlockIndex != 0) { return(states); } states = states .SetState(weeklyArenaState.address, weeklyArenaState.Serialize()) .SetState(RankingState.Address, RankingState.Serialize()) .SetState(ShopState.Address, ShopState.Serialize()) .SetState(TableSheetsState.Address, TableSheetsState.Serialize()) .SetState(GameConfigState.Address, GameConfigState.Serialize()) .SetState(RedeemCodeState.Address, RedeemCodeState.Serialize()) .SetState(AdminState.Address, AdminAddressState.Serialize()) .SetState(ActivatedAccountsState.Address, ActivatedAccountsState.Serialize()) .SetState(GoldCurrencyState.Address, GoldCurrencyState.Serialize()) .SetState(Addresses.GoldDistribution, GoldDistributions.Select(v => v.Serialize()).Serialize()); states = states.MintAsset(GoldCurrencyState.Address, GoldCurrencyState.Currency, 1000000000); return(states); }
public static TableSheets FromTableSheetsState(TableSheetsState tableSheetsState) { if (Cache.TryGetValue(tableSheetsState, out var cached)) { return(cached); } var tableSheets = new TableSheets(); tableSheets.InitializeWithTableSheetsState(tableSheetsState); // Avoid Exception when run parallel tests try { Cache.Add(tableSheetsState, tableSheets); } catch (ArgumentException e) { Console.WriteLine(e); } return(tableSheets); }
public ItemEnhancementTest() { var sheets = new Dictionary <string, string>(); var currentDir = Path.GetDirectoryName(Directory.GetCurrentDirectory()); Debug.Assert(currentDir != null, nameof(currentDir) + " != null"); var baseDir = currentDir.Split(nameof(Lib9c))[0]; var dir = Path.Combine(baseDir, "nekoyume", "Assets", "AddressableAssets", "TableCSV"); var files = Directory.GetFiles(dir, "*.csv", SearchOption.AllDirectories); foreach (var filePath in files) { var fileName = Path.GetFileName(filePath); if (fileName.EndsWith(".csv")) { fileName = fileName.Split(".csv")[0]; } sheets[fileName] = File.ReadAllText(filePath); } _tableSheetsState = new TableSheetsState(sheets); _random = new TestRandom(); }
public override IAccountStateDelta Execute(IActionContext context) { IActionContext ctx = context; var states = ctx.PreviousStates; if (ctx.Rehearsal) { return(states .SetState(TableSheetsState.Address, MarkChanged) .SetState(GameConfigState.Address, MarkChanged)); } CheckPermission(context); var tableSheetsState = TableSheetsState.FromActionContext(ctx); Log.Debug($"[{ctx.BlockIndex}] {TableName} was patched by {ctx.Signer.ToHex()}\n" + "before:\n" + (tableSheetsState.TableSheets.TryGetValue(TableName, out string value) ? value : string.Empty) + "\n" + "after:\n" + TableCsv ); TableSheetsState nextState = tableSheetsState.UpdateTableSheet(TableName, TableCsv); states = states.SetState(TableSheetsState.Address, nextState.Serialize()); if (TableName == nameof(GameConfigSheet)) { var gameConfigState = new GameConfigState(TableCsv); states = states.SetState(GameConfigState.Address, gameConfigState.Serialize()); } return(states); }
public RedeemCodeTest() { _tableSheetsState = TableSheetsImporter.ImportTableSheets(); _tableSheets = TableSheets.FromTableSheetsState(_tableSheetsState); }
public static TableSheets FromActionContext(IActionContext ctx) { var tableSheetsState = TableSheetsState.FromActionContext(ctx); return(FromTableSheetsState(tableSheetsState)); }
public override IAccountStateDelta Execute(IActionContext context) { IActionContext ctx = context; var states = ctx.PreviousStates; if (ctx.Rehearsal) { states = states.SetState(RankingState.Address, MarkChanged); states = states.SetState(avatarAddress, MarkChanged); states = states.SetState(WeeklyArenaAddress, MarkChanged); return(states.SetState(ctx.Signer, MarkChanged)); } var sw = new Stopwatch(); sw.Start(); var started = DateTimeOffset.UtcNow; Log.Debug("HAS exec started."); if (!states.TryGetAgentAvatarStates( ctx.Signer, avatarAddress, out AgentState agentState, out AvatarState avatarState)) { return(LogError( context, "Aborted as the avatar state of the signer was failed to load.")); } sw.Stop(); Log.Debug("HAS Get AgentAvatarStates: {Elapsed}", sw.Elapsed); sw.Restart(); var tableSheetState = TableSheetsState.FromActionContext(ctx); sw.Stop(); Log.Debug("HAS Get TableSheetsState: {Elapsed}", sw.Elapsed); sw.Restart(); var tableSheets = TableSheets.FromTableSheetsState(tableSheetState); sw.Stop(); Log.Debug("HAS Initialize TableSheets: {Elapsed}", sw.Elapsed); // worldId와 stageId가 유효한지 확인합니다. if (!tableSheets.WorldSheet.TryGetValue(worldId, out var worldRow)) { return(LogError( context, "Not fount {WorldId} in TableSheets.WorldSheet.", worldId )); } if (stageId < worldRow.StageBegin || stageId > worldRow.StageEnd) { return(LogError( context, "{WorldId} world is not contains {StageId} stage: {StageBegin}-{StageEnd}", stageId, worldRow.Id, worldRow.StageBegin, worldRow.StageEnd )); } if (!tableSheets.StageSheet.TryGetValue(stageId, out var stageRow)) { return(LogError( context, "Not fount stage id in TableSheets.StageSheet: {StageId}", stageId )); } var worldInformation = avatarState.worldInformation; if (!worldInformation.TryGetWorld(worldId, out var world)) { // NOTE: 이 경우는 아바타 생성 시에는 WorldSheet에 없던 worldId가 새로 추가된 경우로 볼 수 있습니다. if (!worldInformation.TryAddWorld(worldRow, out world)) { return(LogError(context, "Failed to add {WorldId} world to WorldInformation.", worldId)); } } if (!world.IsUnlocked) { return(LogError(context, "Aborted as the world {WorldId} is locked.", worldId)); } if (world.StageBegin != worldRow.StageBegin || world.StageEnd != worldRow.StageEnd) { // NOTE: 이 경우는 아바타 생성 이후에 worldId가 포함하는 stageId의 범위가 바뀐 경우로 볼 수 있습니다. if (!worldInformation.TryUpdateWorld(worldRow, out world)) { return(LogError(context, "Failed to update {WorldId} world in WorldInformation.", worldId)); } if (world.StageBegin != worldRow.StageBegin || world.StageEnd != worldRow.StageEnd) { return(LogError(context, "Failed to update {WorldId} world in WorldInformation.", worldId)); } } if (world.IsStageCleared && stageId > world.StageClearedId + 1 || !world.IsStageCleared && stageId != world.StageBegin) { return(LogError( context, "Aborted as the stage ({WorldId}/{StageId}) is not cleared; cleared stage: {StageClearedId}", worldId, stageId, world.StageClearedId )); } // 장비가 유효한지 검사한다. if (!avatarState.ValidateEquipments(equipments, context.BlockIndex)) { // 장비가 유효하지 않은 에러. return(LogError(context, "Aborted as the equipment is invalid.")); } sw.Restart(); if (avatarState.actionPoint < stageRow.CostAP) { return(LogError( context, "Aborted due to insufficient action point: {ActionPointBalance} < {ActionCost}", avatarState.actionPoint, stageRow.CostAP )); } avatarState.actionPoint -= stageRow.CostAP; avatarState.EquipCostumes(costumes); avatarState.EquipEquipments(equipments); sw.Stop(); Log.Debug("HAS Unequip items: {Elapsed}", sw.Elapsed); sw.Restart(); var simulator = new StageSimulator( ctx.Random, avatarState, foods, worldId, stageId, tableSheets ); sw.Stop(); Log.Debug("HAS Initialize Simulator: {Elapsed}", sw.Elapsed); sw.Restart(); simulator.Simulate(); sw.Stop(); Log.Debug("HAS Simulator.Simulate(): {Elapsed}", sw.Elapsed); Log.Debug( "Execute HackAndSlash({AvatarAddress}); worldId: {WorldId}, stageId: {StageId}, result: {Result}, " + "clearWave: {ClearWave}, totalWave: {TotalWave}", avatarAddress, worldId, stageId, simulator.Log.result, simulator.Log.clearedWaveNumber, simulator.Log.waveCount ); sw.Restart(); if (simulator.Log.IsClear) { try { simulator.Player.worldInformation.ClearStage( worldId, stageId, ctx.BlockIndex, tableSheets.WorldSheet, tableSheets.WorldUnlockSheet ); } catch (FailedToUnlockWorldException e) { Log.Error(e.Message); throw; } } sw.Stop(); Log.Debug("HAS ClearStage: {Elapsed}", sw.Elapsed); sw.Restart(); avatarState.Update(simulator); avatarState.UpdateQuestRewards(ctx); avatarState.updatedAt = DateTimeOffset.UtcNow; states = states.SetState(avatarAddress, avatarState.Serialize()); sw.Stop(); Log.Debug("HAS Set AvatarState: {Elapsed}", sw.Elapsed); sw.Restart(); if (states.TryGetState(RankingState.Address, out Dictionary d) && simulator.Log.IsClear) { var ranking = new RankingState(d); ranking.Update(avatarState); sw.Stop(); Log.Debug("HAS Update RankingState: {Elapsed}", sw.Elapsed); sw.Restart(); var serialized = ranking.Serialize(); sw.Stop(); Log.Debug("HAS Serialize RankingState: {Elapsed}", sw.Elapsed); sw.Restart(); states = states.SetState(RankingState.Address, serialized); } sw.Stop(); Log.Debug("HAS Set RankingState: {Elapsed}", sw.Elapsed); sw.Restart(); if (states.TryGetState(WeeklyArenaAddress, out Dictionary weeklyDict)) { var weekly = new WeeklyArenaState(weeklyDict); if (!weekly.Ended) { if (weekly.ContainsKey(avatarAddress)) { var info = weekly[avatarAddress]; info.Update(avatarState, tableSheets.CharacterSheet); weekly.Update(info); } else { weekly.Set(avatarState, tableSheets.CharacterSheet); } sw.Stop(); Log.Debug("HAS Update WeeklyArenaState: {Elapsed}", sw.Elapsed); sw.Restart(); var weeklySerialized = weekly.Serialize(); sw.Stop(); Log.Debug("HAS Serialize RankingState: {Elapsed}", sw.Elapsed); states = states.SetState(weekly.address, weeklySerialized); } } Result = simulator.Log; var ended = DateTimeOffset.UtcNow; Log.Debug("HAS Total Executed Time: {Elapsed}", ended - started); return(states.SetState(ctx.Signer, agentState.Serialize())); }
public RankingBattleTest() { _tableSheetsState = TableSheetsImporter.ImportTableSheets(); }
public override IAccountStateDelta Execute(IActionContext context) { IActionContext ctx = context; var states = ctx.PreviousStates; if (ctx.Rehearsal) { return(states.SetState(ctx.Signer, MarkChanged) .SetState(AvatarAddress, MarkChanged) .SetState(WeeklyArenaAddress, MarkChanged) .SetState(ctx.Signer, MarkChanged) .MarkBalanceChanged(GoldCurrencyMock, ctx.Signer, WeeklyArenaAddress)); } if (AvatarAddress.Equals(EnemyAddress)) { return(LogError(context, "Aborted as the signer tried to battle for themselves.")); } if (!states.TryGetAgentAvatarStates(ctx.Signer, AvatarAddress, out var agentState, out var avatarState)) { return(LogError(context, "Aborted as the avatar state of the signer was failed to load.")); } // 도전자의 장비가 유효한지 검사한다. // 피도전자의 장비도 검사해야 하는가는 모르겠다. 이후에 필요하다면 추가하는 것으로 한다. if (!avatarState.ValidateEquipments(equipmentIds, context.BlockIndex)) { // 장비가 유효하지 않은 에러. return(LogError(context, "Aborted as the equipment is invalid.")); } if (!avatarState.worldInformation.TryGetUnlockedWorldByStageClearedBlockIndex(out var world)) { return(LogError(context, "Aborted as the WorldInformation was failed to load or not cleared yet.")); } if (world.StageClearedId < GameConfig.RequireClearedStageLevel.ActionsInRankingBoard) { // 스테이지 클리어 부족 에러. return(LogError( context, "Aborted as the signer is not cleared the minimum stage level required to battle with other players yet: {ClearedLevel} < {RequiredLevel}.", world.StageClearedId, GameConfig.RequireClearedStageLevel.ActionsInRankingBoard )); } avatarState.EquipCostumes(costumeIds); avatarState.EquipEquipments(equipmentIds); var enemyAvatarState = states.GetAvatarState(EnemyAddress); if (enemyAvatarState is null) { return(LogError( context, "Aborted as the avatar state of the opponent ({OpponentAddress}) was failed to load.", EnemyAddress )); } var weeklyArenaState = states.GetWeeklyArenaState(WeeklyArenaAddress); //FIXME 오류던지게 고쳐야함 if (weeklyArenaState.Ended) { return(LogError(context, "Aborted as the weekly arena state already ended.")); } if (!weeklyArenaState.ContainsKey(AvatarAddress)) { return(LogError(context, "Aborted as the weekly arena state was failed to load.")); } var arenaInfo = weeklyArenaState[AvatarAddress]; if (arenaInfo.DailyChallengeCount <= 0) { return(LogError(context, "Aborted as the arena state reached the daily limit.")); } if (!arenaInfo.Active) { FungibleAssetValue agentBalance = states.GetBalance(ctx.Signer, states.GetGoldCurrency()); if (agentBalance >= new FungibleAssetValue(agentBalance.Currency, EntranceFee, 0)) { states = states.TransferAsset( ctx.Signer, WeeklyArenaAddress, new FungibleAssetValue( states.GetGoldCurrency(), EntranceFee, 0 ) ); arenaInfo.Activate(); } else { return(LogError( context, "Aborted as the signer's balance ({Balance}) is insufficient to pay entrance fee/stake ({EntranceFee}).", agentBalance, EntranceFee )); } } if (!weeklyArenaState.ContainsKey(EnemyAddress)) { return(LogError( context, "Aborted as the opponent ({OpponentAddress}) is not registered in the weekly arena state.", EnemyAddress )); } Log.Debug(weeklyArenaState.address.ToHex()); var tableSheetState = TableSheetsState.FromActionContext(ctx); var tableSheets = TableSheets.FromTableSheetsState(tableSheetState); var simulator = new RankingSimulator( ctx.Random, avatarState, enemyAvatarState, consumableIds, tableSheets, StageId); simulator.Simulate(); simulator.Log.diffScore = arenaInfo.Update(avatarState, weeklyArenaState[EnemyAddress], simulator.Result); simulator.Log.score = arenaInfo.Score; Result = simulator.Log; foreach (var itemBase in simulator.Reward) { avatarState.inventory.AddItem(itemBase); } return(states .SetState(ctx.Signer, agentState.Serialize()) .SetState(WeeklyArenaAddress, weeklyArenaState.Serialize()) .SetState(AvatarAddress, avatarState.Serialize())); }
public void Dispose() { _tableSheetsState = null; }
public ItemEnhancementTest() { _tableSheetsState = TableSheetsImporter.ImportTableSheets(); _random = new TestRandom(); }