Пример #1
0
 public MruAction(IActionContext context, ConfigSource source)
     : base(context)
 {
     _source = source;
     this.Caption = _source.DisplayName;
     this.IconUri = _source.IconUri;
 }
Пример #2
0
 public AssignCryptoAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.AssignCryptoCaption;
     this.Tooltip = ActionsRes.AssignCryptoTooltip;
     this.IconUri = As.ResourceUri("Key.png");
 }
Пример #3
0
		public void Run(IActionContext actionContext)
		{
			IFlow flow = actionContext.GetFlow();
			INode currentNode = flow.Node;
			
			if ("do bloody thing".Equals(currentNode.Name))
			//'do bloody thing' hasn't been performed
			{
				IExecutionSessionLocal executionComponent = (IExecutionSessionLocal) serviceLocator.GetService(typeof(IExecutionSessionLocal));
				try
				{
					//ae is a robot. Human (in) is incapable. Let robot replace him.
					executionComponent.DelegateActivity(flow.Id, "ae");
					
					//call external component (robot web service) to act on the flow
					System.Console.Out.WriteLine("calling robot web service to act on the flow... [ok]");
					
					//Now, revenge time: director fires originally assigned executor
					System.Console.Out.WriteLine("Isaac, you're fired!");
				}
				catch (ExecutionException e)
				{
					throw new System.SystemException("failed executing task: " + typeof(OvertakingAction) + " " + e.Message);
				}
				finally
				{
					serviceLocator.Release(executionComponent);
				}
			}
		}
Пример #4
0
 public ExitAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.ExitCaption;
     this.IconUri = As.ResourceUri("Close.png");
     this.InputGesture = "Alt+F4";
 }
Пример #5
0
 public AddSectionAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.AddSectionCaption;
     this.Tooltip = ActionsRes.AddSectionTooltip;
     this.IconUri = As.ResourceUri("AddLg.png");
 }
Пример #6
0
 public CollapseAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.CollapseSectionsCaption;
     this.IconUri = As.ResourceUri("Collapse.png");
     this.InputGesture = "F3";
 }
Пример #7
0
 public DeleteAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.DeleteCaption;
     this.Tooltip = ActionsRes.DeleteTooltip;
     this.IconUri = As.ResourceUri("Delete.png");
 }
Пример #8
0
 public OptionsAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.OptionsCaption;
     this.Tooltip = ActionsRes.OptionsTooltip;
     this.IconUri = As.ResourceUri("Options.png");
 }
Пример #9
0
		private void CopyInterpreterToAttributes(InteractiveInterpreter interpreter,
												IActionContext context)
		{
			IDictionaryEnumerator configEnum;
			configEnum=context.GetConfiguration().GetEnumerator();
			while(configEnum.MoveNext())
			{
				DictionaryEntry property;
				property = (DictionaryEntry)configEnum.Current;
				if (!property.Key.Equals("script"))
				{
					object attributeValue = context.GetAttribute((String)property.Key);
					object interpreterValue = interpreter.GetValue((String)property.Key);
					// Change the attribute only if the value changed and is marked for copying
					if (!property.Key.Equals("script") && attributeValue != null 
						&& ! attributeValue.Equals(interpreterValue)
						&& property.Value.ToString().IndexOf("Out")!=-1 )
					{
						if (log.IsDebugEnabled)
						{
							log.Debug("copy from <-interpreter key:"+property.Key+" oldvalue:"+attributeValue+ " newvalue:"+interpreterValue);
						}
						context.SetAttribute((String)property.Key,interpreterValue);
					}
				}
			}
		}
Пример #10
0
 public ExpandAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.ExpandSectionsCaption;
     this.IconUri = As.ResourceUri("Expand.png");
     this.InputGesture = "F2";
 }
Пример #11
0
        public IEnumerable<IActionItem> GetMenuActions(IActionContext context)
        {
            var container = new ActionItemParent(context, "SampleActions")
                                .AddRange(
                                    new SimpleViewAction(context));

            yield return container;
        }
Пример #12
0
 public SaveAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.SaveCaption;
     this.Tooltip = ActionsRes.SaveTooltip;
     this.IconUri = As.ResourceUri("Save.png");
     this.InputGesture = "Ctrl+S";
 }
Пример #13
0
 public NewAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.NewCaption;
     this.Tooltip = ActionsRes.NewTooltip;
     this.IconUri = As.ResourceUri("New.png");
     this.InputGesture = "Ctrl+N";
 }
Пример #14
0
 public RefreshAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.RefreshCaption;
     this.Tooltip = ActionsRes.RefreshTooltip;
     this.IconUri = As.ResourceUri("Refresh.png");
     this.InputGesture = "F5";
 }
Пример #15
0
 public OpenAction(IActionContext context)
     : base(context)
 {
     this.Caption = ActionsRes.OpenCaption;
     this.Tooltip = ActionsRes.OpenTooltip;
     this.IconUri = As.ResourceUri("Open.png");
     this.InputGesture = "Ctrl+O";
 }
Пример #16
0
		public void  Run(IActionContext interactionContext)
		{
			IProcessInstance processInstance = interactionContext.GetProcessInstance();
			
			Job job = new Job(processInstance.ProcessDefinition, "NetBpm.Example.Delegate.OvertakingAction, NetBpm.Example");
			DateTime scheduleDate = DateTime.Now;
//			DateTime scheduleDate = new DateTime((System.DateTime.Now.Ticks - 621355968000000000) / 10000 + 2000);
			job.Date=scheduleDate;
			job.SetAuthentication("cg", "cg");
			
			//When the assigned executor can't be relied on, 
			//director has to step in and make some actions	
			interactionContext.Schedule(job);
		}
Пример #17
0
		public void Run(IActionContext actionContext)
		{
			InteractiveInterpreter interpreter = new InteractiveInterpreter();

			IDictionary configuration = actionContext.GetConfiguration();
			String script = (String) configuration["script"];
			if (script == null)
			{
				throw new ArgumentException("Can’t find boo script in configuration! Please check processdefiniton.xml if action defines <parameter name = \"script\">");
			}

			CopyAttributesToInterpreter(interpreter,actionContext);
			interpreter.Eval(script);
			CopyInterpreterToAttributes(interpreter,actionContext);
		}
Пример #18
0
		public void Run(IActionContext actionContext)
		{
			// Lets show that we have been here :-) 
			log.Debug(" ");
			log.Debug("H   H EEEEE L     L      OOO      W   W  OOO  RRRR  L     DDDD ");
			log.Debug("H   H E     L     L     O   O     W   W O   O R   R L     D   D");
			log.Debug("HHHHH EEE   L     L     O   O     W   W O   O R   R L     D   D");
			log.Debug("H   H E     L     L     O   O     W W W O   O RRRR  L     D   D");
			log.Debug("H   H E     L     L     O   O     W W W O   O R  R  L     D   D");
			log.Debug("H   H EEEEE LLLLL LLLLL  OOO       W W   OOO  R   R LLLLL DDDD ");
			log.Debug(" ");
			
			// The next log message will be stored in the netbpm-logs of the flow. 
			actionContext.AddLog("HELLO WORLD");
		}
Пример #19
0
		private void CopyAttributesToInterpreter(InteractiveInterpreter interpreter,
												IActionContext context)
		{
			IDictionaryEnumerator configEnum;
			configEnum=context.GetConfiguration().GetEnumerator();
			while(configEnum.MoveNext())
			{
				DictionaryEntry property;
				property = (DictionaryEntry)configEnum.Current;
				if (!property.Key.Equals("script") && property.Value.ToString().IndexOf("In")!=-1)
				{
					object attributeValue;
					attributeValue = context.GetAttribute((String)property.Key);
					if (log.IsDebugEnabled)
					{
						log.Debug("copy to ->interpreter key:"+property.Key+" value:"+attributeValue);
					}
					interpreter.SetValue((String)property.Key,attributeValue);
				}
			}
		}
Пример #20
0
		public void Run(IActionContext actionContext)
		{
			IDictionary configuration = actionContext.GetConfiguration();
			String subject = (String) configuration["subject"];
			String message = (String) configuration["message"];
			String from = (String) configuration["from"];
			String to = (String) configuration["to"];

			// resolving the texts
			subject = _attributeExpressionResolver.ResolveAttributeExpression(subject, actionContext);
			message = _attributeExpressionResolver.ResolveAttributeExpression(message, actionContext);
			IUser user = (IUser) _actorExpressionResolver.ResolveArgument(to, actionContext);
			to = user.Email;
			if ((Object) from == null)
			{
				from = actionContext.GetProcessDefinition().Name;
				from = from.ToLower();
				from = from.Replace(' ', '.');
				from += "@netbpm.org";
			}

			SendMail(from, to, subject, message, actionContext);
		}
Пример #21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ActionItemBase"/> class.
 /// </summary>
 /// <param name="context">The action context.</param>
 public ActionItemBase(IActionContext context)
 {
     this.Context = context;
     this.IsVisible = true;
 }
