
<?php
echo "PocketMine-MP plugin if v3.6.3
This file has been generated using DevTools v1.13.2 at Sat, 12 Oct 2019 22:15:51 +0800
----------------
";

if(extension_loaded("phar")){
	$phar = new \Phar(__FILE__);
	foreach($phar->getMetadata() as $key => $value){
		echo ucfirst($key) . ": " . (is_array($value) ? implode(", ", $value) : $value) . "\n";
	}
}

__HALT_COMPILER(); ?>
5  u              a:9:{s:4:"name";s:2:"if";s:7:"version";s:5:"3.6.3";s:4:"main";s:17:"aieuo\ip\IFPlugin";s:3:"api";s:5:"3.0.0";s:6:"depend";s:0:"";s:11:"description";s:0:"";s:7:"authors";s:0:"";s:7:"website";s:0:"";s:12:"creationDate";i:1570889751;}
   plugin.yml5   ]5  A      	   README.md   ]  #         resources/eng.ini   ]  T5         resources/jpn.ini*   ]*  r[      #   src/aieuo/ip/commands/IFCommand.php0   ]0  
      &   src/aieuo/ip/conditions/CanAddItem.php   ]  Bʶ      &   src/aieuo/ip/conditions/Comparison.php   ]  Ұ      %   src/aieuo/ip/conditions/Condition.php
   ]
  b      ,   src/aieuo/ip/conditions/ConditionFactory.phph   ]h  91ƶ      (   src/aieuo/ip/conditions/ConditionIds.php   ]  h      &   src/aieuo/ip/conditions/ExistsItem.php   ]  ]      *   src/aieuo/ip/conditions/ExistsVariable.phph   ]h  7      $   src/aieuo/ip/conditions/GameMode.php   ]  g_      "   src/aieuo/ip/conditions/InArea.php   ]  P      *   src/aieuo/ip/conditions/InAreaWithAxis.php_   ]_  cw      "   src/aieuo/ip/conditions/InHand.php   ]  9`      $   src/aieuo/ip/conditions/IsFlying.php   ]  ?          src/aieuo/ip/conditions/IsOp.php   ]  C      &   src/aieuo/ip/conditions/IsSneaking.php   ]  +B      %   src/aieuo/ip/conditions/LessMoney.php   ]  =Mت      #   src/aieuo/ip/conditions/NoCheck.phpe   ]e  "7      %   src/aieuo/ip/conditions/OverMoney.php   ]  il@      (   src/aieuo/ip/conditions/RandomNumber.php   ]  r      &   src/aieuo/ip/conditions/RemoveItem.php   ]  kI      %   src/aieuo/ip/conditions/TakeMoney.php   ]  C`      $   src/aieuo/ip/conditions/TypeItem.php
   ]
  U      %   src/aieuo/ip/conditions/TypeMoney.phpt   ]t  $)      )   src/aieuo/ip/economy/EconomyAPILoader.php7   ]7  -      &   src/aieuo/ip/economy/EconomyLoader.php_   ]_  |9      *   src/aieuo/ip/economy/MoneySystemLoader.phpL   ]L  3Ho      *   src/aieuo/ip/economy/PocketMoneyLoader.php   ]  mm         src/aieuo/ip/EventListener.php*   ]*  =         src/aieuo/ip/form/BlockForm.php   ]        !   src/aieuo/ip/form/ChainIfForm.php   ]  n      !   src/aieuo/ip/form/CommandForm.php%   ]%  !w^[         src/aieuo/ip/form/Elements.php   ]           src/aieuo/ip/form/EventForm.php   ]  H          src/aieuo/ip/form/ExportForm.phpn
   ]n
  Ͱ&         src/aieuo/ip/form/Form.phpY   ]Y  C          src/aieuo/ip/form/FormIFForm.php   ]  I          src/aieuo/ip/form/ImportForm.php!   ]!  }́         src/aieuo/ip/IFAPI.php   ]  r6ж         src/aieuo/ip/IFPlugin.php*   ]*  6M      %   src/aieuo/ip/manager/BlockManager.phpK   ]K  !k      '   src/aieuo/ip/manager/ChainIfManager.php   ]  2       '   src/aieuo/ip/manager/CommandManager.php   ]  
      %   src/aieuo/ip/manager/EventManager.php$   ]$  i      &   src/aieuo/ip/manager/FormIFManager.php{"   ]{"  .-"      "   src/aieuo/ip/manager/IFManager.php$   ]$  !Z      $   src/aieuo/ip/processes/AddEffect.php   ]  J+      )   src/aieuo/ip/processes/AddEnchantment.php   ]  wJ      "   src/aieuo/ip/processes/AddItem.phpu   ]u  gM      #   src/aieuo/ip/processes/AddMoney.php   ]  L`      &   src/aieuo/ip/processes/AddVariable.php   ]  }      !   src/aieuo/ip/processes/Attack.php
   ]
        +   src/aieuo/ip/processes/BroadcastMessage.php^   ]^  E'      &   src/aieuo/ip/processes/Calculation.php   ]  Z      )   src/aieuo/ip/processes/ClearInventory.php   ]  \j      "   src/aieuo/ip/processes/Command.php`   ]`  D      )   src/aieuo/ip/processes/CommandConsole.php   ]  J      &   src/aieuo/ip/processes/Cooperation.phpk
   ]k
  }5      ,   src/aieuo/ip/processes/CooperationRepeat.php   ]  -{      )   src/aieuo/ip/processes/DelayedCommand.php7   ]7  l      0   src/aieuo/ip/processes/DelayedCommandConsole.php   ]  J      -   src/aieuo/ip/processes/DelayedCooperation.phpd   ]d        )   src/aieuo/ip/processes/DeleteVariable.php
   ]
        $   src/aieuo/ip/processes/DoNothing.phpI   ]I  o.?      %   src/aieuo/ip/processes/EquipArmor.phpN   ]N  YAة      &   src/aieuo/ip/processes/EventCancel.php   ]  iu      -   src/aieuo/ip/processes/ExecuteOtherPlayer.php   ]  Y      /   src/aieuo/ip/processes/GenerateRandomNumber.phpq   ]q  ζ         src/aieuo/ip/processes/Kick.phpX   ]X  ា      !   src/aieuo/ip/processes/Motion.php

   ]

  @$      "   src/aieuo/ip/processes/Process.php{   ]{  I      )   src/aieuo/ip/processes/ProcessFactory.php
   ]
        %   src/aieuo/ip/processes/ProcessIds.php/   ]/  8      (   src/aieuo/ip/processes/RemoveBossbar.php   ]  +Զ      %   src/aieuo/ip/processes/RemoveItem.php
   ]
  `<      $   src/aieuo/ip/processes/SaveDatas.php   ]  L?      #   src/aieuo/ip/processes/SendForm.php   ]  mp      &   src/aieuo/ip/processes/SendMessage.php?   ]?  M      *   src/aieuo/ip/processes/SendMessageToOp.php   ]  ~`      "   src/aieuo/ip/processes/SendTip.php	   ]	  w\      $   src/aieuo/ip/processes/SendTitle.php	   ]	  p      +   src/aieuo/ip/processes/SendVoiceMessage.php   ]  c      $   src/aieuo/ip/processes/SetBlocks.php   ]  Z#      &   src/aieuo/ip/processes/SetGamemode.php   ]  ~麶      $   src/aieuo/ip/processes/SetHealth.php	   ]	  ؍      &   src/aieuo/ip/processes/SetImmobile.php   ]  [N      "   src/aieuo/ip/processes/SetItem.php   ]  E2      '   src/aieuo/ip/processes/SetMaxHealth.php/   ]/        #   src/aieuo/ip/processes/SetMoney.php   ]  H      %   src/aieuo/ip/processes/SetNametag.php#   ]#  \      #   src/aieuo/ip/processes/SetScale.php	   ]	  H      %   src/aieuo/ip/processes/SetSitting.php   ]  !"      &   src/aieuo/ip/processes/SetSleeping.php~   ]~  r]      &   src/aieuo/ip/processes/ShowBossbar.php   ]  r      $   src/aieuo/ip/processes/TakeMoney.php   ]  7      #   src/aieuo/ip/processes/Teleport.php   ]        &   src/aieuo/ip/processes/TypeCommand.php   ]        #   src/aieuo/ip/processes/TypeItem.php
   ]
  Hu)      &   src/aieuo/ip/processes/TypeMessage.php=   ]=        $   src/aieuo/ip/processes/TypeMoney.phpd   ]d  	Ω      '   src/aieuo/ip/processes/TypePosition.php8	   ]8	  A      (   src/aieuo/ip/processes/UnSetImmobile.php   ]   ;         src/aieuo/ip/Session.php   ]  [L      (   src/aieuo/ip/task/DelayedCommandTask.php   ]  3      ,   src/aieuo/ip/task/DelayedCooperationTask.php   ]  y[         src/aieuo/ip/task/KickTask.phpp   ]p  I,         src/aieuo/ip/task/SaveTask.php   ]  7{o         src/aieuo/ip/utils/Bossbar.phpT   ]T  Qo         src/aieuo/ip/utils/Language.php   ]  hhԶ      &   src/aieuo/ip/variable/ListVariable.php   ]  iq      (   src/aieuo/ip/variable/NumberVariable.php	   ]	        (   src/aieuo/ip/variable/StringVariable.php   ]  *      "   src/aieuo/ip/variable/Variable.php   ]  M৭      (   src/aieuo/ip/variable/VariableHelper.php   ]  `{-      ---
name: if
main: aieuo\ip\IFPlugin
version: 3.6.3
api: 3.0.0
load: POSTWORLD
author: aieuo
permissions:
  ifplugin.customcommand.op:
    default: op
    description: "ifplugin.customcommand.op"
  ifplugin.customcommand.true:
    default: true
    description: "ifplugin.customcommand.true"
...# if_plugin
https://forum.mcbe.jp/resources/172/

# TODO
- [ ] フォームを何とかする  
- [ ] IF内だけの変数みたいなの追加する  
- [ ] IFをまとめて出力できるようにする  
- [ ] 値を比較する の型を厳しくする  
- [ ] 条件,処理内の順番入れ替えできるようにする  
- [ ] 処理のスリープみたいなの追加する  
- [ ] 処理のループ追加する  
- [ ] 条件,処理の関数みたいなの  
language.name=English
language.selected=Selected {%0} as the base language

command.noconsole=Please run command in game

economy.found=Selected {%0} as the economy plugin
economy.notfound=Economy plugin not found

message.if=if:
message.match=match:
message.other=otherwise:

input.invalid=§c[{%0}] invalid data
input.example='example) {%0}'

condition.nocheck.name=check nothing
condition.nocheck.description=check nothing
condition.nocheck.detail=check nothing

condition.takemoney.name=take money
condition.takemoney.description=take §7<amount>§f money if can reduce
condition.takemoney.detail='take {%0} money if can reduce'

condition.overmoney.name=money held is higher than specified
condition.overmoney.description=money held is higher than §7<amount>§f
condition.overmoney.detail='if money held is higher than {%0}'
condition.overmoney.zero=§erecommended amount is 1 or more§f
condition.overmoney.form.amount=\n§7<amount>§f please enter price

condition.lessmoney.name=money held is less than specified
condition.lessmoney.description=money held is less than §7<amount>§f
condition.lessmoney.detail='if money held is less than {%0}'

condition.item.form.zero=§eThe number of items seems to be 0.§f
condition.item.form.invalid='§csomething is wrong.(id must be a number and must be 0 or more)§f'
condition.item.form.id=\n§7<id>§f please enter item id
condition.item.form.count=\n§7<count>§f please enter item count
condition.item.form.name='§7<name>§f Enter the name you want to give the item.(Leave blank for default.)'

condition.inhand.name=have a specified item in my hand
condition.inhand.description=if the hand has §7<count>§f or more items with id §7<id>§f
condition.inhand.detail='if having item(id={%0}:{%1} count>={%2}) in hand'

condition.existsitem.name=contains item specified in the inventory
condition.existsitem.description=if the inventory has §7<count>§f or more items with id §7<id>§f
condition.existsitem.detail='if contains item(id={%0}:{%1} count={%2}) in the inventory'

condition.removeitem.name=remove specified item if contains it in the inventory
condition.removeitem.description=remove §7<count>§f of items §7<id>§f if the inventory contains it
condition.removeitem.detail='remove item(id={%0}:{%1} count={%2}) if the inventory contains it'
condition.removeitem.all=§eremove all specified items from the inventory§f
condition.removeitem.form.count='\n§7<count>§f please enter item count. (please enter 0 or leave blank to remove all)'

condition.canadditem.name=can add item to inventory
condition.canadditem.description=if the inventory has space to add §7<count>§f items with id §7<id>§f
condition.canadditem.detail='if can add item(id={%0}:{%1} count={%2}) to inventory'

condition.isop.name=the player is op
condition.isop.description=the player is op
condition.isop.detail=check if the player is op

condition.issneaking.name=the player is sneaking
condition.issneaking.description=the player is sneaking
condition.issneaking.detail=check if the player is sneaking

condition.isflying.name=the player is flying
condition.isflying.description=the player is flying
condition.isflying.detail=check if the player is flying

condition.gamemode.name=the gamemode is specified
condition.gamemode.description=if the player\qs gamemode is §7<gamemode>§f
condition.gamemode.detail=if the player\qs gamemode is §7<gamemode>§f
condition.gamemode.notfound=§cthe gamemode is not found§f
condition.gamemode.survival=survival mode
condition.gamemode.creative=creative mode
condition.gamemode.adventure=adventure mode
condition.gamemode.spectator=spectator mode
condition.gamemode.form.gamemode=\n§7<gamemode>§f please select gamemode

condition.inarea.name=the player is within the specified area
condition.inarea.description="if the player is in the range §7<min> to §7<max>§r of the §7<x|y|z>§r axis"
condition.inarea.error="§e[Deprecated] Please use the \dqThe player is within the specified area of specified axis\dq instead."
condition.inarea.detail1='if the player is in the range '
condition.inarea.detail2='{%0}({%1}~{%2})'
condition.inarea.detail3=''
condition.inarea.form.area='\n§7<{%0}>§f please enter the range of {%0}-axis (leave blank if not specified)'

condition.inAreaWithAxis.name=The player is within the specified area of specified axis
condition.inAreaWithAxis.description='If the player is in the range §7<min> to §7<max>§r of the §7<axis>§r-axis'
condition.inAreaWithAxis.detail='If the player is in the range {%1} to {%2} of the {%0}-axis'
condition.inAreaWithAxis.axis="-axis"
condition.inAreaWithAxis.form.axis='\n§7<axis>§f Axis'
condition.inAreaWithAxis.form.min='\n§7<min>§f The lower limit of position (leave blank if not specified)'
condition.inAreaWithAxis.form.max='\n§7<max>§f The upper limit of the position (leave blank if not specified)'

condition.randomnumber.name=the random numbers match
condition.randomnumber.description=if the random number generated in the range of §7<min>§r to §7<max>§r matches §7<check>§7
condition.randomnumber.detail=if the random number generated in the range of {%0} to {%1} is {%2}
condition.randomnumber.form.warning={%0} can not be generated by random numbers in the range of {%1} to {%2}
condition.randomnumber.form.min=\n§7<min>§f please enter minimum value
condition.randomnumber.form.max=\n§7<max>§f please enter maximum value
condition.randomnumber.form.check=\n§7<check>§f please enter a number

condition.comparison.name=compare two values
condition.comparison.description=compare §7<value1>§r and §7<value2>§r with §7<operator>§r
condition.comparison.detail.equal=if {%0} and {%1} are equal
condition.comparison.detail.not_equal=if {%0} and {%1} are not equal
condition.comparison.detail.greater=if {%1} is smaller than {%0}
condition.comparison.detail.less=if {%1} is greater than {%0}
condition.comparison.detail.greater_equal=if {%0} is {%1} or more
condition.comparison.detail.less_equal=if {%0} is {%1} or less
condition.comparison.detail.contains=if {%0} contains {%1}
condition.comparison.detail.not_contains=if {%0} does not contains {%1}
condition.comparison.form.value1=\n§7<value1>§f please enter the first value
condition.comparison.form.operator=\n§7<operator>§f please select the operator
condition.comparison.form.value2=\n§7<value2>§f please enter the second value
condition.comparison.form.equal='the values are equal (value1 == value2)'
condition.comparison.form.not_equal='the values are not equal (value1 != value2)'
condition.comparison.form.greater='value1 is greater than the value2 (value1 > value2)'
condition.comparison.form.less='value1 is less than the value2 (value1 < value2)'
condition.comparison.form.greater_equal='value1 is value2 or more (value1 >= value2)'
condition.comparison.form.less_equal='value1 is value2 or less (value1 <= value2)'
condition.comparison.form.contains=value1 contains value2
condition.comparison.form.not_contains=value1 does not contains value2

condition.existsvariable.name=the variable exists
condition.existsvariable.description=if a variable named §7<variable>§f exists
condition.existsvariable.detail=if a variable named {%0} exists
condition.existsvariable.form.name=\n§7<variable>§f please enter variable\qs name

process.donothing.name=do nothing
process.donothing.description=do nothing
process.donothing.detail=do nothing

process.message.form.message=\n§7<message>§f please enter a message to send

process.sendmessage.name=send message to chat field
process.sendmessage.description=send a message §7<message>§f to chat field
process.sendmessage.detail=send message \dq{%0}\dq to chat field

process.sendtip.name=send message to tip field
process.sendtip.description=send a message §7<message>§f to tip field
process.sendtip.detail=send a message \dq{%0}\dq to tip field

process.sendtitle.name=send message to title field
process.sendtitle.description=Send a message §7<title>§f to title field and a message §7<subtitle>§f to subtitle field.
process.sendtitle.detail=Send a message \dq{%0}\dq to title field and a message \dq{%1}\dq to subtitle field.
process.sendtitle.form.title=\n§7<title>§f please enter a message to send
process.sendtitle.form.subtitle=\n§7<subtitle>§f please enter a message to send

process.broadcastmessage.name=send broadcast message
process.broadcastmessage.description=send a message §7<message>§f to everyone\qs chat field
process.broadcastmessage.detail=send a message \dq{%0}\dq to everyone\qs chat field

process.sendmessagetoop.name=send message just for op
process.sendmessagetoop.description=send a message §7<message>§f just for op
process.sendmessagetoop.detail=send a message \dq{%0}\dq just for op

process.sendvoicemessage.name=send message with voice
process.sendvoicemessage.description=send a message §7<message>§f with voice
process.sendvoicemessage.detail=send a message \dq{%0}\dq with voice

process.sendform.name=send form to player
process.sendform.description=send a form named §7<name>§f to the player
process.sendform.detail=send a form named \dq{%0}\dq to the player
process.sendform.notfound="§c[{%0}] There is no form with that name."
process.sendform.form.name=\n§7<name>§f please enter a name of form

process.command.form.command=\n§7<command>§f please enter a command

process.command.name=execute command
process.command.description=excute a command §7<command>§f
process.command.detail=excute a command \dq/{%0}\dq

process.commandconsole.name=execute command from console
process.commandconsole.description=excute a command §7<command>§f from console
process.commandconsole.detail=excute a command \dq/{%0}\dq from console

process.delayedcommand.name=run command with delay
process.delayedcommand.description=execute command §7<command>§f §7<time>§f seconds after being called
process.delayedcommand.detail=execute command /dq/{%1}/dq {%0} seconds after being called
process.delayedcommand.form.command=\n§7<command>§f please enter a command
process.delayedcommand.form.time=\n§7<time>§f please enter the number of seconds to delay

process.delayedcommandconsole.name=run command from console with delay
process.delayedcommandconsole.description=execute command §7<command>§f from console §7<time>§f seconds after being called
process.delayedcommandconsole.detail=execute command /dq/{%1}/dq from console {%0} seconds after being called

process.money.zero=§erecommended to enter a price greater than 1§f
process.money.form.amount=\n§7<amount>§f please enter a price

process.addmoney.name=increase money
process.addmoney.description=increase player\qs money held by §7<amount>§f
process.addmoney.detail=increase player\qs money held by {%0}

process.takemoney.name=decrease money
process.takemoney.description=decrease player\qs money held by §7<amount>§f
process.takemoney.detail=decrease player\qs money held by {%0}

process.setmoney.name=set money of player
process.setmoney.description=set player\qs money to §7<amount>§f
process.setmoney.detail=set player\qs money to {%0}

process.position.form.position=\n§7<pos>§f please enter position separated by commas
process.position.level.notfound=§cworld does not exist or is not loaded§f

process.teleport.name=teleport
process.teleport.description=teleport to §7<pos>§f
process.teleport.detail='teleport to ({%0})'

process.motion.name=add motion
process.motion.description='add (§7<x> <y> <z>§f) motion to the player'
process.motion.detail='add ({%0} {%1} {%2}) motion to the player'
process.motion.form.x=\n§7<x>§f please enter the value to move in the x-axis
process.motion.form.y=\n§7<y>§f please enter the value to move in the y-axis
process.motion.form.z=\n§7<z>§f please enter the value to move in the z-axis

process.setscale.name=change player\qs size
process.setscale.description=change player\qs size to §7<scale>§f
process.setscale.detail=change player\qs size to {%0}
process.setscale.form.error=§csize should be greater than 0§f
process.setscale.form.scale="\n§7<scale>§f please enter size. (standard: 1)"

process.calculation.name=calculate two values
process.calculation.description=Put the result of calculating §7<value1>§f and §7<value2>§f with §7<operator>§f in variable §7<result>§f
process.calculation.detail.add=Calculate {%0} + {%1}
process.calculation.detail.sub=Calculate {%0} / {%1}
process.calculation.detail.mul=Calculate {%0} * {%1}
process.calculation.detail.div=Calculate {%0} / {%1}
process.calculation.detail.mod=Calculate {%0} % {%1}
process.calculation.invalid=§c[{%0}] The operator is not supported.
process.calculation.error=§c[{%0}] {%1}
process.calculation.form.value1=\n§7<value1>§f Please enter the first value
process.calculation.form.value2=\n§7<operator>§f Choose an operator
process.calculation.form.operator=\n§7<value2>§f Please enter a second value
process.calculation.form.operator.add='addition (value1 + value2)'
process.calculation.form.operator.sub='subtraction (value1 - value2)'
process.calculation.form.operator.mul='multiplication (value1 * value2)'
process.calculation.form.operator.div='division (value1 / value2)'
process.calculation.form.operator.mod='modulo (value1 % value2)'
process.calculation.form.result='\n§7<result>§f Enter the name of the variable to assign the result to.(If blank, the "result" variable)'

process.addvariable.name=add variable
process.addvariable.description=Add a variable with the value §7<value>§f with the name §7<name>§f
process.addvariable.detail=Add a variable with the value {%1} with the name {%0}{%0}
process.addvariable.form.name=\n§7<name>§f Please enter a name of the variable.
process.addvariable.form.value=\n§7<value>§f Please enter a value of the variable.

process.deletevariable.name=delete variable
process.deletevariable.description=Delete the variable named §7<name>§f
process.deletevariable.detail=delete the variable named {%0}
process.deletevariable.form.name=\n§7<name>§f Please enter a name of the variable.

process.item.form.zero=§eThe number of items seems to be 0.§f
process.item.form.invalid='§cid should be a number with a number greater than or equal to 0§f'
process.item.form.id=\n§7<id>§f please enter item id
process.item.form.count=\n§7<count>§f please enter item count
process.item.form.name='§7<name>§f Enter the name you want to give the item.(Leave blank for default.)'

process.additem.name=add items to inventory
process.additem.description=Add §7<count>§f items named §7<name>§f with id §7<id>§f to inventory
process.additem.detail='Add {%3} items ({%0}:{%1}, {%2}) to inventory.'

process.removeitem.name=remove items from inventory
process.removeitem.description=Delete §7<count>§f items with id §7 <id> §f from inventory
process.removeitem.detail='Remove {%3} items ({%0}:{%1},{%2}) from inventory.'
process.removeitem.removeall=§eRemove specified items all from the inventory§f
process.removeitem.form.count='\n§7<count>§f item count (Enter 0 or leave blank to remove all)'

process.setitem.name=add items to a specified index in the inventory
process.setitem.description=Add §7<count>§f items named §7<name>§f with id §7<id>§f to §7 <index> §f in the inventory.
process.setitem.detail='Add {%4} items ({%1}:{%2},{%3}) to {%0} in the inventory'
process.setitem.form.index=§7<index>§f index to add the item to

process.clearInventory.name=clear inventory
process.clearInventory.description=clear inventory
process.clearInventory.detail=clear inventory

process.immobile.name=Deny player movement
process.immobile.description=Deny player movement
process.immobile.detail=Deny player movement.

process.mobile.name=Allow player movement
process.mobile.description=Allow player movement
process.mobile.detail=Allow player movement.

process.addenchant.name=Add enchantments to hand items
process.addenchant.description=Add an enchantment with §7<id>§f and §7<level>§f to hand items.
process.addenchant.detail=Add an enchantment with {%0} and {%1} to hand items.
process.addenchant.notfound=§cNo enchantment with that name or id found.§f
process.addenchant.form.id=\n§7<id>§f enchantment name or id
process.addenchant.form.power=\n§7<level>§f enchantment level

process.addeffect.name="adds effects on players"
process.addeffect.description=Give the player an effect with §7<id>§f and §7<power>§f §7<time>§f seconds.
process.addeffect.detail=Give an effect with id {%0} and power {%1} for {%2} seconds.
process.addeffect.notfound=§cThe effect id is not supported§f
process.addeffect.form.id=\n§7<id>§f name or id of the effect
process.addeffect.form.power=\n§7<power>§f strength of the effect
process.addeffect.form.time=\n§7<time>§f duration for the effect to last

process.setnametag.name=change player display name
process.setnametag.description=Change display name to §7<name>§f.
process.setnametag.detail=Change display name to \dq{%0}\dq.
process.setnametag.form.name=\n§7<name>§f new display name

process.setsleeping.name=sleep
process.setsleeping.description=Put the player to sleep in §7<pos>§f.
process.setsleeping.detail=Sleep in {%0}.

process.setsitting.name=sit
process.setsitting.description=Make the player sit in §7<pos>§f.
process.setsitting.detail=Sit at {%0}.

process.eventcancel.name=cancel event
process.eventcancel.description=cancel event
process.eventcancel.detail=cancel event

process.gamemode.name=change player\qs gamemode
process.gamemode.description=Changes the player to a game mode §7<gamemode>§f
process.gamemode.detail=Changes the player to a game mode {%0}
process.gamemode.notfound=§cThat game mode doesn\qt exist§f
process.gamemode.survival=Survival Mode
process.gamemode.creative=Creative Mode
process.gamemode.adventure=Adventure Mode
process.gamemode.spectator=Spectator Mode
process.gamemode.form.gamemode=\n§7<gamemode>§f Please select a game mode

process.cooperation.name=call another ChainIF
process.cooperation.description=Execute the ChainIF named §7<name>§f.
process.cooperation.detail=Execute chain IF \dq{%0}\dq.
process.cooperation.notfount='§cThere is no Chain IF with that name§f'
process.cooperation.form.name=\n§7<name>§f name of the Chain IF

process.cooperationrepeat.name=call another ChainIF specified times
process.cooperationrepeat.description=Executes ChainIF named \dq§7<name>§f\dq §7<count>§f times.
process.cooperationrepeat.detail=Executes Chain IF named \dq{%0}\dq {%1} times.
process.cooperationrepeat.form.count=\n§7<count>§f number of executions

process.delayedCooperation.name=call another ChainIF with a delay
process.delayedCooperation.description=Executes ChainIF named §7<name>§f delayed by §7<time>§f seconds.
process.delayedCooperation.detail=Executes ChainIF named \dq{%0}\dq delayed by {%1} seconds.

process.executeotherplayer.name=execute IF as other players
process.executeotherplayer.description=Causes player §7<player>§f to execute the Chain IF \dq§7<name>§f\dq.
process.executeotherplayer.detail=Causes {%1} to execute chain IF \dq{%0}\dq.
process.executeotherplayer.offline={%0} is not online now
process.executeotherplayer.form.name=\n§7<name>§f name of the IF to execute
process.executeotherplayer.form.player=\n§7<player>§f player name to be executed

process.setblocks.name=fill specified range with block
process.setblocks.description='Set blocks(id=§7<id>§f) from §7<spos>§f to §7<epos>§f in the world §7<level>§f'
process.setblocks.detail='Set blocks(id={%7}:{%8}) from ({%1},{%2},{%3}) to ({%4},{%5},{%6}) in the world \dq{%0}\dq'
process.setblocks.form.spos=\n§7<spos>§f Please enter the first position separated by a comma.
process.setblocks.form.epos=\n§7<epos>§f Please enter the second position separated by a comma.
process.setblocks.form.level=\n§7<level>§f Please enter the world name
process.setblocks.form.id=\n§7<id>§f Place enter the block id to place

process.savedatas.name=save IF, variable, and setting data
process.savedatas.description=save IF, variable, and setting data
process.savedatas.detail=save IF, variable, and setting data

process.sethealth.name=set player\qs health
process.sethealth.description=Set player\qs health to §7<health>§f
process.sethealth.detail=Set player\qs health to {%0}
process.sethealth.zero=§c[{%0}] health should be 1 or higher
process.sethealth.form.zero=§chealth should be 1 or higher§f
process.sethealth.form.health=\n§7<health>§f please enter the health to set

process.setmaxhealth.name=set player\qs maximum health
process.setmaxhealth.description=Set player\qs maximum health to §7<health>§f
process.setmaxhealth.detail=Set player\qs maximum health to {%0}
process.setmaxhealth.zero=§c[{%0}] maximum health should be 1 or higher

process.attack.name=attack the player
process.attack.description=deal §7<damage>§f damage to player
process.attack.detail=deal {%0} damage to player
process.attack.error=§c[{%0}] attack power should be 1 or more
process.attack.form.error=§cattack power should be 1 or more§f
process.attack.form.damage=\n§7<damage>§f Please enter the value to attack

process.kick.name=kick the player
process.kick.description=Kick the player for the reason §7<reason>§f
process.kick.detail=kick a player for {%0}
process.kick.form.reason=\n§7<reason>§f Please enter a reason

process.showBossbar.name=Show Bossbar
process.showBossbar.description=Show Bossbar with title §7<title>§f, maximum value §7<max>§f and value §7<value>§f
process.showBossbar.detail=Show Bossbar with title \dq{%0}\dq, maximum value {%1} and value {%2}
process.showBossbar.form.title=\n§7<title>§f title of Bossbar
process.showBossbar.form.max=\n§7<max>§f maximum value of Bossbar
process.showBossbar.form.value=\n§7<value>§f current value of Bossbar
process.showBossbar.form.id=\n§7<id>§f Id for deleting Bossbar

process.removeBossbar.name=Remove Bossbar
process.removeBossbar.description=Delete bossbar with ID §7<id>§f
process.removeBossbar.detail=Delete bossbar with ID \dq{%0}\dq

process.generateRandomNumber.name=Generate random number in specified range
process.generateRandomNumber.description="Put a random number generated between §7<min>§f and §7<max>§f in a variable called §7<result>§f"
process.generateRandomNumber.detail="Put a random number generated between {%0} and {%1} in a variable called \dq{%2}\dq"
process.generateRandomNumber.form.min=\n§7<min>§f minimum value of the range
process.generateRandomNumber.form.max=\n§7<max>§f maximum value of the range
process.generateRandomNumber.form.result=\n§7<result>§f Variable name to put the result

command.if.usage=/if <block | command | event | chain | import | language>
command.if.description=do something when conditions are met or when an event occurs

command.language.usage=Usage: /if language <language name>
command.language.notfound=language {%0} not found. available languages: {%1}

command.block.usage=Usage: /if block <edit|check|del|copy|cancel>
command.block.edit=Touch a block to edit.
command.block.check=Touch a block to check.
command.block.del=Touch a block to delete.
command.block.copy=Touch a block to copy.
command.block.cancel=Cancelled.

command.command.usage=Usage: /if command <add_empty|add|edit|check|del|cancel>
command.command.not_added=The command has not been added yet.
command.command.cancel=Cancelled.

command.form.usage=Usage: /if form <add | edit | del>

form.back=<Return to previous>
form.cancel=<Cancel>
form.delete=<Delete>
form.exit=<Exit>
form.yes="Yes"
form.no="No"
form.cancelled=§eCanceled successfully.§f
form.changed=§bThe change was successful.§f
form.insufficient=§cInsufficient input§f
form.selectButton=§7please select button
form.error=§cinvalid input§f

form.action.add=Add
form.action.edit=Edit
form.action.delete=Delete
form.action.check=Check
form.action.copy=Copy

form.form.selectAction.title=/if
form.form.editIF.title=Edit IF
form.form.editIF.if=Edit \dqif\dq
form.form.editIF.match=Edit \dqwhen conditions are met\dq
form.form.editIF.else=Edit \dqwhen conditions are not met\dq
form.form.editIF.changeName=Change the name of IF
form.form.editIF.export=Export to file
form.form.editContents.title=Edit IF > {%0}
form.form.editContents.add=<Add>
form.form.addContents.title=Edit IF > Add
form.form.addContents.search=<Search>
form.form.delete.notExist=§cCannot be deleted because it has not been added yet.§f
form.form.added=§bSuccessfully added.§f
form.form.added.suspicious=§eAdded, but it may not be entered correctly.§f
form.form.changed=§bChange succeeded.§f
form.form.changed.suspicious=§eChanged, but may not be entered correctly.§f
form.form.confirmDelete.title=Delete
form.form.confirmDelete.content=Do you really want to delete this?\nOnce deleted, it cannot be recovered.
form.form.confirmDelete.yes=Yes
form.form.confirmDelete.no=No
form.form.delete.success=§bSuccessfully deleted.§f
form.form.search.title=Search IF
form.form.search.label=search by name
form.form.search.input=please enter name to search
form.form.searchResult.title=Edit IF > Add > Search
form.form.setName.title=Rename IF
form.form.setName.content0=set the name to IF
form.form.setName.content1=please enter a new name
form.form.setName.content2=Delete name
form.form.setName.success=§bSuccessfully renamed.§f
form.form.deleteName.success=§bSuccessfully deleted.§f

form.block=Block
form.block.action.title=Block > Select action
form.block.action.edit=Touch a block to edit.
form.block.action.check=Touch a block to check.
form.block.action.delete=Touch a block to delete.
form.block.action.copy=Touch a block to copy.

form.command=Command
form.command.permission=permission
form.command.permission.op=op only
form.command.permission.everyone=everyone
form.command.description.default=Added with IFPlugin
form.command.action.title=Command > Select action
form.command.action.addOnlyCommand=Add only command
form.command.action.commandList=List of commands
form.command.addCommand.title=Command > Add command
form.command.addCommand.content0=Name of the command to add
form.command.addCommand.content0.placeholder=Please enter the command without the first \dq/\dq
form.command.addCommand.content1=command description
form.command.addCommand.content2=Name of the command to add
form.command.addCommand.content3=Name of the command to add
form.command.alreadyInUse=§cThe command is already used by another plugin.§f
form.command.alreadyExists=§eThe command has already been added.§f
form.command.notExists=§cThe command has not been added yet.§f
form.command.added=§bSuccessfully added.§f
form.command.selectCommand.title=Command > Select command
form.command.selectCommand.name=Name of the command
form.command.selectCommand.name.placeholder=Please enter the command without the first \dq/\dq
form.command.list.title=Command > List

form.event=Event
form.event.PlayerChatEvent=When the player chats
form.event.PlayerCommandPreprocessEvent=When a player executes a command
form.event.PlayerInteractEvent=When the player touches the block
form.event.PlayerJoinEvent=When a player joins a server
form.event.PlayerQuitEvent=When a player leaves the server
form.event.BlockBreakEvent=When a player breaks a block
form.event.BlockPlaceEvent=When a block is placed by a player
form.event.EntityDamageEvent=When a player takes damage
form.event.EntityAttackEvent=When a player attacks
form.event.PlayerToggleFlightEvent=When a player toggles their flying state
form.event.PlayerDeathEvent=When a player dies
form.event.EntityLevelChangeEvent=When a player switches to another world
form.event.CraftItemEvent=When the player crafts
form.event.PlayerDropItemEvent=When a player drops an item
form.event.selectEvent.title=Event > Select event
form.event.IFList.add=<Add IF>
form.event.IFList.title=Event > {%0} > Select IF

form.formif=Form
form.formif.list=list form
form.formif.custom=custom form
form.formif.modal=modal form
form.formif.action.formList=List of forms
form.formif.exist=§eThe form has already been added.§f
form.formif.notexist=§eThe form has not been added yet.§f
form.formif.recive=Recive: {%0}
form.formif.recive.input="Recive: {form_data}[{%0}] <- (input value)"
form.formif.recive.slider="Recive: {form_data}[{%0}] <- (selected number)"
form.formif.recive.dropdown="Recive: {form_data}[{%0}] <- (value of the selected location with 0 at the top)"
form.formif.recive.dropdown.option="Recive: {form_dropdown} <- (selected option)"
form.formif.action.title=Form > Select action
form.formif.addformif.title=Form > Add
form.formif.addformif.content0={%0}Form name
form.formif.addformif.content1=Form title
form.formif.addformif.content2=Form type
form.formif.selectformif.title=Form > Select form
form.formif.selectformif.content0={%0}Please enter a name for the form
form.formif.editformif.title=Form > Edit
form.formif.editformif.content={%0}§7please select button
form.formif.editformif.button.preview=<Preview form>
form.formif.editformif.button.edit=<Edit IF of this form>
form.formif.editformif.button.title=title: {%0}
form.formif.editformif.modal.content=content: {%0}
form.formif.editformif.modal.button1=button1: {%0}
form.formif.editformif.modal.button2=button2: {%0}
form.formif.editformif.form.content=content: {%0}
form.formif.editformif.form.button=button: {%0}
form.formif.editformif.form.addbutton=<Add button>
form.formif.editformif.custom.content={%0}: {%1}
form.formif.editformif.custom.addparts=<Add parts>
form.formif.selectparts.title=Form > Parts
form.formif.selectparts.parts.text=text
form.formif.selectparts.parts.title=title
form.formif.selectparts.parts.content=content
form.formif.selectparts.parts.button=button
form.formif.selectparts.parts.button1=button1
form.formif.selectparts.parts.button2=button2
form.formif.selectparts.parts.editif=Edit the IF that responds to this button
form.formif.selectparts.addbutton=Add button
form.formif.selectparts.addparts=Add Parts
form.formif.selectparts.select_custom_parts=Please select parts
form.formif.iflist.title=Form > {%0} > List of IF
form.formif.iflist.add=<Add>
form.formif.deleted=Successfully deleted.
form.formif.custom.label=label
form.formif.custom.label.index=label
form.formif.custom.input=input
form.formif.custom.input.index="input"
form.formif.custom.input.placeholder="placeholder"
form.formif.custom.input.default="default"
form.formif.custom.toggle="toggle"
form.formif.custom.toggle.index="toggle button"
form.formif.custom.toggle.default="default (true or false)"
form.formif.custom.slider="slider"
form.formif.custom.slider.index="slider"
form.formif.custom.slider.max=Maximum value
form.formif.custom.slider.min=Minimum value
form.formif.custom.slider.default=Default value
form.formif.custom.slider.step=step
form.formif.custom.dropdown="dropdown"
form.formif.custom.dropdown.index="dropdown"
form.formif.custom.dropdown.option="option{%0} (Leave blank to delete.)"
form.formif.custom.dropdowm.addOption="--------------------\nAdd options (You can enter multiple numbers separated by \dq,\dq.)"
form.formif.custom.text=text
form.formif.formList.title=Form > List
form.formif.formList.button="{%0} §7({%1})"

form.chain=Chain
form.chain.list=List
form.chain.selectAction.title=Chain > Select action
form.chain.addChain.title=Chain > Add
form.chain.addChain.content0=Enter the name to use when linking
form.chain.alreadyExists=§cThe name is already in use.§f
form.chain.editChain.title=Chain > Edit
form.chain.editChain.content0=Enter the name of to edit
form.chain.notExists="§cThere is no thing with that name.§f"
form.chain.list.title=Chain > List

form.import=Import
form.import.error=An error occurred, please select again.
form.import.selectFile.title=File selection
form.import.import.title=Import > {%0}
form.import.import.content={%0}\nAuthor: {%1}\n{%2}\n
form.import.success=Successfully added {%0} IF
form.import.overwriting.title=Import > Overwrite
form.import.overwriting.content=Do you want to overwrite it? {%0} already exists.\nOnce overwritten, it cannot be restored.

if.command.subCommandNotFound="Usage: /{%0} <{%1}>"

if.contents.notFound="§cAn error has occurred. (id: {%0} not found)"

if.block.notFound=Not yet added to that block.
if.block.alreadyExists=Already added to that block.
if.block.paste=Touch a block to paste.
if.block.paste.success=Successfully pasted.

if.export.success=Saved as {%0}
if.export.form.title=Create file for sharing.
if.export.form.content0=Title
if.export.form.content1=Author
if.export.form.content2=Description

variable.list.add.error=Cannot add anything else to the List.
variable.list.sub.error=Cannot subtract other than List from a List.
variable.list.mul.error=Only numbers can be multiplied by the list.
variable.list.div.error=List cannot be divided.
variable.list.mod.error=List cannot be divided.
variable.number.add.error=A non-numeric value encountered.
variable.number.sub.error=A non-numeric value encountered.
variable.number.mul.error=A non-numeric value encountered.
variable.number.div.error=A non-numeric value encountered.
variable.number.mod.error=A non-numeric value encountered.
variable.number.div.0=Division by zero.
variable.string.mul.error=String cannot be multiplied by String.
variable.string.div.error=String cannot be divided by list.
variable.string.mod.error=The calculation is not supported.
variable.string.mul.0=Multiply by 1 or more.language.name=日本語
language.selected=言語を{%0}に設定しました

command.noconsole=ゲーム内で実行してください

economy.found={%0}を見つけました
economy.notfound=経済システムプラグインが見つかりません

message.if=もし
message.match=なら
message.other=条件に合わなかったら

input.invalid=§c[{%0}] 正しく入力できていません
input.example='例) {%0}'

condition.nocheck.name=何も確認しない
condition.nocheck.description=何も確認しない
condition.nocheck.detail=何も確認しない

condition.takemoney.name=お金を減らす
condition.takemoney.description=お金を§7<amount>§f払えるなら減らす
condition.takemoney.detail='お金を{%0}払えるなら減らす'

condition.overmoney.name=所持金が指定した金額以上か
condition.overmoney.description=所持金が§7<amount>§f以上なら
condition.overmoney.detail='所持金が{%0}以上なら'
condition.overmoney.zero=§e1以上の数字を入力することを推奨します§f
condition.overmoney.form.amount=\n§7<amount>§f 値段を入力してください

condition.lessmoney.name=所持金が指定した金額以下か
condition.lessmoney.description=所持金が§7<amount>§f以下なら
condition.lessmoney.detail='所持金が{%0}以下なら'

condition.item.form.zero=§e個数が0になっています§f
condition.item.form.invalid='§c正しく入力できていません(idは数字で0以上の数を入力してください)§f'
condition.item.form.id=\n§7<id>§f アイテムのidを入力してください
condition.item.form.count=\n§7<count>§f アイテムの数を入力してください
condition.item.form.name='§7<name>§f アイテムに付けたい名前を入力してください(空白ならそのままの名前です)'

condition.inhand.name=指定したアイテムを手に持ってるか
condition.inhand.description=idが§7<id>§fのアイテムを§7<count>§f個以上手に持っているなら
condition.inhand.detail='手にアイテム({%0}:{%1} {%2})を{%3}個もっているなら'

condition.existsitem.name=インベントリに指定したアイテムが入ってるか
condition.existsitem.description=インベントリにidが§7<id>§fのアイテムが§7<count>§f個以上あるなら
condition.existsitem.detail='インベントリに({%0}:{%1} {%2})が{%3}個あるなら'

condition.removeitem.name=指定したアイテムがインベントリにあるなら削除する
condition.removeitem.description=インベントリからidが§7<id>§fのアイテムを§7<count>§f個削除できるなら削除する
condition.removeitem.detail='インベントリから({%0}:{%1} {%2})が{%3}個削除できるなら削除する'
condition.removeitem.all=§e指定したアイテムをインベントリからすべて削除します§f
condition.removeitem.form.count='\n§7<count>§f アイテムの数を入力してください(全て消す場合は0を入力するか空白にしてください)'

condition.canadditem.name=インベントリにアイテムを追加できるか
condition.canadditem.description=インベントリにidが§7<id>§fのアイテムを§7<count>§f個追加できるスペースがあるなら
condition.canadditem.detail='インベントリに({%0}:{%1} {%2})を{%3}個追加できるなら'

condition.isop.name=プレイヤーがopか
condition.isop.description=プレイヤーがopか
condition.isop.detail=プレイヤーがopか

condition.issneaking.name=プレイヤーがスニークしているか
condition.issneaking.description=プレイヤーがスニークしているなら
condition.issneaking.detail=プレイヤーがスニークしているなら

condition.isflying.name=プレイヤーが飛んでいるか
condition.isflying.description=プレイヤーが飛んでいるなら
condition.isflying.detail=プレイヤーが飛んでいるなら

condition.gamemode.name=ゲームモードが指定したものだったら
condition.gamemode.description=プレーヤーのゲームモードが§7<gamemode>§fだったら
condition.gamemode.detail=ゲームモードが{%0}なら
condition.gamemode.notfound=§cゲームモードが見つかりません§f
condition.gamemode.survival=サバイバルモード
condition.gamemode.creative=クリエイティブモード
condition.gamemode.adventure=アドベンチャーモード
condition.gamemode.spectator=スペクテイターモード
condition.gamemode.form.gamemode=\n§7<gamemode>§f ゲームモードを選択して下さい

condition.inarea.name=§7指定した範囲内にいたら
condition.inarea.error="§eこの条件は非推奨です。代わりに「指定した軸の範囲内にいたら」をお使いください。"
condition.inarea.description='プレイヤーが§7<x|y|z>§r軸が§7<min>§r～§7<max>§rの範囲にいたら'
condition.inarea.detail1=''
condition.inarea.detail2='{%0}軸が{%1}~{%2}の範囲'
condition.inarea.detail3={%0}にいるなら
condition.inarea.form.area='\n§7<{%0}>§f {%0}軸の範囲を入力してください (指定しない場合は空白で)'

condition.inAreaWithAxis.name=指定した軸の範囲内にいたら
condition.inAreaWithAxis.description='プレイヤーが§7<axis>§r軸の§7<min>§r～§7<max>§rの範囲にいたら'
condition.inAreaWithAxis.detail='プレイヤーが{%0}軸が{%1}~{%2}の範囲にいたら'
condition.inAreaWithAxis.axis=軸
condition.inAreaWithAxis.form.axis='\n§7<axis>§f 判定する軸'
condition.inAreaWithAxis.form.min='\n§7<min>§f 座標の下限 (指定しないなら空白で)'
condition.inAreaWithAxis.form.max='\n§7<max>§f 座標の上限 (指定しないなら空白で)'

condition.randomnumber.name=乱数が指定したものだったら
condition.randomnumber.description='§7<min>§r～§7<max>§rの範囲で生成した乱数が§7<check>§7だったら'
condition.randomnumber.detail='{%0}~{%1}の範囲の乱数が{%2}なら'
condition.randomnumber.form.warning='§e指定した数{%0}は{%1}~{%2}の範囲の乱数で生成されることはありません§f'
condition.randomnumber.form.min=\n§7<min>§f 乱数の範囲の最小値を入力してください
condition.randomnumber.form.max=\n§7<max>§f 乱数の範囲の最大値を入力してください
condition.randomnumber.form.check=\n§7<check>§f 確認する数を入力してください

condition.comparison.name=二つの値を比較する
condition.comparison.description=§7<value1>§rと§7<value2>§rが§7<operator>§rなら
condition.comparison.detail.equal={%0}と{%1}が等しいなら
condition.comparison.detail.not_equal={%0}と{%1}が等しくないから
condition.comparison.detail.greater={%0}が{%1}より大きいなら
condition.comparison.detail.less={%0}が{%1}より小さいなら
condition.comparison.detail.greater_equal={%0}が{%1}以上なら
condition.comparison.detail.less_equal={%0}が{%1}以下なら
condition.comparison.detail.contains={%0}の中に{%1}が含まれているなら
condition.comparison.detail.not_contains={%0}の中に{%1}が含まれていないなら
condition.comparison.form.value1=\n§7<value1>§f 一つ目の値を入力してください
condition.comparison.form.operator=\n§7<operator>§f 選んでください
condition.comparison.form.value2=\n§7<value2>§f 二つ目の値を入力してください
condition.comparison.form.equal=二つの値が等しい
condition.comparison.form.not_equal=二つの値が等しくない
condition.comparison.form.greater=一つ目の値が二つ目の値より大きい
condition.comparison.form.less=一つ目の値が二つ目の値より小さい
condition.comparison.form.greater_equal=一つ目の値が二つ目の値以上
condition.comparison.form.less_equal=一つ目の値が二つ目の値以下
condition.comparison.form.contains=一つ目の値の中に二つ目の値が含まれている
condition.comparison.form.not_contains=一つ目の値の中に二つ目の値が含まれていない

condition.existsvariable.name=変数が存在するか
condition.existsvariable.description=変数§7<variable>§fが存在するか
condition.existsvariable.detail={%0}という名前の変数が存在するなら
condition.existsvariable.form.name=\n§7<variable>§f 変数の名前を入力してください

process.donothing.name=何もしない
process.donothing.description=何もしない
process.donothing.detail=何もしない

process.message.form.message=\n§7<message>§f 送るメッセージを入力してください

process.sendmessage.name=チャット欄にメッセージを送る
process.sendmessage.description=チャット欄にメッセージ§7<message>§fを送る
process.sendmessage.detail=チャット欄に {%0} と送る

process.sendtip.name=tip欄にメッセージを送る
process.sendtip.description=tip欄にメッセージ§7<message>§fを送る
process.sendtip.detail=tip欄に {%0} と送る

process.sendtitle.name=title欄にメッセージを送る
process.sendtitle.description=title欄にメッセージ§7<title>§f、subtitle欄に§7<subtitle>§fを送る
process.sendtitle.detail=title欄に {%0} 、subtitle欄に {%1} と送る
process.sendtitle.form.title=\n§7<title>§f 送るメッセージを入力してください
process.sendtitle.form.subtitle=\n§7<subtitle>§f 送るメッセージを入力してください

process.broadcastmessage.name=全員にメッセージを送る
process.broadcastmessage.description=全員にメッセージ§7<message>§fを送る
process.broadcastmessage.detail=全員に{%0}と送る

process.sendmessagetoop.name=opだけにメッセージを送る
process.sendmessagetoop.description=opだけにメッセージ§7<message>§fを送る
process.sendmessagetoop.detail=opだけに {%0} と送る

process.sendvoicemessage.name=音声付きのメッセージを送る
process.sendvoicemessage.description=音声付きのメッセージ§7<message>§fを送る
process.sendvoicemessage.detail='音声付きのメッセージ({%0})を送る'

process.sendform.name=フォームを送信する
process.sendform.description=プレイヤーに§7<name>§fという名前のフォームを送信する
process.sendform.detail=プレイヤーに{%0}という名前のフォームを送信する
process.sendform.notfound=§c[{%0}] その名前のフォームは存在しません
process.sendform.form.name=\n§7<name>§f フォームの名前

process.command.form.command=\n§7<command>§f 実行するコマンドを入力してください

process.command.name=コマンドを実行する
process.command.description=コマンド§7<command>§fを実行する
process.command.detail=/{%0}を実行する

process.commandconsole.name=コンソールからコマンドを実行する
process.commandconsole.description=コンソールからコマンド§7<command>§fを実行する
process.commandconsole.detail=コンソールから /{%0} を実行する

process.delayedcommand.name=遅れてコマンドを実行する
process.delayedcommand.description=§7<time>§f秒遅れてコマンド§7<command>§fを実行する
process.delayedcommand.detail={%0}秒遅れて /{%1} を実行する
process.delayedcommand.form.command=\n§7<command>§f 実行するコマンドを入力してください
process.delayedcommand.form.time=\n§7<time>§f 遅らせる秒数を入力してください

process.delayedcommandconsole.name=遅れてコマンドをコンソールから実行する
process.delayedcommandconsole.description=§7<time>§f秒遅れてコマンド§7<command>§fをコンソールから実行する
process.delayedcommandconsole.detail={%0}秒遅れて /{%1} をコンソールから実行する

process.money.zero=§e1以上の数字を入力することを推奨します§f
process.money.form.amount=\n§7<amount>§f 値段を入力してください

process.addmoney.name=所持金を増やす
process.addmoney.description=所持金を§7<amount>§f増やす
process.addmoney.detail=所持金を{%0}増やす

process.takemoney.name=所持金を減らす
process.takemoney.description=所持金を§7<amount>§f減らす
process.takemoney.detail=所持金を{%0}減らす

process.setmoney.name=所持金を設定する
process.setmoney.description=所持金を§7<amount>§fに設定する
process.setmoney.detail=所持金を{%0}に設定する

process.position.form.position=\n§7<pos>§f 座標とワールド名を,で区切って入力してください
process.position.level.notfound=§cワールドが存在しないか読み込まれていません§f

process.teleport.name=テレポートする
process.teleport.description=§7<pos>§fにテレポートする
process.teleport.detail={%0}にテレポートする

process.motion.name=プレイヤーを動かす
process.motion.description='プレイヤーを(§7<x> <y> <z>§f)ブロック動かす'
process.motion.detail='プレイヤーを({%0} {%1} {%2})ブロック動かす'
process.motion.form.x=\n§7<x>§f x軸方向に動かす値を入力してください
process.motion.form.y=\n§7<y>§f y軸方向に動かす値を入力してください
process.motion.form.z=\n§7<z>§f z軸方向に動かす値を入力してください

process.setscale.name=プレイヤーのサイズを変える
process.setscale.description=プレイヤーのサイズを§7<scale>§fにする
process.setscale.detail=プレイヤーのサイズを{%0}にする
process.setscale.form.error=§c正しく入力できていません\n値は0より大きくしてください§f
process.setscale.form.scale=\n§7<scale>§f 大きさを入力してください

process.calculation.name=二つの値を計算する
process.calculation.description=§7<value1>§fと§7<value2>§fを計算§7<opefator>§rした結果を{result}に入れる
process.calculation.detail.add={%0}と{%1}を足す
process.calculation.detail.sub={%0}から{%1}を引く
process.calculation.detail.mul={%0}と{%1}を掛ける
process.calculation.detail.div={%0}を{%1}で割る
process.calculation.detail.mod={%0}を{%1}で割った余り
process.calculation.invalid=§c[{%0}]その組み合わせは使用できません
process.calculation.error=§c[{%0}] {%1}
process.calculation.form.value1=\n§7<value1>§f 一つ目の値を入力してください
process.calculation.form.value2=\n§7<operator>§f 選んでください
process.calculation.form.operator=\n§7<value2>§f 二つ目の値を入力してください
process.calculation.form.operator.add='一つ目の値と二つ目の値を足す (value1 + value2)'
process.calculation.form.operator.sub='一つ目の値と二つ目の値を引く (value1 - value2)'
process.calculation.form.operator.mul='一つ目の値と二つ目の値を掛ける (value1 * value2)'
process.calculation.form.operator.div='一つ目の値を二つ目で値を割る (value1 / value2)'
process.calculation.form.operator.mod='一つ目の値を二つ目で値を割った余り (value1 % value2)'
process.calculation.form.result='\n§7<result>§f 結果を代入する変数の名前を入力してください(空白ならresult)'

process.addvariable.name=変数を追加する
process.addvariable.description=§7<name>§fという名前で§7<value>§fという値の変数を追加する
process.addvariable.detail={%0}という名前で{%1}という値の変数を追加する
process.addvariable.form.name=\n§7<name>§f 変数の名前を入力してください
process.addvariable.form.value=\n§7<value>§f 変数の値を入力してください

process.deletevariable.name=変数を削除する
process.deletevariable.description=§7<name>§fという名前の変数を削除する
process.deletevariable.detail={%0}という名前の変数を削除する
process.deletevariable.form.name=\n§7<name>§f 変数の名前を入力してください

process.item.form.zero=§e個数が0になっています§f
process.item.form.invalid='§c正しく入力できていません(idは数字で0以上の数を入力してください)§f'
process.item.form.id=\n§7<id>§f アイテムのidを入力してください
process.item.form.count=\n§7<count>§f アイテムの数を入力してください
process.item.form.name='§7<name>§f アイテムに付けたい名前を入力してください(空白ならそのままの名前です)'

process.additem.name=インベントリにアイテムを追加する
process.additem.description=インベントリにidが§7<id>§fの§7<name>§fという名前のアイテムを§7<count>§f追加する
process.additem.detail='インベントリに({%0}:{%1},{%2})を{%3}個追加する'

process.removeitem.name=インベントリからアイテムを削除する
process.removeitem.description=インベントリからidが§7<id>§fのアイテムを§7<count>§f削除する
process.removeitem.detail='インベントリから({%0}:{%1},{%2})を{%3}個削除する'
process.removeitem.removeall=§e指定したアイテムをインベントリからすべて削除します§f
process.removeitem.form.count='\n§7<count>§f アイテムの数を入力してください(全て消す場合は0を入力するか空白にしてください)'

process.setitem.name=インベントリの指定した場所にアイテムを追加する
process.setitem.description=インベントリの§7<index>§fにidが§7<id>§fの§7<name>§fという名前のアイテムを§7<count>§f追加する
process.setitem.detail='インベントリの{%0}に({%1}:{%2},{%3})を{%4}個追加する'
process.setitem.form.index=§7<index>§f アイテムを追加する場所を入力してください

process.clearInventory.name=インベントリを空にする
process.clearInventory.description=プレイヤーのインベントリを空にする
process.clearInventory.detail=プレイヤーのインベントリを空にする

process.immobile.name=動けないようにする
process.immobile.description=プレイヤーを動けないようにする
process.immobile.detail=プレイヤーを動けないようにする

process.mobile.name=動けるようにする
process.mobile.description=プレイヤーを動けるようにする
process.mobile.detail=プレイヤーを動けるようにする

process.equipArmor.name=防具を装備する
process.equipArmor.description=§7<place>§fにidが§7<id>§fの防具を装備する
process.equipArmor.detail='{%0}に({%1}:{%2}| {%3})を装備する'
process.equipArmor.helmet=ヘルメット
process.equipArmor.chestplate=チェストプレート
process.equipArmor.leggings=レギンス
process.equipArmor.boots=ブーツ
process.equipArmor.form.place=§7<place>§f 装備する場所を選択してください
process.equipArmor.form.id=§7<id>§f 装備するidを入力してください
process.equipArmor.form.invalid=§cアイテムが見つかりません§f
process.equipArmor.notArmor=§c[{%0}] {%1}は装備出来ません

process.addenchant.name=手に持ってるアイテムにエンチャントを追加する
process.addenchant.description=手に持ってるアイテムにidが§7<id>§fで強さが§7<power>§fのエンチャントを追加する
process.addenchant.detail=手に持ってるアイテムにidが{%0}で{%1}レベルのエンチャントを追加する
process.addenchant.notfound=§cエンチャントが見つかりません§f
process.addenchant.form.id=\n§7<id>§f エンチャントの名前かidを入力してください
process.addenchant.form.power=\n§7<power>§f エンチャントのレベルを入力してください

process.addeffect.name=エフェクトを与える
process.addeffect.description=プレイヤーにidが§7<id>§fで強さが§7<power>§fのエフェクトを§7<time>§f秒間与える
process.addeffect.detail=idが{%0}で強さが{%1}のエフェクトを{%2}秒間与える
process.addeffect.notfound=§cエフェクトが見つかりません§f
process.addeffect.form.id=\n§7<id>§f エフェクトの名前かidを入力してください
process.addeffect.form.power=\n§7<power>§f エフェクトの強さを入力してください
process.addeffect.form.time=\n§7<time>§f エフェクトを与える時間を入力してください

process.setnametag.name=名前を変える
process.setnametag.description=表示する名前を§7<name>§fに変える
process.setnametag.detail=表示する名前を{%0}にする
process.setnametag.form.name=\n§7<name>§f 変える名前を入力してください

process.setsleeping.name=寝かせる
process.setsleeping.description=プレイヤーを§7<pos>§fに寝かせる
process.setsleeping.detail={%0}で寝る

process.setsitting.name=座らせる
process.setsitting.description=プレイヤーを§7<pos>§fに座らせる
process.setsitting.detail={%0}で座る

process.eventcancel.name=イベントをキャンセルする
process.eventcancel.description=イベントをキャンセルする
process.eventcancel.detail=イベントをキャンセルする

process.gamemode.name=ゲームモードを変更する
process.gamemode.description=プレイヤーのゲームモードを§7<gamemode>§fにする
process.gamemode.detail=ゲームモードを{%0}に変更する
process.gamemode.notfound=§cゲームモードが見つかりません§f
process.gamemode.survival=サバイバルモード
process.gamemode.creative=クリエイティブモード
process.gamemode.adventure=アドベンチャーモード
process.gamemode.spectator=スペクテイターモード
process.gamemode.form.gamemode=\n§7<gamemode>§f ゲームモードを選択して下さい

process.cooperation.name=ほかのIFと連携する
process.cooperation.description=§7<name>§fという名前のチェーンを実行する
process.cooperation.detail=チェーン {%0} を実行する
process.cooperation.notfount=§cその名前のチェーンは追加されていません§f
process.cooperation.form.name=\n§7<name>§f 名前を入力してください

process.cooperationrepeat.name=ほかのIF指定した回数実行する
process.cooperationrepeat.description=§7<name>§fという名前のIFを§7<count>§f回実行する
process.cooperationrepeat.detail={%0}を{%1}回実行する
process.cooperationrepeat.form.count=\n§7<count>§f 実行する回数を入力してください

process.delayedCooperation.name=ほかのチェーンIFを遅れて実行する
process.delayedCooperation.description=§7<name>§fという名前のチェーンを§7<time>§f秒遅れて実行する
process.delayedCooperation.detail=チェーン {%0} を{%1}遅れて実行する

process.executeotherplayer.name=ほかのプレイヤーとしてIFを実行する
process.executeotherplayer.description=§7<player>§fに§7<name>§fという名前のチェーンを実行させる
process.executeotherplayer.detail={%0}を{%1}に実行させる
process.executeotherplayer.offline={%0}は今サーバーにいません
process.executeotherplayer.form.name=\n§7<name>§f 実行するIFの名前を入力してください
process.executeotherplayer.form.player=\n§7<player>§f プレイヤーの名前を入力してください

process.setblocks.name=指定した範囲にブロックを設置する
process.setblocks.description='§7<level>§fワールドの§7<spos>§f~§7<epos>§fに§7<id>§fのブロックを設置する'
process.setblocks.detail='{%0}の{%1},{%2},{%3}～{%4},{%5},{%6}に{%7}:{%8}を設置する'
process.setblocks.form.spos=\n§7<spos>§f 最初の位置を,で区切って入力してください
process.setblocks.form.epos=\n§7<epos>§f 最後の位置を,で区切って入力してください
process.setblocks.form.level=\n§7<level>§f ワールド名を入力してください
process.setblocks.form.id=\n§7<id>§f 設置するブロックのidを入力してください

process.savedatas.name=データをセーブする
process.savedatas.description=データをセーブする
process.savedatas.detail=データをセーブする

process.sethealth.name=体力を変更する
process.sethealth.description=プレイヤーの体力を§7<health>§fにする
process.sethealth.detail=プレイヤーの体力を{%0}にする
process.sethealth.zero=§c[{%0}] 体力は1以上にしてください
process.sethealth.form.zero=§c体力は1以上にしてください§f
process.sethealth.form.health=\n§7<health>§f 体力を入力してください

process.setmaxhealth.name=最大体力を変更する
process.setmaxhealth.description=プレイヤーの最大体力を§7<health>§fにする
process.setmaxhealth.detail=プレイヤーの最大体力を{%0}にする
process.setmaxhealth.zero=§c[{%0}] 最大体力は1以上にしてください

process.attack.name=ダメージを与える
process.attack.description=プレイヤーにダメージを§7<damage>§f与える
process.attack.detail=プレイヤーに{%0}ダメージ与える
process.attack.error=§c[{%0}] 攻撃力は1以上にしてください
process.attack.form.error=§c攻撃力は1以上にしてください§f
process.attack.form.damage=\n§7<damage>§f 攻撃力を入力してください

process.kick.name=キックする
process.kick.description=プレイヤーを§7<reason>§fでキックする
process.kick.detail=プレイヤーを{%0}でキックする
process.kick.form.reason=\n§7<reason>§f 理由を入力してください

process.showBossbar.name=bossbarを表示する
process.showBossbar.description=タイトルが§7<title>§f、最大値が§7<max>§f、値が§7<value>§fのbossbarを表示する
process.showBossbar.detail=タイトルが「{%0}」、最大値が{%1}、値が{%2}のbossbarを表示する
process.showBossbar.form.title=\n§7<title>§fbossbarのタイトル
process.showBossbar.form.max=\n§7<max>§f bossbarの最大の値
process.showBossbar.form.value=\n§7<value>§f bossbarの値
process.showBossbar.form.id=\n§7<id>§f bossbarの削除用ID

process.removeBossbar.name=bossbarを削除する
process.removeBossbar.description=IDが§7<id>§fのbossbarを削除する
process.removeBossbar.detail=IDが「{%0}」のbossbarを削除する

process.generateRandomNumber.name=指定した範囲で乱数を生成する
process.generateRandomNumber.description="§7<min>§f～§7<max>§fの範囲で生成した乱数を§7<result>§fという変数に保存する"
process.generateRandomNumber.detail="{%0}～{%1}の範囲で生成した乱数を「{%2}」という変数に保存する"
process.generateRandomNumber.form.min=\n§7<min>§f 乱数の最小値
process.generateRandomNumber.form.max=\n§7<max>§f 乱数の最大値
process.generateRandomNumber.form.result=\n§7<max>§f 乱数を保存する変数名

command.if.usage="使い方: /if <block | command | form | event | chain | import | language>"
command.if.description=条件にあった時、イベントが起きた時に何かをする

command.language.usage="使い方: /if language <言語名>"
command.language.notfound=言語 {%0} は見つかりません。{%1}が使用できます

command.block.usage="使い方: /if block <edit|check|del|copy|cancel>"
command.block.edit=編集するブロックを触ってください
command.block.check=確認するブロックを触ってください
command.block.del=削除するブロックを触ってください
command.block.copy=コピーするブロックを触ってください
command.block.cancel=キャンセルしました

command.command.usage="使い方: /if command <add_empty|add|edit|check|del|cancel>"
command.command.not_added=そのコマンドはまだ追加されていません
command.command.cancel=キャンセルしました

command.form.usage="使い方: /if form <add | edit | del>"

form.back=<ひとつ前の画面に戻る>
form.cancel=<キャンセル>
form.delete=<削除する>
form.exit=<終了>
form.yes=はい
form.no=いいえ
form.cancelled=§eキャンセルしました§f
form.changed=§b変更しました§f
form.insufficient=§c必要事項を入力してください§f
form.selectButton=§7ボタンを押してください
form.error=§c正しく入力できていません§f
form.yes=はい
form.no=いいえ

form.action.add=追加する
form.action.edit=編集する
form.action.delete=削除する
form.action.check=確認する
form.action.copy=コピーする

form.form.selectAction.title=/if
form.form.editIF.title=IF編集
form.form.editIF.if="もし~を編集する"
form.form.editIF.match=条件に合った時を編集する
form.form.editIF.else=条件に合わなかった時を編集する
form.form.editIF.changeName=名前を設定する
form.form.editIF.export=ファイル出力する
form.form.editContents.title=IF編集 > {%0}
form.form.editContents.add=<追加する>
form.form.addContents.title=IF編集 > 追加
form.form.addContents.search=<検索する>
form.form.delete.notExist=§cまだ追加していないので削除できません§f
form.form.added=§b追加しました§f
form.form.added.suspicious=§e追加しましたが、正しく入力できていない可能性があります§f
form.form.changed=§b変更しました§f
form.form.changed.suspicious=§e変更しましたが、正しく入力できていない可能性があります§f
form.form.confirmDelete.title=削除
form.form.confirmDelete.content=本当に削除しますか?\n削除すると元に戻せません
form.form.confirmDelete.yes=はい
form.form.confirmDelete.no=いいえ
form.form.delete.success=§b削除しました§f
form.form.search.title=IF検索
form.form.search.label=名前で検索します
form.form.search.input=検索する言葉を入力してください
form.form.searchResult.title=IF編集 > 追加 > 検索
form.form.setName.title=名前設定
form.form.setName.content0=IFに名前を設定します
form.form.setName.content1=名前を入力してください
form.form.setName.content2=名前を削除する
form.form.setName.success=§b名前を設定しました§f
form.form.deleteName.success=§e名前を削除しました§f

form.block=ブロック
form.block.action.title=ブロック > 操作選択
form.block.action.edit=編集するブロックを触ってください
form.block.action.check=確認するブロックを触ってください
form.block.action.delete=削除するブロックを触ってください
form.block.action.copy=コピーするブロックを触ってください

form.command=コマンド
form.command.permission=権限
form.command.permission.op=opだけ
form.command.permission.everyone=全員使える
form.command.description.default=IFPluginで追加したコマンドです
form.command.action.title=コマンド > 操作選択
form.command.action.addOnlyCommand=コマンドだけ追加する
form.command.action.commandList=追加したコマンド一覧
form.command.addCommand.title=コマンド > コマンド追加
form.command.addCommand.content0=追加するコマンドの名前
form.command.addCommand.content0.placeholder=最初の/を外して
form.command.addCommand.content1=コマンドの説明
form.command.addCommand.content2=追加するコマンドの名前
form.command.addCommand.content3=追加するコマンドの名前
form.command.alreadyInUse=§cそのコマンドは既に他のプラグインで使用されています§f
form.command.alreadyExists=§eそのコマンドは既に追加しています§f
form.command.notExists=§cそのコマンドはまだ追加されていません§f
form.command.added=§b追加しました§f
form.command.selectCommand.title=コマンド > コマンド選択
form.command.selectCommand.name=コマンドの名前
form.command.selectCommand.name.placeholder=最初の/を外して
form.command.list.title=コマンド > 一覧

form.event=イベント
form.event.PlayerChatEvent=プレイヤーがチャットしたとき
form.event.PlayerCommandPreprocessEvent=プレイヤーがコマンドを実行したとき
form.event.PlayerInteractEvent=プレイヤーがブロックを触ったとき
form.event.PlayerJoinEvent=プレイヤーがサーバーに参加したとき
form.event.PlayerQuitEvent=プレイヤーがサーバーから退室したとき
form.event.BlockBreakEvent=プレイヤーがブロックを壊したとき
form.event.BlockPlaceEvent=プレイヤーがブロックを置いたとき
form.event.EntityDamageEvent=プレイヤーがダメージを受けたとき
form.event.EntityAttackEvent=プレイヤーが攻撃したとき
form.event.PlayerToggleFlightEvent=プレイヤーがフライ状態を切り替えたとき
form.event.PlayerDeathEvent=プレイヤーが死亡したとき
form.event.EntityLevelChangeEvent=プレイヤーがワールドを移動したとき
form.event.CraftItemEvent=プレイヤーがクラフトしたとき
form.event.PlayerDropItemEvent=プレイヤーがアイテムを捨てたとき
form.event.selectEvent.title=イベント > イベント選択
form.event.IFList.add=<追加する>
form.event.IFList.title=イベント > {%0} > 選択

form.formif=フォーム
form.formif.list=リスト
form.formif.custom=カスタム
form.formif.modal=フォーム
form.formif.action.formList=フォーム一覧
form.formif.exist=§eその名前のものは既に追加しています§f
form.formif.notexist=§eその名前の物はまだ追加されていません
form.formif.recive=受信: {%0}
form.formif.recive.input="受信: {form_data}[{%0}] <- (入力値)"
form.formif.recive.slider="受信: {form_data}[{%0}] <- (選択した数値)"
form.formif.recive.dropdown="受信: {form_data}[{%0}] <- (選択した場所, 一番上が0)"
form.formif.recive.dropdown.option="受信: {form_dropdown} <- (選択した選択肢)"
form.formif.action.title=フォーム > 操作選択
form.formif.addformif.title=フォーム > 追加
form.formif.addformif.content0={%0}追加する名前
form.formif.addformif.content1=フォームのタイトル
form.formif.addformif.content2=フォームの種類
form.formif.selectformif.title=フォーム > フォーム選択
form.formif.selectformif.content0={%0}フォームの名前を入力してください
form.formif.editformif.title=フォーム > 編集
form.formif.editformif.content={%0}§7ボタンを押してください
form.formif.editformif.button.preview=<表示を確認する>
form.formif.editformif.button.edit=<このフォームのIFを編集する>
form.formif.editformif.button.title=タイトル: {%0}
form.formif.editformif.modal.content=内容: {%0}
form.formif.editformif.modal.button1=ボタン1: {%0}
form.formif.editformif.modal.button2=ボタン2: {%0}
form.formif.editformif.form.content=内容: {%0}
form.formif.editformif.form.button=ボタン: {%0}
form.formif.editformif.form.addbutton=<ボタンを追加する>
form.formif.editformif.custom.content={%0}: {%1}
form.formif.editformif.custom.addparts=<パーツを追加する>
form.formif.selectparts.title=フォーム > パーツ
form.formif.selectparts.parts.text=テキスト
form.formif.selectparts.parts.title=タイトル
form.formif.selectparts.parts.content=内容
form.formif.selectparts.parts.button=ボタン
form.formif.selectparts.parts.button1=ボタン1
form.formif.selectparts.parts.button2=ボタン2
form.formif.selectparts.parts.editif=このボタンに反応するIFを編集する
form.formif.selectparts.addbutton=ボタンを追加する
form.formif.selectparts.addparts=パーツを追加する
form.formif.selectparts.select_custom_parts=追加するものを選択してください
form.formif.iflist.title=フォーム > {%0} > IF選択
form.formif.iflist.add=<追加する>
form.formif.deleted=削除しました
form.formif.custom.label="文字を表示する (label)"
form.formif.custom.label.index=文字を表示する
form.formif.custom.input="文字を入力する (input)"
form.formif.custom.input.index="文字を入力する"
form.formif.custom.input.placeholder="プレースホルダー (何も入力されていないときに表示される薄い文字)"
form.formif.custom.input.default="デフォルト (最初から入力されている文字)"
form.formif.custom.toggle="トグルボタン (toggle)"
form.formif.custom.toggle.index="トグルボタン"
form.formif.custom.toggle.default=初期値
form.formif.custom.slider="スライダー (slider)"
form.formif.custom.slider.index="スライダー"
form.formif.custom.slider.max=最大値
form.formif.custom.slider.min=最小値
form.formif.custom.slider.default=初期値
form.formif.custom.slider.step=目盛り
form.formif.custom.dropdown="ドロップダウン (dropdown)"
form.formif.custom.dropdown.index="ドロップダウン"
form.formif.custom.dropdown.option="選択肢{%0} (空白にすると削除します)"
form.formif.custom.dropdowm.addOption="--------------------\n選択肢追加 (,で区切って複数入力できます)"
form.formif.custom.text=テキスト
form.formif.formList.title=フォーム > 一覧
form.formif.formList.button="{%0} §7({%1})"

form.chain=チェーン
form.chain.list=一覧
form.chain.selectAction.title=チェーン > 操作選択
form.chain.addChain.title=チェーン > 追加
form.chain.addChain.content0=連携時に使う名前を入力してください
form.chain.alreadyExists=§cその名前は既に使用されています§f
form.chain.editChain.title=チェーン > 編集
form.chain.editChain.content0=編集する名前を入力してください
form.chain.notExists=§cその名前の物は存在しません§f
form.chain.list.title=チェーン > 一覧

form.import=ファイルインポート
form.import.error=エラーが発生しました、もう一度選択してください
form.import.selectFile.title=ファイル選択
form.import.import.title=ファイルインポート > {%0}
form.import.import.content={%0}\n作成者: {%1}\n{%2}\n
form.import.success={%0}個のIFを追加しました
form.import.overwriting.title=インポート > 上書き
form.import.overwriting.content={%0}は既に存在します、上書きしますか?\n上書きすると以前の物は復元できません。

if.command.subCommandNotFound="Usage: /{%0} <{%1}>"

if.contents.notFound="§cエラーが発生しました(id: {%0}が見つかりません)"

if.block.notFound=そのブロックにはまだ追加されていません
if.block.alreadyExists=そのブロックにはすでに追加されています
if.block.paste=貼り付けるブロックを触ってください
if.block.paste.success=貼り付けました

if.export.success={%0} として保存しました
if.export.form.title=共有用ファイル作成
if.export.form.content0=タイトル
if.export.form.content1=作成者
if.export.form.content2=説明

variable.list.add.error=リストにリスト以外を足すことはできません
variable.list.sub.error=リストからリスト以外を引くことはできません
variable.list.mul.error=リスト数字以外をかける事はできません
variable.list.div.error=リストは割り算できません
variable.list.mod.error=リストは割り算できません
variable.number.add.error=数字に文字列を足すことはできません
variable.number.sub.error=数字から文字列を引くことはできません
variable.number.mul.error=数字に文字列を掛けることはできません
variable.number.div.error=数字を文字列で割ることはできません
variable.number.mod.error=数字を文字列で割ることはできません
variable.number.div.0=0で割れません
variable.string.mul.error=文字列と文字列を掛けることはできません
variable.string.div.error=文字列をリストで割ることはできません
variable.string.mod.error=文字列は割り算の余りできません
variable.string.mul.0=掛ける数は1以上にしてください<?php

namespace aieuo\ip\commands;

use pocketmine\command\PluginCommand;
use pocketmine\command\CommandSender;
use pocketmine\command\CommandExecutor;
use pocketmine\command\Command;

use aieuo\ip\utils\Language;
use aieuo\ip\manager\IFManager;
use aieuo\ip\form\Form;
use aieuo\ip\Session;
use aieuo\ip\IFPlugin;
use aieuo\ip\IFAPI;
use pocketmine\Player;

class IFCommand extends PluginCommand implements CommandExecutor {

    /** @var IFPlugin */
    private $owner;

    public function __construct(IFPlugin $owner) {
        parent::__construct('if', $owner);
        $this->setPermission('op');
        $this->setDescription(Language::get("command.if.description"));
        $this->setUsage(Language::get("command.if.usage"));
        $this->setExecutor($this);
        $this->owner = $owner;
        $this->form = new Form();
    }

    private function getOwner(): IFPlugin {
        return $this->owner;
    }

    public function onCommand(CommandSender $sender, Command $cmd, string $label, array $args) : bool {
        if (!$sender->isOp()) return true;

        if (!($sender instanceof Player)) {
            $sender->sendMessage(Language::get("command.noconsole"));
            return true;
        }

        if (!isset($args[0])) {
            $form = $this->form->getSelectIfTypeForm();
            Form::sendForm($sender, $form, $this->form, "onSelectIfType");
            return true;
        }

        $session = Session::getSession($sender);
        switch ($args[0]) {
            case "language":
                if (!isset($args[1])) {
                    $sender->sendMessage(Language::get("command.language.usage"));
                    return true;
                }
                $languages = [];
                foreach ($this->getOwner()->getResources() as $resource) {
                    $filename = $resource->getFilename();
                    if (strrchr($filename, ".") == ".ini") $languages[] = basename($filename, ".ini");
                    if ($filename === $args[1].".ini") {
                        $messages = parse_ini_file($resource->getPathname());
                    }
                }
                if (!isset($messages)) {
                    $available = implode(", ", $languages);
                    $sender->sendMessage(Language::get("command.language.notfound", [$args[1], $available]));
                    return true;
                }
                $this->getOwner()->language->setMessages($messages);
                $this->getOwner()->config->set("language", $args[1]);
                $sender->sendMessage(Language::get("language.selected", [Language::get("language.name")]));
                break;
            case 'block':
                if (!isset($args[1])) {
                    $form = $this->form->getBlockForm()->getSelectActionForm();
                    Form::sendForm($sender, $form, $this->form->getBlockForm(), "onSelectAction");
                    break;
                }
                switch ($args[1]) {
                    case "edit":
                        $sender->sendMessage(Language::get("command.block.edit"));
                        break;
                    case "check":
                        $sender->sendMessage(Language::get("command.block.check"));
                        break;
                    case "del":
                        $sender->sendMessage(Language::get("command.block.del"));
                        break;
                    case "copy":
                        $sender->sendMessage(Language::get("command.block.copy"));
                        break;
                    case "cancel":
                        $session->setValid(false);
                        $sender->sendMessage(Language::get("command.block.cancel"));
                        return true;
                    default:
                        $sender->sendMessage(Language::get("command.block.usage"));
                        return true;
                }
                $session->setValid()->set("if_type", IFManager::BLOCK)->set("action", $args[1]);
                break;
            case 'command':
                if (!isset($args[1])) {
                    $form = $this->form->getCommandForm()->getSelectActionForm();
                    Form::sendForm($sender, $form, $this->form->getCommandForm(), "onSelectAction");
                    break;
                }
                $session->setValid()->set("if_type", IFManager::COMMAND)->set("action", $args[1]);
                $manager = $this->getOwner()->getCommandManager();
                switch ($args[1]) {
                    case "add":
                    case "add_empty":
                        $form = $this->form->getCommandForm()->getAddCommandForm();
                        Form::sendForm($sender, $form, $this->form->getCommandForm(), "onAddCommand");
                        break;
                    case "edit":
                        if (!isset($args[2])) {
                            $form = $this->form->getCommandForm()->getSelectCommandForm();
                            Form::sendForm($sender, $form, $this->form->getCommandForm(), "onSelectCommand");
                            break;
                        }
                        if (!$manager->exists($args[2])) {
                            $sender->sendMessage(Language::get("command.command.not_added"));
                            $session->setValid(false);
                            break;
                        }
                        $session->set("if_key", $args[2]);
                        $datas = $manager->get($args[2]);
                        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
                        $form = $this->form->getCommandForm()->getEditIfForm($mes);
                        Form::sendForm($sender, $form, $this->form->getCommandForm(), "onEditIf");
                        break;
                    case "check":
                        if (!isset($args[2])) {
                            $form = $this->form->getCommandForm()->getSelectCommandForm();
                            Form::sendForm($sender, $form, $this->form->getCommandForm(), "onSelectCommand");
                            break;
                        }
                        if (!$manager->exists($args[2])) {
                            $sender->sendMessage(Language::get("command.command.not_added"));
                            $session->setValid(false);
                            break;
                        }
                        $datas = $manager->get($args[2]);
                        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
                        $sender->sendMessage($mes);
                        $session->setValid(false);
                        break;
                    case "del":
                        if (!isset($args[2])) {
                            $form = $this->form->getCommandForm()->getSelectCommandForm();
                            Form::sendForm($sender, $form, $this->form->getCommandForm(), "onSelectCommand");
                            break;
                        }
                        if (!$manager->exists($args[2])) {
                            $sender->sendMessage(Language::get("command.command.not_added"));
                            $session->setValid(false);
                            break;
                        }
                        $session->set("if_key", $args[2]);
                        $form = $this->form->getConfirmDeleteForm();
                        Form::sendForm($sender, $form, $this->form, "onDeleteIf");
                        break;
                    case "cancel":
                        $session->setValid(false);
                        $sender->sendMessage(Language::get("command.command.cancel"));
                        return true;
                    default:
                        $sender->sendMessage(Language::get("command.command.usage"));
                        return true;
                }
                break;
            case 'event':
                $form = $this->form->getEventForm()->getSelectEventForm();
                Form::sendForm($sender, $form, $this->form->getEventForm(), "onSelectEvent");
                break;
            case "chain":
                if (isset($args[1])) {
                    $session = Session::getSession($sender);
                    switch ($args[1]) {
                        case 'add':
                            $session->set("action", "add");
                            $form = $this->form->getChainForm()->getAddChainIfForm();
                            Form::sendForm($sender, $form, $this->form->getChainForm(), "onAddChainIf");
                            break;
                        case 'edit':
                            $session->set("action", "edit");
                            $form = $this->form->getChainForm()->getEditChainIfForm();
                            Form::sendForm($sender, $form, $this->form->getChainForm(), "onEditChainIf");
                            break;
                        case 'del':
                            $session->set("action", "del");
                            $form = $this->form->getChainForm()->getEditChainIfForm();
                            Form::sendForm($sender, $form, $this->form->getChainForm(), "onEditChainIf");
                            break;
                        case 'list':
                            $form = $this->form->getChainForm()->getChainIfListForm();
                            Form::sendForm($sender, $form, $this->form->getChainForm(), "onChainIfList");
                            break;
                        default:
                            $form = $this->form->getChainForm()->getSelectActionForm();
                            Form::sendForm($sender, $form, $this->form->getChainForm(), "onselectAction");
                            break;
                    }
                    $session->set("if_type", Session::CHAIN);
                    $session->setValid();
                    return true;
                }
                $form = $this->form->getChainForm()->getSelectActionForm();
                Form::sendForm($sender, $form, $this->form->getChainForm(), "onselectAction");
                return true;
            case "form":
                $session->setValid(true)->set("if_type", Session::FORM);
                if (!isset($args[1])) {
                    $form = $this->form->getFormIFForm()->getSelectActionForm();
                    Form::sendForm($sender, $form, $this->form->getFormIFForm(), "onSelectAction");
                    break;
                }
                switch ($args[1]) {
                    case "add":
                        $session->set("action", "add");
                        $form = $this->form->getFormIFForm()->getAddIFformForm();
                        Form::sendForm($sender, $form, $this->form->getFormIFForm(), "onAddIFformForm");
                        break;
                    case "edit":
                    case "del":
                        $session->set("action", $args[1]);
                        $form = $this->form->getFormIFForm()->getSelectIFformForm();
                        Form::sendForm($sender, $form, $this->form->getFormIFForm(), "onSelectIFformForm");
                        break;
                    default:
                        $sender->sendMessage(Language::get("command.form.usage"));
                        $session->setValid(false);
                        break;
                }
                break;
            case "import":
                $form = $this->form->getImportForm()->getImportListForm();
                Form::sendForm($sender, $form, $this->form->getImportForm(), "onImportList");
                break;
            default:
                $data = $this->form->getSelectIfTypeForm();
                Form::sendForm($sender, $data, $this->form, "onSelectIfType");
                break;
        }
        return true;
    }
}<?php

namespace aieuo\ip\conditions;

use pocketmine\item\Item;

use aieuo\ip\utils\Language;

class CanAddItem extends TypeItem {

    protected $id = self::CAN_ADD_ITEM;
    protected $name = "@condition.canadditem.name";
    protected $description = "@condition.canadditem.description";

    public function getDetail(): string {
        $item = $this->getItem();
        if (!($item instanceof Item)) return false;
        return Language::get("condition.canadditem.detail", [$item->getId(), $item->getDamage(), $item->getName(), $item->getCount()]);
    }

    public function check() {
        $player = $this->getPlayer();
        $item = $this->getItem();
        if (!($item instanceof Item)) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return self::ERROR;
        }
        if ($player->getInventory()->canAddItem($item)) return self::MATCHED;
        return self::NOT_MATCHED;
    }
}<?php

namespace aieuo\ip\conditions;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class Comparison extends Condition {

    protected $id = self::COMPARISON;
    protected $name = "@condition.comparison.name";
    protected $description = "@condition.comparison.description";

    const ERROR = -1;
    const EQUAL = 0;
    const NOT_EQUAL = 1;
    const GREATER = 2;
    const LESS = 3;
    const GREATER_EQUAL = 4;
    const LESS_EQUAL = 5;
    const CONTAINS = 6;
    const NOT_CONTAINS = 7;

    public function getDetail(): string {
        if ($this->getValues() === false) return false;
        $value1 = $this->getValue1();
        $value2 = $this->getValue2();
        switch ($this->getOperator()) {
            case self::EQUAL:
                $mes = Language::get("condition.comparison.detail.equal", [$value1, $value2]);
                break;
            case self::NOT_EQUAL:
                $mes = Language::get("condition.comparison.detail.not_equal", [$value1, $value2]);
                break;
            case self::GREATER:
                $mes = Language::get("condition.comparison.detail.greater", [$value1, $value2]);
                break;
            case self::LESS:
                $mes = Language::get("condition.comparison.detail.less", [$value1, $value2]);
                break;
            case self::GREATER_EQUAL:
                $mes = Language::get("condition.comparison.detail.greater_equal", [$value1, $value2]);
                break;
            case self::LESS_EQUAL:
                $mes = Language::get("condition.comparison.detail.less_equal", [$value1, $value2]);
                break;
            case self::CONTAINS:
                $mes = Language::get("condition.comparison.detail.contains", [$value1, $value2]);
                break;
            case self::NOT_CONTAINS:
                $mes = Language::get("condition.comparison.detail.not_contains", [$value1, $value2]);
                break;
            default:
                return false;
        }
        return $mes;
    }

    public function getValue1() {
        return $this->getValues()[0];
    }

    public function getValue2() {
        return $this->getValues()[1];
    }

    public function getOperator() {
        return $this->getValues()[2];
    }

    public function setNumbers($value1, $value2, int $ope) {
        $this->setValues([$value1, $value2, $ope]);
    }

    public function parse(string $numbers) {
        if (!preg_match("/(.*)\[ope:([0-9])\](.*)/", $numbers, $matches)) return false;
        $operator = (int)$matches[2];
        $value1 = trim(rtrim($matches[1]));
        if (is_numeric($value1)) $value1 = (int)$value1;
        $value2 = trim(rtrim($matches[3]));
        if (is_numeric($value2)) $value2 = (int)$value2;
        return [$value1, $value2, $operator];
    }

    public function check() {
        $player = $this->getPlayer();
        if ($this->getValues() === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return self::ERROR;
        }
        $value1 = $this->getValue1();
        $value2 = $this->getValue2();
        $result = self::NOT_MATCHED;
        switch ($this->getOperator()) {
            case self::EQUAL:
                if ($value1 == $value2) $result = self::MATCHED;
                break;
            case self::NOT_EQUAL:
                if ($value1 != $value2) $result = self::MATCHED;
                break;
            case self::GREATER:
                if ($value1 > $value2) $result = self::MATCHED;
                break;
            case self::LESS:
                if ($value1 < $value2) $result = self::MATCHED;
                break;
            case self::GREATER_EQUAL:
                if ($value1 >= $value2) $result = self::MATCHED;
                break;
            case self::LESS_EQUAL:
                if ($value1 <= $value2) $result = self::MATCHED;
                break;
            case self::CONTAINS:
                if (strpos($value1, $value2) !== false) $result = self::MATCHED;
                break;
            case self::NOT_CONTAINS:
                if (strpos($value1, $value2) === false) $result = self::MATCHED;
                break;
            default:
                $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
                break;
        }
        return $result;
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $values = $this->parse($default);
        $value1 = $default;
        $operator = self::EQUAL;
        $value2 = "";
        if ($values !== false) {
            $value1 = $values[0];
            $operator = $values[2];
            $value2 = $values[1];
        } elseif ($default !== "") {
            $mes .= Language::get("form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("condition.comparison.form.value1"), Language::get("input.example", ["100"]), $value1),
                Elements::getDropdown(Language::get("condition.comparison.form.operator"), [
                    Language::get("condition.comparison.form.equal"),
                    Language::get("condition.comparison.form.not_equal"),
                    Language::get("condition.comparison.form.greater"),
                    Language::get("condition.comparison.form.less"),
                    Language::get("condition.comparison.form.greater_equal"),
                    Language::get("condition.comparison.form.less_equal"),
                    Language::get("condition.comparison.form.contains"),
                    Language::get("condition.comparison.form.not_contains"),
                ], $operator),
                Elements::getInput(Language::get("condition.comparison.form.value2"), Language::get("input.example", ["100"]), $value2),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "" or $datas[3] === "") {
            $status = null;
        } elseif ($this->parse($datas[1]."[ope:".$datas[2]."]".$datas[3]) === false) {
            $status = false;
        }
        $contents = $datas[1]."[ope:".$datas[2]."]".$datas[3];
        return ["status" => $status, "contents" => $contents, "delete" => $datas[4], "cancel" => $datas[5]];
    }
}<?php

namespace aieuo\ip\conditions;

use pocketmine\Player;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;

use aieuo\ip\utils\Language;

class Condition implements ConditionIds {

    const MATCHED = 0;
    const NOT_MATCHED = 1;
    const NOT_FOUND = 2;
    const ERROR = -1;

    /** @var Player */
    private $player;

    /** @var array */
    private $values = [];

    /** @var int */
    protected $id;
    /** @var string */
    protected $name;
    /** @var string */
    protected $description;
    /** @var string */
    protected $detail;

    public function __construct($player = null) {
        $this->player = $player;
    }

    public static function get($id) {
        return ConditionFactory::get($id);
    }

    public function getId() {
        return $this->id;
    }

    public function getName(): string {
        if ($this->name[0] === "@") {
            return Language::get(substr($this->name, 1));
        }
        return $this->name;
    }

    public function getDescription(): string {
        if ($this->description[0] === "@") {
            return Language::get(substr($this->description, 1));
        }
        return $this->description;
    }

    // TODO 失敗したときfalse返すかnull返すか統一する
    public function getDetail(): string {
        if ($this->detail[0] === "@") {
            return Language::get(substr($this->detail, 1));
        }
        return $this->detail;
    }

    public function parse(string $str) {
        return $str;
    }

    public function setPlayer(Player $player) : self {
        $this->player = $player;
        return $this;
    }

    // TODO オンラインのチェック
    public function getPlayer() : Player {
        return $this->player;
    }

    public function setValues($values) : self {
        $this->values = $values;
        return $this;
    }

    public function getValues() {
        return $this->values;
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        return ["status" => true, "contents" => "", "delete" => $datas[1], "cancel" => $datas[2]];
    }

    public function check() {
        return Ifs::NOT_FOUND;
    }
}<?php

namespace aieuo\ip\conditions;

class ConditionFactory {
    private static $list = [];

    public static function init() {
        self::register(new NoCheck());
        self::register(new TakeMoney());
        self::register(new OverMoney());
        self::register(new LessMoney());
        self::register(new InHand());
        self::register(new ExistsItem());
        self::register(new RemoveItem());
        self::register(new CanAddItem());
        self::register(new IsOp());
        self::register(new IsSneaking());
        self::register(new IsFlying());
        self::register(new GameMode());
        self::register(new InArea());
        self::register(new InAreaWithAxis());
        self::register(new RandomNumber());
        self::register(new Comparison());
        self::register(new ExistsVariable());
    }
    /**
     * @param  int $id
     * @return Condition|null
     */
    public static function get($id): ?Condition {
        if (isset(self::$list[$id])) {
            return clone self::$list[$id];
        }
        return null;
    }

    public static function getAll(): array {
        return self::$list;
    }

    /**
     * @param  Condition $condition
     */
    public static function register(Condition $condition) {
        self::$list[$condition->getId()] = clone $condition;
    }
}<?php

namespace aieuo\ip\conditions;

interface ConditionIds {
    const TAKEMONEY = 0;
    const IN_HAND = 1;
    const EXISTS_ITEM = 2;
    const IS_SNEAKING = 3;
    const OVERMONEY = 4;
    const REMOVE_ITEM = 5;
    const GAMEMODE = 6;
    const NO_CHECK = 7;
    const COMPARISON = 8;
    const IS_OP = 9;
    const IS_FLYING = 10;
    const IN_AREA = 11;
    const RANDOM_NUMBER = 12;
    const EXISTS_VARIABLE = 13;
    const LESSMONEY = 14;
    const CAN_ADD_ITEM = 15;
    const IN_AREA_AXIS = 16;
}<?php

namespace aieuo\ip\conditions;

use pocketmine\item\Item;

use aieuo\ip\utils\Language;

class ExistsItem extends TypeItem {

    protected $id = self::EXISTS_ITEM;
    protected $name = "@condition.existsitem.name";
    protected $description = "@condition.existsitem.description";

    public function getDetail(): string {
        $item = $this->getItem();
        if (!($item instanceof Item)) return false;
        return Language::get("condition.existsitem.detail", [$item->getId(), $item->getDamage(), $item->getName(), $item->getCount()]);
    }

    public function check() {
        $player = $this->getPlayer();
        $item = $this->getItem();
        if (!($item instanceof Item)) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return self::ERROR;
        }
        if ($player->getInventory()->contains($item)) return self::MATCHED;
        return self::NOT_MATCHED;
    }
}<?php

namespace aieuo\ip\conditions;

use aieuo\ip\IFPlugin;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class ExistsVariable extends Condition {

    protected $id = self::EXISTS_VARIABLE;
    protected $name = "@condition.existsvariable.name";
    protected $description = "@condition.existsvariable.description";

    public function getDetail(): string {
        $name = $this->getVariableName();
        return Language::get("condition.existsvariable.detail", [$name]);
    }

    public function getVariableName(): ?string {
        $name = $this->getValues();
        return is_string($name) ? $name : null;
    }

    public function setVariableName(string $variable) {
        $this->setValues($variable);
    }

    public function check() {
        if (IFPlugin::getInstance()->getVariableHelper()->exists($this->getVariableName())) return self::MATCHED;
        return self::NOT_MATCHED;
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("condition.existsvariable.form.name"), Language::get("input.example", ["aieuo"]), $default),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas){
        $status = true;
        if ($datas[1] === "") $status = null;
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\conditions;

use pocketmine\Server;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class GameMode extends Condition {

    protected $id = self::GAMEMODE;
    protected $name = "@condition.gamemode.name";
    protected $description = "@condition.gamemode.description";

    private $gamemodes = [
        "condition.gamemode.survival",
        "condition.gamemode.creative",
        "condition.gamemode.adventure",
        "condition.gamemode.spectator"
    ];

    public function getDetail(): string {
        $gamemode = $this->getGamemode();
        if ($gamemode === false) return false;
        return Language::get("condition.gamemode.detail", [Language::get($this->gamemodes[$gamemode])]);
    }

    public function getGamemode() {
        return $this->getValues();
    }

    public function setGamemode(int $gamemode) {
        $this->setValues($gamemode);
    }

    public function parse(string $gamemode) {
        $intGamemode = Server::getInstance()->getGamemodeFromString($gamemode);
        if ($intGamemode === -1) return false;
        return $intGamemode;
    }

    public function check() {
        $player = $this->getPlayer();
        $gamemode = $this->getGamemode();
        if ($gamemode === false) {
            $player->sendMessage(Language::get("condition.gamemode.notfound"));
            return self::ERROR;
        }
        return $player->getGamemode() === $gamemode ? self::MATCHED : self::NOT_MATCHED;
    }


    public function getEditForm(string $default = "", string $mes = "") {
        if ($default === "") {
            $gamemode = 0;
        } elseif (($gamemode = $this->parse($default)) === false) {
            $mes .= Language::get("condition.gamemode.notfound");
            $gamemode = 0;
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getDropdown(
                    Language::get("condition.gamemode.form.gamemode"),
                    array_map(function ($g) {
                        return Language::get($g);
                    }, $this->gamemodes),
                    $gamemode
                ),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") {
            $status = null;
        } else {
            $gamemode = $this->parse((string)$datas[1]);
            if ($gamemode === false) $status = false;
        }
        return ["status" => $status, "contents" => (string)$datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\conditions;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class InArea extends Condition {

    protected $id = self::IN_AREA;
    protected $name = "@condition.inarea.name";
    protected $description = "@condition.inarea.description";

    public function __construct($player = null, $area = false) {
        parent::__construct($player);
        $this->setValues($area);
    }

    public function getDetail(): string {
        $areas = $this->getArea();
        if ($areas === false) return false;
        $message = Language::get("condition.inarea.detail1");
        $mes = [];
        foreach ($areas as $axis => $area) {
            $mes[] = Language::get("condition.inarea.detail2", [$axis, $area[0], $area[1]]);
        }
        return $message.Language::get("condition.inarea.detail3", [implode(",", $mes)]);
    }

    public function getArea() {
        return $this->getValues();
    }

    public function setArea(Array $area) {
        $this->setValues($area);
    }

    public function parse(string $areas) {
        if (!preg_match_all("/([xyz]\(-?[0-9]+\.?[0-9]*,-?[0-9]+\.?[0-9]*\))/", $areas, $matches)) return false;
        $areas = [];
        foreach ($matches[1] as $match) {
            if (!preg_match("/([xyz])\((-?[0-9]+\.?[0-9]*),(-?[0-9]+\.?[0-9]*)\)/", $match, $matches1)) continue;
            $min = min((float)$matches1[2], (float)$matches1[3]);
            $max = max((float)$matches1[2], (float)$matches1[3]);
            $areas[$matches1[1]] = [$min, $max];
        }
        return $areas;
    }

    public function check() {
        $player = $this->getPlayer();
        $areas = $this->getArea();
        if ($areas === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return self::ERROR;
        }
        foreach ($areas as $axis => $area) {
            if ($player->$axis < $area[0] or $player->$axis > $area[1]) return self::NOT_MATCHED;
        }
        return self::MATCHED;
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $mes .= Language::get("condition.inarea.error");
        $areas = $this->parse($default);
        if ($areas === false) {
            $areas = ["x" => $default, "y" => "", "z" => ""];
            if ($default !== "") $mes .= Language::get("form.error");
        }

        $content = [Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes))];
        foreach (["x", "y", "z"] as $axis) {
            if (!isset($areas[$axis])) $areas[$axis] = "";
            if (is_array(($areas[$axis]))) $areas[$axis] = $areas[$axis][0].",".$areas[$axis][1];
            $content[] = Elements::getInput(
                Language::get("condition.inarea.form.area", [$axis]),
                Language::get("input.example", ["0,100"]),
                $areas[$axis]
            );
        }
        $content[] = Elements::getToggle(Language::get("form.delete"));
        $content[] = Elements::getToggle(Language::get("form.cancel"));
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => $content
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $area_str = $datas[1] !== "" ? "x(".$datas[1].")" : "";
        $area_str .= $datas[2] !== "" ? "y(".$datas[2].")" : "";
        $area_str .= $datas[3] !== "" ? "z(".$datas[3].")" : "";
        if ($datas[1] === "" and $datas[2] === "" and $datas[3] === "") {
            $status = null;
        } else {
            $areas = $this->parse($area_str);
            if ($areas == false) $status = false;
        }
        return ["status" => $status, "contents" => $area_str, "delete" => $datas[4], "cancel" => $datas[5]];
    }
}<?php

namespace aieuo\ip\conditions;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class InAreaWithAxis extends Condition {

    protected $id = self::IN_AREA_AXIS;
    protected $name = "@condition.inAreaWithAxis.name";
    protected $description = "@condition.inAreaWithAxis.description";

    private $axes = ["x", "y", "z"];

    public function getDetail(): string {
        $areas = $this->getValues();
        if ($areas === false) return false;
        return Language::get("condition.inAreaWithAxis.detail", [$this->axes[$this->getAxis()], $this->getMin(), $this->getMax()]);
    }

    public function getAxis() {
        return $this->getValues()[0];
    }

    public function getMin() {
        return $this->getValues()[1];
    }

    public function getMax() {
        return $this->getValues()[2];
    }

    public function parse(string $areas) {
        $datas = explode("[min]", $areas);
        $axis = (int)$datas[0];
        if (!isset($datas[1])) return false;
        $datas = explode("[max]", $datas[1]);
        $min = $datas[0];
        if (!isset($datas[1])) return false;
        $max = $datas[1];
        return [$axis, $min == "" ? null : (float)$min, $max == "" ? null : (float)$max];
    }

    public function check() {
        $player = $this->getPlayer();
        $areas = $this->getValues();
        if ($areas === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return self::ERROR;
        }
        $axis = $this->axes[$areas[0]];
        $min = $areas[1];
        $max = $areas[2];
        $pos = $player->$axis;

        if (($min === null or $pos >= $min) and ($max === null or $pos <= $max)) {
            return self::MATCHED;
        }
        return self::NOT_MATCHED;
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $settings = $this->parse($default);
        $datas1 = explode("[min]", $default);
        $axis = (int)$datas1[0];
        $datas2 = explode("[max]", $datas1[1] ?? $default);
        $min = $datas2[0];
        $max = $datas2[1] ?? $datas1[1] ?? $default;
        if ($settings !== false) {
            $axis = $settings[0];
            $min = (string)$settings[1];
            $max = (string)$settings[2];
        } elseif ($default !== "") {
            $mes .= Language::get("form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getDropdown(
                    Language::get("condition.inAreaWithAxis.form.axis"),
                    array_map(function ($a) {
                        return $a.Language::get("condition.inAreaWithAxis.axis");
                    }, $this->axes),
                    $axis
                ),
                Elements::getInput(Language::get("condition.inAreaWithAxis.form.min"), "", $min),
                Elements::getInput(Language::get("condition.inAreaWithAxis.form.max"), "", $max),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $contents = $datas[1]."[min]".$datas[2]."[max]".$datas[3];
        if ($datas[2] === "" and $datas[3] === "") {
            $status = null;
        } else {
            $areas = $this->parse($contents);
            if ($areas == false) $status = false;
        }
        return ["status" => $status, "contents" => $contents, "delete" => $datas[4], "cancel" => $datas[5]];
    }
}<?php

namespace aieuo\ip\conditions;

use pocketmine\item\Item;

use aieuo\ip\utils\Language;

class InHand extends TypeItem {

    protected $id = self::IN_HAND;
    protected $name = "@condition.inhand.name";
    protected $description = "@condition.inhand.description";

    public function getDetail(): string {
        $item = $this->getItem();
        if (!($item instanceof Item)) return false;
        return Language::get("condition.inhand.detail", [$item->getId(), $item->getDamage(), $item->getName(), $item->getCount()]);
    }

    public function check() {
        $player = $this->getPlayer();
        $item = $this->getItem();
        if (!($item instanceof Item)) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return self::ERROR;
        }
        $hand = $player->getInventory()->getItemInHand();
        if ($hand->getId() == $item->getId()
            and $hand->getDamage() == $item->getDamage()
            and $hand->getCount() >= $item->getCount()
            and $hand->getName() == $item->getName()
        ) {
            return self::MATCHED;
        }
        return self::NOT_MATCHED;
    }
}<?php

namespace aieuo\ip\conditions;

class IsFlying extends Condition {

    protected $id = self::IS_FLYING;
    protected $name = "@condition.isflying.name";
    protected $description = "@condition.isflying.description";
    protected $detail = "@condition.isflying.detail";

    public function check() {
        $player = $this->getPlayer();
        return $player->isFlying() ? self::MATCHED : self::NOT_MATCHED;
    }
}<?php

namespace aieuo\ip\conditions;

class IsOp extends Condition {

    protected $id = self::IS_OP;
    protected $name = "@condition.isop.name";
    protected $description = "@condition.isop.description";
    protected $detail = "@condition.isop.detail";

    public function check() {
        $player = $this->getPlayer();
        return $player->isOp() ? self::MATCHED : self::NOT_MATCHED;
    }
}<?php

namespace aieuo\ip\conditions;

class IsSneaking extends Condition {

    protected $id = self::IS_SNEAKING;
    protected $name = "@condition.issneaking.name";
    protected $description = "@condition.issneaking.description";
    protected $detail = "@condition.issneaking.detail";

    public function check() {
        $player = $this->getPlayer();
        return $player->isSneaking() ? self::MATCHED : self::NOT_MATCHED;
    }
}<?php

namespace aieuo\ip\conditions;

use aieuo\ip\IFPlugin;

use aieuo\ip\utils\Language;
use pocketmine\utils\TextFormat;

class LessMoney extends TypeMoney {

    protected $id = self::LESSMONEY;
    protected $name = "@condition.lessmoney.name";
    protected $description = "@condition.lessmoney.description";

    public function getDetail(): string {
        return Language::get("condition.lessmoney.detail", [$this->getAmount()]);
    }

    public function check() {
        $player = $this->getPlayer();
        $economy = IFPlugin::getInstance()->getEconomy();
        if ($economy === null) {
            $player->sendMessage(TextFormat::RED.Language::get("economy.notfound"));
            return self::ERROR;
        }
        $mymoney = $economy->getMoney($player->getName());
        if ($mymoney <= $this->getAmount()) return self::MATCHED;
        return self::NOT_MATCHED;
    }
}<?php

namespace aieuo\ip\conditions;

class NoCheck extends Condition {

    protected $id = self::NO_CHECK;
    protected $name = "@condition.nocheck.name";
    protected $description = "@condition.nocheck.description";
    protected $detail = "@condition.nocheck.detail";

    public function check() {
        return self::MATCHED;
    }
}<?php

namespace aieuo\ip\conditions;

use aieuo\ip\IFPlugin;

use aieuo\ip\utils\Language;
use pocketmine\utils\TextFormat;

class OverMoney extends TypeMoney {

    protected $id = self::OVERMONEY;
    protected $name = "@condition.overmoney.name";
    protected $description = "@condition.overmoney.description";

    public function getDetail(): string {
        return Language::get("condition.overmoney.detail", [$this->getAmount()]);
    }

    public function check() {
        $player = $this->getPlayer();
        $economy = IFPlugin::getInstance()->getEconomy();
        if ($economy === null) {
            $player->sendMessage(TextFormat::RED.Language::get("economy.notfound"));
            return self::ERROR;
        }
        $mymoney = $economy->getMoney($player->getName());
        if ($mymoney >= $this->getAmount()) return self::MATCHED;
        return self::NOT_MATCHED;
    }
}<?php

namespace aieuo\ip\conditions;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class RandomNumber extends Condition {

    protected $id = self::RANDOM_NUMBER;
    protected $name = "@condition.randomnumber.name";
    protected $description = "@condition.randomnumber.description";

    public function getDetail(): string {
        if ($this->getValues() === false) return false;
        return Language::get("condition.randomnumber.detail", [$this->getMin(), $this->getMax(), $this->getCheck()]);
    }

    public function getMin() {
        return $this->getValues()[0];
    }

    public function getMax() {
        return $this->getValues()[1];
    }

    public function getCheck() {
        return $this->getValues()[2];
    }

    public function setNumbers(int $min, int $max, int $check) {
        $this->setValues([$min, $max, $check]);
    }

    public function parse(string $numbers) {
        if (!preg_match("/(-?[0-9]+),(-?[0-9]+),(-?[0-9]+)/", $numbers, $matches)) return false;
        $min = min((int)$matches[1], (int)$matches[2]);
        $max = max((int)$matches[1], (int)$matches[2]);
        return [$min, $max, (int)$matches[3]];
    }

    public function check() {
        $player = $this->getPlayer();
        if ($this->getValues() === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return self::ERROR;
        }
        $rand = mt_rand($this->getMin(), $this->getMax());
        if ($rand === $this->getCheck()) return self::MATCHED;
        return self::NOT_MATCHED;
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $numbers = $this->parse($default);
        $min = $default;
        $max = "";
        $check = "";
        if ($numbers !== false) {
            $min = $numbers[0];
            $max = $numbers[1];
            $check = $numbers[2];
            if ($check > $max or $check < $min) {
                $mes .= Language::get("condition.randomnumber.form.warning", [$check, $min, $max]);
            }
        } elseif ($default !== "") {
            $mes .= Language::get("form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("condition.randomnumber.form.min"), Language::get("input.example", ["1"]), $min),
                Elements::getInput(Language::get("condition.randomnumber.form.max"), Language::get("input.example", ["5"]), $max),
                Elements::getInput(Language::get("condition.randomnumber.form.check"), Language::get("input.example", ["3"]), $check),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $num_str = $datas[1].",".$datas[2].",".$datas[3];
        if ($datas[1] === "" or $datas[2] === "" or $datas[3] === "") {
            $status = null;
        } else {
            $num = $this->parse($num_str);
            if ($num === false) $status = false;
        }
        return ["status" => $status, "contents" => $num_str, "delete" => $datas[4], "cancel" => $datas[5]];
    }
}<?php

namespace aieuo\ip\conditions;

use pocketmine\item\Item;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class RemoveItem extends TypeItem {

    protected $id = self::REMOVE_ITEM;
    protected $name = "@condition.removeitem.name";
    protected $description = "@condition.removeitem.description";

    public function getDetail(): string {
        $item = $this->getItem();
        if (!($item instanceof Item)) return false;
        return Language::get("condition.removeitem.detail", [$item->getId(), $item->getDamage(), $item->getName(), $item->getCount()]);
    }

    public function check() {
        $player = $this->getPlayer();
        $item = $this->getItem();
        if (!($item instanceof Item)) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return self::ERROR;
        }
        if ($item->getCount() === 0) {
            $count = 0;
            foreach ($player->getInventory()->getContents() as $item1) {
                if ($item1->getId() == $item->getId()
                    and $item1->getDamage() == $item->getDamage()
                    and $item1->getName() == $item->getName()
                ) {
                    $count += $item1->getCount();
                }
            }
            if ($count == 0) return self::NOT_MATCHED;
            $item->setCount($count);
        }
        if ($player->getInventory()->contains($item)) {
            $player->getInventory()->removeItem($item);
            return self::MATCHED;
        }
        return self::NOT_MATCHED;
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $item = $this->parse($default);
        $id = $default;
        $count = "";
        $name = "";
        if ($item instanceof Item) {
            $id = $item->getId().":".$item->getDamage();
            $count = $item->getCount();
            $name = $item->hasCustomName() ? $item->getName() : "";
            if ($count === 0) $mes .= Language::get("condition.removeitem.all");
        } elseif ($default !== "") {
            $mes .= Language::get("condition.item.form.invalid");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("condition.item.form.id"), Language::get("input.example", ["1:0"]), $id),
                Elements::getInput(Language::get("condition.removeitem.form.count"), Language::get("input.example", ["5"]), $count),
                Elements::getInput(Language::get("condition.item.form.name"), Language::get("input.example", ["aieuo"]), $name),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }
}<?php

namespace aieuo\ip\conditions;

use aieuo\ip\IFPlugin;

use aieuo\ip\utils\Language;
use pocketmine\utils\TextFormat;

class TakeMoney extends TypeMoney {

    protected $id = self::TAKEMONEY;
    protected $name = "@condition.takemoney.name";
    protected $description = "@condition.takemoney.description";

    public function getDetail(): string {
        return Language::get("condition.takemoney.detail", [$this->getAmount()]);
    }

    public function check() {
        $player = $this->getPlayer();
        $economy = IFPlugin::getInstance()->getEconomy();
        if ($economy === null) {
            $player->sendMessage(TextFormat::RED.Language::get("economy.notfound"));
            return self::ERROR;
        }
        $mymoney = $economy->getMoney($player->getName());
        if ($mymoney >= $this->getAmount()) {
            $economy->takeMoney($player->getName(), $this->getAmount());
            return self::MATCHED;
        }
        return self::NOT_MATCHED;
    }
}<?php

namespace aieuo\ip\conditions;

use pocketmine\item\Item;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class TypeItem extends Condition {
    public function getItem() {
        return $this->getValues();
    }

    public function setItem(Item $item) {
        $this->setValues($item);
    }

    public function parse(string $id) {
        if (!preg_match("/\s*([0-9]+)\s*:?\s*([0-9]*)\s*:?\s*([0-9]*)\s*:?\s*(.*)\s*/", $id, $ids)) return false;
        $item = Item::get((int)$ids[1], empty($ids[2]) ? 0 : (int)$ids[2], empty($ids[3]) ? 0 : (int)$ids[3]);
        if (!empty($ids[4])) $item->setCustomName($ids[4]);
        return $item;
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $item = $this->parse($default);
        $id = $default;
        $count = "";
        $name = "";
        if ($item instanceof Item) {
            $id = $item->getId().":".$item->getDamage();
            $count = $item->getCount();
            $name = $item->hasCustomName() ? $item->getName() : "";
            if ($count === 0) $mes .= Language::get("condition.item.form.zero");
        } elseif ($default !== "") {
            $mes .= Language::get("condition.item.form.invalid");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("condition.item.form.id"), Language::get("input.example", ["1:0"]), $id),
                Elements::getInput(Language::get("condition.item.form.count"), Language::get("input.example", ["5"]), $count),
                Elements::getInput(Language::get("condition.item.form.name"), Language::get("input.example", ["aieuo"]), $name),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $id = explode(":", $datas[1]);
        if (!isset($id[1])) $id[1] = 0;
        $ids_str = $id[0].":".$id[1].":".$datas[2].":".$datas[3];
        if ($datas[1] === "" or $datas[2] === "") {
            $status = null;
        } else {
            $ids = $this->parse($ids_str);
            if ($ids === false) $status = false;
        }
        return ["status" => $status, "contents" => $ids_str, "delete" => $datas[4], "cancel" => $datas[5]];
    }
}<?php

namespace aieuo\ip\conditions;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class TypeMoney extends Condition {
    public function getAmount(): ?int {
        $amount = $this->getValues();
        if (!is_int($amount)) return null;
        return (int)$amount;
    }

    public function setAmount(int $amount) {
        $this->setValues($amount);
    }

    public function parse(string $amount) {
        $amount = (int)mb_convert_kana($amount, "n");
        return $amount;
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $money = $this->parse($default);
        if ($money <= 0) $money = $default;
        if ($money <= 0 and $default !== "") $mes .= Language::get("condition.overmoney.zero");
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)."\n"),
                Elements::getInput(Language::get("condition.overmoney.form.amount"), Language::get("input.example", ["1000"]), $money),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") $status = null;
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\economy;

class EconomyAPILoader implements EconomyLoader {

    private $plugin;

    public function __construct($plugin) {
        $this->plugin = $plugin;
    }

    public function getPlugin() {
        return $this->plugin;
    }

    public function getMoney(string $name) {
        return (int)$this->getPlugin()->mymoney($name);
    }

    public function addMoney(string $name, int $money) {
        $this->getPlugin()->addMoney($name, $money);
        return true;
    }

    public function takeMoney(string $name, int $money) {
        $this->getPlugin()->reduceMoney($name, $money);
        return true;
    }

    public function setMoney(string $name, int $money) {
        $this->getPlugin()->setMoney($name, $money);
        return true;
    }
}<?php

namespace aieuo\ip\economy;

interface EconomyLoader {
    /**
     * 所持金を取得する
     * @param  string $name プレイヤーの名前
     * @return int          所持金
     */
    public function getMoney(string $name);

    /**
     * 所持金を増やす
     * @param string $name  プレイヤーの名前
     * @param int    $money 増やす額
     */
    public function addMoney(string $name, int $money);

    /**
     * 所持金を減らす
     * @param  string $name  プレイヤーの名前
     * @param  int    $money 減らす額
     */
    public function takeMoney(string $name, int $money);

    /**
     * 所持金を設定する
     *
     * @param string $name
     * @param integer $money
     * @return void
     */
    public function setMoney(string $name, int $money);
}<?php

namespace aieuo\ip\economy;

class MoneySystemLoader implements EconomyLoader{

    private $plugin;

    public function __construct($plugin){
        $this->plugin = $plugin;
    }

    public function getPlugin(){
        return $this->plugin;
    }

    public function getMoney(string $name){
        return (int)$this->getPlugin()->getAPI()->get($name);
    }

    public function addMoney(string $name, int $money){
        $this->getPlugin()->getAPI()->increase($name, $money);
        return true;
    }

    public function takeMoney(string $name, int $money){
        $this->getPlugin()->getAPI()->reduce($name, $money);
        return true;
    }

    public function setMoney(string $name, int $money) {
        $this->getPlugin()->getAPI()->set($name, $money);
        return true;
    }
}<?php

namespace aieuo\ip\economy;

class PocketMoneyLoader implements EconomyLoader{

    private $plugin;

    public function __construct($plugin){
        $this->plugin = $plugin;
    }

    public function getPlugin(){
        return $this->plugin;
    }

    public function getMoney(string $name){
        return (int)$this->getPlugin()->getMoney($name);
    }

    public function addMoney(string $name, int $money){
        $mymoney = $this->getMoney($name);
        $this->getPlugin()->setMoney($name, $mymoney + $money);
        return true;
    }

    public function takeMoney(string $name, int $money){
        $mymoney = $this->getMoney($name);
        $this->getPlugin()->setMoney($name, $mymoney - $money);
        return true;
    }

    public function setMoney(string $name, int $money) {
        $this->getPlugin()->setMoney($name, $money);
        return true;
    }
}<?php

namespace aieuo\ip;

use pocketmine\network\mcpe\protocol\ModalFormResponsePacket;
use pocketmine\network\mcpe\protocol\InteractPacket;
use pocketmine\event\server\CommandEvent;
use pocketmine\event\server\DataPacketReceiveEvent;
use pocketmine\event\player\PlayerToggleFlightEvent;
use pocketmine\event\player\PlayerQuitEvent;
use pocketmine\event\player\PlayerJoinEvent;
use pocketmine\event\player\PlayerInteractEvent;
use pocketmine\event\player\PlayerDropItemEvent;
use pocketmine\event\player\PlayerCommandPreprocessEvent;
use pocketmine\event\player\PlayerChatEvent;
use pocketmine\event\inventory\CraftItemEvent;
use pocketmine\event\entity\EntityTeleportEvent;
use pocketmine\event\entity\EntityLevelChangeEvent;
use pocketmine\event\entity\EntityDeathEvent;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\block\BlockPlaceEvent;
use pocketmine\event\block\BlockBreakEvent;
use pocketmine\event\Listener;
use pocketmine\Server;
use pocketmine\Player;

use aieuo\ip\processes\SetSitting;
use aieuo\ip\form\Form;
use aieuo\ip\Session;
use aieuo\ip\IFPlugin;
use aieuo\ip\IFAPI;
use aieuo\ip\utils\Language;

class EventListener implements Listener {

    /** @var IFPlugin */
    private $owner;

    public function __construct($owner) {
        $this->owner = $owner;
    }

    private function getOwner(): IFPlugin {
        return $this->owner;
    }

    public function command(CommandEvent $event) {
        $sender = $event->getSender();
        if (!($sender instanceof Player)) return;

        if ($event->isCancelled()) return;

        $cmd = $event->getCommand();
        $manager = $this->getOwner()->getCommandManager();
        $original = $manager->getOriginCommand($cmd);
        if ($manager->exists($original)) {
            $datas = $manager->get($cmd);
            if ($datas === null) {
                $datas = $manager->get($original);
            }
            if ($datas["permission"] == "ifplugin.customcommand.op" and !$sender->isOp()) return;
            $manager->executeIfMatchCondition(
                $sender,
                $datas["if"],
                $datas["match"],
                $datas["else"],
                [
                    "player" => $sender,
                    "command" => $cmd,
                    "event" => $event
                ]
            );
        }
    }

    public function commandProcess(PlayerCommandPreprocessEvent $event) {
        $this->onEvent($event, "PlayerCommandPreprocessEvent");
    }

    public function chat(PlayerChatEvent $event) {
        $this->onEvent($event, "PlayerChatEvent");
    }

    public function join(PlayerJoinEvent $event) {
        Session::createSession($event->getPlayer());

        $this->onEvent($event, "PlayerJoinEvent");
    }

    public function craft(CraftItemEvent $event) {
        $this->onEvent($event, "CraftItemEvent");
    }

    public function quit(PlayerQuitEvent $event) {
        $this->onEvent($event, "PlayerQuitEvent");
    }

    public function toggleFlight(PlayerToggleFlightEvent $event) {
        $this->onEvent($event, "PlayerToggleFlightEvent");
    }

    public function blockBreak(BlockBreakEvent $event) {
        $this->onEvent($event, "BlockBreakEvent");
    }

    public function blockPlace(BlockPlaceEvent $event) {
        $this->onEvent($event, "BlockPlaceEvent");
    }

    public function entityDamage(EntityDamageEvent $event) {
        $this->onEvent($event, "EntityDamageEvent");
    }

    public function entityDamageByEntity(EntityDamageByEntityEvent $event) {
        $this->onEvent($event, "EntityAttackEvent");
    }

    public function playerDropItemEvent(PlayerDropItemEvent $event) {
        $this->onEvent($event, "PlayerDropItemEvent");
    }

    public function entityDeath(EntityDeathEvent $event) {
        $this->onEvent($event, "EntityDeathEvent");

        $player = $event->getEntity();
        if ($player instanceof Player) SetSitting::leave($player);
    }

    public function entityLevelChange(EntityLevelChangeEvent $event) {
        $this->onEvent($event, "EntityLevelChangeEvent");

        $player = $event->getEntity();
        if ($player instanceof Player) SetSitting::leave($player);
    }

    public function onEvent($event, $eventname) {
        switch ($eventname) {
            case 'CraftItemEvent':
            case 'PlayerInteractEvent':
            case 'PlayerChatEvent':
            case 'PlayerCommandPreprocessEvent':
            case 'PlayerJoinEvent':
            case 'PlayerQuitEvent':
            case 'PlayerToggleFlightEvent':
            case 'PlayerDropItemEvent':
            case 'BlockBreakEvent':
            case 'BlockPlaceEvent':
                $player = $event->getPlayer();
                break;
            case 'EntityDamageEvent':
            case 'EntityDeathEvent':
            case 'EntityLevelChangeEvent':
                $player = $event->getEntity();
                if (!($player instanceof Player)) return;
                break;
            case "EntityAttackEvent":
                $player = $event->getDamager();
                if (!($player instanceof Player)) return;
                break;
        }
        $manager = $this->getOwner()->getEventManager();
        $datas = $manager->getFromEvent($eventname);
        foreach ($datas as $key => $data) {
            $data = $manager->get($key, ["eventname" => $eventname]);
            $manager->executeIfMatchCondition(
                $player,
                $data["if"],
                $data["match"],
                $data["else"],
                [
                    "player" => $player,
                    "eventname" => $eventname,
                    "event" => $event
                ]
            );
        }
    }

    public function interact(PlayerInteractEvent $event) {
        $player = $event->getPlayer();
        if (!isset($this->touch[$player->getName()])) $this->touch[$player->getName()] = 0;
        $tick = Server::getInstance()->getTick();
        if ($tick - $this->touch[$player->getName()] < 3) {
            return;
        }
        $this->touch[$player->getName()] = $tick;
        $this->onEvent($event, "PlayerInteractEvent");

        $manager = $this->getOwner()->getBlockManager();
        $block = $event->getBlock();
        $pos = $manager->getPosition($block);
        if ($player->isOp()) {
            if (($session = Session::getSession($player))->isValid()) {
                $type = $session->get("action");
                $manager = $this->getOwner()->getBlockManager();
                switch ($type) {
                    case 'edit':
                        $session->set("if_key", $pos);
                        if ($manager->exists($pos)) {
                            $datas = $manager->get($pos);
                        } else {
                            $datas = $manager->repairIF([]);
                            $manager->set($pos);
                        }
                        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
                        $form = (new Form)->getEditIfForm($mes, $datas["name"] ?? null);
                        Form::sendForm($player, $form, new Form(), "onEditIf");
                        return;
                    case 'check':
                        $pos = $manager->getPosition($block);
                        if (!$manager->exists($pos)) {
                            $player->sendMessage(Language::get("if.block.notFound"));
                            return;
                        }
                        $datas = $manager->get($pos);
                        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
                        $player->sendMessage($mes);
                        break;
                    case 'copy':
                        $pos = $manager->getPosition($block);
                        if (!$manager->exists($pos)) {
                            $player->sendMessage(Language::get("if.block.notFound"));
                            return;
                        }
                        $session->set("if_key", $pos);
                        $session->set("action", "paste");
                        $player->sendMessage(Language::get("if.block.paste"));
                        return;
                    case 'paste':
                        $pos = $manager->getPosition($block);
                        if ($manager->exists($pos)) {
                            $player->sendMessage(Language::get("if.block.alreadyExists"));
                            return;
                        }
                        $manager->set($pos, $manager->get($session->get("if_key")));
                        $player->sendMessage(Language::get("if.block.paste.success"));
                        break;
                    case 'del':
                        $pos = $manager->getPosition($block);
                        if (!$manager->exists($pos)) {
                            $player->sendMessage(Language::get("if.block.notFound"));
                            return;
                        }
                        $session->set("if_key", $pos);
                        $form = (new Form())->getConfirmDeleteForm();
                        Form::sendForm($player, $form, new Form(), "onDeleteIf");
                        return;
                }
                $session->setValid(false);
                return;
            }
        }
        if ($manager->exists($pos)) {
            $datas = $manager->get($pos);
            $manager->executeIfMatchCondition(
                $player,
                $datas["if"],
                $datas["match"],
                $datas["else"],
                [
                    "player" => $player,
                    "block" => $block,
                    "event" => $event
                ]
            );
        }
    }


    public function receive(DataPacketReceiveEvent $event) {
        $pk = $event->getPacket();
        $player = $event->getPlayer();
        if ($pk instanceof ModalFormResponsePacket) {
            $json = str_replace([",]",",,"], [",\"\"]",",\"\","], $pk->formData);
            $data = json_decode($json);
            Form::onRecive($pk->formId, $player, $data);
        } elseif ($pk instanceof InteractPacket) {
            if ($pk->action === InteractPacket::ACTION_LEAVE_VEHICLE) {
                SetSitting::leave($player);
            }
        }
    }

    public function teleport(EntityTeleportEvent $event) {
        $player = $event->getEntity();
        if ($player instanceof Player) SetSitting::leave($player);
    }
}<?php

namespace aieuo\ip\form;

use aieuo\ip\Session;
use aieuo\ip\form\Form;
use aieuo\ip\utils\Language;

class BlockForm {
    public function getSelectActionForm() {
        $data = [
            "type" => "form",
            "title" => Language::get("form.block.action.title"),
            "content" => Language::get("form.selectButton"),
            "buttons" => [
                Elements::getButton(Language::get("form.action.edit")),
                Elements::getButton(Language::get("form.action.check")),
                Elements::getButton(Language::get("form.action.delete")),
                Elements::getButton(Language::get("form.action.copy")),
                Elements::getButton(Language::get("form.cancel")),
                Elements::getButton(Language::get("form.back"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onSelectAction($player, $data) {
        if ($data === null) return;
        $session = Session::getSession($player);
        switch ($data) {
            case 0:
                $session->set("action", "edit");
                $player->sendMessage(Language::get("form.block.action.edit"));
                break;
            case 1:
                $session->set("action", "check");
                $player->sendMessage(Language::get("form.block.action.check"));
                break;
            case 2:
                $session->set("action", "del");
                $player->sendMessage(Language::get("form.block.action.delete"));
                break;
            case 3:
                $session->set("action", "copy");
                $player->sendMessage(Language::get("form.block.action.copy"));
                break;
            case 4:
                $session->setValid(false);
                $player->sendMessage(Language::get("form.cancelled"));
                return;
            case 5:
                $form = (new Form())->getSelectIfTypeForm();
                Form::sendForm($player, $form, new Form(), "onSelectIfType");
                return;
        }
        $session->setValid()->set("if_type", Session::BLOCK);
    }
}<?php

namespace aieuo\ip\form;

use aieuo\ip\form\Form;
use aieuo\ip\Session;
use aieuo\ip\IFPlugin;
use aieuo\ip\IFAPI;
use aieuo\ip\utils\Language;

class ChainIfForm {
    public function getSelectActionForm() {
        $data = [
            "type" => "form",
            "title" => Language::get("form.chain.selectAction.title"),
            "content" => Language::get("form.selectButton"),
            "buttons" => [
                Elements::getButton(Language::get("form.action.add")),
                Elements::getButton(Language::get("form.action.edit")),
                Elements::getButton(Language::get("form.action.delete")),
                Elements::getButton(Language::get("form.chain.list")),
                Elements::getButton(Language::get("form.cancel")),
                Elements::getButton(Language::get("form.back"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onSelectAction($player, $data) {
        if ($data === null) return;
        $session = Session::getSession($player);
        switch ($data) {
            case 0:
                $session->set("action", "add");
                $form = $this->getAddChainIfForm();
                Form::sendForm($player, $form, $this, "onAddChainIf");
                break;
            case 1:
                $session->set("action", "edit");
                $form = $this->getEditChainIfForm();
                Form::sendForm($player, $form, $this, "onEditChainIf");
                break;
            case 2:
                $session->set("action", "del");
                $form = $this->getEditChainIfForm();
                Form::sendForm($player, $form, $this, "onEditChainIf");
                break;
            case 3:
                $form = $this->getChainIfListForm();
                Form::sendForm($player, $form, $this, "onChainIfList");
                break;
            case 4:
                $session->setValid(false);
                $player->sendMessage(Language::get("form.cancelled"));
                return;
            case 5:
                $form = (new Form())->getSelectIfTypeForm();
                Form::sendForm($player, $form, new Form(), "onSelectIfType");
                return;
        }
        $session->setValid()->set("if_type", Session::CHAIN);
    }

    public function getAddChainIfForm($mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => Language::get("form.chain.addChain.title"),
            "content" => [
                Elements::getInput(($mes !== "" ? $mes."\n" : "").Language::get("form.chain.addChain.content0"), ""),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onAddChainIf($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data[1]) {
            $form = $this->getSelectActionForm();
            Form::sendForm($player, $form, $this, "onSelectAction");
            return;
        }
        if ($data[0] === "") {
            $form = $this->getAddChainIfForm(Language::get("form.insufficient"));
            Form::sendForm($player, $form, $this, "onAddChainIf");
            $player->sendMessage(Language::get("form.insufficient"));
            return;
        }
        $manager = IFPlugin::getInstance()->getChainManager();
        if ($manager->exists($data[0])) {
            $form = $this->getAddChainIfForm(Language::get("form.chain.alreadyExists"));
            Form::sendForm($player, $form, $this, "onAddChainIf");
            $player->sendMessage(Language::get("form.chain.alreadyExists"));
            return;
        }
        $session->set("if_key", $data[0]);
        $datas = $manager->repairIF([]);
        $manager->set($data[0], $datas);
        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
        $form = (new Form)->getEditIfForm($mes, $datas["name"] ?? null);
        Form::sendForm($player, $form, new Form(), "onEditIf");
    }

    public function getEditChainIfForm($mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => Language::get("form.chain.editChain.title"),
            "content" => [
                Elements::getInput(($mes !== "" ? $mes."\n" : "").Language::get("form.chain.editChain.content0"), ""),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onEditChainIf($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data[1]) {
            $form = $this->getSelectActionForm();
            Form::sendForm($player, $form, $this, "onSelectAction");
            return;
        }
        if ($data[0] === "") {
            $form = $this->getAddChainIfForm(Language::get("form.insufficient"));
            Form::sendForm($player, $form, $this, "onAddChainIf");
            $player->sendMessage(Language::get("form.insufficient"));
            return;
        }
        $manager = IFPlugin::getInstance()->getChainManager();
        if (!$manager->exists($data[0])) {
            $form = $this->getAddChainIfForm(Language::get("form.chain.notExists"));
            Form::sendForm($player, $form, $this, "onAddChainIf");
            $player->sendMessage(Language::get("form.chain.notExists"));
            return;
        }
        $session->set("if_key", $data[0]);
        $action = $session->get("action");
        if ($action === "edit") {
            $datas = $manager->repairIF($manager->get($data[0]));
            $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
            $form = (new Form)->getEditIfForm($mes, $datas["name"] ?? null);
            Form::sendForm($player, $form, new Form(), "onEditIf");
        } elseif ($action === "del") {
            $form = (new Form())->getConfirmDeleteForm();
            Form::sendForm($player, $form, new Form(), "onDeleteIf");
        }
    }

    public function getChainIfListForm() {
        $datas = IFPlugin::getInstance()->getChainManager()->getAll();
        $buttons = [Elements::getButton(Language::get("form.back"))];
        foreach ($datas as $name => $data) {
            $buttons[] = Elements::getButton($name);
        }
        $data = [
            "type" => "form",
            "title" => Language::get("form.chain.list.title"),
            "content" => Language::get("form.selectButton"),
            "buttons" => $buttons
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onChainIfList($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data === 0) {
            $form = $this->getSelectActionForm();
            Form::sendForm($player, $form, $this, "onSelectAction");
            return;
        }
        $manager = IFPlugin::getInstance()->getChainManager();
        $ifs = array_slice($manager->getAll(), $data-1, 1, true);
        $key = key($ifs);
        $datas = current($ifs);
        $session->set("if_key", $key);
        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
        $form = (new Form)->getEditIfForm($mes, $datas["name"] ?? null);
        Form::sendForm($player, $form, new Form(), "onEditIf");
    }
}<?php

namespace aieuo\ip\form;

use aieuo\ip\utils\Language;
use aieuo\ip\form\Form;
use aieuo\ip\Session;
use aieuo\ip\IFPlugin;
use aieuo\ip\IFAPI;

class CommandForm {
    public function getSelectActionForm() {
        $data = [
            "type" => "form",
            "title" => Language::get("form.command.action.title"),
            "content" => Language::get("form.selectButton"),
            "buttons" => [
                Elements::getButton(Language::get("form.action.add")),
                Elements::getButton(Language::get("form.command.action.addOnlyCommand")),
                Elements::getButton(Language::get("form.action.edit")),
                Elements::getButton(Language::get("form.action.delete")),
                Elements::getButton(Language::get("form.command.action.commandList")),
                Elements::getButton(Language::get("form.cancel")),
                Elements::getButton(Language::get("form.back"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onSelectAction($player, $data) {
        if ($data === null) return;
        $session = Session::getSession($player);
        switch ($data) {
            case 0:
                $session->set("action", "add");
                break;
            case 1:
                $session->set("action", "add_empty");
                break;
            case 2:
                $session->set("action", "edit");
                break;
            case 3:
                $session->set("action", "del");
                break;
            case 4:
                $form = $this->getCommandListForm();
                Form::sendForm($player, $form, $this, "onCommandList");
                return;
            case 5:
                $session->setValid(false);
                $player->sendMessage(Language::get("form.cancelled"));
                return;
            case 6:
                $form = (new Form())->getSelectIfTypeForm();
                Form::sendForm($player, $form, new Form(), "onSelectIfType");
                return;
        }
        switch ($data) {
            case 0:
            case 1:
                $form = $this->getAddCommandForm();
                Form::sendForm($player, $form, $this, "onAddCommand");
                break;
            case 2:
            case 3:
            case 4:
                $form = $this->getSelectCommandForm();
                Form::sendForm($player, $form, $this, "onSelectCommand");
                break;
        }
        $session->setValid()->set("if_type", Session::COMMAND);
    }


    public function getAddCommandForm($mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => Language::get("form.command.addCommand.title"),
            "content" => [
                Elements::getInput(($mes !== "" ? $mes."\n" : "").Language::get("form.command.addCommand.content0"), Language::get("form.command.addCommand.content0.placeholder")),
                Elements::getInput(Language::get("form.command.addCommand.content1")),
                Elements::getDropdown(Language::get("form.command.permission"), [Language::get("form.command.permission.op"), Language::get("form.command.permission.everyone")], 0),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onAddCommand($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFPlugin::getInstance()->getCommandManager();
        if ($data[3]) {
            $form = $this->getSelectActionForm();
            Form::sendForm($player, $form, $this, "onSelectAction");
            return;
        }
        if ($data[0] === "") {
            $form = $this->getAddCommandForm(Language::get("form.insufficient"));
            Form::sendForm($player, $form, $this, "onAddCommand");
            $player->sendMessage(Language::get("form.insufficient"));
            return;
        }
        if ($manager->isRegisterd($data[0])) {
            $form = $this->getAddCommandForm(Language::get("form.command.alreadyInUse"));
            Form::sendForm($player, $form, $this, "onAddCommand");
            $player->sendMessage(Language::get("form.command.alreadyInUse"));
            return;
        }
        if ($manager->exists($data[0])) {
            $form = $this->getAddCommandForm(Language::get("form.command.alreadyExists"));
            Form::sendForm($player, $form, $this, "onAddCommand");
            $player->sendMessage(Language::get("form.command.alreadyExists"));
            return;
        }
        if ($data[1] === "") $data[1] = Language::get("form.command.description.default");
        $manager->set($data[0], [], ["perm" => $data[2] == 0 ? "ifplugin.customcommand.op" : "ifplugin.customcommand.true", "desc" => $data[1], ]);
        $manager->register($data[0], $data[2] == 0 ? "ifplugin.customcommand.op" : "ifplugin.customcommand.true", $data[1]);
        if ($session->get("action") == "add_empty") {
            $player->sendMessage(Language::get("form.command.added"));
            $session->setValid(false);
            return;
        }
        $session->set("if_key", $data[0]);
        $session->set("description", $data[1]);
        $session->set("permission", $data[2] == 0 ? "ifplugin.customcommand.op" : "ifplugin.customcommand.true");
        $datas = $manager->repairIF([]);
        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
        $form = (new Form)->getEditIfForm($mes, $datas["name"] ?? null);
        Form::sendForm($player, $form, new Form(), "onEditIf");
    }


    public function getSelectCommandForm($mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => Language::get("form.command.selectCommand.title"),
            "content" => [
                Elements::getInput(($mes !== "" ? $mes."\n" : "").Language::get("form.command.selectCommand.name"), Language::get("form.command.selectCommand.name.placeholder")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onSelectCommand($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data[1]) {
            $form = $this->getSelectActionForm();
            Form::sendForm($player, $form, $this, "onSelectAction");
            return;
        }
        if ($data[0] === "") {
            $form = $this->getSelectCommandForm(Language::get("form.insufficient"));
            Form::sendForm($player, $form, $this, "onSelectCommand");
            $player->sendMessage(Language::get("form.insufficient"));
            return;
        }
        $manager = IFPlugin::getInstance()->getCommandManager();
        if (!$manager->exists($data[0])) {
            $form = $this->getSelectCommandForm(Language::get("form.command.notExists"));
            Form::sendForm($player, $form, $this, "onSelectCommand");
            $player->sendMessage(Language::get("form.command.notExists"));
            return;
        }

        $session->set("if_key", $data[0]);
        $action = $session->get("action");
        if ($action == "edit") {
            $datas = $manager->get($data[0]);
            $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
            $form = (new Form)->getEditIfForm($mes, $datas["name"] ?? null);
            Form::sendForm($player, $form, new Form(), "onEditIf");
        } elseif ($action == "del") {
            $form = (new Form())->getConfirmDeleteForm();
            Form::sendForm($player, $form, new Form(), "onDeleteIf");
        }
    }

    public function getCommandListForm() {
        $manager = IFPlugin::getInstance()->getCommandManager();
        $commands = $manager->getAll();
        $buttons = [Elements::getButton(Language::get("form.back"))];
        foreach ($commands as $command => $value) {
            $buttons[] = Elements::getButton($command);
        }
        $data = [
            "type" => "form",
            "title" => Language::get("form.command.list.title"),
            "content" => Language::get("form.selectButton"),
            "buttons" => $buttons
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onCommandList($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data === 0) {
            $form = $this->getSelectActionForm();
            Form::sendForm($player, $form, $this, "onSelectAction");
            return;
        }
        $manager = IFPlugin::getInstance()->getCommandManager();
        $command = key(array_slice($manager->getAll(), $data - 1, 1, true));
        $session->set("if_key", $command);
        $datas = $manager->get($command);
        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
        $form = (new Form)->getEditIfForm($mes, $datas["name"] ?? null);
        Form::sendForm($player, $form, new Form(), "onEditIf");
    }
}<?php

namespace aieuo\ip\form;

class Elements {
    public static function getLabel($text){
        return [
            "type" => "label",
            "text" => (string)$text
        ];
    }

    public static function getInput($text, $placeholder = "", $default = ""){
        return [
            "type" => "input",
            "text" => (string)$text,
            "default" => (string)$default,
            "placeholder" => (string)$placeholder
        ];
    }

    public static function getToggle($text, $default = false){
        return [
            "type" => "toggle",
            "text" => (string)$text,
            "default" => $default,
        ];
    }

    public static function getDropdown($text, $options = [], $default = 0){
        return [
            "type" => "dropdown",
            "text" => (string)$text,
            "options" => $options,
            "default" => $default
        ];
    }

    public static function getSlider($text, $min = 0, $max = 0, $default = 0, $step = 1) {
        return [
            "type" => "slider",
            "text" => (string)$text,
            "min" => (int)$min,
            "max" => (int)$max,
            "default" => (int)$default,
            "step" => (int)$step
        ];
    }

    public static function getButton($text){
        return [
            "text" => (string)$text
        ];
    }
}<?php

namespace aieuo\ip\form;

use aieuo\ip\utils\Language;
use aieuo\ip\form\Form;
use aieuo\ip\Session;
use aieuo\ip\IFPlugin;
use aieuo\ip\IFAPI;

class EventForm {

    private $events = [
        "PlayerChatEvent" => "form.event.PlayerChatEvent",
        "PlayerCommandPreprocessEvent" => "form.event.PlayerCommandPreprocessEvent",
        "PlayerInteractEvent" => "form.event.PlayerInteractEvent",
        "PlayerJoinEvent" => "form.event.PlayerJoinEvent",
        "PlayerQuitEvent" => "form.event.PlayerQuitEvent",
        "BlockBreakEvent" => "form.event.BlockBreakEvent",
        "BlockPlaceEvent" => "form.event.BlockPlaceEvent",
        "EntityDamageEvent" => "form.event.EntityDamageEvent",
        "EntityAttackEvent" => "form.event.EntityAttackEvent",
        "PlayerToggleFlightEvent" => "form.event.PlayerToggleFlightEvent",
        "PlayerDeathEvent" => "form.event.PlayerDeathEvent",
        "EntityLevelChangeEvent" => "form.event.EntityLevelChangeEvent",
        "CraftItemEvent" => "form.event.CraftItemEvent",
        "PlayerDropItemEvent" => "form.event.PlayerDropItemEvent",
    ];

    public function getEvents() {
        return $this->events;
    }

    public function getSelectEventForm(){
        $buttons = [Elements::getButton(Language::get("form.back"))];
        foreach ($this->getEvents() as $key => $event) {
            $buttons[] = Elements::getButton(Language::get($event));
        }
        $data = [
            "type" => "form",
            "title" => Language::get("form.event.selectEvent.title"),
            "content" => Language::get("form.selectButton"),
            "buttons" => $buttons
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onSelectEvent($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data === 0) {
            $form = (new Form())->getSelectIfTypeForm();
            Form::sendForm($player, $form, new Form(), "onSelectIfType");
            return;
        }
        $eventname = key(array_slice($this->getEvents(), $data-1, 1, true));
        $session->set("eventname", $eventname);
        $form = $this->getIfListForm($eventname);
        Form::sendForm($player, $form, $this, "onSelectIf");
        $session->setValid()->set("if_type", Session::EVENT);
    }

    public function getIfListForm($event) {
        $manager = IFPlugin::getInstance()->getEventManager();
        $datas = $manager->getFromEvent($event);
        $buttons = [Elements::getButton(Language::get("form.back")), Elements::getButton(Language::get("form.event.IFList.add"))];
        foreach ($datas as $n => $data) {
            $buttons[] = Elements::getButton(empty($data["name"]) ? $n : $data["name"]);
        }
        $data = [
            "type" => "form",
            "title" => Language::get("form.event.IFList.title", [Language::get("form.event.".$event)]),
            "content" => Language::get("form.selectButton"),
            "buttons" => $buttons
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onSelectIf($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data === 0) {
            $form = $this->getSelectEventForm();
            Form::sendForm($player, $form, $this, "onSelectEvent");
            return;
        }
        $manager = IFPlugin::getInstance()->getEventManager();
        $eventname = $session->get("eventname");
        if ($data === 1) {
            $key = $manager->addEmpty($eventname);
            $session->set("if_key", $key);
            $datas = $manager->repairIF([]);
            $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
            $form = (new Form)->getEditIfForm($mes, $datas["name"] ?? null);
            Form::sendForm($player, $form, new Form(), "onEditIf");
            return;
        }
        $session->set("if_key", $data - 2);
        $datas = $manager->get(strval($data - 2), ["eventname" => $eventname]);
        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
        $form = (new Form)->getEditIfForm($mes, $datas["name"] ?? null);
        Form::sendForm($player, $form, new Form(), "onEditIf");
    }
}<?php

namespace aieuo\ip\form;

use aieuo\ip\manager\IFManager;
use aieuo\ip\Session;
use aieuo\ip\IFPlugin;
use aieuo\ip\IFAPI;
use aieuo\ip\utils\Language;

class ExportForm {
    public function getExportForm($mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => Language::get("if.export.title"),
            "content" => [
                Elements::getInput(($mes === "" ? "" : $mes."\n").Language::get("if.export.form.content0")),
                Elements::getInput(Language::get("if.export.form.content1")),
                Elements::getInput(Language::get("if.export.form.content2")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onExport($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $type = $session->get("if_type");
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);
        $key = $session->get("if_key");
        $datas = $manager->get($key, $options);
        if ($data[3]) {
            $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
            $form = (new Form())->getEditIfForm($mes, $datas["name"] ?? null);
            Form::sendForm($player, $form, new Form(), "onEditIf");
            return;
        }
        if ($data[0] == "" or $data[1] == "" or $data[2] == "") {
            $form = $this->getExportForm(Language::get("form.insufficient"));
            Form::sendForm($player, $form, $this, "onExport");
            $player->sendMessage(Language::get("form.insufficient"));
            return;
        }
        $datas["type"] = $type;
        $datas["options"] = $options;
        $export = [
            "name" => $data[0],
            "author" => $data[1],
            "details" => $data[2],
            "plugin_version" => IFPlugin::getInstance()->getDescription()->getVersion(),
            "ifs" => [
                $key => $datas
            ]
        ];
        $filename = $data[0]."_".$data[1]."_".$type."_".$key.".json";
        $path = IFPlugin::getInstance()->getDataFolder()."exports/".$filename;
        file_put_contents($path, json_encode($export, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
        $player->sendMessage(Language::get("if.export.success", [$filename]));
        $session->setValid(false);
    }
}<?php

namespace aieuo\ip\form;

use pocketmine\network\mcpe\protocol\ModalFormRequestPacket;

use aieuo\ip\utils\Language;
use aieuo\ip\processes\ProcessFactory;
use aieuo\ip\processes\Process;
use aieuo\ip\manager\IFManager;
use aieuo\ip\conditions\ConditionFactory;
use aieuo\ip\conditions\Condition;
use aieuo\ip\Session;
use aieuo\ip\IFPlugin;
use aieuo\ip\IFAPI;

class Form {

    private static $forms = [];

    public static function sendForm($player, $form, $class, $func, $opOnly = true) {
        while (true) {
            $id = mt_rand(0, 999999999);
            if (!isset(self::$forms[$id])) break;
        }
        self::$forms[$id] = [[$class, $func], $opOnly];
        $pk = new ModalFormRequestPacket();
        $pk->formId = $id;
        $pk->formData = $form;
        $player->dataPacket($pk);
    }

    public static function onRecive($id, $player, $datas) {
        if (isset(self::$forms[$id])) {
            if ($player->isOp() or !self::$forms[$id][1]) {
                call_user_func_array(self::$forms[$id][0], [$player, $datas]);
            }
            unset(self::$forms[$id]);
        }
    }

//////////////////////////////////////////////////////////////
    public static function encodeJson($data) {
        $json = json_encode($data, JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING | JSON_UNESCAPED_UNICODE);
        return $json;
    }

//////////////////////////////////////////////////////////////
    public function getBlockForm() {
        return new BlockForm();
    }

    public function getCommandForm() {
        return new CommandForm();
    }

    public function getEventForm() {
        return new EventForm();
    }

    public function getChainForm() {
        return new ChainIfForm();
    }

    public function getFormIFForm() {
        return new FormIFForm();
    }

    public function getExportForm() {
        return new ExportForm();
    }

    public function getImportForm() {
        return new ImportForm();
    }

    public function getSelectIfTypeForm() {
        $data = [
            "type" => "form",
            "title" => Language::get("form.form.selectAction.title"),
            "content" => Language::get("form.selectButton"),
            "buttons" => [
                Elements::getButton(Language::get("form.block")),
                Elements::getButton(Language::get("form.command")),
                Elements::getButton(Language::get("form.event")),
                Elements::getButton(Language::get("form.formif")),
                Elements::getButton(Language::get("form.chain")),
                Elements::getButton(Language::get("form.import")),
                Elements::getButton(Language::get("form.exit"))
            ]
        ];
        $json = self::encodeJson($data);
        return $json;
    }

    public function onSelectIfType($player, $data) {
        if ($data === null) return;
        $session = Session::getSession($player);
        switch ($data) {
            case 0:
                $session->set("if_type", Session::BLOCK);
                $form = $this->getBlockForm()->getSelectActionForm();
                Form::sendForm($player, $form, $this->getBlockForm(), "onSelectAction");
                break;
            case 1:
                $session->set("if_type", Session::COMMAND);
                $form = $this->getCommandForm()->getSelectActionForm();
                Form::sendForm($player, $form, $this->getCommandForm(), "onSelectAction");
                break;
            case 2:
                $session->set("if_type", Session::EVENT);
                $form = $this->getEventForm()->getSelectEventForm();
                Form::sendForm($player, $form, $this->getEventForm(), "onSelectEvent");
                break;
            case 3:
                $session->set("if_type", Session::FORM);
                $form = $this->getFormIFForm()->getSelectActionForm();
                Form::sendForm($player, $form, $this->getFormIFForm(), "onSelectAction");
                break;
            case 4:
                $session->set("if_type", Session::CHAIN);
                $form = $this->getChainForm()->getSelectActionForm();
                Form::sendForm($player, $form, $this->getChainForm(), "onSelectAction");
                break;
            case 5:
                $form = $this->getImportForm()->getImportListForm();
                Form::sendForm($player, $form, $this->getImportForm(), "onImportList");
                break;
            case 6:
                $session->setValid(false);
                break;
        }
    }

    public function getEditIfForm($mes, $name = null) {
        $data = [
            "type" => "form",
            "title" => empty($name) ? Language::get("form.form.editIF.title") : $name,
            "content" => $mes,
            "buttons" => [
                Elements::getButton(Language::get("form.form.editIF.if")),
                Elements::getButton(Language::get("form.form.editIF.match")),
                Elements::getButton(Language::get("form.form.editIF.else")),
                Elements::getButton(Language::get("form.action.delete")),
                Elements::getButton(Language::get("form.form.editIF.changeName")),
                Elements::getButton(Language::get("form.form.editIF.export")),
                Elements::getButton(Language::get("form.exit"))
            ]
        ];
        $data = self::encodeJson($data);
        return $data;
    }

    public function onEditIf($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);
        $key = $session->get("if_key");
        $datas = $manager->get($key, $options);
        if ($data == 0) {
            $form = $this->getEditContentsForm($datas["if"], "", "if");
            $session->set("type", "if");
        } elseif ($data == 1) {
            $form = $this->getEditContentsForm($datas["match"], "", "match");
            $session->set("type", "match");
        } elseif ($data == 2) {
            $form = $this->getEditContentsForm($datas["else"], "", "else");
            $session->set("type", "else");
        } elseif ($data == 3) {
            $form = $this->getConfirmDeleteForm();
            Form::sendForm($player, $form, $this, "onDeleteIf");
            return;
        } elseif ($data == 4) {
            $form = $this->getChangeNameForm(isset($datas["name"]) ? $datas["name"] : "");
            Form::sendForm($player, $form, $this, "onChangeName");
            return;
        } elseif ($data == 5) {
            $form = $this->getExportForm()->getExportForm();
            Form::sendForm($player, $form, $this->getExportForm(), "onExport");
            return;
        } else {
            $session->setValid(false);
            return;
        }
        Form::sendForm($player, $form, $this, "onEditIfContents");
    }

    public function getEditContentsForm($datas, $mes = "", $type = "") {
        $data = [
            "type" => "form",
            "title" => Language::get("form.form.editContents.title", [Language::get("form.form.editIF.".$type)]),
            "content" => ($mes === "" ? "" : $mes."\n").Language::get("form.selectButton"),
            "buttons" => []
        ];
        $data["buttons"] = [
            Elements::getButton(Language::get("form.back")),
            Elements::getButton(Language::get("form.form.editContents.add")),
        ];
        foreach ($datas as $key => $value) {
            if ($value["id"] < 100) {
                $content = Condition::get($value["id"]);
            } else {
                $content = Process::get($value["id"]);
            }
            $content->setValues($content->parse($value["content"]));
            $message = $content->getDetail();
            $data["buttons"][] = Elements::getButton($message === false ? $content->getDescription() : $message);
        }
        $data = self::encodeJson($data);
        return $data;
    }

    public function onEditIfContents($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);
        $key = $session->get("if_key");
        $datas = $manager->get($key, $options);
        if ($data == 0) { // ひとつ前のformに戻る
            $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
            $form = $this->getEditIfForm($mes, $datas["name"] ?? null);
            Form::sendForm($player, $form, $this, "onEditIf");
            return;
        }
        if ($data == 1) { // 新しく追加する
            $form = $this->getAddContentsForm($session->get("type"));
            Form::sendForm($player, $form, $this, "onAddContent");
            return;
        }

        // 追加されているものを選択した
        $data -= 2;
        $ifData = $datas[$session->get("type")][$data];
        if ($session->get("type") == "if") {
            $datas = Condition::get($ifData["id"]);
        } else {
            $datas = Process::get($ifData["id"]);
        }
        $session->set("contents", $datas);
        $session->set("num", $data);
        $form = $datas->getEditForm((string)$ifData["content"]);
        Form::sendForm($player, $form, $this, "onUpdateContent");
    }

    public function getAddContentsForm($type, $mes = "") {
        if ($type == "if") {
            $datas = ConditionFactory::getAll();
        } else {
            $datas = ProcessFactory::getAll();
        }
        $buttons[] = Elements::getButton(Language::get("form.back"));
        $buttons[] = Elements::getButton(Language::get("form.form.addContents.search"));
        foreach ($datas as $data) {
            $buttons[] = Elements::getButton($data->getName());
        }
        $data = [
            "type" => "form",
            "title" => Language::get("form.form.addContents.title"),
            "content" => ($mes === "" ? "" : $mes."\n").Language::get("form.selectButton"),
            "buttons" => $buttons
        ];
        $json = self::encodeJson($data);
        return $json;
    }

    public function onAddContent($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);
        if ($data == 0) {
            $key = $session->get("if_key");
            $datas = $manager->get($key, $options);
            $form = $this->getEditContentsForm($datas[$session->get("type")], "", $session->get("type"));
            Form::sendForm($player, $form, $this, "onEditIfContents");
            return;
        }
        if ($data == 1) {
            $form = $this->getSearchForm();
            Form::sendForm($player, $form, $this, "onSearch");
            return;
        }
        $data -= 2;
        if ($session->get("type") == "if") {
            $all = ConditionFactory::getAll();
            $datas = Condition::get(current(array_slice($all, $data, 1, true))->getId());
        } else {
            $all = ProcessFactory::getAll();
            $datas = Process::get(current(array_slice($all, $data, 1, true))->getId());
        }
        $session->set("contents", $datas);
        $form = $datas->getEditForm();
        Form::sendForm($player, $form, $this, "onEdit");
    }

    public function onEdit($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);
        $content = $session->get("contents");
        $datas = $content->parseFormData($data);
        if ($datas["cancel"]) {
            $form = $this->getAddContentsForm($session->get("type"));
            Form::sendForm($player, $form, $this, "onAddContent");
            return;
        }
        if ($datas["delete"]) {
            $player->sendMessage(Language::get("form.form.delete.notExist"));
            $form = $this->getAddContentsForm($session->get("type"), Language::get("form.form.delete.notExist"));
            Form::sendForm($player, $form, $this, "onAddContent");
            return;
        }
        if ($datas["status"] === null) {
            $form = $content->getEditForm($datas["contents"], Language::get("form.insufficient"));
            Form::sendForm($player, $form, $this, "onEdit");
            return;
        }
        $mes = Language::get("form.form.added");
        if ($datas["status"] === false) $mes = Language::get("form.form.added.suspicious");
        $key = $session->get("if_key");
        $manager->add($key, $session->get("type"), $content->getId(), $datas["contents"], $options);
        $contents = $manager->get($key, $options);
        $form = $this->getEditContentsForm($contents[$session->get("type")], $mes, $session->get("type"));
        Form::sendForm($player, $form, $this, "onEditIfContents");
        $player->sendMessage($mes);
    }

    public function onUpdateContent($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);
        $content = $session->get("contents");
        $datas = $content->parseFormData($data);
        if ($datas["cancel"]) {
            $key = $session->get("if_key");
            $form = $this->getEditContentsForm($manager->get($key, $options)[$session->get("type")], "", $session->get("type"));
            Form::sendForm($player, $form, $this, "onEditIfContents");
            return;
        }
        if ($datas["delete"]) {
            $form = $this->getConfirmDeleteForm();
            Form::sendForm($player, $form, $this, "onDeleteContent");
            return;
        }
        if ($datas["status"] === null) {
            $form = $content->getEditForm($datas["contents"], Language::get("form.insufficient"));
            Form::sendForm($player, $form, $this, "onEdit");
            return;
        }

        $mes = Language::get("form.form.changed");
        if ($datas["status"] === false) $mes = Language::get("form.form.changed.suspicious");
        $key = $session->get("if_key");
        $manager->updateContent($key, $session->get("type"), $session->get("num"), $datas["contents"], $options);
        $contents = $manager->get($key, $options);
        $form = $this->getEditContentsForm($contents[$session->get("type")], $mes, $session->get("type"));
        Form::sendForm($player, $form, $this, "onEditIfContents");
        $player->sendMessage($mes);
    }

    public function getConfirmDeleteForm() {
        $data = [
            "type" => "modal",
            "title" => Language::get("form.form.confirmDelete.title"),
            "content" => Language::get("form.form.confirmDelete.content"),
            "button1" => Language::get("form.form.confirmDelete.yes"),
            "button2" => Language::get("form.form.confirmDelete.no")
        ];
        $data = self::encodeJson($data);
        return $data;
    }

    public function onDeleteContent($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);

        $key = $session->get("if_key");
        if ($data) {
            $manager->del($key, $session->get("type"), $session->get("num"), $options);
            $form = $this->getEditContentsForm($manager->get($key, $options)[$session->get("type")], Language::get("form.form.delete.success"), $session->get("type"));
            Form::sendForm($player, $form, $this, "onEditIfContents");
            $player->sendMessage(Language::get("form.form.delete.success"));
        } else {
            $contents = $manager->get($key, $options);
            $ifData = $contents[$session->get("type")][$session->get("num")];
            $form = $manager->get($key, $options)->getEditForm($ifData["contents"], Language::get("form.cancelled"));
            Form::sendForm($player, $form, $this, "onEdit");
            $player->sendMessage(Language::get("form.cancelled"));
        }
    }

    public function onDeleteIf($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);

        if ($data) {
            $manager->remove($session->get("if_key"), $options);
            $player->sendMessage(Language::get("form.form.delete.success"));
        } else {
            $player->sendMessage(Language::get("form.cancelled"));
        }
        $session->setValid(false);
    }

    public function getSearchForm($mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => Language::get("form.form.search.title"),
            "content" => [
                Elements::getLabel(Language::get("form.form.search.label").(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("form.form.search.input"))
            ]
        ];
        $data = self::encodeJson($data);
        return $data;
    }

    public function onSearch($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data[1] === "") {
            $form = $this->getSearchForm(Language::get("form.insufficient"));
            Form::sendForm($player, $form, $this, "onSearch");
            return;
        }
        if ($session->get("type") == "if") {
            $all = ConditionFactory::getAll();
        } else {
            $all = ProcessFactory::getAll();
        }
        $keywords = explode(" ", $data[1]);
        $result = array_filter($all, function ($item) use ($keywords) {
            $contains = true;
            foreach ($keywords as $keyword) {
                if (strpos($item->getName(), $keyword) === false) $contains = false;
            }
            return($contains);
        });
        $session->set("searchResult", $result);

        $buttons[] = Elements::getButton(Language::get("form.back"));
        foreach ($result as $item) {
            $buttons[] = Elements::getButton($item->getName());
        }
        $data = [
            "type" => "form",
            "title" => Language::get("form.form.searchResult.title"),
            "content" => Language::get("form.selectButton"),
            "buttons" => $buttons
        ];
        Form::sendForm($player, self::encodeJson($data), $this, "onSearchResult");
    }

    public function onSearchResult($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);
        if ($data == 0) {
            $key = $session->get("if_key");
            $datas = $manager->get($key, $options);
            $form = $this->getEditContentsForm($datas[$session->get("type")], "", $session->get("type"));
            Form::sendForm($player, $form, $this, "onEditIfContents");
            return;
        }
        $data -= 1;
        $all = $session->get("searchResult");
        if ($session->get("type") == "if") {
            $datas = Condition::get(current(array_slice($all, $data, 1, true))->getId());
        } else {
            $datas = Process::get(current(array_slice($all, $data, 1, true))->getId());
        }
        $session->set("contents", $datas);
        $form = $datas->getEditForm();
        Form::sendForm($player, $form, $this, "onEdit");
    }

    public function getChangeNameForm($name = "") {
        $data = [
            "type" => "custom_form",
            "title" => Language::get("form.form.setName.title"),
            "content" => [
                Elements::getLabel(Language::get("form.form.setName.content0")),
                Elements::getInput(Language::get("form.form.setName.content1"), "", $name),
                Elements::getToggle(Language::get("form.form.setName.content2")),
                Elements::getToggle(Language::get("form.cancel")),
            ]
        ];
        $data = self::encodeJson($data);
        return $data;
    }

    public function onChangeName($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);
        $key = $session->get("if_key");
        $datas = $manager->get($key, $options);
        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
        if ($data[3]) {
            $form = $this->getEditIfForm($mes, $datas["name"] ?? null);
            Form::sendForm($player, $form, $this, "onEditIf");
            return;
        }
        if ($data[2]) {
            $mes = Language::get("form.deleteName.success")."\n".$mes;
            $player->sendMessage(Language::get("form.deleteName.success"));
            $manager->setName($key, "", $options);
        } else {
            $mes = Language::get("form.form.setName.success")."\n".$mes;
            $player->sendMessage(Language::get("form.form.setName.success"));
            $manager->setName($key, $data[1], $options);
        }
        $form = $this->getEditIfForm($mes, $datas["name"] ?? null);
        Form::sendForm($player, $form, $this, "onEditIf");
    }
}
<?php

namespace aieuo\ip\form;

use aieuo\ip\utils\Language;
use aieuo\ip\manager\IFManager;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\conditions\Condition;
use aieuo\ip\conditions\Comparison;
use aieuo\ip\Session;
use aieuo\ip\IFPlugin;
use aieuo\ip\IFAPI;

class FormIFForm {
    public function getSelectActionForm(){
        $data = [
            "type" => "form",
            "title" => Language::get("form.formif.action.title"),
            "content" => Language::get("form.selectButton"),
            "buttons" => [
                Elements::getButton(Language::get("form.action.add")),
                Elements::getButton(Language::get("form.action.edit")),
                Elements::getButton(Language::get("form.action.delete")),
                Elements::getButton(Language::get("form.formif.action.formList")),
                Elements::getButton(Language::get("form.cancel")),
                Elements::getButton(Language::get("form.back"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onSelectAction($player, $data) {
        if ($data === null) return;
        $session = Session::getSession($player);
        $session->setValid()->set("if_type", Session::FORM);
        switch ($data) {
            case 0:
                $session->set("action", "add");
                Form::sendForm($player, $this->getAddIFformForm(), $this, "onAddIFformForm");
                return;
            case 1:
                $session->set("action", "edit");
                break;
            case 2:
                $session->set("action", "del");
                break;
            case 3:
                Form::sendForm($player, $this->getFormIFListForm(), $this, "onFormIFList");
                return;
            case 4:
                $session->setValid(false);
                $player->sendMessage(Language::get("form.cancelled"));
                return;
            case 5:
                $session->setValid(false);
                $form = (new Form())->getSelectIfTypeForm();
                Form::sendForm($player, $form, new Form(), "onSelectIfType");
                return;
        }
        Form::sendForm($player, $this->getSelectIFformForm(), $this, "onSelectIFformForm");
    }

    public function getAddIFformForm($mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => Language::get("form.formif.addformif.title"),
            "content" => [
                Elements::getInput(Language::get("form.formif.addformif.content0", [$mes !== "" ? $mes."\n" : ""])),
                Elements::getInput(Language::get("form.formif.addformif.content1")),
                Elements::getDropdown(Language::get("form.formif.addformif.content2"), [
                    Language::get("form.formif.list"),
                    Language::get("form.formif.custom"),
                    Language::get("form.formif.modal"),
                ], 0),
                Elements::getToggle(Language::get("form.cancel")),
            ],
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onAddIFformForm($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFPlugin::getInstance()->getFormIFManager();
        if ($data[3]) {
            $form = $this->getSelectActionForm();
            Form::sendForm($player, $form, $this, "onSelectAction");
            return;
        }
        if ($data[0] === "") {
            $form = $this->getAddIFformForm(Language::get("form.insufficient"));
            Form::sendForm($player, $form, $this, "onAddIFformForm");
            $player->sendMessage(Language::get("form.insufficient"));
            return;
        }
        if ($manager->exists($data[0])) {
            $form = $this->getAddIFformForm(Language::get("form.formif.exist"));
            Form::sendForm($player, $form, $this, "onAddIFformForm");
            $player->sendMessage(Language::get("form.formif.exist"));
            return;
        }
        $form = ["title" => $data[1] == "" ? $data[0] : $data[1]];
        switch ($data[2]) {
            case 0:
                $form["type"] = "form";
                $form["content"] = "content";
                $form["buttons"] = [];
                break;
            case 1:
                $form["type"] = "custom_form";
                $form["content"] = [];
                break;
            case 2:
                $form["type"] = "modal";
                $form["content"] = "content";
                $form["button1"] = "button1";
                $form["button2"] = "button2";
                break;
        }
        $json = Form::encodeJson($form);
        $session->set("if_key", $data[0])->set("form", $form);
        $datas = $manager->repairIF([]);
        $datas["form"] = $json;
        $manager->set($data[0], $datas);
        Form::sendForm($player, $this->getEditIFformForm($form), $this, "onEditIFformForm");
    }

    public function getSelectIFformForm($mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => Language::get("form.formif.selectformif.title"),
            "content" => [
                Elements::getInput(Language::get("form.formif.selectformif.content0", [$mes !== "" ? $mes."\n" : ""])),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onSelectIFformForm($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data[1]) {
            $form = $this->getSelectActionForm();
            Form::sendForm($player, $form, $this, "onSelectAction");
            return;
        }
        if ($data[0] === "") {
            $form = $this->getSelectIFformForm(Language::get("form.insufficient"));
            Form::sendForm($player, $form, $this, "onSelectIFformForm");
            $player->sendMessage(Language::get("form.insufficient"));
            return;
        }
        $manager = IFPlugin::getInstance()->getFormIFManager();
        if (!$manager->exists($data[0])) {
            $form = $this->getSelectIFformForm(Language::get("form.formif.notexist"));
            Form::sendForm($player, $form, $this, "onSelectIFformForm");
            $player->sendMessage(Language::get("form.formif.notexist"));
            return;
        }

        $session->set("if_key", $data[0]);
        $action = $session->get("action");
        if ($action == "edit") {
            $form = $manager->getIF($data[0])["form"];
            $session->set("form", json_decode($form, true));
            Form::sendForm($player, $this->getEditIFformForm(json_decode($form, true)), $this, "onEditIFformForm");
        } elseif ($action == "del") {
            $form = (new Form())->getConfirmDeleteForm();
            Form::sendForm($player, $form, $this, "onDeleteIf");
        }
    }

    public function getEditIFformForm($form, $mes = "") {
        $type = $form["type"];
        $buttons = [
            ["text" => Language::get("form.formif.editformif.button.preview")],
            ["text" => Language::get("form.formif.editformif.button.edit")],
            ["text" => Language::get("form.formif.editformif.button.title", [$form["title"]])],
        ];
        switch ($type) {
            case 'modal':
                $buttons[] = ["text" => Language::get("form.formif.editformif.modal.content", [$form["content"]])];
                $buttons[] = ["text" => Language::get("form.formif.editformif.modal.button1", [$form["button1"]])];
                $buttons[] = ["text" => Language::get("form.formif.editformif.modal.button2", [$form["button2"]])];
                break;
            case "form":
                $buttons[] = ["text" => Language::get("form.formif.editformif.form.content", [$form["content"]])];
                foreach ($form["buttons"] as $button) {
                    $buttons[] = ["text" => Language::get("form.formif.editformif.form.button", [$button["text"]])];
                }
                $buttons[] = ["text" => Language::get("form.formif.editformif.form.addbutton")];
                break;
            case "custom_form":
                foreach ($form["content"] as $content) {
                    $buttons[] = ["text" => Language::get("form.formif.editformif.custom.content", [Language::get("form.formif.custom.".$content["type"].".index"), $content["text"]])];
                }
                $buttons[] = ["text" => Language::get("form.formif.editformif.custom.addparts")];
                break;
        }
        $data = [
            "type" => "form",
            "title" => Language::get("form.formif.editformif.title"),
            "content" => Language::get("form.formif.editformif.content", [$mes !== "" ? $mes."\n" : ""]),
            "buttons" => $buttons
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onEditIFformForm($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $form = $session->get("form");
        if ($data === 0) {
            Form::sendForm($player, str_replace("\\\\n", "\\n", Form::encodeJson($form)), $this, "onPreviewIFform");
            return;
        }
        if ($data === 1) {
            Form::sendForm($player, $this->getIfListForm($session->get("if_key")), $this, "onSelectIf");
            return;
        }
        $session->set("form_select_place", $data-2);
        Form::sendForm($player, $this->getSelectPartsForm($form, $data-2), $this, "onSelectParts");
    }

    public function onPreviewIFform($player, $data) {
        $session = Session::getSession($player);
        $form = $session->get("form");
        Form::sendForm($player, $this->getEditIFformForm($form), $this, "onEditIFformForm");
    }

    public function getSelectPartsForm($form, $place, $mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => Language::get("form.formif.selectparts.title"),
            "content" => [Elements::getToggle(($mes !== "" ? $mes."\n" : "").Language::get("form.cancel"))],
        ];
        switch ($form["type"]) {
            case 'modal':
                switch ($place) {
                    case 0:
                        $data["content"][] = Elements::getLabel(Language::get("form.formif.selectparts.parts.title"));
                        $data["content"][] = Elements::getInput(Language::get("form.formif.selectparts.parts.text"), "", $form["title"]);
                        break;
                    case 1:
                        $data["content"][] = Elements::getLabel(Language::get("form.formif.selectparts.parts.content"));
                        $data["content"][] = Elements::getInput(Language::get("form.formif.selectparts.parts.text"), "", $form["content"]);
                        break;
                    case 2:
                        $data["content"][] = Elements::getLabel(
                            Language::get("form.formif.selectparts.parts.button1")."\n".
                            Language::get("form.formif.recive", ["{form_data} <- true"])
                        );
                        $data["content"][] = Elements::getInput(Language::get("form.formif.selectparts.parts.text"), "", $form["button1"]);
                        $data["content"][] = Elements::getToggle(Language::get("form.formif.selectparts.parts.editif"));
                        break;
                    case 3:
                        $data["content"][] = Elements::getLabel(
                            Language::get("form.formif.selectparts.parts.button2")."\n".
                            Language::get("form.formif.recive", ["{form_data} <- false"])
                        );
                        $data["content"][] = Elements::getInput(Language::get("form.formif.selectparts.parts.text"), "", $form["button2"]);
                        $data["content"][] = Elements::getToggle(Language::get("form.formif.selectparts.parts.editif"));
                        break;
                }
                break;
            case "form":
                if ($place == 0) {
                    $data["content"][] = Elements::getLabel(Language::get("form.formif.selectparts.parts.title"));
                    $data["content"][] = Elements::getInput(Language::get("form.formif.selectparts.parts.text"), "", $form["title"]);
                    break;
                }
                if ($place == 1) {
                    $data["content"][] = Elements::getLabel(Language::get("form.formif.selectparts.parts.content"));
                    $data["content"][] = Elements::getInput(Language::get("form.formif.selectparts.parts.text"), "", $form["content"]);
                    break;
                }
                $place -= 2;
                if (!isset($form["buttons"][$place])) {
                    $data["content"][] = Elements::getLabel(Language::get("form.formif.selectparts.addbutton"));
                    $data["content"][] = Elements::getInput(Language::get("form.formif.selectparts.parts.text"));
                    $data["content"][] = Elements::getToggle(Language::get("form.formif.selectparts.parts.editif"));
                    break;
                }
                $data["content"][] = Elements::getLabel(
                    Language::get("form.formif.selectparts.parts.button")."\n".
                    Language::get("form.formif.recive", ["{form_data} <- $place"])."\n".
                    Language::get("form.formif.recive", ["{form_button} <- ".$form["buttons"][$place]["text"]])
                );
                $data["content"][] = Elements::getInput(Language::get("form.formif.selectparts.parts.text"), "", $form["buttons"][$place]["text"]);
                $data["content"][] = Elements::getToggle(Language::get("form.formif.selectparts.parts.editif"));
                $data["content"][] = Elements::getToggle(Language::get("form.action.delete"));
                break;
            case "custom_form":
                if ($place == 0) {
                    $data["content"][] = Elements::getLabel(Language::get("form.formif.selectparts.parts.title"));
                    $data["content"][] = Elements::getInput(Language::get("form.formif.selectparts.parts.text"), "", $form["title"]);
                    break;
                }
                $place -= 1;
                if (!isset($form["content"][$place])) {
                    $data["content"][] = Elements::getLabel(Language::get("form.formif.selectparts.addparts"));
                    $data["content"][] = Elements::getDropdown(
                        Language::get("form.formif.selectparts.select_custom_parts"),
                        array_map(function ($partsname) {
                            return Language::get("form.formif.custom.".$partsname);
                        }, array_keys($this->getCustomFormParts()))
                    );
                    break;
                }
                $parts = $form["content"][$place];
                $data["content"] = array_merge($data["content"], $this->getCustomFormParts($parts["type"], $parts, $place));
                break;
        }
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onSelectParts($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $form = $session->get("form");
        $place = $session->get("form_select_place");
        if ($data[0]) {
            Form::sendForm($player, $this->getEditIFformForm($form, Language::get("form.cancelled")), $this, "onEditIFformForm");
            return;
        }
        $manager = IFPlugin::getInstance()->getFormIFManager();
        $datas = $manager->getIF($session->get("if_key"));
        switch ($form["type"]) {
            case 'modal':
                switch ($place) {
                    case 0:
                        $partsname = "title";
                        break;
                    case 1:
                        $partsname = "content";
                        break;
                    case 2:
                        $partsname = "button1";
                        break;
                    case 3:
                        $partsname = "button2";
                        break;
                }
                $form[$partsname] = $data[2];
                if (isset($data[3]) and $data[3]) {
                    $session->set("form", $form);
                    $datas["form"] = Form::encodeJson($form);
                    $manager->set($session->get("if_key"), $datas);
                    $responses = array_filter($datas["ifs"], function ($ifs) use ($partsname) {
                        $comparison = false;
                        foreach ($ifs["if"] as $ifdata) {
                            if ($ifdata["id"] === Condition::COMPARISON and ($content = Condition::get(Condition::COMPARISON)->parse($ifdata["content"])) !== false) {
                                if ($content[0] !== "{form_data}" or $content[1] !== Comparison::EQUAL or $content[2] != ($partsname === "button1")) continue;
                                $comparison = true;
                            }
                        }
                        return $comparison;
                    });
                    if (count($responses) === 0) {
                        $session->set("form_place", count($datas["ifs"]));
                        $options = IFPlugin::getInstance()->getOptionsBySession($session);
                        $manager->add($session->get("if_key"), "if", Condition::COMPARISON, "{form_data}[ope:0]".($partsname === "button1" ? "true" : "false"), $options);
                        $ifdata = $manager->get($session->get("if_key"), $options);
                    } else {
                        $ifdata = array_shift($responses);
                        $session->set("form_place", array_keys($datas["ifs"], $ifdata)[0]);
                    }
                    $mes = IFAPI::createIFMessage($ifdata["if"], $ifdata["match"], $ifdata["else"]);
                    $form = (new Form)->getEditIfForm($mes);
                    Form::sendForm($player, $form, new Form(), "onEditIf");
                    return;
                }
                break;
            case "form":
                switch ($place) {
                    case 0:
                        $form["title"] = $data[2];
                        break;
                    case 1:
                        $form["content"] = $data[2];
                        break;
                    default:
                        $place -= 2;
                        $form["buttons"][$place] = ["text" => $data[2]];
                        if (isset($data[4]) and $data[4]) {
                            unset($form["buttons"][$place]);
                            $form["buttons"] = array_merge($form["buttons"]);
                            break;
                        }
                        if ($data[3]) {
                            $session->set("form", $form);
                            $datas["form"] = Form::encodeJson($form);
                            $manager->set($session->get("if_key"), $datas);
                            $responses = array_filter($datas["ifs"], function ($ifs) use ($place) {
                                $comparison = false;
                                foreach ($ifs["if"] as $ifdata) {
                                    if ($ifdata["id"] === Condition::COMPARISON and ($content = Condition::get(Condition::COMPARISON)->parse($ifdata["content"])) !== false) {
                                        if ($content[0] !== "{form_data}" or $content[1] !== Comparison::EQUAL or $content[2] !== $place) continue;
                                        $comparison = true;
                                    }
                                }
                                return $comparison;
                            });
                            if (count($responses) === 0) {
                                $session->set("form_place", count($datas["ifs"]));
                                $options = IFPlugin::getInstance()->getOptionsBySession($session);
                                $manager->add($session->get("if_key"), "if", Condition::COMPARISON, "{form_data}[ope:0]$place", $options);
                                $ifdata = $manager->get($session->get("if_key"), $options);
                            } else {
                                $ifdata = array_shift($responses);
                                $session->set("form_place", array_keys($datas["ifs"], $ifdata)[0]);
                            }
                            $mes = IFAPI::createIFMessage($ifdata["if"], $ifdata["match"], $ifdata["else"]);
                            $form = (new Form)->getEditIfForm($mes);
                            Form::sendForm($player, $form, new Form(), "onEditIf");
                            return;
                        }
                        break;
                }
                break;
            case "custom_form":
                switch ($place) {
                    case 0:
                        $form["title"] = $data[2];
                        break;
                    default:
                        $place -= 1;
                        if (!isset($form["content"][$place])) {
                            $partsname = array_keys($this->getCustomFormParts())[$data[2]];
                            $form["content"][] = Elements::{"get".$partsname}($partsname);
                            break;
                        }
                        if ($data[1]) {
                            unset($form["content"][$place]);
                            $form["content"] = array_merge($form["content"]);
                            break;
                        }
                        $parts = $form["content"][$place];
                        switch ($parts["type"]) {
                            case 'label':
                                $form["content"][$place] = Elements::getLabel($data[3]);
                                break;
                            case "input":
                                $form["content"][$place] = Elements::getInput($data[3], $data[4], $data[5]);
                                break;
                            case "toggle":
                                $form["content"][$place] = Elements::getToggle($data[3], $data[4]);
                                break;
                            case "slider":
                                $form["content"][$place] = Elements::getSlider($data[3], (int)$data[4], (int)$data[5], (int)$data[6], (int)$data[7]);
                                break;
                            case "dropdown":
                                $options = $form["content"][$place]["options"];
                                $count = count($options);
                                for ($i=0; $i<$count; $i++) {
                                    $options[$i] = $data[$i+4];
                                }
                                $options = array_merge($options, explode(",", $data[$count+4]));
                                $options = array_filter($options, function ($option) {
                                    return(trim(rtrim($option)) !== "");
                                });
                                $options = array_values($options);
                                $form["content"][$place] = Elements::getDropdown($data[3], $options);
                                break;
                        }
                        break;
                }
                break;
        }
        $session->set("form", $form);
        $datas["form"] = Form::encodeJson($form);
        $manager->set($session->get("if_key"), $datas);
        $player->sendMessage(Language::get("form.changed"));
        Form::sendForm($player, $this->getEditIFformForm($form, Language::get("form.changed")), $this, "onEditIFformForm");
    }

    public function getCustomFormParts($name = "", $default = null, $place = null) {
        $parts = [
            "label" => [
                Elements::getToggle(Language::get("form.action.delete")),
                Elements::getLabel(
                    Language::get("form.formif.custom.label")."\n".
                    ($place === null ? "" : Language::get("form.formif.recive", ["{form_data}[$place] <- \"\""]))
                ),
                Elements::getInput(Language::get("form.formif.custom.text"), "", $default["text"] ?? ""),
            ],
            "input" => [
                Elements::getToggle(Language::get("form.action.delete")),
                Elements::getLabel(
                    Language::get("form.formif.custom.input")."\n".
                    ($place === null ? "" : Language::get("form.formif.recive.input", [$place]))
                ),
                Elements::getInput(Language::get("form.formif.custom.text"), "", $default["text"] ?? ""),
                Elements::getInput(Language::get("form.formif.custom.input.placeholder"), "", $default["placeholder"] ?? ""),
                Elements::getInput(Language::get("form.formif.custom.input.default"), "", $default["default"] ?? ""),
            ],
            "toggle" => [
                Elements::getToggle(Language::get("form.action.delete")),
                Elements::getLabel(
                    Language::get("form.formif.custom.toggle")."\n".
                    ($place === null ? "" : Language::get("form.formif.recive", ["{form_data}[$place] <- (true | false)"]))
                ),
                Elements::getInput(Language::get("form.formif.custom.text"), "", $default["text"] ?? ""),
                Elements::getToggle(Language::get("form.formif.custom.toggle.default"), $default["default"] ?? false),
            ],
            "slider" => [
                Elements::getToggle(Language::get("form.action.delete")),
                Elements::getLabel(
                    Language::get("form.formif.custom.slider")."\n".
                    ($place === null ? "" : Language::get("form.formif.recive.slider", [$place]))
                ),
                Elements::getInput(Language::get("form.formif.custom.text"), "", $default["text"] ?? ""),
                Elements::getInput(Language::get("form.formif.custom.slider.min"), "", $default["min"] ?? ""),
                Elements::getInput(Language::get("form.formif.custom.slider.max"), "", $default["max"] ?? ""),
                Elements::getInput(Language::get("form.formif.custom.slider.default"), "", $default["default"] ?? ""),
                Elements::getInput(Language::get("form.formif.custom.slider.step"), "", $default["step"] ?? ""),
            ],
            "dropdown" => [
                Elements::getToggle(Language::get("form.action.delete")),
                Elements::getLabel(
                    Language::get("form.formif.custom.dropdown")."\n".
                    ($place === null ? "" : Language::get("form.formif.recive.dropdown", [$place]))."\n".
                    ($place === null ? "" : Language::get("form.formif.recive.dropdown.option"))
                ),
                Elements::getInput(Language::get("form.formif.custom.text"), "", $default["text"] ?? ""),
            ],
        ];
        if (isset($default["options"])) {
            foreach ($default["options"] as $i => $option) {
                $parts["dropdown"][] = Elements::getInput(Language::get("form.formif.custom.dropdown.option", [$i]), "", $option);
            }
        }
        $parts["dropdown"][] = Elements::getInput(Language::get("form.formif.custom.dropdowm.addOption"));
        if (empty($name)) return $parts;
        return $parts[$name];
    }

    public function getIfListForm($name) {
        $manager = IFPlugin::getInstance()->getFormIFManager();
        $datas = $manager->getIF($name);
        $buttons = [Elements::getButton(Language::get("form.back")), Elements::getButton(Language::get("form.formif.iflist.add"))];
        foreach ($datas["ifs"] as $n => $data) {
            $buttons[] = Elements::getButton(empty($data["name"]) ? $n : $data["name"]);
        }
        $data = [
            "type" => "form",
            "title" => Language::get("form.formif.iflist.title", [$name]),
            "content" => Language::get("form.selectButton"),
            "buttons" => $buttons
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onSelectIf($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data === 0) {
            $form = $session->get("form");
            Form::sendForm($player, $this->getEditIFformForm($form), $this, "onEditIFformForm");
            return;
        }
        $manager = IFPlugin::getInstance()->getFormIFManager();
        $datas = $manager->getIF($session->get("if_key"));
        if ($data === 1) {
            $session->set("form_place", count($datas["ifs"]));
            $mes = IFAPI::createIFMessage([], [], []);
            $form = $this->getEditIfForm($mes);
            Form::sendForm($player, $form, $this, "onEditIf");
            return;
        }
        $session->set("form_place", $data - 2);
        $datas = $datas["ifs"][$data-2];
        $mes = IFAPI::createIFMessage($datas["if"], $datas["match"], $datas["else"]);
        $form = $this->getEditIfForm($mes);
        Form::sendForm($player, $form, $this, "onEditIf");
    }

    public function onDeleteIf($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFPlugin::getInstance()->getFormIFManager();

        if ($data) {
            $manager->removeIF($session->get("if_key"));
            $player->sendMessage(Language::get("form.formif.deleted"));
        } else {
            $player->sendMessage(Language::get("form.cancelled"));
        }
        $session->setValid(false);
    }

    public function getFormIFListForm() {
        $manager = IFPlugin::getInstance()->getFormIFManager();
        $forms = $manager->getAll();
        $buttons = [Elements::getButton(Language::get("form.back"))];
        foreach ($forms as $formName => $value) {
            switch (json_decode($value["form"], true)["type"]) {
                case "form":
                    $formType = Language::get("form.formif.list");
                    break;
                case "modal":
                    $formType = Language::get("form.formif.modal");
                    break;
                case "custom_form":
                    $formType = Language::get("form.formif.custom");
                    break;
                default:
                    $formType = "";
            }
            $buttons[] = Elements::getButton(Language::get("form.formif.formList.button", [$formName, $formType]));
        }
        $data = [
            "type" => "form",
            "title" => Language::get("form.formif.formList.title"),
            "content" => Language::get("form.formif.formList.title"),
            "buttons" => $buttons
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onFormIFList($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data === 0) {
            $form = $this->getSelectActionForm();
            Form::sendForm($player, $form, $this, "onSelectAction");
            return;
        }
        $manager = IFPlugin::getInstance()->getFormIFManager();
        $formName = key(array_slice($manager->getAll(), $data - 1, 1, true));
        $form = $manager->getIF($formName)["form"];
        $session->set("if_key", $formName);
        $session->set("form", json_decode($form, true));
        Form::sendForm($player, $this->getEditIFformForm(json_decode($form, true)), $this, "onEditIFformForm");
    }

    public function getEditIfForm($mes, $name = null) {
        $data = [
            "type" => "form",
            "title" => empty($name) ? Language::get("form.form.editIF.title") : $name,
            "content" => $mes,
            "buttons" => [
                Elements::getButton(Language::get("form.form.editIF.if")),
                Elements::getButton(Language::get("form.form.editIF.match")),
                Elements::getButton(Language::get("form.form.editIF.else")),
                Elements::getButton(Language::get("form.action.delete")),
                Elements::getButton(Language::get("form.form.editIF.changeName")),
                Elements::getButton(Language::get("form.form.editIF.export")),
                Elements::getButton(Language::get("form.back")),
                Elements::getButton(Language::get("form.exit")),
            ]
        ];
        $data = Form::encodeJson($data);
        return $data;
    }

    public function onEditIf($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $manager = IFManager::getBySession($session);
        $options = IFPlugin::getInstance()->getOptionsBySession($session);
        $key = $session->get("if_key");
        $datas = $manager->get($key, $options);
        if ($data == 0) {
            $form = (new Form)->getEditContentsForm($datas["if"], "", "if");
            $session->set("type", "if");
        } elseif ($data == 1) {
            $form = (new Form)->getEditContentsForm($datas["match"], "", "match");
            $session->set("type", "match");
        } elseif ($data == 2) {
            $form = (new Form)->getEditContentsForm($datas["else"], "", "else");
            $session->set("type", "else");
        } elseif ($data == 3) {
            $form = (new Form)->getConfirmDeleteForm();
            Form::sendForm($player, $form, (new Form), "onDeleteIf");
            return;
        } elseif ($data == 4) {
            $form = (new Form)->getChangeNameForm(isset($datas["name"]) ? $datas["name"] : "");
            Form::sendForm($player, $form, (new Form), "onChangeName");
            return;
        } elseif ($data == 5) {
            $form = (new Form)->getExportForm()->getExportForm();
            Form::sendForm($player, $form, (new Form)->getExportForm(), "onExport");
            return;
        } elseif ($data == 6) {
            Form::sendForm($player, $this->getIfListForm($session->get("if_key")), $this, "onSelectIf");
            return;
        } else {
            $session->setValid(false);
            return;
        }
        Form::sendForm($player, $form, (new Form), "onEditIfContents");
    }
}<?php

namespace aieuo\ip\form;

use aieuo\ip\Session;
use aieuo\ip\IFPlugin;
use aieuo\ip\IFAPI;
use aieuo\ip\utils\Language;

class ImportForm {
    public function getImportListForm($mes = "") {
        $buttons = [Elements::getButton(Language::get("form.back"))];
        $files = glob(IFPlugin::getInstance()->getDataFolder()."imports/*.json");
        foreach ($files as $file) {
            if (is_dir($file)) continue;
            $datas = json_decode(file_get_contents($file), true);
            $buttons[] = Elements::getButton($datas["name"]." | ".$datas["author"]);
        }
        $data = [
            "type" => "form",
            "title" => Language::get("form.import.selectFile.title"),
            "content" => ($mes === "" ? "" : $mes."\n").Language::get("form.selectButton"),
            "buttons" => $buttons
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onImportList($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data == 0) {
            $data = (new Form())->getSelectIfTypeForm();
            Form::sendForm($player, $data, new Form(), "onSelectIfType");
            return;
        }
        $files = glob(IFPlugin::getInstance()->getDataFolder()."imports/*.json");
        if (!isset($files[$data - 1])) {
            $form = $this->getImportListForm(Language::get("form.import.error"));
            Form::sendForm($player, $form, $this, "onImportList");
            return;
        }
        $path = $files[$data - 1];
        $session->set("path", $path);
        $form = $this->getImportForm(json_decode(file_get_contents($path), true));
        Form::sendForm($player, $form, $this, "onImport");
    }

    public function getImportForm($datas) {
        $mes = Language::get("form.import.import.content", [$datas["name"], $datas["author"], $datas["details"]]);
        foreach ($datas["ifs"] as $key => $value) {
            $mes .= "---------------------------\n";
            $mes .= "§l".$key."§r§f\n".IFAPI::createIFMessage($value["if"], $value["match"], $value["else"])."\n";
        }
        $data = [
            "type" => "custom_form",
            "title" => Language::get("form.import.import.title", [$datas["name"]]),
            "content" => [
                Elements::getLabel($mes),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function onImport($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data[1]) {
            $form = $this->getImportListForm(Language::get("form.cancelled"));
            Form::sendForm($player, $form, $this, "onImportList");
            return;
        }
        $file = json_decode(file_get_contents($session->get("path")), true);
        $this->importDatas($player, $file);
    }

    public function importDatas($player, $file, $count = 0) {
        $session = Session::getSession($player);
        foreach ($file["ifs"] as $key => $datas) {
            if ($datas["type"] === Session::BLOCK) {
                $manager = IFPlugin::getInstance()->getBlockManager();

                if ($manager->exists($key) and !isset($session->get("overwrite")[$key])) {
                    $session->set("file", $file);
                    $session->set("if_key", $key);
                    $session->set("count", $count);
                    $form = $this->getConfirmOverwriteForm($key);
                    Form::sendForm($player, $form, $this, "onConfirmOverwrite");
                    return;
                } elseif ($manager->exists($key) and !$session->get("overwrite")[$key]) {
                    continue;
                }

                $manager->set($key, [
                    "if" => $datas["if"],
                    "match" => $datas["match"],
                    "else" => $datas["else"],
                    "author" => $file["author"]
                ]);
                $count ++;
            } elseif ($datas["type"] === Session::COMMAND) {
                $manager = IFPlugin::getInstance()->getCommandManager();

                if (!$manager->exists($key) and $manager->isRegisterd($key)) continue;
                if ($manager->exists($key) and !isset($session->get("overwrite")[$key])) {
                    $session->set("file", $file);
                    $session->set("if_key", $key);
                    $session->set("count", $count);
                    $form = $this->getConfirmOverwriteForm($key);
                    Form::sendForm($player, $form, $this, "onConfirmOverwrite");
                    return;
                } elseif ($manager->exists($key) and !$session->get("overwrite")[$key]) {
                    continue;
                }

                $manager->set($key, [
                    "if" => $datas["if"],
                    "match" => $datas["match"],
                    "else" => $datas["else"],
                    "author" => $file["author"]
                ], [
                    "desc" => $datas["description"],
                    "perm" => $datas["permission"]
                ]);
                $manager->register($key, $datas["description"], $datas["permission"]);
                $count ++;
            } elseif ($datas["type"] === Session::EVENT) {
                $manager = IFPlugin::getInstance()->getEventManager();
                $manager->addByEvent($datas["options"]["eventname"], $datas + ["author" => $file["author"]]);
                $count ++;
            } elseif ($datas["type"] === Session::CHAIN) {
                $manager = IFPlugin::getInstance()->getChainManager();

                if ($manager->exists($key) and !isset($session->get("overwrite")[$key])) {
                    $session->set("file", $file);
                    $session->set("if_key", $key);
                    $session->set("count", $count);
                    $form = $this->getConfirmOverwriteForm($key);
                    Form::sendForm($player, $form, $this, "onConfirmOverwrite");
                    return;
                } elseif ($manager->exists($key) and !$session->get("overwrite")[$key]) {
                    continue;
                }

                $manager->set($key, [
                    "if" => $datas["if"],
                    "match" => $datas["match"],
                    "else" => $datas["else"],
                    "author" => $file["author"]
                ]);
                $count ++;
            }
            unset($file["ifs"][$key]);
        }
        $player->sendMessage(Language::get("form.import.success", [$count]));
        $session->setValid(false);
    }

    public function getConfirmOverwriteForm($name) {
        $data = [
            "type" => "modal",
            "title" => Language::get("form.import.overwriting.title"),
            "content" => Language::get("form.import.overwriting.content", [$name]),
            "button1" => Language::get("form.yes"),
            "button2" => Language::get("form.no")
        ];
        $data = Form::encodeJson($data);
        return $data;
    }

    public function onConfirmOverwrite($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        if ($data) {
            if (($overwrite = $session->get("overwrite")) === "") {
                $session->set("overwrite", [$session->get("if_key") => true]);
            } else {
                $overwrite[$session->get("if_key")] = true;
                $session->set("overwrite", $overwrite);
            }
            $this->importDatas($player, $session->get("file"), $session->get("count"));
        } else {
            if (($overwrite = $session->get("overwrite")) === "") {
                $session->set("overwrite", [$session->get("if_key") => false]);
            } else {
                $overwrite[$session->get("if_key")] = false;
                $session->set("overwrite", $overwrite);
            }
            $this->importDatas($player, $session->get("file"), $session->get("count"));
        }
    }
}<?php

namespace aieuo\ip;

use pocketmine\event\Event;
use pocketmine\Server;

use aieuo\ip\variable\StringVariable;
use aieuo\ip\variable\NumberVariable;
use aieuo\ip\variable\ListVariable;
use aieuo\ip\utils\Language;
use aieuo\ip\processes\Process;
use aieuo\ip\conditions\Condition;

class IFAPI {

    public function checkCondition($player, $datas, $options = []) {
        $matched = true;
        foreach ($datas as $data) {
            $result = ($co = Condition::get($data["id"]))
                        ->setPlayer($player)
                        ->setValues(
                            $co->parse(
                                str_replace("\\n", "\n", IFPlugin::getInstance()
                                  ->getVariableHelper()
                                  ->replaceVariables($data["content"], $this->getReplaceDatas($options)))
                            )
                        )->check();
            if ($result === Condition::ERROR or $result === Condition::NOT_FOUND) {
                return $result;
            } elseif ($result === Condition::NOT_MATCHED) {
                $matched = false;
            }
        }
        return $matched ? Condition::MATCHED : Condition::NOT_MATCHED;
    }

    public function executeProcess($player, $datas, $options) {
        $replaceDatas = $this->getReplaceDatas($options);
        foreach ($datas as $data) {
            $process = Process::get($data["id"]);
            $process->replaceDatas = $replaceDatas;
            if (isset($options["event"]) and $options["event"] instanceof Event) $process->setEvent($options["event"]);
            if ($data["id"] === Process::EVENT_CANCEL) {
                $process->setValues($options["event"])->execute();
                continue;
            }
            $process->setPlayer($player)
                ->setValues(
                    $process->parse(
                        str_replace("\\n", "\n", IFPlugin::getInstance()
                        ->getVariableHelper()
                        ->replaceVariables($data["content"], $replaceDatas))
                    )
                )->execute();
        }
    }

    public function executeIfMatchCondition($player, $datas1, $datas2, $datas3, $options = []) {
        $match = $this->checkCondition($player, $datas1, $options);
        switch ($match) {
            case Condition::MATCHED:
                $datas = $datas2;
                break;
            case Condition::NOT_MATCHED:
                $datas = $datas3;
                break;
            case Condition::NOT_FOUND:
                $player->sendMessage(Language::get("if.contents.notFound", [$datas["id"]]));
            case Condition::ERROR:
            default:
                return false;
        }
        $this->executeProcess($player, $datas, $options);
        return true;
    }

    public function getReplaceDatas($datas) {
        $player = $datas["player"];
        $server = Server::getInstance();
        $onlines = [];
        foreach ($server->getOnlinePlayers() as $p) {
            $onlines[] = $p->getName();
        }
        $ops = [];
        foreach ($server->getOps()->getAll() as $p => $value) {
            $ops[] = $p;
        }
        $variables = [
            "player" => new StringVariable("player", $player->__toString()),
            "player_name" => new StringVariable("player_name", $player->getName()),
            "nametag" => new StringVariable("nametag", $player->getDisplayName()),
            "player_pos" => new StringVariable("player_pos", $player->x.",".$player->y.",".$player->z.",".$player->level->getFolderName()),
            "player_x" => new NumberVariable("player_x", $player->x),
            "player_y" => new NumberVariable("player_y", $player->y),
            "player_z" => new NumberVariable("player_z", $player->z),
            "player_level" => new StringVariable("player_level", $player->level->getFolderName()),
            "firstplayed" => new NumberVariable("firstplayed", $player->getFirstPlayed()),
            "lastplayed" => new NumberVariable("lastplayed", $player->getLastPlayed()),
            "hand_index" => new NumberVariable("hand_index", $player->getInventory()->getHeldItemIndex()),
            "hand_item" => new StringVariable("hand_item", $player->getInventory()->getItemInHand()->__toString()),
            "hand_name" => new StringVariable("hand_name", $player->getInventory()->getItemInHand()->getName()),
            "hand_id" => new NumberVariable("hand_id", $player->getInventory()->getItemInHand()->getId()),
            "hand_damage" => new NumberVariable("hand_damage", $player->getInventory()->getItemInHand()->getDamage()),
            "hand_count" => new NumberVariable("hand_count", $player->getInventory()->getItemInHand()->getCount()),
            "server_name" => new StringVariable("server_name", $server->getName()),
            "microtime" => new NumberVariable("microtime", microtime(true)),
            "time" => new StringVariable("time", date("h:i:s")),
            "date" => new StringVariable("date", date("m/d")),
            "default_level" => new StringVariable("default_level", $server->getDefaultLevel()->getFolderName()),
            "onlines" => new ListVariable("onlines", $onlines),
            "ops" => new ListVariable("ops", $ops)
        ];
        return $variables;
    }

    public static function createIFMessage(array $ifs, array $matchs, array $others): string {
        $mes = Language::get("message.if")."\n";
        foreach ($ifs as $if) {
            $content = Condition::get($if["id"]);
            $content->setValues($content->parse($if["content"]));
            $mes .= $content->getDetail() === false ?
                        $content->getDescription()."§f,\n":
                        $content->getDetail()."§f,\n";
        }
        $mes .= "\n".Language::get("message.match")."\n";
        foreach ($matchs as $match) {
            $process1 = Process::get($match["id"]);
            $process1->setValues($process1->parse($match["content"]));
            $mes .= $process1->getDetail() === false ?
                        $process1->getDescription()."§f,\n":
                        $process1->getDetail()."§f,\n";
        }
        $mes .= "\n".Language::get("message.other")."\n";
        foreach ($others as $other) {
            $process2 = Process::get($other["id"]);
            $process2->setValues($process2->parse($other["content"]));
            $mes .= $process2->getDetail() === false ?
                        $process2->getDescription()."§f,\n":
                        $process2->getDetail()."§f,\n";
        }
        return $mes;
    }
}<?php
namespace aieuo\ip;

use pocketmine\utils\Config;
use pocketmine\plugin\PluginBase;
use pocketmine\event\Listener;

use aieuo\ip\variable\VariableHelper;
use aieuo\ip\utils\Language;
use aieuo\ip\task\SaveTask;
use aieuo\ip\processes\ProcessFactory;
use aieuo\ip\manager\FormIFManager;
use aieuo\ip\manager\EventManager;
use aieuo\ip\manager\CommandManager;
use aieuo\ip\manager\ChainIfManager;
use aieuo\ip\manager\BlockManager;
use aieuo\ip\economy\PocketMoneyLoader;
use aieuo\ip\economy\MoneySystemLoader;
use aieuo\ip\economy\EconomyLoader;
use aieuo\ip\economy\EconomyAPILoader;

use aieuo\ip\conditions\ConditionFactory;
use aieuo\ip\commands\IFCommand;

use aieuo\ip\Session;
use aieuo\ip\IFAPI;

class IFPlugin extends PluginBase implements Listener {
    private static $instance;

    private $loaded = false;

    public function onEnable() {
        $this->getServer()->getPluginManager()->registerEvents(new EventListener($this), $this);
        if (!file_exists($this->getDataFolder())) @mkdir($this->getDataFolder(), 0721, true);
        if (!file_exists($this->getDataFolder()."exports")) @mkdir($this->getDataFolder()."exports", 0721, true);
        if (!file_exists($this->getDataFolder()."imports")) @mkdir($this->getDataFolder()."imports", 0721, true);
        $this->config = new Config($this->getDataFolder()."config.yml", Config::YAML, [
            "wait" => 0,
            "save_time" => 10*20*60,
            "language" => "eng",
        ]);
        $this->config->save();
        $this->wait = $this->config->get("wait");
        $language = $this->config->get("language", "eng");
        $languages = [];
        foreach ($this->getResources() as $resource) {
            $filename = $resource->getFilename();
            if (strrchr($filename, ".") == ".ini") $languages[] = basename($filename, ".ini");
            if ($filename === $language.".ini") {
                $messages = parse_ini_file($resource->getPathname());
            }
        }
        if (!isset($messages)) {
            $languageList = implode(", ", $languages);
            switch ($this->getServer()->getLanguage()->getLang()) {
                case "eng":
                    $errors = ["Failed to load language file", "available languages are: [".$languageList."]"];
                    break;
                default:
                    $errors = ["言語ファイルの読み込みに失敗しました", $languageList." が使用できます"];
            }
            foreach ($errors as $error) {
                $this->getLogger()->warning($error);
            }
            $this->getServer()->getPluginManager()->disablePlugin($this);
            return;
        }
        $this->language = new Language($messages);

        $this->getServer()->getCommandMap()->register("ifPlugin", new IFCommand($this));

        $this->loadEconomySystemPlugin();

        $this->command = new CommandManager($this);
        $this->block = new BlockManager($this);
        $this->event = new EventManager($this);
        $this->chain = new ChainIfManager($this);
        $this->formif = new FormIFManager($this);

        $this->api = new IFAPI();

        $this->variables = new VariableHelper($this);
        $this->variables->loadDataBase();

        $savetime = (int)$this->config->get("save_time", 10*20*60);
        $this->getScheduler()->scheduleRepeatingTask(new SaveTask($this), (int)$savetime);

        self::$instance = $this;

        ConditionFactory::init();
        ProcessFactory::init();

        $this->loaded = true;
    }

    public function onDisable() {
        if (!$this->loaded) return;
        $this->command->save();
        $this->block->save();
        $this->event->save();
        $this->chain->save();
        $this->formif->save();
        $this->variables->save();
        $this->config->save();
    }

    public static function getInstance(): self {
        return self::$instance;
    }

    public function getBlockManager(): BlockManager {
        return $this->block;
    }

    public function getCommandManager(): CommandManager {
        return $this->command;
    }

    public function getEventManager(): EventManager {
        return $this->event;
    }

    public function getChainManager(): ChainIfManager {
        return $this->chain;
    }

    public function getFormIFManager(): FormIFManager {
        return $this->formif;
    }

    public function getAPI(): IFAPI {
        return $this->api;
    }

    public function getVariableHelper(): VariableHelper {
        return $this->variables;
    }

    public function getEconomy() : ?EconomyLoader {
        return $this->economy;
    }

    public function loadEconomySystemPlugin() {
        if (($plugin = $this->getServer()->getPluginManager()->getPlugin("EconomyAPI")) !== null) {
            $this->economy = new EconomyAPILoader($plugin);
            $this->getLogger()->info(Language::get("economy.found", ["EconomyAPI"]));
        } elseif (($plugin = $this->getServer()->getPluginManager()->getPlugin("MoneySystem")) !== null) {
            $this->economy = new MoneySystemLoader($plugin);
            $this->getLogger()->info(Language::get("economy.found", ["MoneySystem"]));
        } elseif (($plugin = $this->getServer()->getPluginManager()->getPlugin("PocketMoney")) !== null) {
            $this->economy = new PocketMoneyLoader($plugin);
            $this->getLogger()->info(Language::get("economy.found", ["PocketMoney"]));
        } else {
            $this->economy = null;
            $this->getLogger()->warning(Language::get("economy.notfound"));
        }
    }

    public function getOptionsBySession(Session $session) {
        $type = $session->get("if_type");
        if ($type === Session::BLOCK) {
            $options = [];
        } elseif ($type === Session::COMMAND) {
            $options = ["desc" => $session->get("description"), "perm" => $session->get("permission")];
        } elseif ($type === Session::EVENT) {
            $options = ["eventname" => $session->get("eventname")];
        } elseif ($type === Session::CHAIN) {
            $options = [];
        } elseif ($type === Session::FORM) {
            $options = ["place" => $session->get("form_place")];
        }
        return $options;
    }
}
<?php

namespace aieuo\ip\manager;

use pocketmine\block\SignPost;
use pocketmine\tile\Sign;

use aieuo\ip\variable\StringVariable;
use aieuo\ip\variable\NumberVariable;
use aieuo\ip\variable\ListVariable;

class BlockManager extends IFManager {

    public function __construct($owner){
        parent::__construct($owner, "blocks");
    }

    public function set(string $key, array $datas = [], array $options = []) {
        $datas = $this->repairIF($datas);
        parent::set($key, $datas);
    }

    public function getPosition($block){
        return $block->x.",".$block->y.",".$block->z.",".$block->level->getFolderName();
    }

    public function getReplaceDatas($datas) {
        $variables = parent::getReplaceDatas($datas);
        $block = $datas["block"];
        $event = $datas["event"];
        $add = [
            "block" => new StringVariable("block", $block->__toString()),
            "block_name" => new StringVariable("block_name", $block->getName()),
            "block_id" => new NumberVariable("block_id", $block->getId()),
            "block_damage" => new NumberVariable("block_damage", $block->getDamage()),
            "block_ids" => new StringVariable("block_ids", $block->getId().":".$block->getDamage()),
            "block_pos" => new StringVariable("block_pos", $block->x.",".$block->y.",".$block->z.",".$block->level->getFolderName()),
            "block_x" => new NumberVariable("block_x", $block->x),
            "block_y" => new NumberVariable("block_y", $block->y),
            "block_z" => new NumberVariable("block_z", $block->z),
            "block_level" => new StringVariable("block_level", $block->level->getFolderName()),
            "touch_face" => new NumberVariable("touch_face", $event->getFace())
        ];
        if ($block instanceof SignPost) {
            $sign = $block->level->getTile($block);
            if ($sign instanceof Sign) {
                $variables["sign_lines"] = new ListVariable("sign_lines", $sign->getText());
            }
        }
        return array_merge($variables, $add);
    }
}<?php

namespace aieuo\ip\manager;

use aieuo\ip\variable\StringVariable;
use aieuo\ip\variable\NumberVariable;

class ChainIfManager extends IFManager {

    public function __construct($owner) {
        parent::__construct($owner, "chains");
    }

    public function set($key, $datas = [], $options = []) {
        $datas = $this->repairIF($datas);
        parent::set($key, $datas);
    }

    public function getReplaceDatas($datas) {
        $variables = parent::getReplaceDatas($datas);
        if (isset($datas["count"])) $variables["i"] = new NumberVariable("i", $datas["count"]);
        if (isset($datas["origin"])) {
            $origin = $datas["origin"];
            $add = [
                "origin_name" => new StringVariable("origin_name", $origin->getName()),
                "origin_pos" => new StringVariable("origin_pos", $origin->x.",".$origin->y.",".$origin->z.",".$origin->level->getFolderName()),
                "origin_x" => new NumberVariable("origin_x", $origin->x),
                "origin_y" => new NumberVariable("origin_y", $origin->y),
                "origin_z" => new NumberVariable("origin_z", $origin->z),
                "origin_level" => new StringVariable("origin_level", $origin->level->getFolderName())
            ];
            $variables = array_merge($variables, $add);
        }
        if (isset($datas["replaces"])) $variables = array_merge($datas["replaces"], $variables);
        return $variables;
    }
}<?php

namespace aieuo\ip\manager;

use aieuo\ip\utils\Language;
use pocketmine\command\PluginCommand;

use aieuo\ip\variable\StringVariable;
use aieuo\ip\variable\ListVariable;

class CommandManager extends IFManager {

    private $command_list = [];

    public function __construct($owner) {
        parent::__construct($owner, "commands");
        $this->registerCommands();
    }

    public function set($key, $datas = [], $options = []) {
        $datas = $this->repairIF($datas);
        if ($options["desc"] === "") $options["desc"] = Language::get("form.command.description.default");
        if ($options["perm"] === "") $options["perm"] = "ifplugin.customcommand.op";
        $datas["description"] = $options["desc"];
        $datas["permission"] = $options["perm"];
        parent::set($key, $datas);
    }

    public function add($key, $type, $id, $content, $args = []) {
        $datas = [];
        if ($this->exists($key))$datas = $this->get($key);
        $datas[$type][] = [
            "id" => $id,
            "content" => $content
        ];
        $this->register($key, $args["desc"], $args["perm"]);
        $this->set($key, $datas, $args);
    }

    public function remove($key) {
        $this->unregister($key);
        parent::remove($key);
    }

    public function registerCommands() {
        foreach ($this->getAll() as $command => $value) {
            $permission = $value["permission"];
            switch ($permission) {
                case 'ifplugin.customcommand.op':
                case 'ifplugin.customcommand.true':
                    break;
                case true:
                case 'true':
                case 'default':
                    $permission = "ifplugin.customcommand.true";
                    break;
                default:
                    $permission = "ifplugin.customcommand.op";
                    break;
            }
            if ($this->isSubcommand($command)) $command = $this->getOriginCommand($command);
            if (!$this->isRegisterd($command)) {
                $this->register($command, $permission, $value["description"]);
            }
        }
    }

    public function register($command, $permission = null, $description = null) {
        $permission = $permission ?? "ifplugin.customcommand.op";
        $description = $description ?? Language::get("form.command.description.default");
        if ($this->isSubcommand($command)) $command = $this->getOriginCommand($command);
        if (!$this->isRegisterd($command)) {
            $newCommand = new PluginCommand($command, $this->getOwner());
            $newCommand->setDescription($description);
            $newCommand->setPermission($permission);
            $this->getServer()->getCommandMap()->register("ifPlugin", $newCommand);
            $this->command_list[$command] = $newCommand;
            return true;
        }
        return false;
    }

    public function unregister($command) {
        $count = count($this->getSubcommands($command));
        if (!$this->isSubcommand($command) and $this->exists($command)) $count ++;
        if ($count <= 1) {
            $this->getServer()->getCommandMap()->unregister($this->command_list[$command]);
        }
        unset($this->command_list[$command]);
    }

    public function isRegisterd($command) {
        $exist = $this->getServer()->getPluginCommand($command);
        if ($exist === null)return false;
        return true;
    }

    public function isSubcommand($command) {
        $subcommand = false;
        if (strpos($command, " ") !== false)$subcommand = true;
        return $subcommand;
    }

    public function getSubcommands($command) {
        $array = [];
        $command = explode(" ", $command)[0];
        $commands = $this->getAll();
        foreach ($commands as $cmd => $value) {
            $cmds = explode(" ", $cmd);
            if (array_shift($cmds) == $command) {
                if (isset($cmds[0])) {
                    $sub = implode(" ", $cmds);
                    $array[] = $sub;
                }
            }
        }
        return $array;
    }

    public function getOriginCommand($command) {
        if (!$this->isSubcommand($command)) return $command;
        $commands = explode(" ", $command);
        return $commands[0];
    }

    public function getReplaceDatas($datas) {
        $result = parent::getReplaceDatas($datas);
        $command = $datas["command"];
        $cmds = explode(" ", substr($command, 1));
        $result["cmd"] = new StringVariable("cmd", array_shift($cmds));
        $result["args"] = new ListVariable("args", $cmds);
        return $result;
    }
}<?php

namespace aieuo\ip\manager;

use pocketmine\Player;
use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\block\SignPost;
use pocketmine\tile\Sign;

use aieuo\ip\variable\StringVariable;
use aieuo\ip\variable\NumberVariable;
use aieuo\ip\variable\ListVariable;

class EventManager extends IFManager {

    public function __construct($owner) {
        parent::__construct($owner, "events");
    }

    public function get(string $key, array $args = []): ?array {
        $datass = $this->getFromEvent($args["eventname"]);
        if (!isset($datass[$key]))return [];
        $datas = $datass[$key];
        $datas = $this->repairIF($datas);
        return $datas;
    }

    public function add($key, $type, $id, $content, $args = []) {
        $datas = $this->getFromEvent($args["eventname"]);
        $datas[$key][$type][] = [
            "id" => $id,
            "content" => $content
        ];
        $this->set($args["eventname"], $datas);
    }

    public function getCount($event) {
        $datas = $this->getFromEvent($event);
        return count($datas);
    }

    public function addEmpty($event) {
        $datas = $this->getFromEvent($event);
        $data = [
            "if" => [],
            "match" => [],
            "else" => []
        ];
        $datas[] = $data;
        $this->set($event, $datas);
        return count($datas) -1;
    }

    public function getFromEvent($event) {
        $datas = [];
        if (isset(($all = $this->getAll())[$event]))$datas = $all[$event];
        return $datas;
    }

    public function addByEvent($event, $add) {
        $add = $this->repairIF($add);
        $datas = $this->getFromEvent($event);
        $datas[] = $add;
        $this->set($event, $datas);
    }

    public function del($key, $type, $num, $options = []) {
        $datas = $this->getFromEvent($options["eventname"]);
        if (!isset($datas[$key]))return false;
        unset($datas[$key][$type][$num]);
        $datas[$key][$type] = array_merge($datas[$key][$type]);
        $this->set($options["eventname"], $datas);
        return true;
    }

    public function updateContent($key, $type, $num, $new, $options = []) {
        $datas = $this->getFromEvent($options["eventname"]);
        if (!isset($datas[$key])) return false;
        $datas[$key][$type][$num]["content"] = $new;
        $this->set($options["eventname"], $datas);
        return true;
    }

    public function remove($key, $options = []) {
        $datas = $this->getFromEvent($options["eventname"]);
        if (!isset($datas[$key])) return false;
        unset($datas[$key]);
        $datas = array_merge($datas);
        $this->set($options["eventname"], $datas);
        return true;
    }

    public function setName($key, $name, $options = []) {
        $datas = $this->getFromEvent($options["eventname"]);
        if (!isset($datas[$key])) return false;
        $datas[$key]["name"] = $name;
        $this->set($options["eventname"], $datas);
        return true;
    }

    public function getReplaceDatas($datas) {
        $result = parent::getReplaceDatas($datas);
        $event = $datas["event"];
        $eventname = $datas["eventname"];
        $variables = [];
        if ($eventname == "PlayerInteractEvent"
            or $eventname == "BlockBreakEvent"
            or $eventname == "BlockPlaceEvent"
        ) {
            $block = $event->getBlock();
            $variables["block"] = new StringVariable("block", $block->__toString());
            $variables["block_name"] = new StringVariable("block_name", $block->getName());
            $variables["block_id"] = new NumberVariable("block_id", $block->getId());
            $variables["block_damage"] = new NumberVariable("block_damage", $block->getDamage());
            $variables["block_ids"] = new StringVariable("block_ids", $block->getId().":".$block->getDamage());
            $variables["block_pos"] = new StringVariable("block_pos", $block->x.",".$block->y.",".$block->z.",".$block->level->getFolderName());
            $variables["block_level"] = new StringVariable("block_level", $block->level->getFolderName());
            if ($block instanceof SignPost) {
                $sign = $block->level->getTile($block);
                if ($sign instanceof Sign) {
                    $variables["sign_lines"] = new ListVariable("sign_lines", $sign->getText());
                }
            }
        }
        if ($eventname == "PlayerChatEvent"
            or $eventname == "PlayerCommandPreprocessEvent"
        ) {
            $variables["mes"] = new StringVariable("mes", $event->getMessage());
        }
        if ($eventname == "PlayerCommandPreprocessEvent") {
            $args = explode(" ", $variables["mes"]->getValue());
            $variables["cmd"] = new StringVariable("cmd", array_shift($args));
            $variables["args"] = new ListVariable("args", $args);
        }
        if ($eventname == "PlayerDropItemEvent") {
            $item = $event->getItem();
            $variables["item"] = new StringVariable("item", $item->__toString());
            $variables["item_name"] = new StringVariable("item_name", $item->getName());
            $variables["item_id"] = new NumberVariable("item_id", $item->getId());
            $variables["item_damage"] = new NumberVariable("item_damage", $item->getDamage());
            $variables["item_count"] = new NumberVariable("item_count", $item->getCount());
        }
        if ($eventname == "CraftItemEvent") {
            $inputs = $event->getInputs();
            $outputs = $event->getOutputs();
            $inputnames = [];
            $inputids = [];
            foreach ($inputs as $input) {
                $inputnames[] = $input->getName();
                $inputids[] = $input->getId().":".$input->getDamage();
            }
            $outputnames = [];
            $outputids = [];
            foreach ($outputs as $output) {
                $outputnames[] = $output->getName();
                $outputids[] = $output->getId().":".$output->getDamage();
            }
            $variables["input_name"] = new ListVariable("input_name", $inputnames);
            $variables["input_id"] = new ListVariable("input_id", $inputids);
            $variables["output_name"] = new ListVariable("output_name", $outputnames);
            $variables["output_id"] = new ListVariable("output_id", $outputids);
        }
        if ($eventname == "EntityDamageEvent") {
            $variables["event_damage"] = new NumberVariable("event_damage", $event->getBaseDamage());
            $variables["evant_cause"] = new NumberVariable("evant_cause", $event->getCause());
            if ($event instanceof EntityDamageByEntityEvent) {
                $damager = $event->getDamager();
                if ($damager instanceof Player) {
                    $variables["attacker"] = new StringVariable("attacker", $damager->__toString());
                    $variables["attacker_name"] = new StringVariable("attacker_name", $damager->getName());
                    $variables["attacker_pos"] = new StringVariable("attacker_pos", $damager->x.",".$damager->y.",".$damager->z.",".$damager->level->getFolderName());
                    $variables["attacker_x"] = new NumberVariable("attacker_x", $damager->x);
                    $variables["attacker_y"] = new NumberVariable("attacker_y", $damager->y);
                    $variables["attacker_z"] = new NumberVariable("attacker_z", $damager->z);
                    $variables["attacker_level"] = new StringVariable("attacker_level", $damager->level->getFolderName());
                }
            }
        }
        if ($eventname == "EntityAttackEvent") {
            $variables["event_damage"] = new NumberVariable("event_damage", $event->getBaseDamage());
            $variables["evant_cause"] = new NumberVariable("evant_cause", $event->getCause());
            if ($event instanceof EntityDamageByEntityEvent) {
                $player = $event->getEntity();
                if ($player instanceof Player) {
                    $variables["target"] = new StringVariable("target", $player->__toString());
                    $variables["target_name"] = new StringVariable("target_name", $player->getName());
                    $variables["target_pos"] = new StringVariable("target_pos", $player->x.",".$player->y.",".$player->z.",".$player->level->getFolderName());
                    $variables["target_x"] = new NumberVariable("target_x", $player->x);
                    $variables["target_y"] = new NumberVariable("target_y", $player->y);
                    $variables["target_z"] = new NumberVariable("target_z", $player->z);
                    $variables["target_level"] = new StringVariable("target_level", $player->level->getFolderName());
                }
            }
        }
        if ($eventname == "EntityLevelChangeEvent") {
            $variables["origin_level"] = new StringVariable("origin_level", $event->getOrigin()->getFolderName());
            $variables["target_level"] = new StringVariable("target_level", $event->getTarget()->getFolderName());
        }
        return array_merge($result, $variables);
    }
}<?php

namespace aieuo\ip\manager;

use aieuo\ip\variable\StringVariable;
use aieuo\ip\variable\NumberVariable;
use aieuo\ip\variable\ListVariable;
use aieuo\ip\IFPlugin;
use aieuo\ip\form\Elements;

class FormIFManager extends IFManager {

    public function __construct($owner) {
        parent::__construct($owner, "forms");
    }

    public function set(string $key, array $datas = [], array $options = []) {
        if (!isset($datas["ifs"])) $datas["ifs"] = [];
        parent::set($key, $datas);
    }

    public function get(string $key, array $options = []): ?array {
        if (!$this->exists($key)) return [];
        $datas = parent::get($key);
        if (!isset($datas["ifs"][$options["place"]])) return $this->repairIF([]);
        $ifdata = $this->repairIF($datas["ifs"][$options["place"]]);
        return $ifdata;
    }

    public function getIF($key) {
        $datas = parent::get($key);
        $datas["form"] = str_replace("\\\\n", "\\n", $datas["form"]);
        return $datas;
    }

    public function add($key, $type, $id, $content, $options = []) {
        $datas = $this->getIF($key);
        if (!isset($options["place"])) {
            $data = $this->repairIF([]);
            $data[$type][] = [
                "id" => $id,
                "content" => $content
            ];
            $datas["ifs"][] = $data;
        } else {
            $datas["ifs"][$options["place"]][$type][] = [
                "id" => $id,
                "content" => $content
            ];
            $datas["ifs"][$options["place"]] = $this->repairIF($datas["ifs"][$options["place"]]);
        }
        $this->set($key, $datas);
    }

    public function updateContent($key, $type, $num, $new, $options = []) {
        if (!$this->exists($key)) return false;
        $datas = $this->getIF($key);
        $datas["ifs"][$options["place"]][$type][$num]["content"] = $new;
        $this->set($key, $datas);
        return true;
    }

    public function setName($key, $name, $options = []) {
        if (!$this->exists($key)) return false;
        $datas = $this->getIF($key);
        $datas["ifs"][$options["place"]]["name"] = $name;
        $this->set($key, $datas);
        return true;
    }

    public function del($key, $type, $num, $options = []) {
        if (!$this->exists($key)) return false;
        $datas = $this->getIF($key);
        unset($datas["ifs"][$options["place"]][$type][$num]);
        $datas["ifs"][$options["place"]][$type] = array_merge($datas["ifs"][$options["place"]][$type]);
        $this->set($key, $datas);
        return true;
    }

    public function remove($key, $options = []) {
        if (!$this->exists($key)) return false;
        $datas = $this->getIF($key);
        unset($datas["ifs"][$options["place"]]);
        $datas["ifs"] = array_merge($datas["ifs"]);
        $this->set($key, $datas);
        return true;
    }

    public function removeIF($key) {
        parent::remove($key);
    }

    public function getReplaceDatas($datas) {
        $variables = parent::getReplaceDatas($datas);
        $variables["form_name"] = new StringVariable("form_name", $datas["form_name"]);
        $form = $datas["form"];
        switch ($form["type"]) {
            case 'form':
                $variables["form_data"] = new NumberVariable("form_data", $datas["form_data"]);
                $variables["form_button"] = new StringVariable("form_button", $form["buttons"][$datas["form_data"]]["text"]);
                break;
            case "modal":
                $variables["form_data"] = new StringVariable("form_data", $datas["form_data"]?"true":"false");
                break;
            case "custom_form":
                $add = [];
                $dropdowns = [];
                foreach ($datas["form_data"] as $key => $value) {
                    $content = $form["content"][$key];
                    switch ($content["type"]) {
                        case 'label':
                        case 'input':
                        case "slider":
                            $add[] = $value;
                            break;
                        case "dropdown":
                            $add[] = $value;
                            $dropdowns[] = $content["options"][$value];
                            break;
                        case "toggle":
                            $add[] = $value ? "true" : "false";
                            break;
                    }
                }
                $variables["form_data"] = new ListVariable("form_data", $add);
                $variables["form_dropdown"] = new ListVariable("form_dropdown", $dropdowns);
                break;
        }
        return $variables;
    }

    public function getForm($name, $replaces) {
        $form = json_decode($this->getIF($name)["form"], true);
        $variableHelper = IFPlugin::getInstance()->getVariableHelper();
        $form["title"] = $variableHelper->replaceVariables($form["title"], $replaces);
        switch ($form["type"]) {
            case "modal":
                $form["content"] = $variableHelper->replaceVariables($form["content"], $replaces);
                $form["button1"] = $variableHelper->replaceVariables($form["button1"], $replaces);
                $form["button2"] = $variableHelper->replaceVariables($form["button2"], $replaces);
                break;
            case "form":
                $form["content"] = $variableHelper->replaceVariables($form["content"], $replaces);
                $buttons = [];
                foreach ($form["buttons"] as $button) {
                    $variables = $variableHelper->findVariables($button["text"], $replaces);
                    foreach ($variables as $variableName => $variable) {
                        if ($variable instanceof ListVariable) {
                            $add = array_map(function ($value) use ($button, $variableName, $variableHelper, $replaces) {
                                $text = str_replace("{".$variableName."}", $value, $button["text"]);
                                $text = $variableHelper->replaceVariables($text, $replaces);
                                return Elements::getButton($text);
                            }, $variable->getValue());
                            $buttons = array_merge($buttons, $add);
                            continue 2;
                        }
                    }
                    $buttons[] = Elements::getButton($variableHelper->replaceVariables($button["text"], $replaces));
                }
                $form["buttons"] = $buttons;
                break;
            case "custom_form":
                $contents = [];
                foreach ($form["content"] as $content) {
                    $content["text"] = $variableHelper->replaceVariables($content["text"], $replaces);
                    switch ($content["type"]) {
                        case "input":
                            $content["default"] = $variableHelper->replaceVariables($content["default"], $replaces);
                            $content["placeholder"] = $variableHelper->replaceVariables($content["placeholder"], $replaces);
                            break;
                        case "dropdown":
                            $options = [];
                            foreach ($content["options"] as $option) {
                                $variables = $variableHelper->findVariables($option, $replaces);
                                foreach ($variables as $variableName => $variable) {
                                    if ($variable instanceof ListVariable) {
                                        $add = array_map(function ($value) use ($option, $variableName, $variableHelper, $replaces) {
                                            $text = str_replace("{".$variableName."}", $value, $option);
                                            return $variableHelper->replaceVariables($text, $replaces);
                                        }, $variable->getValue());
                                        $options = array_merge($options, $add);
                                        continue 2;
                                    }
                                }
                                $options[] = $variableHelper->replaceVariables($option, $replaces);
                            }
                            $content["options"] = $options;
                            break;
                    }
                    $contents[] = $content;
                }
                $form["content"] = $contents;
                break;
        }
        return $form;
    }
}<?php

namespace aieuo\ip\manager;

use pocketmine\utils\Config;
use pocketmine\Server;

use aieuo\ip\Session;
use aieuo\ip\IFPlugin;
use aieuo\ip\IFAPI;

class IFManager extends IFAPI {

    const BLOCK = 0;
    const COMMAND = 1;
    const EVENT = 2;
    const CHAIN = 3;
    const FORM = 4;

    /** @var IFPlugin */
    private $owner;
    /** @var Config */
    private $config;

    /**
     * @param Session $session
     * @return IFManager|null
     */
    public static function getBySession(Session $session): ?IFManager {
        $type = $session->get("if_type");
        if ($type === null) return null;
        switch ($type) {
            case IFManager::BLOCK:
                $manager = IFPlugin::getInstance()->getBlockManager();
                break;
            case IFManager::COMMAND:
                $manager = IFPlugin::getInstance()->getCommandManager();
                break;
            case IFManager::EVENT:
                $manager = IFPlugin::getInstance()->getEventManager();
                break;
            case IFManager::CHAIN:
                $manager = IFPlugin::getInstance()->getChainManager();
                break;
            case IFManager::FORM:
                $manager = IFPlugin::getInstance()->getFormIFManager();
                break;
            default:
                $manager = null;
        }
        return $manager;
    }

    public function __construct(IFPlugin $owner, string $type) {
        $this->owner = $owner;
        $this->config = new Config($owner->getDataFolder() . $type. ".yml", Config::YAML, []);
    }

    public function getOwner(): IFPlugin {
        return $this->owner;
    }

    public function getServer(): Server {
        return $this->getOwner()->getServer();
    }

    public function getConfig(): Config {
        return $this->config;
    }

    /**
     * @param  string $key
     * @param  array  $options
     * @return array|null
     */
    public function get(string $key, array $options = []): ?array {
        if (!$this->exists($key)) return null;
        $datas = $this->config->get($key);
        $datas = $this->repairIF($datas);
        return $datas;
    }

    /**
     * @param string $key
     * @param array  $options
     * @return boolean
     */
    public function exists(string $key, array $options = []): bool {
        return $this->config->exists($key);
    }

    /**
     * @param string $key
     * @param array  $datas
     * @param array  $options
     */
    public function set(string $key, array $datas = [], array $options = []) {
        $this->config->set($key, $datas);
    }

    /**
     * @return array
     */
    public function getAll(): array {
        return $this->config->getAll();
    }

    /**
     * @param string $key
     * @param string $type
     * @param int    $id
     * @param string $content
     * @param array  $options
     */
    public function add($key, $type, $id, $content, $options = []) {
        $datas = [];
        if ($this->exists($key))$datas = $this->get($key);
        $datas = $this->repairIF($datas);
        $datas[$type][] = [
            "id" => $id,
            "content" => $content
        ];
        $this->config->set($key, $datas);
    }

    /**
     * @param  string $key
     * @param  string $type
     * @param  int $num
     * @return bool
     */
    public function del($key, $type, $num, $options = []) {
        if (!$this->exists($key)) return false;
        $datas = $this->get($key);
        unset($datas[$type][$num]);
        $datas[$type] = array_merge($datas[$type]);
        $this->config->set($key, $datas);
        return true;
    }

    /**
     * @param  string $key
     * @param  string $type
     * @param  int $num
     * @return bool
     */
    public function updateContent($key, $type, $num, $new, $options = []) {
        if (!$this->exists($key)) return false;
        $datas = $this->get($key);
        $datas[$type][$num]["content"] = $new;
        $this->config->set($key, $datas);
        return true;
    }

    /**
     * @param string $key
     * @param string $name
     * @param array $options
     */
    public function setName($key, $name, $options = []) {
        if (!$this->exists($key)) return false;
        $datas = $this->get($key);
        $datas["name"] = $name;
        $this->config->set($key, $datas);
        return true;
    }

    /**
     * @param  string $key
     */
    public function remove($key) {
        $this->config->remove($key);
    }

    public function save() {
        $this->config->save();
    }

    /**
     * @param  array $datas
     * @return array
     */
    public function repairIF($datas) {
        if (!isset($datas["if"]))$datas["if"] = [];
        if (!isset($datas["match"]))$datas["match"] = [];
        if (!isset($datas["else"]))$datas["else"] = [];
        return $datas;
    }

    public function getReplaceDatas($datas) {
        return parent::getReplaceDatas($datas);
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\entity\Effect;
use pocketmine\entity\EffectInstance;

use aieuo\ip\utils\Language;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;

class AddEffect extends Process {

    protected $id = self::ADD_EFFECT;
    protected $name = "@process.addeffect.name";
    protected $description = "@process.addeffect.description";

    public function getDetail(): string {
        $effect = $this->getEffect();
        if (!($effect instanceof EffectInstance)) return false;
        return Language::get("process.addeffect.detail", [$effect->getId(), $effect->getAmplifier() + 1, $effect->getDuration() / 20]);
    }

    public function getEffect() {
        return $this->getValues();
    }

    public function setEffect(EffectInstance $effect) {
        $this->setValues($effect);
    }

    public function parse(string $content) {
        $args = explode(",", $content);
        if (!isset($args[1])) $args[1] = 1;
        if (!isset($args[2]) or (float)$args[2] <= 0) $args[2] = 30;
        $effect = Effect::getEffectByName($args[0]);
        $args[1] --;
        if ($effect === null) $effect = Effect::getEffect((int)$args[0]);
        if ($effect === null) return null;
        return new EffectInstance($effect, (float)$args[2] * 20, (int)$args[1], true);
    }

    public function execute() {
        $player = $this->getPlayer();
        $effect = $this->getEffect();
        if (!($effect instanceof EffectInstance)) {
            if ($effect === false) $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            if ($effect === null) $player->sendMessage(Language::get("process.addeffect.notfound"));
            return;
        }
        $player->addEffect($effect);
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $effect = $this->parse($default);
        $id = $default;
        $power = "";
        $time = "";
        if ($effect instanceof EffectInstance) {
            $id = $effect->getId();
            $power = $effect->getAmplifier() + 1;
            $time = $effect->getDuration() / 20;
        } elseif ($default !== "") {
            if ($effect === false)$mes .= Language::get("form.error");
            if ($effect === null)$mes .= Language::get("process.addeffect.notfound");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.addeffect.form.id"), Language::get("input.example", ["1"]), $id),
                Elements::getInput(Language::get("process.addeffect.form.power"), Language::get("input.example", ["5"]), $power),
                Elements::getInput(Language::get("process.addeffect.form.time"), Language::get("input.example", ["5"]), $time),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $effect_str = $datas[1].",".$datas[2].",".$datas[3];
        if ($datas[1] === "" or $datas[2] === "" or $datas[3] === "") $status = null;
        return ["status" => $status, "contents" => $effect_str, "delete" => $datas[4], "cancel" => $datas[5]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\enchantment\EnchantmentInstance;

use aieuo\ip\utils\Language;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;

class AddEnchantment extends Process {

    protected $id = self::ADD_ENCHANTMENT;
    protected $name = "@process.addenchant.name";
    protected $description = "@process.addenchant.description";

    public function getDetail(): string {
        $enchant = $this->getEnchantment();
        if (!($enchant instanceof EnchantmentInstance)) return false;
        return Language::get("process.addenchant.detail", [$enchant->getId(), $enchant->getLevel()]);
    }

    public function getEnchantment() {
        return $this->getValues();
    }

    public function setEnchantment(EnchantmentInstance $enchant) {
        $this->setValues($enchant);
    }

    public function parse(string $content) {
        $args = explode(",", $content);
        if (!isset($args[1]) or (int)$args[1] <= 0) $args[1] = 1;
        if (is_numeric($args[0])) {
            $enchantment = Enchantment::getEnchantment((int)$args[0]);
        } else {
            $enchantment = Enchantment::getEnchantmentByName($args[0]);
        }
        if (!($enchantment instanceof Enchantment)) return null;
        return new EnchantmentInstance($enchantment, (int)$args[1]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $enchant = $this->getEnchantment();
        if (!($enchant instanceof EnchantmentInstance)) {
            if ($enchant === false) $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            if ($enchant === null) $player->sendMessage(Language::get("process.addenchant.notfound"));
            return;
        }
        $item = $player->getInventory()->getItemInHand();
        $item->addEnchantment($enchant);
        $player->getInventory()->setItemInHand($item);
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $enchant = $this->parse($default);
        $id = $default;
        $power = "";
        if ($enchant instanceof EnchantmentInstance) {
            $id = $enchant->getId();
            $power = $enchant->getLevel();
        } elseif ($default !== "") {
            if ($enchant === false) $mes .= Language::get("form.error");
            if ($enchant === null) $mes .= Language::get("process.addenchant.notfound");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.addenchant.form.id"), Language::get("input.example", ["1"]), $id),
                Elements::getInput(Language::get("process.addenchant.form.power"), Language::get("input.example", ["5"]), $power),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $enchant_str = $datas[1].",".$datas[2];
        if ($datas[1] === "" or $datas[2] === "") $status = null;
        return ["status" => $status, "contents" => $enchant_str, "delete" => $datas[3], "cancel" => $datas[4]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\item\Item;

use aieuo\ip\utils\Language;

class AddItem extends TypeItem {

    protected $id = self::ADD_ITEM;
    protected $name = "@process.additem.name";
    protected $description = "@process.additem.description";

    public function getDetail(): string {
        $item = $this->getItem();
        if (!($item instanceof Item)) return false;
        return Language::get("process.additem.detail", [$item->getId(), $item->getDamage(), $item->getName(), $item->getCount()]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $item = $this->getItem();
        if (!($item instanceof Item)) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $player->getInventory()->addItem($item);
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\utils\Language;
use aieuo\ip\IFPlugin;

class AddMoney extends TypeMoney {

    protected $id = self::ADDMONEY;
    protected $name = "@process.addmoney.name";
    protected $description = "@process.addmoney.description";

    public function getDetail(): string {
        return Language::get("process.addmoney.detail", [$this->getAmount()]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $economy = IFPlugin::getInstance()->getEconomy();
        if ($economy === null) {
            $player->sendMessage(Language::get("economy.notfound"));
            return;
        }
        $economy->addMoney($player->getName(), $this->getAmount());
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;
use aieuo\ip\variable\Variable;
use aieuo\ip\utils\Language;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;

class AddVariable extends Process {

    protected $id = self::ADD_VARIABLE;
    protected $name = "@process.addvariable.name";
    protected $description = "@process.addvariable.description";

    public function getDetail(): string {
        $variable = $this->getVariable();
        if ($variable === false) return false;
        return Language::get("process.addvariable.detail", [$variable->getName(), $variable->getString()]);
    }

    public function getVariable(): ?Variable {
        $variable = $this->getValues();
        if (!($variable instanceof Variable)) return null;
        return $variable;
    }

    public function setVariable(Variable $variable) {
        $this->setValues($variable);
    }

    public function parse(string $content) {
        $datas = explode(";", $content);
        if (!isset($datas[1]) or $datas[1] === "") return false;
        $helper = IFPlugin::getInstance()->getVariableHelper();
        $value = $helper->currentType($datas[1]);
        return Variable::create($datas[0], $value, $helper->getType($datas[1]));
    }

    public function execute() {
        $player = $this->getPlayer();
        $variable = $this->getVariable();
        if ($variable === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        IFPlugin::getInstance()->getVariableHelper()->add($variable);
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $var = $this->parse($default);
        $name = $default;
        $value = "";
        if ($var instanceof Variable) {
            $name = $var->getName();
            $value = $var->getString();
            if (is_numeric($value) and $var->getType() === Variable::STRING) {
                $value = "(str)".$value;
            } elseif (!is_numeric($value) and $var->getType() === Variable::NUMBER) {
                $value = "(num)".$value;
            }
        } elseif ($default !== "") {
            $mes .= Language::get("form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.addvariable.form.name"), Language::get("input.example", ["aieuo"]), $name),
                Elements::getInput(Language::get("process.addvariable.form.value"), Language::get("input.example", ["1000"]), $value),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $var_str = $datas[1].";".$datas[2];
        if ($datas[1] === "" or $datas[2] === "") {
            $status = null;
        } else {
            $var = $this->parse($var_str);
            if ($var === false) $status = false;
        }
        return ["status" => $status, "contents" => $var_str, "delete" => $datas[3], "cancel" => $datas[4]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\event\entity\EntityDamageEvent;

use aieuo\ip\utils\Language;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;

class Attack extends Process {

    protected $id = self::ATTACK;
    protected $name = "@process.attack.name";
    protected $description = "@process.attack.description";

    public function getDetail(): string {
        $damage = $this->getDamage();
        if ($damage === false) return false;
        return Language::get("process.attack.detail", [$damage]);
    }

    public function getDamage() {
        return $this->getValues();
    }

    public function setDamage(float $damage) {
        $this->setValues($damage);
    }

    public function parse(string $content) {
        $damage = (float)$content;
        if ($damage <= 0) return false;
        return $damage;
    }

    public function execute() {
        $player = $this->getPlayer();
        $damage = $this->getDamage();
        if ($damage === false) {
            $player->sendMessage(Language::get("process.attack.error", [$this->getName()]));
            return;
        }
        $event = new EntityDamageEvent($player, EntityDamageEvent::CAUSE_ENTITY_ATTACK, (float)$damage);
        $player->attack($event);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $damage = $this->parse($default);
        if ($damage === false) {
            if ($default !== "") $mes .= Language::get("process.attack.form.error");
            $damage = $default;
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.attack.form.damage"), Language::get("input.example", ["5"]), $damage),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") {
            $status = null;
        } else {
            $damage = $this->parse($datas[1]);
            if ($damage === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\Server;

use aieuo\ip\utils\Language;

class BroadcastMessage extends TypeMessage {

    protected $id = self::BROADCASTMESSAGE;
    protected $name = "@process.broadcastmessage.name";
    protected $description = "@process.broadcastmessage.description";

    public function getDetail(): string {
        $message = $this->getMessage();
        return Language::get("process.broadcastmessage.detail", [$message]);
    }

    public function execute() {
        Server::getInstance()->broadcastMessage($this->getMessage());
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;
use aieuo\ip\variable\Variable;
use aieuo\ip\variable\StringVariable;
use aieuo\ip\variable\NumberVariable;
use aieuo\ip\variable\ListVariable;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class Calculation extends Process {

    protected $id = self::CALCULATION;
    protected $name = "@process.calculation.name";
    protected $description = "@process.calculation.description";

    const ERROR = -1;
    const ADDITION = 0;
    const SUBTRACTION = 1;
    const MULTIPLICATION = 2;
    const DIVISION = 3;
    const MODULO = 4;

    public function getDetail(): string {
        if ($this->getValues() === false) return false;
        $variable1 = $this->getValue1();
        $variable2 = $this->getValue2();
        for ($i = 1; $i <= 2; $i ++) {
            ${"value".$i} = ${"variable".$i}->getValue();

            if (${"variable".$i} instanceof StringVariable and is_numeric(${"value".$i})) {
                ${"value".$i} = "(str)".${"value".$i};
            } elseif (${"variable".$i} instanceof NumberVariable and !is_numeric(${"value".$i})) {
                ${"value".$i} = "(num)".${"value".$i};
            } elseif (${"variable".$i} instanceof ListVariable) {
                ${"value".$i} = ${"variable".$i}->toStringVariable()->getValue();
            }
        }
        $operator = $this->getOperator();
        switch ($operator) {
            case self::ADDITION:
                $mes = Language::get("process.calculation.detail.add", [$value1, $value2]);
                break;
            case self::SUBTRACTION:
                $mes = Language::get("process.calculation.detail.sub", [$value1, $value2]);
                break;
            case self::MULTIPLICATION:
                $mes = Language::get("process.calculation.detail.mul", [$value1, $value2]);
                break;
            case self::DIVISION:
                $mes = Language::get("process.calculation.detail.div", [$value1, $value2]);
                break;
            case self::MODULO:
                $mes = Language::get("process.calculation.detail.mod", [$value1, $value2]);
                break;
            default:
                return false;
        }
        return $mes;
    }

    public function getValue1() {
        return $this->getValues()[0];
    }

    public function getValue2() {
        return $this->getValues()[1];
    }

    public function getOperator() {
        return $this->getValues()[2];
    }

    public function getAssignName() {
        return $this->getValues()[3];
    }

    public function setNumbers(Variable $value1, Variable $value2, int $ope, string $assign = "result") {
        $this->setValues([$value1, $value2, $ope, $assign]);
    }

    public function parse(string $numbers) {
        if (!preg_match("/\s*(.+)\s*\[ope:([0-9])\]\s*(.+)\s*;\s*([^;]*)\s*$/", $numbers, $matches)) return false;
        $helper = IFPlugin::getInstance()->getVariableHelper();
        $operator = (int)$matches[2];
        $value1 = $matches[1];
        $value2 = $matches[3];
        $assign = $matches[4] === "" ? "result" : $matches[4];
        $type1 = $helper->getType($value1);
        $value1 = $helper->currentType($value1);
        $var1 = Variable::create("value1", $value1, $type1);
        $type2 = $helper->getType($value2);
        $value2 = $helper->currentType($value2);
        $var2 = Variable::create("value2", $value2, $type2);
        return [$var1, $var2, $operator, $assign];
    }

    public function execute() {
        $player = $this->getPlayer();
        if ($this->getValues() === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $variable1 = $this->getValue1();
        $variable2 = $this->getValue2();
        $operator = $this->getOperator();
        $name = $this->getAssignName();
        switch ($operator) {
            case self::ADDITION:
                $result = $variable1->addition($variable2, $name);
                break;
            case self::SUBTRACTION:
                $result = $variable1->subtraction($variable2, $name);
                break;
            case self::MULTIPLICATION:
                $result = $variable1->multiplication($variable2, $name);
                break;
            case self::DIVISION:
                $result = $variable1->division($variable2, $name);
                break;
            case self::MODULO:
                $result = $variable1->modulo($variable2, $name);
                break;
            default:
                $player->sendMessage(Language::get("process.calculation.invalid", [$this->getName()]));
                return;
        }
        if ($result->getName() == "ERROR") {
            $player->sendMessage(Language::get("process.calculation.error"), [$this->getName(), $result->getValue()]);
            return;
        }
        IFPlugin::getInstance()->getVariableHelper()->add($result);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $values = $this->parse($default);
        $value0 = $default;
        $value1 = "";
        $operator = self::ADDITION;
        $name = "";
        if ($values !== false) {
            for ($i = 0; $i <= 1; $i ++) {
                ${"value".$i} = $values[$i]->getValue();

                if ($values[$i] instanceof StringVariable and is_numeric(${"value".$i})) {
                    ${"value".$i} = "(str)".${"value".$i};
                } elseif ($values[$i] instanceof NumberVariable and !is_numeric(${"value".$i})) {
                    ${"value".$i} = "(num)".${"value".$i};
                } elseif ($values[$i] instanceof ListVariable) {
                    ${"value".$i} = $values[$i]->toStringVariable()->getValue();
                }
            }
            $operator = $values[2];
            $name = $values[3];
        } elseif ($default !== "") {
            $mes .= Language::get("form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.calculation.form.value1"), Language::get("input.example", ["100"]), $value0),
                Elements::getDropdown(Language::get("process.calculation.form.operator"), [
                    Language::get("process.calculation.form.operator.add"),
                    Language::get("process.calculation.form.operator.sub"),
                    Language::get("process.calculation.form.operator.mul"),
                    Language::get("process.calculation.form.operator.div"),
                    Language::get("process.calculation.form.operator.mod"),
                ], $operator),
                Elements::getInput(Language::get("process.calculation.form.value2"), Language::get("input.example", ["50"]), $value1),
                Elements::getInput(Language::get("process.calculation.form.result"), Language::get("input.example", ["aieuo"]), $name),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $values_str = $datas[1]."[ope:".$datas[2]."]".$datas[3].";".$datas[4];
        if ($datas[1] === "" or $datas[2] === "" or $datas[3] === "") {
            $status = null;
        } else {
            $values = $this->parse($values_str);
            if ($values === false) $status = false;
        }
        return ["status" => $status, "contents" => $values_str, "delete" => $datas[5], "cancel" => $datas[6]];
    }
}<?php

namespace aieuo\ip\processes;

class ClearInventory extends Process {
    protected $id = self::CLEAR_INVENTORY;
    protected $name = "@process.clearInventory.name";
    protected $description = "@process.clearInventory.description";
    protected $detail = "@process.clearInventory.detail";

    public function execute() {
        $player = $this->getPlayer();
        $player->getInventory()->clearAll();
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\Server;

use aieuo\ip\utils\Language;

class Command extends TypeCommand {

    protected $id = self::COMMAND;
    protected $name = "@process.command.name";
    protected $description = "@process.command.description";

    public function getDetail(): string {
        $command = $this->getCommand();
        return Language::get("process.command.detail", [$command]);
    }

    public function execute() {
        $player = $this->getPlayer();
        Server::getInstance()->dispatchCommand($player, $this->getCommand());
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\Server;
use pocketmine\command\ConsoleCommandSender;

use aieuo\ip\utils\Language;

class CommandConsole extends TypeCommand {

    protected $id = self::COMMAND_CONSOLE;
    protected $name = "@process.commandconsole.name";
    protected $description = "@process.commandconsole.description";

    public function getDetail(): string {
        $command = $this->getCommand();
        return Language::get("process.commandconsole.detail", [$command]);
    }

    public function execute() {
        Server::getInstance()->dispatchCommand(new ConsoleCommandSender, $this->getCommand());
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\event\Event;

use aieuo\ip\IFPlugin;
use aieuo\ip\utils\Language;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;

class Cooperation extends Process {

    protected $id = self::COOPERATION;
    protected $name = "@process.cooperation.name";
    protected $description = "@process.cooperation.description";

    public function getDetail(): string {
        $name = $this->getCooperationName();
        return Language::get("process.cooperation.detail", [$name]);
    }

    public function getCooperationName(): ?string {
        $name = $this->getValues();
        return is_string($name) ? $name : null;
    }

    public function setCooperationName(string $name) {
        $this->setValues($name);
    }

    public function execute() {
        $player = $this->getPlayer();
        $manager = IFPlugin::getInstance()->getChainManager();
        if (!$manager->exists($this->getCooperationName())) {
            $player->sendMessage(Language::get("process.cooperation.notfount"));
            return;
        }
        $datas = $manager->get($this->getCooperationName());
        $options = [
            "player" => $player,
        ];
        if ($this->getEvent() instanceof Event) $options["event"] = $this->getEvent();
        $options["replaces"] = $this->replaceDatas;
        $manager->executeIfMatchCondition(
            $player,
            $datas["if"],
            $datas["match"],
            $datas["else"],
            $options
        );
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $manager = IFPlugin::getInstance()->getChainManager();
        if ($default !== "" and !$manager->exists($default)) $mes .= Language::get("process.cooperation.notfount");
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.cooperation.form.name"), Language::get("input.example", ["aieuo"]), $default),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") $status = null;
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\event\Event;

use aieuo\ip\IFPlugin;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class CooperationRepeat extends Process {

    protected $id = self::COOPERATION_REPEAT;
    protected $name = "@process.cooperationrepeat.name";
    protected $description = "@process.cooperationrepeat.description";

    public function getDetail(): string {
        $name = $this->getCooperationName();
        $count = $this->getCount();
        return Language::get("process.cooperationrepeat.detail", [$name, $count]);
    }

    public function getCooperationName() {
        return $this->getValues()[0];
    }

    public function getCount() {
        return $this->getValues()[1];
    }

    public function setNames(string $name, int $count) {
        $this->setValues([$name, $count]);
    }

    public function parse(string $content) {
        $datas = explode(";", $content);
        if (!isset($datas[1])) return false;
        $count = array_pop($datas);
        $name = implode(";", $datas);
        return [$name, $count];
    }

    public function execute() {
        $player = $this->getPlayer();
        $manager = IFPlugin::getInstance()->getChainManager();
        if (!$manager->exists($this->getCooperationName())) {
            $player->sendMessage(Language::get("process.cooperation.notfound"));
            return;
        }
        $datas = $manager->get($this->getCooperationName());
        $count = $this->getCount();
        for ($i = 0; $i < $count; $i ++) {
            $options = [
                "player" => $player,
                "count" => $i,
            ];
            if ($this->getEvent() instanceof Event) $options["event"] = $this->getEvent();
            $options["replaces"] = $this->replaceDatas;
            $manager->executeIfMatchCondition(
                $player,
                $datas["if"],
                $datas["match"],
                $datas["else"],
                $options
            );
        }
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $manager = IFPlugin::getInstance()->getChainManager();
        $names = $this->parse($default);
        $name = $default;
        $count = "";
        if ($names === false and $default !== "") {
            $mes .= Language::get("form.error");
        } else {
            $name = $names[0];
            $count = $names[1];
        }
        if ($default !== "" and !$manager->exists($name)) $mes .= Language::get("process.cooperation.notfound");
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.cooperation.form.name"), Language::get("input.example", ["aieuo"]), $name),
                Elements::getInput(Language::get("process.cooperationrepeat.form.count"), Language::get("input.example", ["5"]), $count),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $status = true;
        if ($datas[1] === "" or $datas[2] === "") {
            $status = null;
        } else {
            $names = $this->parse($datas[1].";".$datas[2]);
            if ($names === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1].";".$datas[2], "delete" => $datas[3], "cancel" => $datas[4]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;
use aieuo\ip\task\DelayedCommandTask;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class DelayedCommand extends Process {

    protected $id = self::DELAYED_COMMAND;
    protected $name = "@process.delayedcommand.name";
    protected $description = "@process.delayedcommand.description";

    public function getDetail(): string {
        if ($this->getValues() === false) return false;
        $command = $this->getCommand();
        $time = $this->getTime();
        return Language::get("process.delayedcommand.detail", [$time, $command]);
    }

    public function getTime() {
        return $this->getValues()[1];
    }

    public function getCommand() {
        return $this->getValues()[0];
    }

    public function setCommands(string $command, int $time) {
        $this->setValues($command, $time);
    }

    public function parse(string $commands) {
        if (!preg_match("/([0-9]+),(.+)/", $commands, $matches)) return false;
        return [$matches[2], (int)$matches[1]];
    }

    public function execute() {
        $player = $this->getPlayer();
        if ($this->getValues() === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $time = $this->getTime();
        $command = $this->getCommand();
        IFPlugin::getInstance()->getScheduler()->scheduleDelayedTask(new DelayedCommandTask($player, $command), $time*20);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $commands = $this->parse($default);
        $command = $default;
        $time = "";
        if ($commands !== false) {
            $command = $commands[0];
            $time = $commands[1];
        } elseif ($default !== "") {
            $mes .= Language::get("form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.delayedcommand.form.command"), Language::get("input.example", ["help"]), $command),
                Elements::getInput(Language::get("process.delayedcommand.form.time"), Language::get("input.example", ["10"]), $time),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "" or $datas[2] === "") {
            $status = null;
        } else {
            $value = $this->parse($datas[2].",".$datas[1]);
            if ($value === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[2].",".$datas[1], "delete" => $datas[3], "cancel" => $datas[4]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;
use pocketmine\command\ConsoleCommandSender;
use aieuo\ip\task\DelayedCommandTask;
use aieuo\ip\utils\Language;

class DelayedCommandConsole extends DelayedCommand {

    protected $id = self::DELAYED_COMMAND_CONSOLE;
    protected $name = "@process.delayedcommandconsole.name";
    protected $description = "@process.delayedcommandconsole.description";

    public function getDetail(): string {
        if ($this->getValues() === false) return false;
        $command = $this->getCommand();
        $time = $this->getTime();
        return Language::get("process.delayedcommandconsole.detail", [$time, $command]);
    }

    public function execute() {
        $player = $this->getPlayer();
        if ($this->getValues() === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $time = $this->getTime();
        $command = $this->getCommand();
        IFPlugin::getInstance()->getScheduler()->scheduleDelayedTask(new DelayedCommandTask(new ConsoleCommandSender(), $command), $time*20);
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;
use aieuo\ip\utils\Language;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\task\DelayedCooperationTask;

class DelayedCooperation extends Process {

    protected $id = self::DELAYED_COOPERATION;
    protected $name = "@process.delayedCooperation.name";
    protected $description = "@process.delayedCooperation.description";

    public function getDetail(): string {
        $name = $this->getCooperationName();
        $time = $this->getTime();
        return Language::get("process.delayedCooperation.detail", [$name, $time]);
    }

    public function getCooperationName(): ?string {
        $name = $this->getValues()[1] ?? null;
        return is_string($name) ? $name : null;
    }

    public function getTime(): ?float {
        $time = $this->getValues()[0] ?? null;
        return is_float($time) ? $time : null;
    }

    public function parse(string $content) {
        $names = explode("[name]", $content);
        if (!isset($names[1])) return false;
        if (!preg_match("/([0-9]+.?[0-9]*)/", $names[0], $matches)) return false;
        return [(float)$matches[1], $names[1]];
    }

    public function execute() {
        $player = $this->getPlayer();
        $time = $this->getTime();
        $name = $this->getCooperationName();
        if ($time === null or $name === null) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        IFPlugin::getInstance()->getScheduler()->scheduleDelayedTask(new DelayedCooperationTask($player, $name, $this->getEvent(), $this->replaceDatas), $time*20);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $manager = IFPlugin::getInstance()->getChainManager();
        $names = $this->parse($default);
        $name = explode("[name]", $default)[1] ?? $default;
        $time = explode("[name]", $default)[0];
        if ($default !== "" and $names === false) {
            $mes .= Language::get("form.error");
        } elseif ($default !== "" and !$manager->exists($name)) {
            $mes .= Language::get("process.cooperation.notfount");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.cooperation.form.name"), Language::get("input.example", ["aieuo"]), $name),
                Elements::getInput(Language::get("process.delayedcommand.form.time"), Language::get("input.example", ["10"]), $time),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "" or $datas[2] === "") {
            $status = null;
        } else {
            $value = $this->parse($datas[2]."[name]".$datas[1]);
            if ($value === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[2]."[name]".$datas[1], "delete" => $datas[3], "cancel" => $datas[4]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class DeleteVariable extends Process {

    protected $id = self::DELETE_VARIABLE;
    protected $name = "@process.deletevariable.name";
    protected $description = "@process.deletevariable.description";

    public function getDetail(): string {
        return Language::get("process.deletevariable.detail", [$this->getVariableName()]);
    }

    public function getVariableName(): ?string {
        $name = $this->getValues();
        return is_string($name) ? $name : null;
    }

    public function setVariableName(string $variable) {
        $this->setValues($variable);
    }

    public function execute() {
        IFPlugin::getInstance()->getVariableHelper()->del($this->getVariableName());
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.deletevariable.form.name"), Language::get("input.example", ["aieuo"]), $default),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") $status = null;
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

class DoNothing extends Process {

    protected $id = self::DO_NOTHING;
    protected $name = "@process.donothing.name";
    protected $description = "@process.donothing.description";
    protected $detail = "@process.donothing.detail";

    public function execute() {
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\item\ItemBlock;
use pocketmine\item\Item;
use pocketmine\item\Armor;
use aieuo\ip\utils\Language;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;

class EquipArmor extends Process {

    protected $id = self::EQUIP_ARMOR;
    protected $name = "@process.equipArmor.name";
    protected $description = "@process.equipArmor.description";

    private $places = [
        "process.equipArmor.helmet",
        "process.equipArmor.chestplate",
        "process.equipArmor.leggings",
        "process.equipArmor.boots",
    ];

    public function getDetail(): string {
        $place = $this->getPlace();
        $armor = $this->getArmor();
        if (!is_int($place) or !($armor instanceof Item)) return false;
        return Language::get("process.equipArmor.detail", [Language::get($this->places[$place]), $armor->getId(), $armor->getDamage(), $armor->getName()]);
    }

    public function getPlace() {
        return $this->getValues()[0];
    }

    public function getArmor() {
        return $this->getValues()[1];
    }

    public function parse(string $content) {
        $place = explode("[item]", $content)[0];
        $id = explode("[item]", $content)[1] ?? "";
        if (!preg_match("/\s*([0-9]+)\s*:?\s*([0-9]*)\s*/", $id, $ids)) return false;
        $item = Item::get((int)$ids[1], empty($ids[2]) ? 0 : (int)$ids[2]);
        return [(int)$place, $item];
    }

    public function execute() {
        $player = $this->getPlayer();
        $place = $this->getPlace();
        $armor = $this->getArmor();
        if (!($armor instanceof Item)) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        } elseif (!($armor instanceof Armor) and !($armor instanceof ItemBlock)) {
            $player->sendMessage(Language::get("process.equipArmor.notArmor", [$this->getName(), $armor->getName()]));
            return;
        }
        $player->getArmorInventory()->setItem($place, $armor);
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $datas = $this->parse($default);
        $place = 0;
        $armor = explode("[item]", $default)[1] ?? $default;
        if ($armor instanceof Armor or $armor instanceof ItemBlock) {
            $place = $datas[0];
            $armor = $datas->getId().":".$datas->getDamage();
        } elseif ($default !== "" and $armor instanceof Item) {
            $mes .= Language::get("process.equipArmor.notArmor", [$armor->getName()]);
        } elseif ($default !== "") {
            $mes .= Language::get("process.equipArmor.form.invalid");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getDropdown(Language::get("process.equipArmor.form.place"), array_map(function ($item) {
                    return Language::get($item);
                }, $this->places), $place),
                Elements::getInput(Language::get("process.equipArmor.form.id"), Language::get("input.example", ["5"]), $armor),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $ids_str = $datas[1]."[item]".$datas[2];
        if ($datas[2] === "") {
            $status = null;
        } else {
            $ids = $this->parse($ids_str);
            if ($ids === false) $status = false;
        }
        if ($datas[1] === "" or $datas[2] === "") $status = null;
        return ["status" => $status, "contents" => $ids_str, "delete" => $datas[3], "cancel" => $datas[4]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\event\Event;
use pocketmine\event\Cancellable;

class EventCancel extends Process {

    protected $id = self::EVENT_CANCEL;
    protected $name = "@process.eventcancel.name";
    protected $description = "@process.eventcancel.description";
    protected $detail = "@process.eventcancel.detail";

    public function getCancelEvent() {
        return $this->getValues();
    }

    public function setCancelEvent(Event $event) {
        $this->setValues($event);
    }

    public function execute() {
        $event = $this->getCancelEvent();
        if ($event instanceof Cancellable) $event->setCancelled();
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\Server;

use aieuo\ip\IFPlugin;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class ExecuteOtherPlayer extends Process {

    protected $id = self::EXECUTE_OTHER_PLAYER;
    protected $name = "@process.executeotherplayer.name";
    protected $description = "@process.executeotherplayer.description";

    public function getDetail(): string {
        $cname = $this->getCooperationName();
        $pname = $this->getPlayerName();
        return Language::get("process.executeotherplayer.detail", [$cname, $pname]);
    }

    public function getCooperationName() {
        return $this->getValues()[0];
    }

    public function getPlayerName() {
        return $this->getValues()[1];
    }

    public function setNames(string $name, string $playerName) {
        $this->setValues([$name, $playerName]);
    }

    public function parse(string $content) {
        $datas = explode(";", $content);
        if (!isset($datas[1])) return false;
        $pname = array_pop($datas);
        $cname = implode(";", $datas);
        return [$cname, $pname];
    }

    public function execute() {
        $player = $this->getPlayer();
        $manager = IFPlugin::getInstance()->getChainManager();
        if (!$manager->exists($this->getCooperationName())) {
            $player->sendMessage(Language::get("process.cooperation.notfount"));
            return;
        }
        $playerName = $this->getPlayerName();
        $target = Server::getInstance()->getPlayer($playerName);
        if ($target === null) {
            $player->sendMessage(Language::get("process.executeotherplayer.offline", [$playerName]));
            return;
        }
        $datas = $manager->get($this->getCooperationName());
        $manager->executeIfMatchCondition(
            $target,
            $datas["if"],
            $datas["match"],
            $datas["else"],
            [
                "player" => $target,
                "origin" => $player
            ]
        );
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $manager = IFPlugin::getInstance()->getChainManager();
        $names = $this->parse($default);
        $cname = $default;
        $pname = "";
        if ($names === false and $default !== "") {
            $mes .= Language::get("form.error");
        } else {
            $cname = $names[0];
            $pname = $names[1];
        }
        if ($default !== "" and !$manager->exists($cname)) $mes .= Language::get("process.cooperation.notfount");
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.executeotherplayer.form.name"), Language::get("input.example", ["aieuo"]), $cname),
                Elements::getInput(Language::get("process.executeotherplayer.form.player"), Language::get("input.example", ["aiueo421"]), $pname),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "" or $datas[2] === "") {
            $status = null;
        } else {
            $names = $this->parse($datas[1].";".$datas[2]);
            if ($names === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1].";".$datas[2], "delete" => $datas[3], "cancel" => $datas[4]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;
use aieuo\ip\variable\Variable;
use aieuo\ip\utils\Language;
use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;

class GenerateRandomNumber extends Process {

    protected $id = self::GENERATE_RANDOM_NUMBER;
    protected $name = "@process.generateRandomNumber.name";
    protected $description = "@process.generateRandomNumber.description";

    public function getDetail(): string {
        $values = $this->getValues();
        if ($values === false) return false;
        return Language::get("process.generateRandomNumber.detail", [$this->getMin(), $this->getMax(), $this->getResultName()]);
    }

    public function getMin() {
        return $this->getValues()[0];
    }

    public function getMax() {
        return $this->getValues()[1];
    }

    public function getResultName() {
        return $this->getValues()[2];
    }

    public function parse(string $content) {
        $datas = explode("[max]", $content);
        $min = (int)$datas[0];
        if (!isset($datas[1])) return false;
        $datas = explode("[result]", $datas[1]);
        $max = (int)$datas[0];
        $result = empty($datas[1]) ? "result" : $datas[1];
        return [min($min, $max), max($min, $max), $result];
    }

    public function execute() {
        $player = $this->getPlayer();
        if ($this->getValues() === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $number = mt_rand($this->getMin(), $this->getMax());
        $variable = Variable::create($this->getResultName(), $number);
        IFPlugin::getInstance()->getVariableHelper()->add($variable);
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $datas = $this->parse($default);
        $datas1 = explode("[max]", $default);
        $min = $datas1[0];
        $datas2 = explode("[result]", $datas1[1] ?? $default);
        $max = $datas2[0];
        $result = $datas2[1] ?? $datas1[1] ?? $default;
        if ($datas !== false) {
            $min = $datas[0];
            $max = $datas[1];
            $result = $datas[2];
        } elseif ($default !== "") {
            $mes .= Language::get("form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.generateRandomNumber.form.min"), Language::get("input.example", ["0"]), $min),
                Elements::getInput(Language::get("process.generateRandomNumber.form.max"), Language::get("input.example", ["9"]), $max),
                Elements::getInput(Language::get("process.generateRandomNumber.form.result"), Language::get("input.example", ["result"]), $result),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $contents = $datas[1]."[max]".$datas[2]."[result]".$datas[3];
        if ($datas[1] === "" or $datas[2] === "") {
            $status = null;
        } else {
            $result = $this->parse($contents);
            if ($result === false) $status = false;
        }
        return ["status" => $status, "contents" => $contents, "delete" => $datas[4], "cancel" => $datas[5]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;
use aieuo\ip\task\KickTask;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class Kick extends Process {

    protected $id = self::KICK;
    protected $name = "@process.kick.name";
    protected $description = "@process.kick.description";

    public function getDetail(): string {
        $reason = $this->getReason();
        return Language::get("process.kick.detail", [$reason]);
    }

    public function getReason(): ?string {
        $reason = $this->getValues();
        return is_string($reason) ? $reason : null;
    }

    public function setReason(string $reason) {
        $this->setValues($reason);
    }

    public function execute() {
        $player = $this->getPlayer();
        $reason = $this->getReason();
        IFPlugin::getInstance()->getScheduler()->scheduleDelayedTask(new KickTask($player, $reason), 5);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.kick.form.reason"), Language::get("input.example", ["aieuo"]), $default),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") $status = null;
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\math\Vector3;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class Motion extends TypePosition {

    protected $id = self::MOTION;
    protected $name = "@process.motion.name";
    protected $description = "@process.motion.description";

    public function getDetail(): string {
        $pos = $this->getPosition();
        if ($pos === false) return false;
        return Language::get("process.motion.detail", [$pos->x, $pos->y, $pos->z]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $pos = $this->getPosition();
        if (!($pos instanceof Vector3)) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $player->setMotion($pos);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $pos = $this->parse($default);
        $x = $default;
        $y = "";
        $z = "";
        if ($pos instanceof Vector3) {
            $x = $pos->x;
            $y = $pos->y;
            $z = $pos->z;
        } elseif ($default !== "") {
            $mes .= Language::get("form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.motion.form.x"), Language::get("input.example", ["1"]), $x),
                Elements::getInput(Language::get("process.motion.form.y"), Language::get("input.example", ["10"]), $y),
                Elements::getInput(Language::get("process.motion.form.z"), Language::get("input.example", ["100"]), $z),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "" and $datas[2] === "" and $datas[3] === "") {
            $status = null;
        } else {
            $pos = $this->parse($datas[1].",".$datas[2].",".$datas[3]);
            if ($pos === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1].",".$datas[2].",".$datas[3], "delete" => $datas[4], "cancel" => $datas[5]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\Player;
use pocketmine\event\Event;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class Process implements ProcessIds {

    /** @var Player */
    private $player;

    /** @var array */
    private $values = [];

    /** @var Event */
    private $event = null;

    /** @var int */
    protected $id;
    /** @var string */
    protected $name;
    /** @var string */
    protected $description;
    /** @var string */
    protected $detail;

    public $replaceDatas = [];

    public function __construct($player = null) {
        $this->player = $player;
    }

    public static function get($id) {
        return ProcessFactory::get($id);
    }

    public function getId() {
        return $this->id;
    }

    public function getName() {
        if ($this->name[0] === "@") {
            return Language::get(substr($this->name, 1));
        }
        return $this->name;
    }

    public function getDescription() {
        if ($this->description[0] === "@") {
            return Language::get(substr($this->description, 1));
        }
        return $this->description;
    }

    // TODO 失敗したときfalse返すかnull返すか統一する
    public function getDetail(): string {
        if ($this->detail[0] === "@") {
            return Language::get(substr($this->detail, 1));
        }
        return $this->detail;
    }

    public function parse(string $str) {
        return $str;
    }

    public function setPlayer(Player $player) : self {
        $this->player = $player;
        return $this;
    }

    // TODO オンラインのチェック
    public function getPlayer() : Player {
        return $this->player;
    }

    public function setValues($values) : self {
        $this->values = $values;
        return $this;
    }

    public function getValues() {
        return $this->values;
    }

    public function setEvent(Event $event) {
        $this->event = $event;
    }

    public function getEvent() : ?Event {
        return $this->event;
    }

    public function getEditForm(string $default = "", string $mes = "") {
        if ($mes !== "") $mes = "\n".$mes;
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().$mes),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        return ["status" => true, "contents" => "", "delete" => $datas[1], "cancel" => $datas[2]];
    }

    public function execute() {
    }
}<?php

namespace aieuo\ip\processes;

class ProcessFactory {
    private static $list = [];

    public static function init() {
        self::register(new DoNothing());
        self::register(new SendMessage());
        self::register(new SendTip());
        self::register(new SendTitle());
        self::register(new BroadcastMessage());
        self::register(new SendMessageToOp());
        self::register(new SendVoiceMessage());
        self::register(new SendForm());
        self::register(new Command());
        self::register(new CommandConsole());
        self::register(new DelayedCommand());
        self::register(new DelayedCommandConsole());
        self::register(new AddMoney());
        self::register(new TakeMoney());
        self::register(new SetMoney());
        self::register(new Teleport());
        self::register(new Motion());
        self::register(new SetScale());
        self::register(new Calculation());
        self::register(new AddVariable());
        self::register(new DeleteVariable());
        self::register(new AddItem());
        self::register(new RemoveItem());
        self::register(new SetItem());
        self::register(new ClearInventory());
        self::register(new SetImmobile());
        self::register(new UnSetImmobile());
        self::register(new EquipArmor());
        self::register(new AddEnchantment());
        self::register(new AddEffect());
        self::register(new SetNametag());
        self::register(new SetSleeping());
        self::register(new SetSitting());
        self::register(new EventCancel());
        self::register(new SetGamemode());
        self::register(new Cooperation());
        self::register(new CooperationRepeat());
        self::register(new DelayedCooperation());
        self::register(new ExecuteOtherPlayer());
        self::register(new SetBlocks());
        self::register(new SaveDatas());
        self::register(new SetHealth());
        self::register(new SetMaxHealth());
        self::register(new Attack());
        self::register(new Kick());
        self::register(new ShowBossbar());
        self::register(new RemoveBossbar());
        self::register(new GenerateRandomNumber());
    }

    /**
     * @param  int $id
     * @return Process|null
     */
    public static function get($id): ?Process {
        if (isset(self::$list[$id])) {
            return clone self::$list[$id];
        }
        return null;
    }

    public static function getAll(): array {
        return self::$list;
    }

    /**
     * @param  Process $process
     */
    public static function register(Process $process) {
        self::$list[$process->getId()] = clone $process;
    }
}<?php

namespace aieuo\ip\processes;

interface ProcessIds {
    const COMMAND = 100;
    const SENDMESSAGE = 101;
    const SENDTIP = 102;
    const TELEPORT = 103;
    const BROADCASTMESSAGE = 104;
    const COMMAND_CONSOLE = 105;
    const DO_NOTHING = 106;
    const ADD_ITEM = 107;
    const REMOVE_ITEM = 108;
    const SET_IMMOBILE = 109;
    const UNSET_IMMOBILE = 110;
    const SET_HEALTH = 111;
    const SET_MAXHEALTH = 112;
    const SET_GAMEMODE = 113;
    const SET_NAMETAG = 114;
    const ADD_ENCHANTMENT = 115;
    const ADD_EFFECT = 116;
    const EVENT_CANCELL = 117;
    const SENDMESSAGE_TO_OP = 118;
    const SET_SLEEPING = 119;
    const SET_SITTING = 120;
    const ATTACK = 121;
    const KICK = 122;
    const SENDVOICEMESSAGE = 123;
    const SENDTITLE = 124;
    const MOTION = 125;
    const DELAYED_COMMAND = 126;
    const CALCULATION = 127;
    const ADD_VARIABLE = 128;
    const SET_SCALE = 129;
    const EVENT_CANCEL = 130;
    const SET_ITEM = 131;
    const SAVE_DATAS = 132;
    const ADDMONEY = 133;
    const TAKEMONEY = 134;
    const COOPERATION = 135;
    const DELETE_VARIABLE = 136;
    const SET_BLOCKS = 137;
    const COOPERATION_REPEAT = 138;
    const EXECUTE_OTHER_PLAYER = 139;
    const DELAYED_COMMAND_CONSOLE = 140;
    const SEND_FORM = 141;
    const SETMONEY = 142;
    const CLEAR_INVENTORY = 143;
    const EQUIP_ARMOR = 144;
    const DELAYED_COOPERATION = 144;
    const SHOW_BOSSBAR = 155;
    const REMOVE_BOSSBAR = 156;
    const GENERATE_RANDOM_NUMBER = 157;
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Bossbar;
use aieuo\ip\utils\Language;

class RemoveBossbar extends Process {

    protected $id = self::REMOVE_BOSSBAR;
    protected $name = "@process.removeBossbar.name";
    protected $description = "@process.removeBossbar.description";

    public function getDetail(): string {
        $id = $this->getBossbarId();
        return Language::get("process.removeBossbar.detail", [$id]);
    }

    public function getBossbarId(): ?string {
        $id = $this->getValues();
        if (!is_string($id)) return null;
        return $id;
    }

    public function parse(string $content) {
        return $content;
    }

    public function execute() {
        $player = $this->getPlayer();
        if ($this->getValues() === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        Bossbar::remove($player, $this->getBossbarId());
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $id = $default;
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.showBossbar.form.id"), Language::get("input.example", ["aieuo"]), $id),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") {
            $status = null;
        }
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\item\Item;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class RemoveItem extends TypeItem {

    protected $id = self::REMOVE_ITEM;
    protected $name = "@process.removeitem.name";
    protected $description = "@process.removeitem.description";

    public function getDetail(): string {
        $item = $this->getItem();
        if (!($item instanceof Item)) return false;
        return Language::get("process.removeitem.detail", [$item->getId(), $item->getDamage(), $item->getName(), $item->getCount()]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $item = $this->getItem();
        if ($item->getCount() > 0) {
            $player->getInventory()->removeItem($item);
            return;
        }
        $count = 0;
        foreach ($player->getInventory()->getContents() as $item1) {
            if ($item1->getId() == $item->getId() and $item1->getDamage() == $item->getDamage()) {
                $count += $item1->getCount();
            }
        }
        $item->setCount($count);
        if ($item->getCount() > 0) {
            $player->getInventory()->removeItem($item);
        }
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $item = $this->parse($default);
        $id = $default;
        $count = "";
        $name = "";
        if ($item instanceof Item) {
            $id = $item->getId().":".$item->getDamage();
            $count = $item->getCount();
            $name = $item->hasCustomName() ? $item->getName() : "";
            if ($count === 0) $mes .= Language::get("process.removeitem.removeall");
        } elseif ($default !== "") {
            $mes .= Language::get("process.item.form.invalid");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.item.form.id"), Language::get("input.example", ["1:0"]), $id),
                Elements::getInput(Language::get("process.removeitem.form.count"), Language::get("input.example", ["5"]), $count),
                Elements::getInput(Language::get("process.item.form.name"), Language::get("input.example", ["aieuo"]), $name),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;

class SaveDatas extends Process {

    protected $id = self::SAVE_DATAS;
    protected $name = "@process.savedatas.name";
    protected $description = "@process.savedatas.description";
    protected $detail = "@process.savedatas.detail";

    public function execute() {
        IFPlugin::getInstance()->getBlockManager()->save();
        IFPlugin::getInstance()->getCommandManager()->save();
        IFPlugin::getInstance()->getEventManager()->save();
        IFPlugin::getInstance()->getChainManager()->save();
        IFPlugin::getInstance()->getFormIFManager()->save();
        IFPlugin::getInstance()->getVariableHelper()->save();
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\Session;
use aieuo\ip\utils\Language;

class SendForm extends Process {

    protected $id = self::SEND_FORM;
    protected $name = "@process.sendform.name";
    protected $description = "@process.sendform.description";

    public function getDetail(): string {
        $name = $this->getFormName();
        return Language::get("process.sendform.detail", [$name]);
    }

    public function getFormName(): ?string {
        $name = $this->getValues();
        return is_string($name) ? $name : null;
    }

    public function setFormName(string $name) {
        $this->setValues($name);
    }

    public function execute() {
        $player = $this->getPlayer();
        $name = $this->getFormName();
        $manager = IFPlugin::getInstance()->getFormIFManager();
        if (!$manager->exists($name)) {
            $player->sendMessage(Language::get("process.sendform.notfound", [$this->getName()]));
            return;
        }
        $form = json_encode($manager->getForm($name, $this->replaceDatas));
        Session::getSession($player)->set("form_name", $name);
        Form::sendForm($player, $form, $this, "onRecive", false);
    }

    public function onRecive($player, $data) {
        $session = Session::getSession($player);
        if ($data === null) {
            $session->setValid(false, false);
            return;
        }
        $formName = $session->get("form_name");
        $manager = IFPlugin::getInstance()->getFormIFManager();
        if (!$manager->exists($formName)) {
            $player->sendMessage(Language::get("process.sendform.notfound", [$this->getName()]));
            return;
        }
        $datas = $manager->getIF($formName);
        $form = $manager->getForm($formName, $this->replaceDatas);
        foreach ($datas["ifs"] as $ifdata) {
            $manager->executeIfMatchCondition(
                $player,
                $ifdata["if"],
                $ifdata["match"],
                $ifdata["else"],
                [
                    "player" => $player,
                    "form" => $form,
                    "form_name" => $formName,
                    "form_data" => $data,
                ]
            );
        }
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.sendform.form.name"), Language::get("input.example", ["aieuo"]), $default),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") $status = null;
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\utils\Language;

class SendMessage extends TypeMessage {

    protected $id = self::SENDMESSAGE;
    protected $name = "@process.sendmessage.name";
    protected $description = "@process.sendmessage.description";

    public function getDetail(): string {
        $message = $this->getMessage();
        return Language::get("process.sendmessage.detail", [$message]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $player->sendMessage($this->getMessage());
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\Server;

use aieuo\ip\utils\Language;

class SendMessageToOp extends TypeMessage {

    protected $id = self::SENDMESSAGE_TO_OP;
    protected $name = "@process.sendmessagetoop.name";
    protected $description = "@process.sendmessagetoop.description";

    public function getDetail(): string {
        $message = $this->getMessage();
        return Language::get("process.sendmessagetoop.detail", [$message]);
    }

    public function execute() {
        $players = Server::getInstance()->getOnlinePlayers();
        foreach ($players as $player) {
            if ($player->isOp()) {
                $player->sendMessage($this->getMessage());
            }
        }
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\utils\Language;

class SendTip extends TypeMessage {

    protected $id = self::SENDTIP;
    protected $name = "@process.sendtip.name";
    protected $description = "@process.sendtip.description";

    public function getDetail(): string {
        return Language::get("process.sendtip.detail", [$this->getMessage()]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $player->sendTip($this->getMessage());
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\form\Elements;
use aieuo\ip\form\Form;
use aieuo\ip\utils\Language;

class SendTitle extends Process {

    protected $id = self::SENDTITLE;
    protected $name = "@process.sendtitle.name";
    protected $description = "@process.sendtitle.description";

    public function getDetail(): string {
        return Language::get("process.sendtitle.detail", [$this->getTitle(), $this->getSubTitle()]);
    }

    public function getTitle(): ?string {
        $message = $this->getValues()[0];
        if (!is_string($message)) return null;
        return $message;
    }

    public function getSubTitle(): ?string {
        $message = $this->getValues()[1];
        if (!is_string($message)) return null;
        return $message;
    }

    public function parse(string $content) {
        $datas = explode("[subtitle]", $content);
        $title = $datas[0];
        $subtitls = $datas[1] ?? "";
        return [$title, $subtitls];
    }

    public function execute() {
        $player = $this->getPlayer();
        $player->addTitle($this->getTitle(), $this->getSubTitle());
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $messages = $this->parse($default);
        $title = $messages[0];
        $subtitle = $messages[1];
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.sendtitle.form.title"), Language::get("input.example", ["aieuo"]), $title),
                Elements::getInput(Language::get("process.sendtitle.form.subtitle"), Language::get("input.example", ["aiueo"]), $subtitle),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "" or $datas[2] === "") {
            $status = null;
        } else {
            $names = $this->parse($datas[1]."[subtitle]".$datas[2]);
            if ($names === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1]."[subtitle]".$datas[2], "delete" => $datas[3], "cancel" => $datas[4]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\lang\TranslationContainer;

use aieuo\ip\utils\Language;

class SendVoiceMessage extends TypeMessage {

    protected $id = self::SENDVOICEMESSAGE;
    protected $name = "@process.sendvoicemessage.name";
    protected $description = "@process.sendvoicemessage.description";

    public function getDetail(): string {
        $message = $this->getMessage();
        return Language::get("process.sendvoicemessage.detail", [$message]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $text = new TranslationContainer($this->getMessage());
        $player->sendMessage($text);
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\Server;
use pocketmine\math\Vector3;
use pocketmine\level\Level;
use pocketmine\block\Block;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class SetBlocks extends TypePosition {

    protected $id = self::SET_BLOCKS;
    protected $name = "@process.setblocks.name";
    protected $description = "@process.setblocks.description";

    public function getDetail(): string {
        if ($this->getValues() === false) return false;
        $spos = $this->getStartPosition();
        $epos = $this->getEndPosition();
        $level = $this->getLevel();
        $block = $this->getBlock();
        $sx = min($spos->x, $epos->x);
        $sy = min($spos->y, $epos->y);
        $sz = min($spos->z, $epos->z);
        $ex = max($spos->x, $epos->x);
        $ey = max($spos->y, $epos->y);
        $ez = max($spos->z, $epos->z);
        return Language::get("process.setblocks.detail", [$level->getFolderName(), $sx, $sy, $sz, $ex, $ey, $ez, $block->getId(), $block->getDamage()]);
    }

    public function getStartPosition() {
        return $this->getValues()[0];
    }

    public function getEndPosition() {
        return $this->getValues()[1];
    }

    public function getLevel() {
        return $this->getValues()[2];
    }

    public function getBlock() {
        return $this->getValues()[3];
    }

    public function setSettings(Vector3 $spos, Vector3 $epos, Level $level, Block $block) {
        $this->setValues([$spos, $epos, $level, $block]);
    }

    public function parse(string $content) {
        $settings = explode(";", $content);
        if (!isset($settings[3])) return false;
        $spos = parent::parse($settings[0]);
        if (!($spos instanceof Vector3)) return false;
        $epos = parent::parse($settings[1]);
        if (!($epos instanceof Vector3)) return false;
        $level = Server::getInstance()->getLevelByName($settings[2]);
        if (!($level instanceof Level)) return false;
        $ids = explode(":", $settings[3]);
        $block = Block::get($ids[0], isset($ids[1]) ? $ids[1] : 0);
        return [$spos, $epos, $level, $block];
    }

    public function execute() {
        if ($this->getValues() === false) return false;
        $spos = $this->getStartPosition();
        $epos = $this->getEndPosition();
        $level = $this->getLevel();
        $block = $this->getBlock();
        $sx = min($spos->x, $epos->x);
        $sy = min($spos->y, $epos->y);
        $sz = min($spos->z, $epos->z);
        $ex = max($spos->x, $epos->x);
        $ey = max($spos->y, $epos->y);
        $ez = max($spos->z, $epos->z);
        for ($x = $sx; $x <= $ex; $x ++) {
            for ($y = $sy; $y <= $ey; $y ++) {
                for ($z = $sz; $z <= $ez; $z ++) {
                    $level->setBlock(new Vector3($x, $y, $z), $block);
                }
            }
        }
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $settings = $this->parse($default);
        $spos_str = $default;
        $epos_str = "";
        $level_str = "";
        $id = "";
        if ($settings !== false) {
            $spos = $settings[0];
            $spos_str = $spos->x.",".$spos->y.",".$spos->z;
            $epos = $settings[1];
            $epos_str = $epos->x.",".$epos->y.",".$epos->z;
            $level = $settings[2];
            $level_str = $level->getFolderName();
            $block = $settings[3];
            $id = $block->getId().":".$block->getDamage();
        } elseif ($default !== "") {
            $mes .= Language::get("form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.setblocks.form.spos"), Language::get("input.example", ["0,0,0"]), $spos_str),
                Elements::getInput(Language::get("process.setblocks.form.epos"), Language::get("input.example", ["5,10,5"]), $epos_str),
                Elements::getInput(Language::get("process.setblocks.form.level"), Language::get("input.example", ["world"]), $level_str),
                Elements::getInput(Language::get("process.setblocks.form.id"), Language::get("input.example", ["1:0"]), $id),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "" or $datas[2] === "" or $datas[3] === "" or $datas[4] === "") {
            $status = null;
        } else {
            $settings = $this->parse($datas[1].";".$datas[2].";".$datas[3].";".$datas[4]);
            if ($settings === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1].";".$datas[2].";".$datas[3].";".$datas[4], "delete" => $datas[5], "cancel" => $datas[6]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\Server;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class SetGamemode extends Process {

    protected $id = self::SET_GAMEMODE;
    protected $name = "@process.gamemode.name";
    protected $description = "@process.gamemode.description";

    private $gamemodes = [
        "process.gamemode.survival",
        "process.gamemode.creative",
        "process.gamemode.adventure",
        "process.gamemode.spectator"
    ];

    public function getGamemode(): ?int {
        $gamemode = $this->getValues();
        if (!(is_int($gamemode) and $gamemode >= 0 and $gamemode <= 3)) return null;
        return $gamemode;
    }

    public function setGamemode(int $gamemode) {
        $this->setValues($gamemode);
    }

    public function parse(string $content) {
        $gamemode = Server::getInstance()->getGamemodeFromString($content);
        if ($gamemode === -1) return false;
        return $gamemode;
    }

    public function getDetail(): string {
        $gamemode = $this->getGamemode();
        if ($gamemode === false) return false;
        return Language::get("process.gamemode.detail", [Language::get($this->gamemodes[$gamemode])]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $gamemode = $this->getGamemode();
        if ($gamemode === false) {
            $player->sendMessage(Language::get("process.gamemode.notfound"));
            return;
        }
        $player->setGamemode($gamemode);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $gamemode = $this->parse($default);
        if ($gamemode === false) {
            if ($default !== "") $mes .= Language::get("process.gamemode.notfound");
            $gamemode = 0;
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getDropdown(
                    Language::get("process.gamemode.form.gamemode"),
                    array_map(function ($g) {
                        return Language::get($g);
                    }, $this->gamemodes),
                    $gamemode
                ),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") {
            $status = null;
        } else {
            $gamemode = $this->parse($datas[1]);
            if ($gamemode === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class SetHealth extends Process {

    protected $id = self::SET_HEALTH;
    protected $name = "@process.sethealth.name";
    protected $description = "@process.sethealth.description";

    public function getDetail(): string {
        $health = $this->getHealth();
        if ($health === false) return false;
        return Language::get("process.sethealth.detail", [$health]);
    }

    public function getHealth(): ?int {
        $health = $this->getValues();
        if (!is_int($health) or $health <= 0) return null;
        return $health;
    }

    public function setHealth(int $health) {
        $this->setValues($health);
    }

    public function parse(string $content) {
        $health = (int)$content;
        if ($health <= 0) return false;
        return $health;
    }

    public function execute() {
        $player = $this->getPlayer();
        $health = $this->gethealth();
        if ($health === false) {
            $player->sendMessage(Language::get("process.sethealth.zero", [$this->getName()]));
            return;
        }
        $player->setHealth($health);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $health = $this->parse($default);
        if ($health === false) {
            if ($default !== "") $mes = Language::get("process.sethealth.form.zero");
            $health = $default;
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.sethealth.form.health"), Language::get("input.example", ["10"]), $health),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") {
            $status = null;
        } else {
            $health = $this->parse($datas[1]);
            if ($health === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

class SetImmobile extends Process {

    protected $id = self::SET_IMMOBILE;
    protected $name = "@process.immobile.name";
    protected $description = "@process.immobile.description";
    protected $detail = "@process.immobile.detail";

    public function execute() {
        $player = $this->getPlayer();
        $player->setImmobile();
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\item\Item;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class SetItem extends Process {

    protected $id = self::SET_ITEM;
    protected $name = "@process.setitem.name";
    protected $description = "@process.setitem.description";

    public function getDetail(): string {
        if ($this->getValues()) return false;
        $item = $this->getItem();
        if (!($item instanceof Item)) return false;
        $index = $this->getIndex();
        return Language::get("process.setitem.detail", [$index, $item->getId(), $item->getDamage(), $item->getName(), $item->getCount()]);
    }

    public function getIndex() {
        return $this->getValues()[0];
    }

    public function getItem() {
        return $this->getValues()[1];
    }

    public function setItems(int $index, Item $item) {
        $this->setValues([$index, $item]);
    }

    public function parse(string $id) {
        if (!preg_match("/\s*([0-9]+)\s*,\s*([0-9]+)\s*:?\s*([0-9]*)\s*:?\s*([0-9]*)\s*:?\s*(\.*)\s*/", $id, $ids)) return false;
        $item = Item::get((int)$ids[2], empty($ids[3]) ? 0 : (int)$ids[3], empty($ids[4]) ? 0 : (int)$ids[4]);
        if (!empty($ids[5])) $item->setCustomName($ids[5]);
        return [(int)$ids[1], $item];
    }

    public function execute() {
        $player = $this->getPlayer();
        if ($this->getValues() === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $item = $this->getItem();
        $index = $this->getIndex();
        $player->getInventory()->setItem($index, $item);
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $items = $this->parse($default);
        $id = $default;
        $count = "";
        $name = "";
        $index = "";
        if ($items === false and $default !== "") {
            $mes .= Language::get("process.item.form.invalid");
        } elseif ($items[1] instanceof Item) {
            $item = $items[1];
            $id = $item->getId().":".$item->getDamage();
            $count = $item->getCount();
            $name = $item->hasCustomName() ? $item->getName() : "";
            if ($count === 0) $mes .= Language::get("process.item.form.zero");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.item.form.id"), Language::get("input.example", ["1:0"]), $id),
                Elements::getInput(Language::get("process.item.form.count"), Language::get("input.example", ["5"]), $count),
                Elements::getInput(Language::get("process.item.form.name"), Language::get("input.example", ["aieuo"]), $name),
                Elements::getInput(Language::get("process.setitem.form.index"), Language::get("input.example", ["0"]), $index),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $id = explode(":", $datas[1]);
        if (!isset($id[1])) $id[1] = 0;
        $ids_str = $datas[4].",".$id[0].":".$id[1].":".$datas[2].($datas[3] !== "" ? ":".$datas[3] : "");
        if ($datas[1] === "" or $datas[2] === "" or $datas[4] === "") {
            $status = null;
        } else {
            $ids = $this->parse($ids_str);
            if ($ids === false) $status = false;
        }
        return ["status" => $status, "contents" => $ids_str, "delete" => $datas[5], "cancel" => $datas[6]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\utils\Language;

class SetMaxHealth extends SetHealth {

    protected $id = self::SET_MAXHEALTH;
    protected $name = "@process.setmaxhealth.name";
    protected $description = "@process.setmaxhealth.description";

    public function getDetail(): string {
        $health = $this->getHealth();
        if ($health === false) return false;
        return Language::get("process.setmaxhealth.detail", [$health]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $health = $this->getHealth();
        if ($health === false) {
            $player->sendMessage(Language::get("process.setmaxhealth.zero", [$this->getName()]));
            return;
        }
        $player->setMaxHealth($health);
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\utils\Language;
use aieuo\ip\IFPlugin;

class SetMoney extends TypeMoney {

    protected $id = self::SETMONEY;
    protected $name = "@process.setmoney.name";
    protected $description = "@process.setmoney.description";

    public function getDetail(): string {
        return Language::get("process.setmoney.detail", [$this->getAmount()]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $economy = IFPlugin::getInstance()->getEconomy();
        if ($economy === null) {
            $player->sendMessage(Language::get("economy.notfound"));
            return;
        }
        $economy->setMoney($player->getName(), $this->getAmount());
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class SetNametag extends Process {

    protected $id = self::SET_NAMETAG;
    protected $name = "@process.setnametag.name";
    protected $description = "@process.setnametag.description";

    public function getDetail(): string {
        return Language::get("process.setnametag.detail", [$this->getChangeName()]);
    }

    public function getChangeName(): ?string {
        $name = $this->getValues();
        if (!is_string($name)) return null;
        return $name;
    }

    public function setChangeName(string $name) {
        $this->setValues($name);
    }

    public function execute() {
        $player = $this->getPlayer();
        $name = $this->getChangeName();
        $player->setNametag($name);
        $player->setDisplayName($name);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.setnametag.form.name"), Language::get("input.example", ["aieuo"]), $default),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") $status = null;
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class SetScale extends Process {

    protected $id = self::SET_SCALE;
    protected $name = "@process.setscale.name";
    protected $description = "@process.setscale.description";

    public function getDetail(): string {
        $scale = $this->getScale();
        if ($scale === false) return false;
        return Language::get("process.setscale.detail", [$this->getName()]);
    }

    public function getScale(): ?float {
        $scale = $this->getValues();
        if (!is_numeric($scale)) return null;
        return (float)$scale;
    }

    public function setScale(float $scale) {
        $this->setValues($scale);
    }

    public function parse(string $content) {
        $scale = (float)$content;
        if ($scale <= 0) return false;
        return $scale;
    }

    public function execute() {
        $player = $this->getPlayer();
        $scale = $this->getScale();
        if ($scale === null) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $player->setScale($scale);
    }


    public function getEditForm(string $default = "", string $mes = "") {
        $scale = $this->parse($default);
        if ($scale === false and $default !== "") {
            $scale = $default;
            $mes .= Language::get("process.setscale.form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.setscale.form.scale"), Language::get("input.example", ["2"]), $scale),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") {
            $status = null;
        } else {
            $scale = $this->parse($datas[1]);
            if ($scale === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\Player;
use pocketmine\entity\Entity;
use pocketmine\level\Position;
use pocketmine\network\mcpe\protocol\AddActorPacket;
use pocketmine\network\mcpe\protocol\types\EntityLink;
use pocketmine\network\mcpe\protocol\RemoveActorPacket;

use aieuo\ip\utils\Language;

class SetSitting extends TypePosition {

    protected $id = self::SET_SITTING;
    protected $name = "@process.setsitting.name";
    protected $description = "@process.setsitting.description";

    private static $entityIds = [];

    public function getDetail(): string {
        $pos = $this->getPosition();
        if ($pos === false) return false;
        return Language::get("process.setsitting.detail", [$pos->x.",".$pos->y.",".$pos->z.",".$pos->level->getFolderName()]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $pos = $this->getPosition();
        if (!($pos instanceof Position)) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $pk = new AddActorPacket();
        $pk->entityRuntimeId = ++Entity::$entityCount;
        $pk->type = 84;
        $pk->position = $pos;
        $pk->links = [new EntityLink($pk->entityRuntimeId, $player->getId(), EntityLink::TYPE_RIDER)];
        $pk->metadata = [
            Entity::DATA_FLAGS => [Entity::DATA_TYPE_LONG, 1 << Entity::DATA_FLAG_INVISIBLE]
        ];
        $player->dataPacket($pk);
        self::leave($player);
        self::$entityIds[$player->getName()] = $pk->entityRuntimeId;
    }

    public static function leave(Player $player) {
        if (isset(self::$entityIds[$player->getName()])) {
            $pk = new RemoveActorPacket();
            $pk->entityUniqueId = self::$entityIds[$player->getName()];
            if ($player->isOnline()) $player->dataPacket($pk);
            unset(self::$entityIds[$player->getName()]);
        }
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\level\Position;

use aieuo\ip\utils\Language;

class SetSleeping extends TypePosition {

    protected $id = self::SET_SLEEPING;
    protected $name = "@process.setsleeping.name";
    protected $description = "@process.setsleeping.description";

    public function getDetail(): string {
        $pos = $this->getPosition();
        if ($pos === false) return false;
        return Language::get("process.setsleeping.description", [$pos->x.",".$pos->y.",".$pos->z.",".$pos->level->getFolderName()]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $pos = $this->getPosition();
        if (!($pos instanceof Position)) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $player->sleepOn($pos);
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Bossbar;
use aieuo\ip\utils\Language;

class ShowBossbar extends Process {

    protected $id = self::SHOW_BOSSBAR;
    protected $name = "@process.showBossbar.name";
    protected $description = "@process.showBossbar.description";

    public function getDetail(): string {
        $title = $this->getTitle();
        $max = $this->getMaxValue();
        $current = $this->getCurrentValue();
        return Language::get("process.showBossbar.detail", [$title, $max, $current]);
    }

    public function getTitle(): ?string {
        return $this->getValues()[0] ?? null;
    }

    public function getMaxValue(): ?float {
        return $this->getValues()[1] ?? null;
    }

    public function getCurrentValue(): ?float {
        return $this->getValues()[2] ?? null;
    }

    public function getBossbarId(): ?string {
        return $this->getValues()[3] ?? null;
    }

    public function parse(string $content) {
        $titles = explode("[max]", $content);
        if (!isset($titles[1])) return false;
        $title = $titles[0];
        $values = explode("[value]", $titles[1]);
        if (!isset($values[1])) return false;
        $max = $values[0];
        $ids = explode("[id]", $values[1]);
        if (!isset($ids[1])) return false;
        $value = $ids[0];
        $id = $ids[1];
        return [$title, (float)$max, (float)$value, $id];
    }

    public function execute() {
        $player = $this->getPlayer();
        if ($this->getValues() === false) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        Bossbar::add($player, $this->getBossbarId(), $this->getTitle(), $this->getMaxValue(), $this->getCurrentValue()/$this->getMaxValue());
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $settings = $this->parse($default);
        $titles = explode("[max]", $default);
        $title = $titles[0];
        $values = explode("[value]", $titles[1] ?? $default);
        $max = $values[0];
        $ids = explode("[id]", $values[1] ?? $titles[1] ?? $default);
        $value = $ids[0];
        $id = $ids[1] ?? $values[1] ?? $titles[1] ?? $default;
        if ($settings !== false) {
            $title = $settings[0];
            $max = $settings[1];
            $value = $settings[2];
            $id = $settings[3];
        } elseif ($default !== "") {
            $mes .= Language::get("form.error");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.showBossbar.form.title"), Language::get("input.example", ["aieuo"]), $title),
                Elements::getInput(Language::get("process.showBossbar.form.max"), Language::get("input.example", ["100"]), $max),
                Elements::getInput(Language::get("process.showBossbar.form.value"), Language::get("input.example", ["1"]), $value),
                Elements::getInput(Language::get("process.showBossbar.form.id"), Language::get("input.example", ["aieuo"]), $id),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $contents = $datas[1]."[max]".$datas[2]."[value]".$datas[3]."[id]".$datas[4];
        if ($datas[1] === "" or $datas[2] === "" or $datas[3] === "" or $datas[3] === "") {
            $status = null;
        } else {
            $result = $this->parse($contents);
            if ($result === false) $status = false;
        }
        return ["status" => $status, "contents" => $contents, "delete" => $datas[5], "cancel" => $datas[6]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\IFPlugin;
use aieuo\ip\utils\Language;

class TakeMoney extends TypeMoney {

    protected $id = self::TAKEMONEY;
    protected $name = "@process.takemoney.name";
    protected $description = "@process.takemoney.description";

    public function getDetail(): string {
        return Language::get("process.takemoney.detail", [$this->getAmount()]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $economy = IFPlugin::getInstance()->getEconomy();
        if ($economy === null) {
            $player->sendMessage(Language::get("economy.notfound"));
            return;
        }
        $economy->takeMoney($player->getName(), $this->getAmount());
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\level\Position;

use aieuo\ip\utils\Language;

class Teleport extends TypePosition {

    protected $id = self::TELEPORT;
    protected $name = "@process.teleport.name";
    protected $description = "@process.teleport.description";

    public function getDetail(): string {
        $pos = $this->getPosition();
        if ($pos === false or $pos->level === null) return false;
        return Language::get("process.teleport.detail", [$pos->x.",".$pos->y.",".$pos->z.",".$pos->level->getFolderName()]);
    }

    public function execute() {
        $player = $this->getPlayer();
        $pos = $this->getPosition();
        if (!($pos instanceof Position)) {
            $player->sendMessage(Language::get("input.invalid", [$this->getName()]));
            return;
        }
        $player->teleport($pos);
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class TypeCommand extends Process {

    public function getCommand(): ?string {
        $command = $this->getValues();
        if (!is_string($command)) return null;
        return $command;
    }

    public function setCommand(string $command) {
        $this->setValues($command);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.command.form.command"), Language::get("input.example", ["help"]), $default),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") {
            $status = null;
        } else {
            $command = $this->parse($datas[1]);
            if ($command === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

use pocketmine\item\Item;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class TypeItem extends Process {

    public function getItem(): ?Item {
        $item = $this->getValues();
        if (!($item instanceof Item)) return null;
        return $item;
    }

    public function setItem(Item $item) {
        $this->setValues($item);
    }

    public function parse(string $id) {
        if (!preg_match("/\s*([0-9]+)\s*:?\s*([0-9]*)\s*:?\s*([0-9]*)\s*:?\s*(.*)\s*/", $id, $ids)) return false;
        $item = Item::get((int)$ids[1], empty($ids[2]) ? 0 : (int)$ids[2], empty($ids[3]) ? 0 : (int)$ids[3]);
        if (!empty($ids[4])) $item->setCustomName($ids[4]);
        return $item;
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $item = $this->parse($default);
        $id = $default;
        $count = "";
        $name = "";
        if ($item instanceof Item) {
            $id = $item->getId().":".$item->getDamage();
            $count = $item->getCount();
            $name = $item->hasCustomName() ? $item->getName() : "";
            if ($count === 0) $mes .= Language::get("process.item.form.zero");
        } elseif ($default !== "") {
            $mes .= Language::get("process.item.form.invalid");
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.item.form.id"), Language::get("input.example", ["1:0"]), $id),
                Elements::getInput(Language::get("process.item.form.count"), Language::get("input.example", ["5"]), $count),
                Elements::getInput(Language::get("process.item.form.name"), Language::get("input.example", ["aieuo"]), $name),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        $id = explode(":", $datas[1]);
        if (!isset($id[1])) $id[1] = 0;
        $ids_str = $id[0].":".$id[1].":".$datas[2].":".$datas[3];
        if ($datas[1] === "" or $datas[2] === "") {
            $status = null;
        } else {
            $ids = $this->parse($ids_str);
            if ($ids === false) $status = false;
        }
        return ["status" => $status, "contents" => $ids_str, "delete" => $datas[4], "cancel" => $datas[5]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class TypeMessage extends Process {

    public function getMessage(): ?string {
        $message = $this->getValues();
        if (!is_string($message)) return null;
        return $message;
    }

    public function setMessage(string $message) {
        $this->setValues($message);
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.message.form.message"), Language::get("input.example", ["aieuo"]), $default),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") $status = null;
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class TypeMoney extends Process {

    public function getAmount(): ?int {
        $amount = $this->getValues();
        if (!is_int($amount)) return null;
        return $amount;
    }

    public function setAmount(int $amount) {
        $this->setValues($amount);
    }

    public function parse(string $amount) {
        $amount = (int)mb_convert_kana($amount, "n");
        return $amount;
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $money = $this->parse($default);
        if ($money <= 0) $money = $default;
        if ($money <= 0 and $default !== "") $mes .= Language::get("process.money.zero");
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)."\n"),
                Elements::getInput(Language::get("process.money.form.amount"), Language::get("input.example", ["1000"]), $money),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") $status = null;
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}
<?php

namespace aieuo\ip\processes;

use pocketmine\Server;
use pocketmine\level\Position;

use aieuo\ip\form\Form;
use aieuo\ip\form\Elements;
use aieuo\ip\utils\Language;

class TypePosition extends Process {

    public function getPosition() {
        return $this->getValues();
    }

    public function setPosition(string $pos) {
        $this->setValues($pos);
    }

    public function parse(string $pos) {
        if (!preg_match("/\s*(-?[0-9]+\.?[0-9]*)\s*,\s*(-?[0-9]+\.?[0-9]*)\s*,\s*(-?[0-9]+\.?[0-9]*)\s*,?\s*(.*)\s*/", $pos, $matches)) return false;
        if (empty($matches[4])) $matches[4] = "world";
        return new Position((float)$matches[1], (float)$matches[2], (float)$matches[3], Server::getInstance()->getLevelByName($matches[4]));
    }

    public function getEditForm(string $default = "", string $mes = "") {
        $pos = $this->parse($default);
        if ($pos instanceof Position) {
            if ($pos->level === null) {
                $mes .= Language::get("process.position.level.notfound");
                $position = $default;
            } else {
                $position = $pos->x.",".$pos->y.",".$pos->z.",".$pos->level->getFolderName();
            }
        } else {
            if ($default !== "") $mes .= Language::get("form.error");
            $position = $default;
        }
        $data = [
            "type" => "custom_form",
            "title" => $this->getName(),
            "content" => [
                Elements::getLabel($this->getDescription().(empty($mes) ? "" : "\n".$mes)),
                Elements::getInput(Language::get("process.position.form.position"), Language::get("input.example", ["1,15,30,world"]), $position),
                Elements::getToggle(Language::get("form.delete")),
                Elements::getToggle(Language::get("form.cancel"))
            ]
        ];
        $json = Form::encodeJson($data);
        return $json;
    }

    public function parseFormData(array $datas) {
        $status = true;
        if ($datas[1] === "") {
            $status = null;
        } else {
            $pos = $this->parse($datas[1]);
            if ($pos === false) $status = false;
        }
        return ["status" => $status, "contents" => $datas[1], "delete" => $datas[2], "cancel" => $datas[3]];
    }
}<?php

namespace aieuo\ip\processes;

class UnSetImmobile extends Process {

    protected $id = self::UNSET_IMMOBILE;
    protected $name = "@process.mobile.name";
    protected $description = "@process.mobile.description";
    protected $detail = "@process.mobile.detail";

    public function execute() {
        $player = $this->getPlayer();
        $player->setImmobile(false);
    }
}<?php

namespace aieuo\ip;

use pocketmine\Player;

class Session {

    const BLOCK = 0;
    const COMMAND = 1;
    const EVENT = 2;
    const CHAIN = 3;
    const FORM = 4;

    private static $sessions = [];

    /**
     * @param  Player $player
     * @return Session|null
     */
    public static function getSession(Player $player): ?Session {
        if (!isset(self::$sessions[$player->getName()])) return null;
        return self::$sessions[$player->getName()];
    }

    public static function createSession(Player $player) {
        self::$sessions[$player->getName()] = new Session();
    }

////////////////////////////////////////////////////////////////////////

    /** @var bool */
    private $valid = false;
    private $if_type = null;
    /** @var array */
    private $datas = [];

    public function isValid(): bool {
        return $this->valid;
    }

    public function setValid($valid = true, $deleteDatas = true): self {
        $this->valid = $valid;
        if (!$valid and $deleteDatas) $this->removeAll();
        return $this;
    }

    public function get($key, $default = null) {
        if (!isset($this->datas[$key])) return $default;
        return $this->datas[$key];
    }

    public function set($key, $data): self {
        $this->datas[$key] = $data;
        return $this;
    }

    public function remove($key) {
        unset($this->datas[$key]);
    }

    public function removeAll() {
        $this->datas = [];
    }
}<?php
namespace aieuo\ip\task;

use pocketmine\scheduler\Task;
use pocketmine\command\CommandSender;
use pocketmine\Server;

class DelayedCommandTask extends Task {
    public function __construct(CommandSender $player, string $command) {
        $this->player = $player;
        $this->command = $command;
    }

    public function onRun(int $currentTick) {
        Server::getInstance()->dispatchCommand($this->player, $this->command);
    }
}<?php
namespace aieuo\ip\task;

use pocketmine\scheduler\Task;
use pocketmine\event\Event;
use pocketmine\Player;
use aieuo\ip\utils\Language;
use aieuo\ip\IFPlugin;

class DelayedCooperationTask extends Task {
    public function __construct(Player $player, string $name, ?Event $event, ?array $replaces) {
        $this->player = $player;
        $this->name = $name;
        $this->event = $event;
        $this->replaceDatas = $replaces;
    }

    public function onRun(int $currentTick) {
        $manager = IFPlugin::getInstance()->getChainManager();
        if (!$manager->exists($this->name)) {
            $this->player->sendMessage(Language::get("process.cooperation.notfount"));
            return;
        }
        $datas = $manager->get($this->name);
        $options = [
            "player" => $this->player,
        ];
        if ($this->event instanceof Event) $options["event"] = $this->event;
        $options["replaces"] = $this->replaceDatas;
        $manager->executeIfMatchCondition(
            $this->player,
            $datas["if"],
            $datas["match"],
            $datas["else"],
            $options
        );
    }
}<?php
namespace aieuo\ip\task;

use pocketmine\scheduler\Task;
use pocketmine\Player;

class KickTask extends Task {
    public function __construct(Player $player, string $reason) {
        $this->player = $player;
        $this->reason = $reason;
    }

    public function onRun(int $currentTick) {
        $this->player->kick($this->reason);
    }
}<?php
namespace aieuo\ip\task;

use pocketmine\scheduler\Task;

class SaveTask extends Task {
    public function __construct($owner) {
        $this->owner = $owner;
    }

    public function onRun(int $currentTick) {
        $this->owner->getBlockManager()->save();
        $this->owner->getCommandManager()->save();
        $this->owner->getEventManager()->save();
        $this->owner->getChainManager()->save();
        $this->owner->getVariableHelper()->save();
    }
}<?php

namespace aieuo\ip\utils;

use pocketmine\entity\Attribute;
use pocketmine\entity\Entity;
use pocketmine\entity\EntityIds;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\AddActorPacket;
use pocketmine\network\mcpe\protocol\BossEventPacket;
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
use pocketmine\network\mcpe\protocol\SetActorDataPacket;
use pocketmine\Player;

class Bossbar {
    /** @var array */
    public static $bars = [];

    /** @var float */
    private $max = 1;
    /** @var float */
    private $per = 1;
    /** @var string */
    private $title = "";
    /** @var int */
    private $entityId;

    public function __construct(string $title, float $max = 1, float $per = 1) {
        $this->title = $title;
        $this->max = $max;
        $this->per = $per;
        $this->entityId = Entity::$entityCount++;
    }

    public function setTitle(string $title) {
        $this->title = $title;
    }

    public function getTitle(): string {
        return $this->title;
    }

    public function setMax(float $max) {
        $this->max = $max;
    }

    public function getMax(): float {
        return $this->max;
    }

    public function setPercentage(float $per) {
        if ($per > $this->max) $per = $this->max;
        $this->per = $per;
    }

    public function getPercentage(): float {
        return $this->per;
    }

    public function getEntityId(): int {
        return $this->entityId;
    }

    public static function add(Player $player, string $id, string $title, float $max, float $per) {
        if (isset(self::$bars[$player->getName()][$id])) self::remove($player, $id);
        $bar = new Bossbar($title, $max, $per);
        self::$bars[$player->getName()][$id] = $bar;

        $pk = new AddActorPacket();
        $pk->entityRuntimeId = $bar->getEntityId();
        $pk->type = EntityIds::SHULKER;
        $pk->metadata = [
            Entity::DATA_FLAGS => [Entity::DATA_TYPE_LONG, (1 << Entity::DATA_FLAG_INVISIBLE) | (1 << Entity::DATA_FLAG_IMMOBILE)],
            Entity::DATA_NAMETAG => [Entity::DATA_TYPE_STRING, $title]
        ];
        $pk->position = new Vector3(0, 0, 0);
        $player->sendDataPacket($pk);

        $pk2 = new BossEventPacket();
        $pk2->bossEid = $bar->getEntityId();
        $pk2->eventType = BossEventPacket::TYPE_SHOW;
        $pk2->title = $title;
        $pk2->healthPercent = $per;
        $pk2->color = 0;
        $pk2->overlay = 0;
        $pk2->unknownShort = 0;
        $player->sendDataPacket($pk2);
    }

    public static function remove(Player $player, string $id) {
        if (!isset(self::$bars[$player->getName()][$id])) return;
        $bar = self::$bars[$player->getName()][$id];
        $pk = new BossEventPacket();
        $pk->bossEid = $bar->getEntityId();
        $pk->eventType = BossEventPacket::TYPE_HIDE;
        $player->sendDataPacket($pk);

        $pk2 = new RemoveActorPacket();
        $pk2->entityUniqueId = $bar->getEntityId();
        $player->sendDataPacket($pk2);

        unset(self::$bars[$player->getName()][$id]);
    }
}<?php

namespace aieuo\ip\utils;

class Language {

    public static $messages = [];

    public function __construct($messages) {
        $this->setMessages($messages);
    }

    public function setMessages($messages) {
        self::$messages = $messages;
    }

    public static function get(string $key, array $replaces = []): string {
        if (isset(self::$messages[$key])) {
            $message = self::$messages[$key];
            foreach ($replaces as $cnt => $value) {
                $message = str_replace("{%".$cnt."}", $value, $message);
            }
            $message = str_replace(["\\n", "\\q", "\\dq"], ["\n", "'", "\""], $message);
            return $message;
        }
        return $key;
    }
}<?php

namespace aieuo\ip\variable;

use aieuo\ip\utils\Language;

class ListVariable extends Variable {

    public $type = Variable::LIST;

    public function getString() {
        return implode(", ", $this->getValue());
    }

    public function addition(Variable $var, string $name = "result") {
        if ($var->getType() !== Variable::LIST) {
            return new StringVariable("ERROR", Language::get("variable.list.add.error"));
        }
        $result = array_merge($this->getValue(), $var->getValue());
        return new ListVariable($name, $result);
    }

    public function subtraction(Variable $var, string $name = "result") {
        if ($var->getType() !== Variable::LIST) {
            return new StringVariable("ERROR", Language::get("variable.list.sub.error"));
        }
        $result = array_diff($this->getValue(), $var->getValue());
        $result = array_values($result);
        return new ListVariable($name, $result);
    }

    public function multiplication(Variable $var, string $name = "result") {
        if ($var->getType() !== Variable::NUMBER) {
            return new StringVariable("ERROR", Language::get("variable.list.mul.error"));
        }
        $result = [];
        $max = (int)$var->getValue();
        for ($i=0; $i<$max; $i ++) {
            $result = array_merge($result, $this->getValue());
        }
        return new ListVariable($name, $result);
    }

    public function division(Variable $var, string $name = "result") {
        return new StringVariable("ERROR", Language::get("variable.list.div.error"));
    }

    public function modulo(Variable $var, string $name = "result") {
        return new StringVariable("ERROR", Language::get("variable.list.mod.error"));
    }

    public function getValueFromIndex($index) {
        if (!isset($this->value[$index])) return null;
        return $this->value[$index];
    }

    public function getCount() {
        return count($this->value);
    }

    public function toStringVariable() {
        $variable = new StringVariable($this->getName(), "(list)".implode(",", $this->getValue()));
        return $variable;
    }
}<?php

namespace aieuo\ip\variable;

use aieuo\ip\utils\Language;

class NumberVariable extends Variable {

    public $type = Variable::NUMBER;

    public function getString(): string {
        return (string)$this->getValue();
    }

    public function addition(Variable $var, string $resultname = "result"): Variable {
        if ($var->getType() !== Variable::NUMBER) {
            return new StringVariable("ERROR", Language::get("variable.number.add.error"));
        }
        $result = $this->getValue() + $var->getValue();
        return new NumberVariable($resultname, $result);
    }

    public function subtraction(Variable $var, string $resultname = "result"): Variable {
        if ($var->getType() !== Variable::NUMBER) {
            return new StringVariable("ERROR", Language::get("variable.number.sub.error"));
        }
        $result = $this->getValue() - $var->getValue();
        return new NumberVariable($resultname, $result);
    }

    public function multiplication(Variable $var, string $resultname = "result"): Variable {
        if ($var->getType() !== Variable::NUMBER) {
            return new StringVariable("ERROR", Language::get("variable.number.mul.error"));
        }
        $result = $this->getValue() * $var->getValue();
        return new NumberVariable($resultname, $result);
    }

    public function division(Variable $var, string $resultname = "result"): Variable {
        if ($var->getType() !== Variable::NUMBER) {
            return new StringVariable("ERROR", Language::get("variable.number.div.error"));
        }
        if ($var->getValue() === 0) {
            return new StringVariable("ERROR", Language::get("variable.number.div.0"));
        }
        $result = $this->getValue() / $var->getValue();
        return new NumberVariable($resultname, $result);
    }

    public function modulo(Variable $var, string $resultname = "result"): Variable {
        if ($var->getType() !== Variable::NUMBER) {
            return new StringVariable("ERROR", Language::get("variable.number.mod.error"));
        }
        if ($var->getValue() === 0) {
            return new StringVariable("ERROR", Language::get("variable.number.div.0"));
        }
        $result = $this->getValue() % $var->getValue();
        return new NumberVariable($resultname, $result);
    }

    public function toStringVariable(): Variable {
        $variable = new StringVariable($this->getName(), (string)$this->getValue());
        return $variable;
    }
}<?php

namespace aieuo\ip\variable;

use aieuo\ip\utils\Language;

class StringVariable extends Variable {

    public $type = Variable::STRING;

    public function getString() {
        return $this->getValue();
    }

    public function addition(Variable $var, string $name = "result"): Variable {
        $result = $this->getValue().$var->getValue();
        return new StringVariable($name, $result);
    }

    public function subtraction(Variable $var, string $name = "result"): Variable {
        $result = str_replace((string)$var->getValue(), "", $this->getValue());
        return new StringVariable($name, $result);
    }

    public function multiplication(Variable $var, string $name = "result"): Variable {
        if ($var->getType() !== Variable::NUMBER) {
            return new StringVariable("ERROR", Language::get("variable.string.mul.error"));
        }
        if ($var->getValue() <= 0) {
            return new StringVariable("ERROR", Language::get("variable.string.mul.0"));
        }
        $result = str_repeat($this->getValue(), (int)$var->getValue());
        return new StringVariable($name, $result);
    }

    public function division(Variable $var, string $name = "result"): Variable {
        if ($var->getType() !== Variable::STRING) {
            return new StringVariable("ERROR", Language::get("variable.string.div.error"));
        }
        $result = array_map(function ($value) {
            return trim(rtrim($value));
        }, explode((string)$var->getValue(), (string)$this->getValue()));
        return new ListVariable($name, $result);
    }

    public function modulo(Variable $var, string $name = "result"): Variable {
        return new StringVariable("ERROR", Language::get("variable.string.mod.error"));
    }
}<?php
namespace aieuo\ip\variable;

abstract class Variable {
    const STRING = 0;
    const NUMBER = 1;
    const LIST = 2;
    const MAP = 3;

    /** @var string 変数の名前 */
    protected $name;
    /** @var string 変数の値 */
    protected $value;
    /** @var int 変数の型 */
    public $type;

    public static function create($name, $value, $type = self::STRING) {
        if ($type === self::STRING) {
            $var = new StringVariable($name, $value);
        } elseif ($type === self::NUMBER) {
            $var = new NumberVariable($name, $value);
        } elseif ($type === self::LIST) {
            if (is_array($value)) {
                $var = new ListVariable($name, $value);
            } else {
                $var = (new StringVariable("string", $value))->division(new StringVariable("delimiter", ","), $name);
            }
        }
        return $var;
    }

    public function __construct($name, $value) {
        $this->name = $name;
        $this->value = $value;
    }

    public function getName() {
        return $this->name;
    }

    /**
     * @return string|int|array
     */
    public function getValue() {
        return $this->value;
    }

    public function getType() {
        return $this->type;
    }

    /**
     * 変数同士を足す
     * @param Variable $var
     * @param string   $name
     */
    abstract public function addition(Variable $var, string $name = "result");

    /**
     * 変数同士を引く
     * @param Variable $var
     * @param string   $name
     */
    abstract public function subtraction(Variable $var, string $name = "result");

    /**
     * 変数同士を掛ける
     * @param Variable $var
     * @param string   $name
     */
    abstract public function multiplication(Variable $var, string $name = "result");

    /**
     * 変数同士を割る
     * @param Variable $var
     * @param string   $name
     */
    abstract public function division(Variable $var, string $name = "result");

    /**
     * 変数同士を割った余り
     * @param Variable $var
     * @param string   $name
     */
    abstract public function modulo(Variable $var, string $name = "result");
}<?php

namespace aieuo\ip\variable;

class VariableHelper {

    const STRING_VARIABLE = 0;
    const INTEGER_VARIABLE = 1;
    const ARRAY_VARIABLE = 2;

    private $variables = [];

    public function __construct($owner) {
        $this->owner = $owner;
    }

    public function loadDataBase() {
        $owner = $this->owner;
        if (!file_exists($owner->getDataFolder()."if.db")) {
            $this->db = new \SQLite3($owner->getDataFolder()."if.db", SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);
        } else {
            $this->db = new \SQLite3($owner->getDataFolder()."if.db", SQLITE3_OPEN_READWRITE);
        }
        $this->db->query("CREATE TABLE IF NOT EXISTS variables (name TEXT, value TEXT, type INT)");
    }

    /**
     * @param  string $name
     * @param  bool $save
     * @return bool
     */
    public function exists(String $name, $save = false) {
        if (isset($this->variables[$name]) and !$save)return true;
        $datas = $this->db->query("SELECT * FROM variables WHERE name=\"$name\"")->fetchArray();
        return !empty($datas);
    }

    /**
     * @param  string $name
     * @param  bool $save
     * @return string | Variable
     */
    public function get(String $name, $save = false) {
        if (isset($this->variables[$name]) and !$save) return $this->variables[$name];
        if (!$this->exists($name, true)) return "";
        $datas = $this->db->query("SELECT * FROM variables WHERE name=\"$name\"")->fetchArray();
        return Variable::create($datas["name"], $this->currentType($datas["value"]), $datas["type"]);
    }

    /**
     * @param Variable $val
     * @param bool $save
     */
    public function add(Variable $val, $save = false) {
        if (!$save) {
            $this->variables[$val->getName()] = $val;
            return;
        }
        $name = $val->getName();
        $type = $val->getType();
        if (!($val instanceof StringVariable)) $val = $val->toStringVariable();
        $value = $val->getValue();
        if ($this->exists($name, true)) {
            $stmt = $this->db->prepare("UPDATE variables set value=:value, type=:type WHERE name=:name");
        } else {
            $stmt = $this->db->prepare("INSERT OR REPLACE INTO variables VALUES(:name,:value,:type)");
        }
        $stmt->bindValue(":name", $name, SQLITE3_TEXT);
        $stmt->bindValue(":value", $value, SQLITE3_TEXT);
        $stmt->bindValue(":type", $type, SQLITE3_INTEGER);
        $stmt->execute();
    }

    /**
     * @param  String $name
     * @return bool
     */
    public function del(String $name) {
        if (isset($this->variables[$name])) {
            unset($this->variables[$name]);
        }
        if (!$this->exists($name))return false;
        $this->db->query("DELETE FROM variables WHERE name=\"$name\"");
        return true;
    }

    public function save() {
        unset($this->variables["result"]);
        foreach ($this->variables as $variable) {
            $this->add($variable, true);
        }
        $this->variables = [];
    }

    public function findVariables($string, $variables = []) {
        foreach (["/\[({[^{}]+})\]/" => 2, "/({[^{}]+})/" => 1] as $pattern => $n) {
            $result = [];
            if (preg_match_all($pattern, $string, $matches)) {
                foreach ($matches[0] as $name) {
                    $name = mb_substr($name, $n, -$n);
                    $val = isset($variables[$name]) ? $variables[$name] : $this->get($name);
                    if (!($val instanceof Variable)) continue;
                    $result[$name] = $val;
                }
            }
        }
        return $result;
    }

    /**
     * 文字列の中にある変数を置き換える
     * @param  string $string
     * @param  array $variables
     * @return string
     */
    public function replaceVariables($string, $variables = []) {
        foreach (["/\[({[^{}]+})\]/" => 2, "/({[^{}]+})/" => 1] as $pattern => $n) {
            while (preg_match_all($pattern, $string, $matches)) {
                foreach ($matches[0] as $name) {
                    $name = mb_substr($name, $n, -$n);
                    $val = isset($variables[$name]) ? $variables[$name] : $this->get($name);
                    if (!($val instanceof Variable)) {
                        $string = str_replace("{".$name."}", "§cUndefined variable: ".$name."§r", $string);
                        continue;
                    }
                    $string = $this->replace($string, $val);
                }
            }
        }
        return $string;
    }

    /**
     * 変数を置き換える
     * @param  string $string
     * @param  Variable $variable
     * @return string
     */
    public function replace($string, $variable) {
        if (strpos($string, "{".$variable->getName()."}") === false) return $string;
        if ($variable instanceof ListVariable) {
            $haystack = explode("{".$variable->getName()."}", $string)[1];
            if (preg_match("/^\[([0-9]+)\].*/", $haystack, $index)) {
                $value = $variable->getValueFromIndex($index[1]);
                if ($value === null) $value = "§cUndefined index: ".$variable->getName()."[".$index[1]."]§r";
                $string = str_replace("{".$variable->getName()."}"."[".$index[1]."]", $value, $string);
                return $string;
            }
            if (preg_match("/^\.([a-z]+[0-9a-z]*).*/", $haystack, $method)) {
                if ($method[1] === "length") {
                    $string = str_replace("{".$variable->getName()."}".".".$method[1], $variable->getCount(), $string);
                }
                return $string;
            }
            $variable = new StringVariable($variable->getName(), $variable->getString());
        }
        $string = str_replace("{".$variable->getName()."}", $variable->getValue(), $string);
        return $string;
    }

    /**
     * 文字列が変数か調べる
     * @param  string  $variable
     * @return boolean
     */
    public function isVariable(string $variable) {
        return preg_match("/^{.+}$/", $variable);
    }

    /**
     * 文字列に変数が含まれているか調べる
     * @param  string  $variable
     * @return boolean
     */
    public function containsVariable(string $variable) {
        return preg_match("/.*{.+}.*/", $variable);
    }

    /**
     * 文字列の型を調べる
     * @param  string $string
     * @return int
     */
    public function getType(string $string) {
        if (substr($string, 0, 5) === "(str)") {
            $type = Variable::STRING;
        } elseif (substr($string, 0, 5) === "(num)") {
            $type = Variable::NUMBER;
        } elseif (substr($string, 0, 6) === "(list)") {
            $type = Variable::LIST;
        } elseif (is_numeric($string)) {
            $type = Variable::NUMBER;
        } else {
            $type = Variable::STRING;
        }
        return $type;
    }

    /**
     * 文字列の型を変更する
     * @param  string $string
     * @return string | float | value
     */
    public function currentType(string $value) {
        if (mb_substr($value, 0, 5) === "(str)") {
            $value = mb_substr($value, 5);
        } elseif (mb_substr($value, 0, 5) === "(num)") {
            $value = mb_substr($value, 5);
            if (!$this->containsVariable($value)) $value = (float)$value;
        } elseif (substr($value, 0, 6) === "(list)") {
            $value = mb_substr($value, 6);
            if (!$this->containsVariable($value)) $value = Variable::create("list", $value, Variable::LIST)->getValue();
        } elseif (is_numeric($value)) {
            $value = (float)$value;
        }
        return $value;
    }
}h;Ѯ p
/tI   GBMB