Пример #22
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IActionContext ctx    = context;
            var            states = ctx.PreviousStates;

            if (ctx.Rehearsal)
            {
                states = states
                         .SetState(buyerAvatarAddress, MarkChanged)
                         .SetState(ctx.Signer, MarkChanged)
                         .SetState(sellerAvatarAddress, MarkChanged)
                         .MarkBalanceChanged(
                    GoldCurrencyMock,
                    ctx.Signer,
                    sellerAgentAddress,
                    GoldCurrencyState.Address);
                return(states.SetState(ShopState.Address, MarkChanged));
            }

            if (ctx.Signer.Equals(sellerAgentAddress))
            {
                throw new InvalidAddressException("Aborted as the signer is the seller.");
            }

            var sw = new Stopwatch();

            sw.Start();
            var started = DateTimeOffset.UtcNow;

            Log.Debug("Buy exec started.");

            if (!states.TryGetAvatarState(ctx.Signer, buyerAvatarAddress, out var buyerAvatarState))
            {
                throw new FailedLoadStateException("Aborted as the avatar state of the buyer was failed to load.");
            }
            sw.Stop();
            Log.Debug("Buy Get Buyer AgentAvatarStates: {Elapsed}", sw.Elapsed);
            sw.Restart();

            if (!buyerAvatarState.worldInformation.IsStageCleared(GameConfig.RequireClearedStageLevel.ActionsInShop))
            {
                buyerAvatarState.worldInformation.TryGetLastClearedStageId(out var current);
                throw new NotEnoughClearedStageLevelException(GameConfig.RequireClearedStageLevel.ActionsInShop, current);
            }

            if (!states.TryGetState(ShopState.Address, out Bencodex.Types.Dictionary shopStateDict))
            {
                throw new FailedLoadStateException("Aborted as the shop state was failed to load.");
            }

            sw.Stop();
            Log.Debug("Buy Get ShopState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            Log.Debug("Execute Buy; buyer: {Buyer} seller: {Seller}", buyerAvatarAddress, sellerAvatarAddress);
            // 상점에서 구매할 아이템을 찾는다.
            Dictionary products = (Dictionary)shopStateDict["products"];

            IKey productIdSerialized = (IKey)productId.Serialize();

            if (!products.ContainsKey(productIdSerialized))
            {
                throw new ItemDoesNotExistException(
                          $"Aborted as the shop item ({productId}) was failed to get from the shop."
                          );
            }

            ShopItem shopItem = new ShopItem((Dictionary)products[productIdSerialized]);

            if (!shopItem.SellerAgentAddress.Equals(sellerAgentAddress))
            {
                throw new ItemDoesNotExistException(
                          $"Aborted as the shop item ({productId}) of seller ({shopItem.SellerAgentAddress}) is different from ({sellerAgentAddress})."
                          );
            }
            sw.Stop();
            Log.Debug($"Buy Get Item: {sw.Elapsed}");
            sw.Restart();

            if (!states.TryGetAvatarState(sellerAgentAddress, sellerAvatarAddress, out var sellerAvatarState))
            {
                throw new FailedLoadStateException(
                          $"Aborted as the seller agent/avatar was failed to load from {sellerAgentAddress}/{sellerAvatarAddress}."
                          );
            }
            sw.Stop();
            Log.Debug($"Buy Get Seller AgentAvatarStates: {sw.Elapsed}");
            sw.Restart();

            // 돈은 있냐?
            FungibleAssetValue buyerBalance = states.GetBalance(context.Signer, states.GetGoldCurrency());

            if (buyerBalance < shopItem.Price)
            {
                throw new InsufficientBalanceException(
                          ctx.Signer,
                          buyerBalance,
                          $"Aborted as the buyer ({ctx.Signer}) has no sufficient gold: {buyerBalance} < {shopItem.Price}"
                          );
            }

            var tax        = shopItem.Price.DivRem(100, out _) * TaxRate;
            var taxedPrice = shopItem.Price - tax;

            // 세금을 송금한다.
            states = states.TransferAsset(
                context.Signer,
                GoldCurrencyState.Address,
                tax);

            // 구매자의 돈을 판매자에게 송금한다.
            states = states.TransferAsset(
                context.Signer,
                sellerAgentAddress,
                taxedPrice
                );

            products      = (Dictionary)products.Remove(productIdSerialized);
            shopStateDict = shopStateDict.SetItem("products", products);

            // 구매자, 판매자에게 결과 메일 전송
            buyerResult = new Buy.BuyerResult
            {
                shopItem   = shopItem,
                itemUsable = shopItem.ItemUsable
            };
            var buyerMail = new BuyerMail(buyerResult, ctx.BlockIndex, ctx.Random.GenerateRandomGuid(), ctx.BlockIndex);

            buyerResult.id = buyerMail.id;

            sellerResult = new Buy.SellerResult
            {
                shopItem   = shopItem,
                itemUsable = shopItem.ItemUsable,
                gold       = taxedPrice
            };
            var sellerMail = new SellerMail(sellerResult, ctx.BlockIndex, ctx.Random.GenerateRandomGuid(),
                                            ctx.BlockIndex);

            sellerResult.id = sellerMail.id;

            buyerAvatarState.UpdateV2(buyerMail);
            buyerAvatarState.UpdateFromAddItem(buyerResult.itemUsable, false);
            sellerAvatarState.UpdateV2(sellerMail);

            // 퀘스트 업데이트
            buyerAvatarState.questList.UpdateTradeQuest(TradeType.Buy, shopItem.Price);
            sellerAvatarState.questList.UpdateTradeQuest(TradeType.Sell, shopItem.Price);

            buyerAvatarState.updatedAt   = ctx.BlockIndex;
            buyerAvatarState.blockIndex  = ctx.BlockIndex;
            sellerAvatarState.updatedAt  = ctx.BlockIndex;
            sellerAvatarState.blockIndex = ctx.BlockIndex;

            var materialSheet = states.GetSheet <MaterialItemSheet>();

            buyerAvatarState.UpdateQuestRewards(materialSheet);
            sellerAvatarState.UpdateQuestRewards(materialSheet);

            states = states.SetState(sellerAvatarAddress, sellerAvatarState.Serialize());
            sw.Stop();
            Log.Debug("Buy Set Seller AvatarState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            states = states.SetState(buyerAvatarAddress, buyerAvatarState.Serialize());
            sw.Stop();
            Log.Debug("Buy Set Buyer AvatarState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            states = states.SetState(ShopState.Address, shopStateDict);
            sw.Stop();
            var ended = DateTimeOffset.UtcNow;

            Log.Debug("Buy Set ShopState: {Elapsed}", sw.Elapsed);
            Log.Debug("Buy Total Executed Time: {Elapsed}", ended - started);

            return(states);
        }
Пример #23
0
 public void Unrender(
     IActionContext context,
     IAccountStateDelta nextStates)
 {
 }
Пример #24
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IActionContext ctx                     = context;
            var            states                  = ctx.PreviousStates;
            var            inventoryAddress        = avatarAddress.Derive(LegacyInventoryKey);
            var            worldInformationAddress = avatarAddress.Derive(LegacyWorldInformationKey);
            var            questListAddress        = avatarAddress.Derive(LegacyQuestListKey);

            if (ctx.Rehearsal)
            {
                states = states.SetState(rankingMapAddress, MarkChanged);
                states = states.SetState(avatarAddress, MarkChanged);
                states = states
                         .SetState(inventoryAddress, MarkChanged)
                         .SetState(worldInformationAddress, MarkChanged)
                         .SetState(questListAddress, MarkChanged);
                return(states.SetState(ctx.Signer, MarkChanged));
            }

            var addressesHex = GetSignerAndOtherAddressesHex(context, avatarAddress);

            var sw = new Stopwatch();

            sw.Start();
            var started = DateTimeOffset.UtcNow;

            Log.Verbose("{AddressesHex}HAS exec started", addressesHex);

            if (!states.TryGetAvatarStateV2(ctx.Signer, avatarAddress, out AvatarState avatarState, out _))
            {
                throw new FailedLoadStateException($"{addressesHex}Aborted as the avatar state of the signer was failed to load.");
            }

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Get AgentAvatarStates: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            if (avatarState.RankingMapAddress != rankingMapAddress)
            {
                throw new InvalidAddressException($"{addressesHex}Invalid ranking map address");
            }

            var worldSheet = states.GetSheet <WorldSheet>();

            if (!worldSheet.TryGetValue(worldId, out var worldRow, false))
            {
                throw new SheetRowNotFoundException(addressesHex, nameof(WorldSheet), worldId);
            }

            if (stageId < worldRow.StageBegin ||
                stageId > worldRow.StageEnd)
            {
                throw new SheetRowColumnException(
                          $"{addressesHex}{worldId} world is not contains {worldRow.Id} stage: " +
                          $"{worldRow.StageBegin}-{worldRow.StageEnd}");
            }

            var stageSheet = states.GetSheet <StageSheet>();

            if (!stageSheet.TryGetValue(stageId, out var stageRow))
            {
                throw new SheetRowNotFoundException(addressesHex, nameof(StageSheet), stageId);
            }

            var worldInformation = avatarState.worldInformation;

            if (!worldInformation.TryGetWorld(worldId, out var world))
            {
                // NOTE: Add new World from WorldSheet
                worldInformation.AddAndUnlockNewWorld(worldRow, ctx.BlockIndex, worldSheet);
            }

            if (!world.IsUnlocked)
            {
                throw new InvalidWorldException($"{addressesHex}{worldId} is locked.");
            }

            if (world.StageBegin != worldRow.StageBegin ||
                world.StageEnd != worldRow.StageEnd)
            {
                worldInformation.UpdateWorld(worldRow);
            }

            if (world.IsStageCleared && stageId > world.StageClearedId + 1 ||
                !world.IsStageCleared && stageId != world.StageBegin)
            {
                throw new InvalidStageException(
                          $"{addressesHex}Aborted as the stage ({worldId}/{stageId}) is not cleared; " +
                          $"cleared stage: {world.StageClearedId}"
                          );
            }

            if (worldId == GameConfig.MimisbrunnrWorldId)
            {
                throw new InvalidWorldException($"{addressesHex}{worldId} can't execute HackAndSlash action.");
            }

            avatarState.ValidateEquipmentsV2(equipments, context.BlockIndex);
            avatarState.ValidateConsumable(foods, context.BlockIndex);
            avatarState.ValidateCostume(costumes);

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Validate: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            var costumeStatSheet = states.GetSheet <CostumeStatSheet>();

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS get CostumeStatSheet: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            if (playCount <= 0)
            {
                throw new PlayCountIsZeroException($"{addressesHex}playCount must be greater than 0. " +
                                                   $"current playCount : {playCount}");
            }

            var totalCostActionPoint = stageRow.CostAP * playCount;

            if (avatarState.actionPoint < totalCostActionPoint)
            {
                throw new NotEnoughActionPointException(
                          $"{addressesHex}Aborted due to insufficient action point: " +
                          $"{avatarState.actionPoint} < totalAP({totalCostActionPoint}) = cost({stageRow.CostAP}) * boostCount({playCount})"
                          );
            }

            avatarState.actionPoint -= totalCostActionPoint;

            var items = equipments.Concat(costumes);

            avatarState.EquipItems(items);
            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Unequip items: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            // Update QuestList only when QuestSheet.Count is greater than QuestList.Count
            var questList  = avatarState.questList;
            var questSheet = states.GetQuestSheet();

            if (questList.Count() < questSheet.Count)
            {
                questList.UpdateList(
                    questSheet,
                    states.GetSheet <QuestRewardSheet>(),
                    states.GetSheet <QuestItemRewardSheet>(),
                    states.GetSheet <EquipmentItemRecipeSheet>());
            }

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Update QuestList: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            var simulator = new StageSimulator(
                ctx.Random,
                avatarState,
                foods,
                worldId,
                stageId,
                states.GetStageSimulatorSheets(),
                costumeStatSheet,
                StageSimulator.ConstructorVersionV100080,
                playCount);

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Initialize Simulator: {Elapsed}", addressesHex, sw.Elapsed);

            sw.Restart();
            simulator.Simulate(playCount);
            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Simulator.SimulateV2(): {Elapsed}", addressesHex, sw.Elapsed);

            Log.Verbose(
                "{AddressesHex}Execute HackAndSlash({AvatarAddress}); worldId: {WorldId}, stageId: {StageId}, result: {Result}, " +
                "clearWave: {ClearWave}, totalWave: {TotalWave}",
                addressesHex,
                avatarAddress,
                worldId,
                stageId,
                simulator.Log.result,
                simulator.Log.clearedWaveNumber,
                simulator.Log.waveCount
                );

            sw.Restart();
            if (simulator.Log.IsClear)
            {
                var worldUnlockSheet = states.GetSheet <WorldUnlockSheet>();
                simulator.Player.worldInformation.ClearStage(
                    worldId,
                    stageId,
                    ctx.BlockIndex,
                    worldSheet,
                    worldUnlockSheet
                    );
            }

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS ClearStage: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            avatarState.Update(simulator);

            var materialSheet = states.GetSheet <MaterialItemSheet>();

            avatarState.UpdateQuestRewards(materialSheet);

            avatarState.updatedAt = ctx.BlockIndex;
            avatarState.mailBox.CleanUp();
            states = states
                     .SetState(avatarAddress, avatarState.SerializeV2())
                     .SetState(inventoryAddress, avatarState.inventory.Serialize())
                     .SetState(worldInformationAddress, avatarState.worldInformation.Serialize())
                     .SetState(questListAddress, avatarState.questList.Serialize());

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Set AvatarState: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            if (simulator.Log.IsClear && states.TryGetState(rankingMapAddress, out Dictionary d))
            {
                var ranking = new RankingMapState(d);
                ranking.Update(avatarState);

                sw.Stop();
                Log.Verbose("{AddressesHex}HAS Update RankingState: {Elapsed}", addressesHex, sw.Elapsed);
                sw.Restart();

                var serialized = ranking.Serialize();

                sw.Stop();
                Log.Verbose("{AddressesHex}HAS Serialize RankingState: {Elapsed}", addressesHex, sw.Elapsed);
                sw.Restart();
                states = states.SetState(rankingMapAddress, serialized);
            }
            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Set RankingState: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            TimeSpan totalElapsed = DateTimeOffset.UtcNow - started;

            Log.Verbose("{AddressesHex}HAS Total Executed Time: {Elapsed}", addressesHex, totalElapsed);
            return(states);
        }
 public ActiveConfigurationChangedMessage(IActionContext currentContext)
 {
     this.Context = currentContext;
 }
Пример #26
0
 public void Run(IActionContext actionContext)
 {
     actionContext.SetAttribute("the text attrib",":(");
 }
Пример #27
0
 public static void Execute(
     this IActor actor, IActionContext context, Func <IAction, bool> predicate) =>
 actor.FindAction(context, predicate).Iter(a => a.Execute(context));
Пример #28
0
 void ITestCase.Execute(IActionContext context)
 {
     Execute(context);
 }
Пример #29
0
 protected virtual void Execute(IActionContext context)
 {
 }
Пример #30
0
 public void UnrenderActionError(
     IAction action,
     IActionContext context,
     Exception exception
     ) =>
 Queue(() => ActionRenderer.UnrenderActionError(action, context, exception));
Пример #31
0
 public void UnrenderAction(
     IAction action,
     IActionContext context,
     IAccountStateDelta nextStates
     ) =>
 Queue(() => ActionRenderer.UnrenderAction(action, context, nextStates));
Пример #32
0
        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));
            }

            var addressesHex = GetSignerAndOtherAddressesHex(context, AvatarAddress, EnemyAddress);

            Log.Warning("ranking_battle is deprecated. Please use ranking_battle2");
            if (AvatarAddress.Equals(EnemyAddress))
            {
                throw new InvalidAddressException($"{addressesHex}Aborted as the signer tried to battle for themselves.");
            }

            if (!states.TryGetAgentAvatarStates(
                    ctx.Signer,
                    AvatarAddress,
                    out var agentState,
                    out var avatarState))
            {
                throw new FailedLoadStateException($"{addressesHex}Aborted as the avatar state of the signer was failed to load.");
            }

            var costumes = new HashSet <int>(costumeIds);

            avatarState.ValidateEquipments(equipmentIds, context.BlockIndex);
            avatarState.ValidateConsumable(consumableIds, context.BlockIndex);
            avatarState.ValidateCostume(costumes);

            if (!avatarState.worldInformation.TryGetUnlockedWorldByStageClearedBlockIndex(out var world) ||
                world.StageClearedId < GameConfig.RequireClearedStageLevel.ActionsInRankingBoard)
            {
                throw new NotEnoughClearedStageLevelException(
                          addressesHex,
                          GameConfig.RequireClearedStageLevel.ActionsInRankingBoard,
                          world.StageClearedId);
            }

            avatarState.EquipCostumes(costumes);
            avatarState.EquipEquipments(equipmentIds);

            var enemyAvatarState = states.GetAvatarState(EnemyAddress);

            if (enemyAvatarState is null)
            {
                throw new FailedLoadStateException($"{addressesHex}Aborted as the avatar state of the opponent ({EnemyAddress}) was failed to load.");
            }

            var weeklyArenaState = states.GetWeeklyArenaState(WeeklyArenaAddress);

            if (weeklyArenaState.Ended)
            {
                throw new WeeklyArenaStateAlreadyEndedException(
                          addressesHex + WeeklyArenaStateAlreadyEndedException.BaseMessage);
            }

            if (!weeklyArenaState.ContainsKey(AvatarAddress))
            {
                throw new WeeklyArenaStateNotContainsAvatarAddressException(addressesHex, AvatarAddress);
            }

            var arenaInfo = weeklyArenaState[AvatarAddress];

            if (arenaInfo.DailyChallengeCount <= 0)
            {
                throw new NotEnoughWeeklyArenaChallengeCountException(
                          addressesHex + NotEnoughWeeklyArenaChallengeCountException.BaseMessage);
            }

            if (!arenaInfo.Active)
            {
                FungibleAssetValue agentBalance = default;
                try
                {
                    agentBalance = states.GetBalance(ctx.Signer, states.GetGoldCurrency());
                }
                catch (InvalidOperationException)
                {
                    throw new NotEnoughFungibleAssetValueException(addressesHex, EntranceFee, agentBalance);
                }

                if (agentBalance >= new FungibleAssetValue(agentBalance.Currency, EntranceFee, 0))
                {
                    states = states.TransferAsset(
                        ctx.Signer,
                        WeeklyArenaAddress,
                        new FungibleAssetValue(
                            states.GetGoldCurrency(),
                            EntranceFee,
                            0
                            )
                        );
                    arenaInfo.Activate();
                }
                else
                {
                    throw new NotEnoughFungibleAssetValueException(addressesHex, EntranceFee, agentBalance);
                }
            }

            if (!weeklyArenaState.ContainsKey(EnemyAddress))
            {
                throw new WeeklyArenaStateNotContainsAvatarAddressException(addressesHex, EnemyAddress);
            }

            Log.Verbose("{WeeklyArenaStateAddress}", weeklyArenaState.address.ToHex());

            var simulator = new RankingSimulator(
                ctx.Random,
                avatarState,
                enemyAvatarState,
                consumableIds,
                states.GetRankingSimulatorSheets(),
                StageId,
                arenaInfo,
                weeklyArenaState[EnemyAddress]);

            simulator.Simulate();

            Result = simulator.Log;

            foreach (var itemBase in simulator.Reward.OrderBy(i => i.Id))
            {
                avatarState.inventory.AddItem(itemBase);
            }

            return(states
                   .SetState(ctx.Signer, agentState.Serialize())
                   .SetState(WeeklyArenaAddress, weeklyArenaState.Serialize())
                   .SetState(AvatarAddress, avatarState.Serialize()));
        }
Пример #33
0
 public override void Render(IActionContext context, IAccountStateDelta nextStates)
 {
 }
Пример #34
0
		public void Run(IActionContext actionContext)
		{
			actionContext.SetAttribute("available",Evaluation.DISAPPROVE);
		}
Пример #35
0
 protected virtual void OnValidOutput(IActionContext actionContext, object result)
 {
 }
Пример #36
0
 /// <summary>
 /// 在执行Api行为后触发
 /// </summary>
 /// <param name="filterContext">上下文</param>
 protected sealed override void OnExecuted(IActionContext filterContext)
 {
     this.OnExecuted(filterContext as ActionContext);
 }
Пример #37
0
 protected virtual void OnValidInputs(IActionContext actionContext)
 {
 }
Пример #38
0
        protected virtual IAction OnCreateActionInstance(IActionFactoryService actionFactoryService, IActionContext actionContext)
        {
            _ = actionFactoryService ?? throw new ArgumentNullException(nameof(actionFactoryService));
            var action = actionFactoryService.CreateAction(actionContext);

            if (action == null)
            {
            }
            return(action);
        }
Пример #39
0
 public static void Execute(this IActor actor, IActionContext context) =>
 actor.FindAction(context).Iter(a => a.Execute(context));
Пример #40
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IActionContext ctx           = context;
            var            states        = ctx.PreviousStates;
            var            avatarAddress = ctx.Signer.Derive(
                string.Format(
                    CultureInfo.InvariantCulture,
                    DeriveFormat,
                    index
                    )
                );
            var inventoryAddress        = avatarAddress.Derive(LegacyInventoryKey);
            var worldInformationAddress = avatarAddress.Derive(LegacyWorldInformationKey);
            var questListAddress        = avatarAddress.Derive(LegacyQuestListKey);

            if (ctx.Rehearsal)
            {
                states = states.SetState(ctx.Signer, MarkChanged);
                for (var i = 0; i < AvatarState.CombinationSlotCapacity; i++)
                {
                    var slotAddress = avatarAddress.Derive(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            CombinationSlotState.DeriveFormat,
                            i
                            )
                        );
                    states = states.SetState(slotAddress, MarkChanged);
                }

                return(states
                       .SetState(avatarAddress, MarkChanged)
                       .SetState(Addresses.Ranking, MarkChanged)
                       .SetState(inventoryAddress, MarkChanged)
                       .SetState(worldInformationAddress, MarkChanged)
                       .SetState(questListAddress, MarkChanged)
                       .MarkBalanceChanged(GoldCurrencyMock, GoldCurrencyState.Address, context.Signer));
            }

            CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context);

            var addressesHex = GetSignerAndOtherAddressesHex(context, avatarAddress);

            if (!Regex.IsMatch(name, GameConfig.AvatarNickNamePattern))
            {
                throw new InvalidNamePatternException(
                          $"{addressesHex}Aborted as the input name {name} does not follow the allowed name pattern.");
            }

            var sw = new Stopwatch();

            sw.Start();
            var started = DateTimeOffset.UtcNow;

            Log.Verbose("{AddressesHex}CreateAvatar exec started", addressesHex);
            AgentState existingAgentState = states.GetAgentState(ctx.Signer);
            var        agentState         = existingAgentState ?? new AgentState(ctx.Signer);
            var        avatarState        = states.GetAvatarState(avatarAddress);

            if (!(avatarState is null))
            {
                throw new InvalidAddressException(
                          $"{addressesHex}Aborted as there is already an avatar at {avatarAddress}.");
            }

            if (!(0 <= index && index < GameConfig.SlotCount))
            {
                throw new AvatarIndexOutOfRangeException(
                          $"{addressesHex}Aborted as the index is out of range #{index}.");
            }

            if (agentState.avatarAddresses.ContainsKey(index))
            {
                throw new AvatarIndexAlreadyUsedException(
                          $"{addressesHex}Aborted as the signer already has an avatar at index #{index}.");
            }
            sw.Stop();
            Log.Verbose("{AddressesHex}CreateAvatar Get AgentAvatarStates: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            Log.Verbose("{AddressesHex}Execute CreateAvatar; player: {AvatarAddress}", addressesHex, avatarAddress);

            agentState.avatarAddresses.Add(index, avatarAddress);

            // Avoid NullReferenceException in test
            var materialItemSheet = ctx.PreviousStates.GetSheet <MaterialItemSheet>();

            var rankingState = ctx.PreviousStates.GetRankingState0();

            var rankingMapAddress = rankingState.UpdateRankingMap(avatarAddress);

            avatarState = CreateAvatar0.CreateAvatarState(name, avatarAddress, ctx, materialItemSheet, rankingMapAddress);

            if (hair < 0)
            {
                hair = 0;
            }
            if (lens < 0)
            {
                lens = 0;
            }
            if (ear < 0)
            {
                ear = 0;
            }
            if (tail < 0)
            {
                tail = 0;
            }

            avatarState.Customize(hair, lens, ear, tail);

            foreach (var address in avatarState.combinationSlotAddresses)
            {
                var slotState =
                    new CombinationSlotState(address, GameConfig.RequireClearedStageLevel.CombinationEquipmentAction);
                states = states.SetState(address, slotState.Serialize());
            }

            avatarState.UpdateQuestRewards2(materialItemSheet);

            sw.Stop();
            Log.Verbose("{AddressesHex}CreateAvatar CreateAvatarState: {Elapsed}", addressesHex, sw.Elapsed);
            var ended = DateTimeOffset.UtcNow;

            Log.Verbose("{AddressesHex}CreateAvatar Total Executed Time: {Elapsed}", addressesHex, ended - started);
            return(states
                   .SetState(ctx.Signer, agentState.Serialize())
                   .SetState(Addresses.Ranking, rankingState.Serialize())
                   .SetState(inventoryAddress, avatarState.inventory.Serialize())
                   .SetState(worldInformationAddress, avatarState.worldInformation.Serialize())
                   .SetState(questListAddress, avatarState.questList.Serialize())
                   .SetState(avatarAddress, avatarState.SerializeV2()));
        }
Пример #41
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            var states = context.PreviousStates;

            if (context.Rehearsal)
            {
                states = states.SetState(RedeemCodeState.Address, MarkChanged);
                states = states.SetState(AvatarAddress, MarkChanged);
                states = states.SetState(context.Signer, MarkChanged);
                states = states.MarkBalanceChanged(GoldCurrencyMock, GoldCurrencyState.Address);
                states = states.MarkBalanceChanged(GoldCurrencyMock, context.Signer);
                return(states);
            }

            CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context);

            var addressesHex = GetSignerAndOtherAddressesHex(context, AvatarAddress);

            if (!states.TryGetAvatarState(context.Signer, AvatarAddress, out AvatarState avatarState))
            {
                return(states);
            }

            var redeemState = states.GetRedeemCodeState();

            if (redeemState is null)
            {
                return(states);
            }

            int redeemId;

            try
            {
                redeemId = redeemState.Redeem(Code, AvatarAddress);
            }
            catch (InvalidRedeemCodeException)
            {
                Log.Error("{AddressesHex}Invalid Code", addressesHex);
                throw;
            }
            catch (DuplicateRedeemException e)
            {
                Log.Warning("{AddressesHex}{Message}", addressesHex, e.Message);
                throw;
            }

            var row        = states.GetSheet <RedeemRewardSheet>().Values.First(r => r.Id == redeemId);
            var itemSheets = states.GetItemSheet();

            foreach (RedeemRewardSheet.RewardInfo info in row.Rewards)
            {
                switch (info.Type)
                {
                case RewardType.Item:
                    for (var i = 0; i < info.Quantity; i++)
                    {
                        if (info.ItemId is int itemId)
                        {
                            ItemBase item = ItemFactory.CreateItem(itemSheets[itemId], context.Random);
                            // We should fix count as 1 because ItemFactory.CreateItem
                            // will create a new item every time.
                            avatarState.inventory.AddItem2(item, count: 1);
                        }
                    }
                    break;

                case RewardType.Gold:
                    states = states.TransferAsset(
                        GoldCurrencyState.Address,
                        context.Signer,
                        states.GetGoldCurrency() * info.Quantity
                        );
                    break;

                default:
                    // FIXME: We should raise exception here.
                    break;
                }
            }
            states = states.SetState(AvatarAddress, avatarState.Serialize());
            states = states.SetState(RedeemCodeState.Address, redeemState.Serialize());
            return(states);
        }
Пример #42
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            var states = context.PreviousStates;

            if (context.Rehearsal)
            {
                states = states.SetState(sellerAvatarAddress, MarkChanged);
                states = ShardedShopState.AddressKeys.Aggregate(
                    states,
                    (current, addressKey) => current.SetState(
                        ShardedShopState.DeriveAddress(itemSubType, addressKey),
                        MarkChanged));
                return(states.SetState(context.Signer, MarkChanged));
            }

            CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context);

            var addressesHex = GetSignerAndOtherAddressesHex(context, sellerAvatarAddress);

            var sw = new Stopwatch();

            sw.Start();
            var started = DateTimeOffset.UtcNow;

            Log.Verbose("{AddressesHex}Sell exec started", addressesHex);

            if (price.Sign < 0)
            {
                throw new InvalidPriceException(
                          $"{addressesHex}Aborted as the price is less than zero: {price}.");
            }

            if (!states.TryGetAgentAvatarStates(
                    context.Signer,
                    sellerAvatarAddress,
                    out _,
                    out var avatarState))
            {
                throw new FailedLoadStateException(
                          $"{addressesHex}Aborted as the avatar state of the signer was failed to load.");
            }

            sw.Stop();
            Log.Verbose(
                "{AddressesHex}Sell Get AgentAvatarStates: {Elapsed}",
                addressesHex,
                sw.Elapsed);
            sw.Restart();

            if (!avatarState.worldInformation.IsStageCleared(
                    GameConfig.RequireClearedStageLevel.ActionsInShop))
            {
                avatarState.worldInformation.TryGetLastClearedStageId(out var current);
                throw new NotEnoughClearedStageLevelException(
                          addressesHex,
                          GameConfig.RequireClearedStageLevel.ActionsInShop,
                          current);
            }

            sw.Stop();
            Log.Verbose("{AddressesHex}Sell IsStageCleared: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            switch (itemSubType)
            {
            case ItemSubType.EquipmentMaterial:
            case ItemSubType.FoodMaterial:
            case ItemSubType.MonsterPart:
            case ItemSubType.NormalMaterial:
                throw new InvalidShopItemException(
                          $"{addressesHex}Aborted because {nameof(itemSubType)}({itemSubType}) does not support.");
            }

            if (count < 1)
            {
                throw new InvalidShopItemException(
                          $"{addressesHex}Aborted because {nameof(count)}({count}) should be greater than or equal to 1.");
            }

            if (!avatarState.inventory.TryGetTradableItems(tradableId, context.BlockIndex, count, out List <Inventory.Item> inventoryItems))
            {
                throw new ItemDoesNotExistException(
                          $"{addressesHex}Aborted because the tradable item({tradableId}) was failed to load from avatar's inventory.");
            }

            IEnumerable <ITradableItem> tradableItems = inventoryItems.Select(i => (ITradableItem)i.item).ToList();
            var expiredBlockIndex = context.BlockIndex + ExpiredBlockIndex;

            foreach (var ti in tradableItems)
            {
                if (!ti.ItemSubType.Equals(itemSubType))
                {
                    throw new InvalidItemTypeException(
                              $"{addressesHex}Expected ItemSubType: {ti.ItemSubType}. Actual ItemSubType: {itemSubType}");
                }

                if (ti is INonFungibleItem)
                {
                    if (count != 1)
                    {
                        throw new ArgumentOutOfRangeException(
                                  $"{addressesHex}Aborted because {nameof(count)}({count}) should be 1 because {nameof(tradableId)}({tradableId}) is non-fungible item.");
                    }
                }
            }

            ITradableItem tradableItem = avatarState.inventory.SellItem(tradableId, context.BlockIndex, count);

            var productId          = context.Random.GenerateRandomGuid();
            var shardedShopAddress = ShardedShopState.DeriveAddress(itemSubType, productId);

            if (!states.TryGetState(shardedShopAddress, out BxDictionary serializedSharedShopState))
            {
                var shardedShopState = new ShardedShopState(shardedShopAddress);
                serializedSharedShopState = (BxDictionary)shardedShopState.Serialize();
            }

            sw.Stop();
            Log.Verbose(
                "{AddressesHex}Sell Get ShardedShopState: {Elapsed}",
                addressesHex,
                sw.Elapsed);
            sw.Restart();

            var    serializedProductList = (BxList)serializedSharedShopState[ProductsKey];
            string productKey;
            string itemIdKey;

            switch (tradableItem.ItemType)
            {
            case ItemType.Consumable:
            case ItemType.Equipment:
                productKey = LegacyItemUsableKey;
                itemIdKey  = LegacyItemIdKey;
                break;

            case ItemType.Costume:
                productKey = LegacyCostumeKey;
                itemIdKey  = LegacyCostumeItemIdKey;
                break;

            case ItemType.Material:
                productKey = TradableFungibleItemKey;
                itemIdKey  = LegacyCostumeItemIdKey;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            BxDictionary serializedProductDictionary;

            if (tradableItem.ItemType == ItemType.Material)
            {
                // Find expired TradableMaterial
                serializedProductDictionary = serializedProductList
                                              .Select(p => (BxDictionary)p)
                                              .FirstOrDefault(p =>
                {
                    var materialItemId =
                        ((BxDictionary)p[productKey])[itemIdKey].ToItemId();
                    var requiredBlockIndex = p[ExpiredBlockIndexKey].ToLong();
                    var sellerAgentAddress = p[LegacySellerAgentAddressKey].ToAddress();
                    var avatarAddress      = p[LegacySellerAvatarAddressKey].ToAddress();
                    return(TradableMaterial.DeriveTradableId(materialItemId).Equals(tradableItem.TradableId) &&
                           requiredBlockIndex <= context.BlockIndex &&
                           context.Signer.Equals(sellerAgentAddress) &&
                           sellerAvatarAddress.Equals(avatarAddress));
                });
            }
            else
            {
                var serializedTradeId = tradableItem.TradableId.Serialize();
                serializedProductDictionary = serializedProductList
                                              .Select(p => (BxDictionary)p)
                                              .FirstOrDefault(p =>
                {
                    var sellerAgentAddress = p[LegacySellerAgentAddressKey].ToAddress();
                    var avatarAddress      = p[LegacySellerAvatarAddressKey].ToAddress();
                    return(((BxDictionary)p[productKey])[itemIdKey].Equals(serializedTradeId) &&
                           context.Signer.Equals(sellerAgentAddress) &&
                           sellerAvatarAddress.Equals(avatarAddress));
                });
            }

            // Remove expired ShopItem to prevent copy.
            if (!serializedProductDictionary.Equals(BxDictionary.Empty))
            {
                serializedProductList = (BxList)serializedProductList.Remove(serializedProductDictionary);
            }
            var shopItem = new ShopItem(
                context.Signer,
                sellerAvatarAddress,
                productId,
                price,
                expiredBlockIndex,
                tradableItem,
                count);
            var serializedShopItem = shopItem.Serialize();

            serializedProductList     = serializedProductList.Add(serializedShopItem);
            serializedSharedShopState = serializedSharedShopState.SetItem(
                ProductsKey,
                new List <IValue>(serializedProductList));

            sw.Stop();
            Log.Verbose("{AddressesHex}Sell Get Register Item: {Elapsed}", addressesHex,
                        sw.Elapsed);
            sw.Restart();

            avatarState.updatedAt  = context.BlockIndex;
            avatarState.blockIndex = context.BlockIndex;

            var result = new SellCancellation.Result
            {
                shopItem                  = shopItem,
                itemUsable                = shopItem.ItemUsable,
                costume                   = shopItem.Costume,
                tradableFungibleItem      = shopItem.TradableFungibleItem,
                tradableFungibleItemCount = shopItem.TradableFungibleItemCount,
            };
            var mail = new SellCancelMail(
                result,
                context.BlockIndex,
                context.Random.GenerateRandomGuid(),
                expiredBlockIndex);

            result.id = mail.id;
            avatarState.Update(mail);

            states = states.SetState(sellerAvatarAddress, avatarState.Serialize());
            sw.Stop();
            Log.Verbose("{AddressesHex}Sell Set AvatarState: {Elapsed}", addressesHex, sw.Elapsed);
            sw.Restart();

            states = states.SetState(shardedShopAddress, serializedSharedShopState);
            sw.Stop();
            var ended = DateTimeOffset.UtcNow;

            Log.Verbose("{AddressesHex}Sell Set ShopState: {Elapsed}", addressesHex, sw.Elapsed);
            Log.Verbose(
                "{AddressesHex}Sell Total Executed Time: {Elapsed}",
                addressesHex,
                ended - started);

            return(states);
        }
Пример #43
0
        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));
            }

            var sw = new Stopwatch();

            sw.Start();
            var started = DateTimeOffset.UtcNow;

            Log.Debug(
                "RankingBattle exec started. costume: ({CostumeIds}), equipment: ({EquipmentIds})",
                string.Join(",", costumeIds),
                string.Join(",", equipmentIds)
                );

            if (AvatarAddress.Equals(EnemyAddress))
            {
                throw new InvalidAddressException("Aborted as the signer tried to battle for themselves.");
            }

            if (!states.TryGetAvatarState(ctx.Signer, AvatarAddress, out var avatarState))
            {
                throw new FailedLoadStateException("Aborted as the avatar state of the signer was failed to load.");
            }

            sw.Stop();
            Log.Debug("RankingBattle Get AgentAvatarStates: {Elapsed}", sw.Elapsed);
            sw.Restart();

            var items = equipmentIds.Concat(costumeIds);

            avatarState.ValidateEquipmentsV2(equipmentIds, context.BlockIndex);
            avatarState.ValidateConsumable(consumableIds, context.BlockIndex);
            avatarState.ValidateCostume(costumeIds);

            sw.Stop();
            Log.Debug("RankingBattle Validate Equipments: {Elapsed}", sw.Elapsed);
            sw.Restart();

            avatarState.EquipItems(items);

            sw.Stop();
            Log.Debug("RankingBattle Equip Equipments: {Elapsed}", sw.Elapsed);
            sw.Restart();

            if (!avatarState.worldInformation.TryGetUnlockedWorldByStageClearedBlockIndex(out var world) ||
                world.StageClearedId < GameConfig.RequireClearedStageLevel.ActionsInRankingBoard)
            {
                throw new NotEnoughClearedStageLevelException(
                          GameConfig.RequireClearedStageLevel.ActionsInRankingBoard,
                          world.StageClearedId);
            }

            var enemyAvatarState = states.GetAvatarState(EnemyAddress);

            if (enemyAvatarState is null)
            {
                throw new FailedLoadStateException($"Aborted as the avatar state of the opponent ({EnemyAddress}) was failed to load.");
            }

            sw.Stop();
            Log.Debug("RankingBattle Get Enemy AvatarState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            var weeklyArenaState = states.GetWeeklyArenaState(WeeklyArenaAddress);

            sw.Stop();
            Log.Debug("RankingBattle Get WeeklyArenaState ({Address}): {Elapsed}", WeeklyArenaAddress, sw.Elapsed);
            sw.Restart();

            if (weeklyArenaState.Ended)
            {
                throw new WeeklyArenaStateAlreadyEndedException();
            }

            if (!weeklyArenaState.ContainsKey(AvatarAddress))
            {
                throw new WeeklyArenaStateNotContainsAvatarAddressException(AvatarAddress);
            }

            var arenaInfo = weeklyArenaState[AvatarAddress];

            if (arenaInfo.DailyChallengeCount <= 0)
            {
                throw new NotEnoughWeeklyArenaChallengeCountException();
            }

            if (!arenaInfo.Active)
            {
                arenaInfo.Activate();
            }

            if (!weeklyArenaState.ContainsKey(EnemyAddress))
            {
                throw new WeeklyArenaStateNotContainsAvatarAddressException(EnemyAddress);
            }

            Log.Debug(weeklyArenaState.address.ToHex());

            sw.Stop();
            Log.Debug("RankingBattle Validate ArenaInfo: {Elapsed}", sw.Elapsed);
            sw.Restart();

            var costumeStatSheet = states.GetSheet <CostumeStatSheet>();

            sw.Stop();
            Log.Debug("RankingBattle Get CostumeStatSheet: {Elapsed}", sw.Elapsed);
            sw.Restart();

            var simulator = new RankingSimulator(
                ctx.Random,
                avatarState,
                enemyAvatarState,
                consumableIds,
                states.GetRankingSimulatorSheets(),
                StageId,
                arenaInfo,
                weeklyArenaState[EnemyAddress],
                costumeStatSheet);

            simulator.SimulateV2();

            sw.Stop();
            Log.Debug(
                "RankingBattle Simulate() with equipment:({Equipment}), costume:({Costume}): {Elapsed}",
                string.Join(",", simulator.Player.Equipments.Select(r => r.ItemId)),
                string.Join(",", simulator.Player.Costumes.Select(r => r.ItemId)),
                sw.Elapsed
                );

            Log.Debug(
                "Execute RankingBattle({AvatarAddress}); result: {Result} event count: {EventCount}",
                AvatarAddress,
                simulator.Log.result,
                simulator.Log.Count
                );
            sw.Restart();

            Result = simulator.Log;

            foreach (var itemBase in simulator.Reward.OrderBy(i => i.Id))
            {
                Log.Debug($"RankingBattle Add Reward Item({itemBase.Id}): {{Elapsed}}", sw.Elapsed);
                avatarState.inventory.AddItem(itemBase);
            }

            states = states.SetState(WeeklyArenaAddress, weeklyArenaState.Serialize());

            sw.Stop();
            Log.Debug("RankingBattle Serialize WeeklyArenaState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            states = states.SetState(AvatarAddress, avatarState.Serialize());

            sw.Stop();
            Log.Debug("RankingBattle Serialize AvatarState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            var ended = DateTimeOffset.UtcNow;

            Log.Debug("RankingBattle Total Executed Time: {Elapsed}", ended - started);
            return(states);
        }
Пример #44
0
 /// <summary>
 /// 执行前
 /// </summary>
 /// <param name="filterContext"></param>
 protected sealed override void OnExecuting(IActionContext filterContext)
 {
     this.OnExecuting(filterContext.Action, filterContext.Action.Parameters[this.index]);
 }
Пример #45
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IActionContext ctx                     = context;
            var            states                  = ctx.PreviousStates;
            var            inventoryAddress        = avatarAddress.Derive(LegacyInventoryKey);
            var            worldInformationAddress = avatarAddress.Derive(LegacyWorldInformationKey);
            var            questListAddress        = avatarAddress.Derive(LegacyQuestListKey);

            if (ctx.Rehearsal)
            {
                states = states.SetState(RankingMapAddress, MarkChanged);
                states = states.SetState(avatarAddress, MarkChanged);
                states = states.SetState(WeeklyArenaAddress, MarkChanged);
                states = states
                         .SetState(inventoryAddress, MarkChanged)
                         .SetState(worldInformationAddress, MarkChanged)
                         .SetState(questListAddress, MarkChanged);
                return(states.SetState(ctx.Signer, MarkChanged));
            }

            CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context);

            var addressesHex = GetSignerAndOtherAddressesHex(context, avatarAddress);

            var sw = new Stopwatch();

            sw.Start();
            var started = DateTimeOffset.UtcNow;

            Log.Verbose("{AddressesHex}HAS exec started", addressesHex);

            if (!states.TryGetAvatarStateV2(ctx.Signer, avatarAddress, out AvatarState avatarState))
            {
                throw new FailedLoadStateException($"{addressesHex}Aborted as the avatar state of the signer was failed to load.");
            }

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Get AgentAvatarStates: {Elapsed}", addressesHex, sw.Elapsed);

            sw.Restart();

            if (avatarState.RankingMapAddress != RankingMapAddress)
            {
                throw new InvalidAddressException($"{addressesHex}Invalid ranking map address");
            }

            // worldId와 stageId가 유효한지 확인합니다.
            var worldSheet = states.GetSheet <WorldSheet>();

            if (!worldSheet.TryGetValue(worldId, out var worldRow, false))
            {
                throw new SheetRowNotFoundException(addressesHex, nameof(WorldSheet), worldId);
            }

            if (stageId < worldRow.StageBegin ||
                stageId > worldRow.StageEnd)
            {
                throw new SheetRowColumnException(
                          $"{addressesHex}{worldId} world is not contains {worldRow.Id} stage: " +
                          $"{worldRow.StageBegin}-{worldRow.StageEnd}");
            }

            var stageSheet = states.GetSheet <StageSheet>();

            if (!stageSheet.TryGetValue(stageId, out var stageRow))
            {
                throw new SheetRowNotFoundException(addressesHex, nameof(StageSheet), stageId);
            }

            var worldInformation = avatarState.worldInformation;

            if (!worldInformation.TryGetWorld(worldId, out var world))
            {
                // NOTE: Add new World from WorldSheet
                worldInformation.AddAndUnlockNewWorld(worldRow, ctx.BlockIndex, worldSheet);
            }

            if (!world.IsUnlocked)
            {
                throw new InvalidWorldException($"{addressesHex}{worldId} is locked.");
            }

            if (world.StageBegin != worldRow.StageBegin ||
                world.StageEnd != worldRow.StageEnd)
            {
                worldInformation.UpdateWorld(worldRow);
            }

            if (world.IsStageCleared && stageId > world.StageClearedId + 1 ||
                !world.IsStageCleared && stageId != world.StageBegin)
            {
                throw new InvalidStageException(
                          $"{addressesHex}Aborted as the stage ({worldId}/{stageId}) is not cleared; " +
                          $"cleared stage: {world.StageClearedId}"
                          );
            }

            avatarState.ValidateEquipmentsV2(equipments, context.BlockIndex);
            avatarState.ValidateConsumable(foods, context.BlockIndex);
            avatarState.ValidateCostume(costumes);

            var costumeStatSheet = states.GetSheet <CostumeStatSheet>();

            sw.Restart();
            if (avatarState.actionPoint < stageRow.CostAP)
            {
                throw new NotEnoughActionPointException(
                          $"{addressesHex}Aborted due to insufficient action point: " +
                          $"{avatarState.actionPoint} < {stageRow.CostAP}"
                          );
            }

            avatarState.actionPoint -= stageRow.CostAP;

            var items = equipments.Concat(costumes);

            avatarState.EquipItems(items);
            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Unequip items: {Elapsed}", addressesHex, sw.Elapsed);

            sw.Restart();
            var characterSheet = states.GetSheet <CharacterSheet>();
            var simulator      = new StageSimulator(
                ctx.Random,
                avatarState,
                foods,
                worldId,
                stageId,
                states.GetStageSimulatorSheets(),
                costumeStatSheet,
                StageSimulator.ConstructorVersionV100025);

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Initialize Simulator: {Elapsed}", addressesHex, sw.Elapsed);

            sw.Restart();
            simulator.Simulate4();
            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Simulator.SimulateV2(): {Elapsed}", addressesHex, sw.Elapsed);

            Log.Verbose(
                "{AddressesHex}Execute HackAndSlash6({AvatarAddress}); worldId: {WorldId}, stageId: {StageId}, result: {Result}, " +
                "clearWave: {ClearWave}, totalWave: {TotalWave}",
                addressesHex,
                avatarAddress,
                worldId,
                stageId,
                simulator.Log.result,
                simulator.Log.clearedWaveNumber,
                simulator.Log.waveCount
                );

            sw.Restart();
            if (simulator.Log.IsClear)
            {
                var worldUnlockSheet = states.GetSheet <WorldUnlockSheet>();
                simulator.Player.worldInformation.ClearStage(
                    worldId,
                    stageId,
                    ctx.BlockIndex,
                    worldSheet,
                    worldUnlockSheet
                    );
            }

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS ClearStage: {Elapsed}", addressesHex, sw.Elapsed);

            sw.Restart();
            avatarState.Update(simulator);

            var materialSheet = states.GetSheet <MaterialItemSheet>();

            avatarState.UpdateQuestRewards2(materialSheet);

            avatarState.updatedAt = ctx.BlockIndex;
            avatarState.mailBox.CleanUp();
            states = states
                     .SetState(avatarAddress, avatarState.SerializeV2())
                     .SetState(inventoryAddress, avatarState.inventory.Serialize())
                     .SetState(worldInformationAddress, avatarState.worldInformation.Serialize())
                     .SetState(questListAddress, avatarState.questList.Serialize());

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Set AvatarState: {Elapsed}", addressesHex, sw.Elapsed);

            sw.Restart();
            if (states.TryGetState(RankingMapAddress, out Dictionary d) && simulator.Log.IsClear)
            {
                var ranking = new RankingMapState(d);
                ranking.Update(avatarState);

                sw.Stop();
                Log.Verbose("{AddressesHex}HAS Update RankingState: {Elapsed}", addressesHex, sw.Elapsed);
                sw.Restart();

                var serialized = ranking.Serialize();

                sw.Stop();
                Log.Verbose("{AddressesHex}HAS Serialize RankingState: {Elapsed}", addressesHex, sw.Elapsed);
                sw.Restart();
                states = states.SetState(RankingMapAddress, serialized);
            }

            sw.Stop();
            Log.Verbose("{AddressesHex}HAS Set RankingState: {Elapsed}", addressesHex, sw.Elapsed);

            sw.Restart();
            if (simulator.Log.stageId >= GameConfig.RequireClearedStageLevel.ActionsInRankingBoard &&
                simulator.Log.IsClear &&
                states.TryGetState(WeeklyArenaAddress, out Dictionary weeklyDict))
            {
                var weekly = new WeeklyArenaState(weeklyDict);
                if (!weekly.Ended)
                {
                    if (weekly.ContainsKey(avatarAddress))
                    {
                        var info = weekly[avatarAddress];
                        info.UpdateV2(avatarState, characterSheet, costumeStatSheet);
                        weekly.Update(info);
                    }
                    else
                    {
                        weekly.SetV2(avatarState, characterSheet, costumeStatSheet);
                    }

                    sw.Stop();
                    Log.Verbose("{AddressesHex}HAS Update WeeklyArenaState: {Elapsed}", addressesHex, sw.Elapsed);

                    sw.Restart();
                    var weeklySerialized = weekly.Serialize();
                    sw.Stop();
                    Log.Verbose("{AddressesHex}HAS Serialize RankingState: {Elapsed}", addressesHex, sw.Elapsed);

                    states = states.SetState(weekly.address, weeklySerialized);
                }
            }

            Result = simulator.Log;

            var ended = DateTimeOffset.UtcNow;

            Log.Verbose("{AddressesHex}HAS Total Executed Time: {Elapsed}", addressesHex, ended - started);
            return(states);
        }
Пример #46
0
		public void SendMail(String from, String to, String subject, String body, IActionContext interactionContext)
		{
			log.Info("sending mail from '+ from +'to '" + to + "' with subject '" + subject + "' and body '" + body + "'");

		}
Пример #47
0
 public IAccountStateDelta Execute(IActionContext context)
 {
     return(context.PreviousStates);
 }
Пример #48
0
 public AboutAction(IActionContext context)
     : base(context)
 {
     this.Caption = string.Format(ActionsRes.AboutCaption, CommonRes.AppName);
 }
Пример #49
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IAccountStateDelta states = context.PreviousStates;
            Address            monsterCollectionAddress = MonsterCollectionState0.DeriveAddress(context.Signer, collectionRound);

            if (context.Rehearsal)
            {
                return(states
                       .SetState(monsterCollectionAddress, MarkChanged)
                       .SetState(context.Signer, MarkChanged)
                       .MarkBalanceChanged(GoldCurrencyMock, context.Signer, monsterCollectionAddress));
            }

            CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context);

            MonsterCollectionSheet monsterCollectionSheet = states.GetSheet <MonsterCollectionSheet>();

            AgentState agentState = states.GetAgentState(context.Signer);

            if (agentState is null)
            {
                throw new FailedLoadStateException("Aborted as the agent state failed to load.");
            }

            if (agentState.MonsterCollectionRound != collectionRound)
            {
                throw new InvalidMonsterCollectionRoundException(
                          $"Expected collection round is {agentState.MonsterCollectionRound}, but actual collection round is {collectionRound}.");
            }

            if (!monsterCollectionSheet.TryGetValue(level, out MonsterCollectionSheet.Row _))
            {
                throw new SheetRowNotFoundException(nameof(MonsterCollectionSheet), level);
            }

            Currency currency = states.GetGoldCurrency();
            // Set default gold value.
            FungibleAssetValue requiredGold = currency * 0;
            FungibleAssetValue balance      = states.GetBalance(context.Signer, states.GetGoldCurrency());

            MonsterCollectionState0 monsterCollectionState;
            int currentLevel = 1;
            MonsterCollectionRewardSheet monsterCollectionRewardSheet = states.GetSheet <MonsterCollectionRewardSheet>();

            if (states.TryGetState(monsterCollectionAddress, out Dictionary stateDict))
            {
                monsterCollectionState = new MonsterCollectionState0(stateDict);

                if (monsterCollectionState.ExpiredBlockIndex < context.BlockIndex)
                {
                    throw new MonsterCollectionExpiredException(
                              $"{monsterCollectionAddress} has already expired on {monsterCollectionState.ExpiredBlockIndex}");
                }

                if (monsterCollectionState.Level >= level)
                {
                    throw new InvalidLevelException($"The level must be greater than {monsterCollectionState.Level}.");
                }

                currentLevel = monsterCollectionState.Level + 1;
                long rewardLevel = monsterCollectionState.GetRewardLevel(context.BlockIndex);
                monsterCollectionState.Update(level, rewardLevel, monsterCollectionRewardSheet);
            }
            else
            {
                monsterCollectionState = new MonsterCollectionState0(monsterCollectionAddress, level, context.BlockIndex, monsterCollectionRewardSheet);
            }

            for (int i = currentLevel; i < level + 1; i++)
            {
                requiredGold += currency * monsterCollectionSheet[i].RequiredGold;
            }

            if (balance < requiredGold)
            {
                throw new InsufficientBalanceException(context.Signer, requiredGold,
                                                       $"There is no sufficient balance for {context.Signer}: {balance} < {requiredGold}");
            }
            states = states.TransferAsset(context.Signer, monsterCollectionAddress, requiredGold);
            states = states.SetState(monsterCollectionAddress, monsterCollectionState.Serialize());
            return(states);
        }
Пример #50
0
 public IEnumerable<IActionItem> GetToolBarActions(IActionContext context)
 {
     yield break;
 }
Пример #51
0
 /// <summary>
 /// 执行后
 /// </summary>
 /// <param name="filterContext"></param>
 protected sealed override void OnExecuted(IActionContext filterContext)
 {
 }
Пример #52
0
        protected virtual object OnRunAction(IAction action, IExecuteContext executeContext, IActionContext actionContext)
        {
            _ = executeContext ?? throw new ArgumentNullException(nameof(executeContext));
            _ = action ?? throw new ArgumentNullException(nameof(action));
            int       loopCount = Math.Max(1, executeContext.ActionRetryCount);
            Exception error     = null;

            for (int i = 0; i < loopCount && !executeContext.Token.IsCancellationRequested; i++)
            {
                try
                {
                    return(action.Run(actionContext));
                }
                catch (Exception ex)
                {
                    this.logger.LogWarning("Error in execute action [{0}] {1} time(s).\n{2}", executeContext.ActionFullName, i, ex);
                    error = ex;
                }
            }
            throw error;
        }
Пример #53
0
 /// <summary>
 /// 在执行Api行为后触发
 /// </summary>
 /// <param name="filterContext">上下文</param>      
 protected sealed override void OnExecuted(IActionContext filterContext)
 {
     this.OnExecuted(filterContext as ActionContext);
 }
Пример #54
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            var states = context.PreviousStates;

            if (context.Rehearsal)
            {
                states = states
                         .SetState(context.Signer, MarkChanged)
                         .SetState(avatarAddress, MarkChanged)
                         .MarkBalanceChanged(GoldCurrencyMock, GoldCurrencyState.Address, context.Signer);
                return(states);
            }

            if (!states.TryGetAgentAvatarStates(context.Signer, avatarAddress, out AgentState _,
                                                out AvatarState avatarState))
            {
                // FIXME: 오류 처리 필요하지 않나요?
            }

            var tableSheets = TableSheets.FromActionContext(context);

            foreach (var pair in chestList)
            {
                var itemId = pair.Key;
                var count  = pair.Value;
                if (avatarState.inventory.TryGetMaterial(itemId, out var inventoryItem) && inventoryItem.count >= count)
                {
                    var chest = (Chest)inventoryItem.item;
                    foreach (var info in chest.Rewards)
                    {
                        switch (info.Type)
                        {
                        case RewardType.Item:
                            var itemRow =
                                tableSheets.MaterialItemSheet.Values.FirstOrDefault(r => r.Id == info.ItemId);
                            if (itemRow is null)
                            {
                                continue;
                            }
                            var material = ItemFactory.CreateMaterial(itemRow);
                            avatarState.inventory.AddItem(material, info.Quantity);
                            break;

                        case RewardType.Gold:
                            states = states.TransferAsset(
                                GoldCurrencyState.Address,
                                context.Signer,
                                states.GetGoldCurrency() * info.Quantity
                                );
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(nameof(info.Type), info.Type, null);
                        }
                    }

                    avatarState.inventory.RemoveMaterial(itemId, count);
                }
            }

            states = states.SetState(avatarAddress, avatarState.Serialize());
            return(states);
        }
Пример #55
0
 public void SetInvokedProcessContext(IActionContext invokedProcessContext)
 {
     this._invokedProcessContext = invokedProcessContext;
 }
Пример #56
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IActionContext ctx         = context;
            var            states      = ctx.PreviousStates;
            var            slotAddress = AvatarAddress.Derive(
                string.Format(
                    CultureInfo.InvariantCulture,
                    CombinationSlotState.DeriveFormat,
                    SlotIndex
                    )
                );

            if (ctx.Rehearsal)
            {
                return(states
                       .SetState(AvatarAddress, MarkChanged)
                       .SetState(slotAddress, MarkChanged)
                       .SetState(ctx.Signer, MarkChanged)
                       .MarkBalanceChanged(GoldCurrencyMock, ctx.Signer, BlacksmithAddress));
            }

            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."));
            }

            var slotState = states.GetCombinationSlotState(AvatarAddress, SlotIndex);

            if (slotState is null || !(slotState.Validate(avatarState, ctx.BlockIndex)))
            {
                return(LogError(
                           context,
                           "Aborted as the slot state is failed to load or invalid: {@SlotState} @ {SlotIndex}",
                           slotState,
                           SlotIndex
                           ));
            }

            var tableSheets   = TableSheets.FromActionContext(ctx);
            var recipeSheet   = tableSheets.EquipmentItemRecipeSheet;
            var materialSheet = tableSheets.MaterialItemSheet;
            var materials     = new Dictionary <Material, int>();

            // 레시피 검증
            if (!recipeSheet.TryGetValue(RecipeId, out var recipe))
            {
                return(LogError(
                           context,
                           "Aborted as the recipe {RecipeId} was failed to load from the sheet.",
                           RecipeId
                           ));
            }

            if (!(SubRecipeId is null))
            {
                if (!recipe.SubRecipeIds.Contains((int)SubRecipeId))
                {
                    return(LogError(
                               context,
                               "Aborted as the subrecipe {SubRecipeId} was failed to load from the sheet.",
                               SubRecipeId
                               ));
                }
            }

            // 메인 레시피 해금 검사.
            if (!avatarState.worldInformation.IsStageCleared(recipe.UnlockStage))
            {
                return(LogError(
                           context,
                           "Aborted as the signer is not cleared the minimum stage level required to use the recipe {@Recipe} yet.",
                           recipe
                           ));
            }

            if (!materialSheet.TryGetValue(recipe.MaterialId, out var material))
            {
                return(LogError(
                           context,
                           "Aborted as the material {MaterialId} was failed to load from the sheet.",
                           recipe.MaterialId
                           ));
            }

            if (!avatarState.inventory.RemoveMaterial(material.ItemId, recipe.MaterialCount))
            {
                return(LogError(
                           context,
                           "Aborted as the player has no enough material ({Material} * {Quantity})",
                           material,
                           recipe.MaterialCount
                           ));
            }

            var equipmentMaterial = ItemFactory.CreateMaterial(materialSheet, material.Id);

            materials[equipmentMaterial] = recipe.MaterialCount;

            BigInteger requiredGold        = recipe.RequiredGold;
            var        requiredActionPoint = recipe.RequiredActionPoint;

            // 장비 제작
            if (!tableSheets.EquipmentItemSheet.TryGetValue(recipe.ResultEquipmentId, out var equipRow))
            {
                return(LogError(
                           context,
                           "Aborted as the equipment item {EquipmentId} was failed to load from the sheet.",
                           recipe.ResultEquipmentId
                           ));
            }

            var requiredBlockIndex = ctx.BlockIndex + recipe.RequiredBlockIndex;
            var equipment          = (Equipment)ItemFactory.CreateItemUsable(
                equipRow,
                ctx.Random.GenerateRandomGuid(),
                requiredBlockIndex
                );

            // 서브 레시피 검증
            HashSet <int> optionIds = null;

            if (SubRecipeId.HasValue)
            {
                var subSheet = tableSheets.EquipmentItemSubRecipeSheet;
                if (!subSheet.TryGetValue((int)SubRecipeId, out var subRecipe))
                {
                    return(LogError(
                               context,
                               "Aborted as the subrecipe {SubRecipeId} was failed to load from the subsheet.",
                               SubRecipeId
                               ));
                }

                // 서브 레시피 해금 검사.
                if (!avatarState.worldInformation.IsStageCleared(subRecipe.UnlockStage))
                {
                    return(LogError(
                               context,
                               "Aborted as the signer is not cleared the minimum stage level required to use the subrecipe {@SubRecipe} yet.",
                               subRecipe
                               ));
                }

                requiredBlockIndex  += subRecipe.RequiredBlockIndex;
                requiredGold        += subRecipe.RequiredGold;
                requiredActionPoint += subRecipe.RequiredActionPoint;

                foreach (var materialInfo in subRecipe.Materials)
                {
                    if (!materialSheet.TryGetValue(materialInfo.Id, out var subMaterialRow))
                    {
                        return(LogError(
                                   context,
                                   "Aborted as the meterial info {MaterialInfoId} was failed to load from the submaterial sheet.",
                                   materialInfo.Id
                                   ));
                    }

                    if (!avatarState.inventory.RemoveMaterial(subMaterialRow.ItemId,
                                                              materialInfo.Count))
                    {
                        return(LogError(
                                   context,
                                   "Aborted as the player has no enough material ({Material} * {Quantity})",
                                   subMaterialRow,
                                   materialInfo.Count
                                   ));
                    }

                    var subMaterial = ItemFactory.CreateMaterial(materialSheet, materialInfo.Id);
                    materials[subMaterial] = materialInfo.Count;
                }

                optionIds = SelectOption(tableSheets, subRecipe, ctx.Random, equipment);
                equipment.Update(requiredBlockIndex);
            }

            // 자원 검증
            BigInteger agentBalance = states.GetBalance(ctx.Signer, states.GetGoldCurrency());

            if (agentBalance < requiredGold || avatarState.actionPoint < requiredActionPoint)
            {
                return(LogError(
                           context,
                           "Aborted due to insufficient action point: {ActionPointBalance} < {ActionCost}",
                           avatarState.actionPoint,
                           requiredActionPoint
                           ));
            }

            avatarState.actionPoint -= requiredActionPoint;
            if (!(optionIds is null))
            {
                foreach (var id in optionIds)
                {
                    agentState.unlockedOptions.Add(id);
                }
            }

            // FIXME: BlacksmithAddress 계좌로 돈이 쌓이기만 하는데 이걸 어떻게 순환시킬지 기획이 필요.
            if (requiredGold > 0)
            {
                states = states.TransferAsset(ctx.Signer, BlacksmithAddress, states.GetGoldCurrency(), requiredGold);
            }

            var result = new CombinationConsumable.ResultModel
            {
                actionPoint = requiredActionPoint,
                gold        = requiredGold,
                materials   = materials,
                itemUsable  = equipment,
                recipeId    = RecipeId,
                subRecipeId = SubRecipeId,
                itemType    = ItemType.Equipment,
            };

            slotState.Update(result, ctx.BlockIndex, requiredBlockIndex);
            var mail = new CombinationMail(result, ctx.BlockIndex, ctx.Random.GenerateRandomGuid(),
                                           requiredBlockIndex);

            result.id = mail.id;
            avatarState.Update(mail);
            avatarState.questList.UpdateCombinationEquipmentQuest(RecipeId, SubRecipeId);
            avatarState.UpdateFromCombination(equipment);
            avatarState.UpdateQuestRewards(ctx);
            return(states
                   .SetState(AvatarAddress, avatarState.Serialize())
                   .SetState(slotAddress, slotState.Serialize())
                   .SetState(ctx.Signer, agentState.Serialize()));
        }
Пример #57
0
 public SimpleViewAction(IActionContext context)
     : base(context)
 {
     this.Caption = "Go to simple view";
     this.Tooltip = "Navigates to the simple view";
 }
        /// <summary>
        /// Override the validation to handle check for existing accounts with same
        /// username or email address.
        /// </summary>
        /// <param name="ctx">The action context.</param>
        /// <returns></returns>
        protected override BoolResult <Account> PerformValidation(IActionContext ctx, EntityAction entityAction)
        {
            if (!Settings.EnableValidation)
            {
                return(BoolResult <Account> .True);
            }

            bool validationResult = true;

            if (entityAction == EntityAction.Delete)
            {
                // No logic for now.
            }
            if (entityAction == EntityAction.Create || entityAction == EntityAction.Update)
            {
                // Validate the actual entity data members.
                IEntityValidator <Account> validator = this.GetValidator();
                validationResult = validator.Validate(ctx.Item, ctx.Errors);
                Account entity = ctx.Item as Account;

                // Check for username / email duplicates.
                if (entityAction == EntityAction.Create)
                {
                    // Check for duplicate usernames.
                    IList <Account> userNameDups = this.GetByFilter("UserNameLowered = '" + entity.UserNameLowered + "'").Item;
                    IList <Account> emailDups    = this.GetByFilter("EmailLowered = '" + entity.EmailLowered + "'").Item;
                    if (userNameDups != null && userNameDups.Count > 0)
                    {
                        ctx.Errors.Add("Username : "******" is already taken.");
                        validationResult = false;
                    }
                    if (emailDups != null && emailDups.Count > 0)
                    {
                        ctx.Errors.Add("Email : " + entity.EmailLowered + " is already taken.");
                        validationResult = false;
                    }
                }
                else if (entityAction == EntityAction.Update)
                {
                    ctx.Id = entity.Id;
                    Account entityBeforeUpdate = Get(ctx).Item;
                    if (string.Compare(entityBeforeUpdate.UserName, entity.UserName, true) != 0)
                    {
                        ctx.Errors.Add("Can not change username");
                    }
                }

                // Make sure password is encrypted.
                try { string decrypted = Crypto.Decrypt(entity.Password); }
                catch (Exception)
                {
                    ctx.Errors.Add("Password was not encrypted. Encrypt using method SetPassword(plainText);");
                    validationResult = false;
                }
            }

            // Now append all the errors.
            if (!validationResult)
            {
                if (ctx.CombineMessageErrors)
                {
                    string errorMessage = ValidationUtils.BuildSingleErrorMessage(ctx.Errors, Environment.NewLine);
                    return(new BoolResult <Account>(null, false, errorMessage, ValidationResults.Empty, StatusResults.Empty));
                }
            }
            return(BoolResult <Account> .True);
        }
Пример #59
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            var states      = context.PreviousStates;
            var slotAddress = avatarAddress.Derive(
                string.Format(
                    CultureInfo.InvariantCulture,
                    CombinationSlotState.DeriveFormat,
                    slotIndex
                    )
                );

            if (context.Rehearsal)
            {
                return(states
                       .SetState(avatarAddress, MarkChanged)
                       .SetState(slotAddress, MarkChanged));
            }

            CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context);

            var addressesHex = GetSignerAndOtherAddressesHex(context, avatarAddress);

            Log.Warning("{AddressesHex}rapid_combination is deprecated. Please use rapid_combination2", addressesHex);
            if (!states.TryGetAgentAvatarStates(
                    context.Signer,
                    avatarAddress,
                    out var agentState,
                    out var avatarState))
            {
                throw new FailedLoadStateException($"{addressesHex}Aborted as the avatar state of the signer was failed to load.");
            }

            var slotState = states.GetCombinationSlotState(avatarAddress, slotIndex);

            if (slotState?.Result is null)
            {
                throw new CombinationSlotResultNullException($"{addressesHex}CombinationSlot Result is null. ({avatarAddress}), ({slotIndex})");
            }

            if (!slotState.Validate(avatarState, context.BlockIndex))
            {
                throw new CombinationSlotUnlockException(
                          $"{addressesHex}Aborted as the slot state is invalid. slot index: {slotIndex}, context block index: {context.BlockIndex}");
            }

            var diff = slotState.Result.itemUsable.RequiredBlockIndex - context.BlockIndex;

            if (diff <= 0)
            {
                throw new RequiredBlockIndexException($"{addressesHex}Already met the required block index. context block index: {context.BlockIndex}, required block index: {slotState.Result.itemUsable.RequiredBlockIndex}");
            }

            var gameConfigState = states.GetGameConfigState();

            if (gameConfigState is null)
            {
                throw new FailedLoadStateException($"{addressesHex}Aborted as the GameConfigState was failed to load.");
            }

            var count             = CalculateHourglassCount(gameConfigState, diff);
            var materialItemSheet = states.GetSheet <MaterialItemSheet>();
            var row       = materialItemSheet.Values.First(r => r.ItemSubType == ItemSubType.Hourglass);
            var hourGlass = ItemFactory.CreateMaterial(row);

            if (!avatarState.inventory.RemoveFungibleItem2(hourGlass, count))
            {
                throw new NotEnoughMaterialException(
                          $"{addressesHex}Aborted as the player has no enough material ({row.Id} * {count})");
            }

            slotState.Update(context.BlockIndex, hourGlass, count);
            avatarState.UpdateFromRapidCombination(
                (CombinationConsumable5.ResultModel)slotState.Result,
                context.BlockIndex
                );
            return(states
                   .SetState(avatarAddress, avatarState.Serialize())
                   .SetState(slotAddress, slotState.Serialize()));
        }
Пример #60
0
        public static Option <IAction> FindAction(this IActor actor, IActionContext context)
        {
            Ensure.That(actor, nameof(actor)).IsNotNull();

            return(actor.Actions.Values.Find(a => a.AllowedFor(context)));
        }