First commit

This commit is contained in:
2025-02-26 13:42:34 +01:00
commit f465c9072c
2467 changed files with 426214 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,745 @@
<?xml version="1.0" encoding="UTF-8"?>
<spells>
<instant group="attack" spellid="62" name="Annihilation" words="exori gran ico" lvl="110" mana="300" prem="1" range="1" needtarget="1" blockwalls="1" needweapon="1" exhaustion="30000" groupcooldown="4000" needlearn="0" script="attack/annihilation.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="attack" spellid="169" name="Apprentice's Strike" words="exori min flam" lvl="8" mana="6" prem="0" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="attack/apprentices strike.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="80" name="Berserk" words="exori" lvl="35" mana="115" prem="1" needweapon="1" exhaustion="4000" groupcooldown="2000" needlearn="0" script="attack/berserk.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="support" spellid="133" name="Blood Rage" words="utito tempo" lvl="60" mana="290" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/blood rage.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="attack" spellid="61" name="Brutal Strike" words="exori ico" lvl="16" mana="30" prem="1" range="1" needtarget="1" blockwalls="1" needweapon="1" exhaustion="6000" groupcooldown="2000" needlearn="0" script="attack/brutal strike.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="support" spellid="90" name="Cancel Invisibility" words="exana ina" lvl="26" mana="200" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/cancel invisibility.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="support" spellid="93" name="Challenge" words="exeta res" lvl="20" mana="30" prem="1" aggressive="0" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/challenge.lua">
<vocation name="Elite Knight" />
</instant>
<instant group="support" spellid="131" name="Charge" words="utani tempo hur" lvl="25" mana="100" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/charge.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="support" spellid="38" name="Creature Illusion" words="utevo res ina" lvl="23" mana="100" aggressive="0" params="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="Illusion">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="healing" spellid="144" name="Cure Bleeding" words="exana kor" lvl="45" mana="30" aggressive="0" selftarget="1" exhaustion="6000" groupcooldown="1000" needlearn="0" script="healing/cure bleeding.lua">
<vocation name="Druid" />
<vocation name="Knight" />
<vocation name="Elder Druid" />
<vocation name="Elite Knight" />
</instant>
<instant group="healing" spellid="145" name="Cure Burning" words="exana flam" lvl="30" mana="30" aggressive="0" selftarget="1" exhaustion="6000" groupcooldown="1000" needlearn="0" script="healing/cure burning.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="healing" spellid="147" name="Cure Curse" words="exana mort" lvl="80" mana="40" aggressive="0" selftarget="1" exhaustion="6000" groupcooldown="1000" needlearn="0" script="healing/cure curse.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="healing" spellid="146" name="Cure Electrification" words="exana vis" lvl="22" mana="30" aggressive="0" selftarget="1" exhaustion="6000" groupcooldown="1000" needlearn="0" script="healing/cure electrification.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="healing" spellid="29" name="Cure Poison" words="exana pox" lvl="10" mana="30" aggressive="0" selftarget="1" exhaustion="6000" groupcooldown="1000" needlearn="0" script="healing/antidote.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Knight" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
<vocation name="Elite Knight" />
</instant>
<instant group="attack" spellid="139" name="Curse" words="utori mort" lvl="75" mana="30" range="3" aggressive="1" blockwalls="1" needtarget="1" exhaustion="50000" groupcooldown="2000" needlearn="0" script="attack/curse.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="attack" spellid="87" name="Death Strike" words="exori mort" lvl="16" mana="20" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="attack/death strike.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="attack" spellid="124" name="Divine Caldera" words="exevo mas san" lvl="50" mana="160" prem="1" selftarget="1" exhaustion="4000" groupcooldown="2000" needlearn="0" script="attack/divine caldera.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="healing" spellid="125" name="Divine Healing" words="exura san" lvl="35" mana="160" prem="0" selftarget="1" aggressive="0" exhaustion="1000" groupcooldown="1000" needlearn="0" script="healing/divine healing.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="attack" spellid="122" name="Divine Missile" words="exori san" lvl="40" mana="20" prem="1" range="4" casterTargetOrDirection="1" needlearn="0" blockwalls="1" exhaustion="2000" groupcooldown="2000" script="attack/divine missile.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="attack" spellid="140" name="Electrify" words="utori vis" lvl="34" mana="30" range="3" aggressive="1" blockwalls="1" needtarget="1" exhaustion="30000" groupcooldown="2000" needlearn="0" script="attack/electrify.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="support" spellid="129" name="Enchant Party" words="utori mas sio" lvl="32" mana="120" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="party/enchant.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="attack" spellid="22" name="Energy Beam" words="exevo vis lux" lvl="23" mana="40" direction="1" exhaustion="4000" groupcooldown="2000" needlearn="0" script="attack/energy beam.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="attack" spellid="88" name="Energy Strike" words="exori vis" lvl="12" mana="20" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="attack/energy strike.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="13" name="Energy Wave" words="exevo vis hur" lvl="38" mana="170" direction="1" exhaustion="8000" groupcooldown="2000" needlearn="0" script="attack/energy wave.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="attack" spellid="142" name="Envenom" words="utori pox" lvl="50" mana="30" range="3" aggressive="1" blockwalls="1" needtarget="1" exhaustion="40000" groupcooldown="2000" needlearn="0" script="attack/envenom.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="118" name="Eternal Winter" words="exevo gran mas frigo" lvl="60" mana="1050" prem="1" selftarget="1" exhaustion="40000" groupcooldown="4000" needlearn="0" script="attack/eternal winter.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="111" name="Ethereal Spear" words="exori con" lvl="23" mana="25" prem="1" range="7" needtarget="1" exhaustion="2000" groupcooldown="2000" blockwalls="1" needlearn="0" script="attack/ethereal spear.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="attack" spellid="105" name="Fierce Berserk" words="exori gran" lvl="90" mana="340" prem="1" needweapon="1" exhaustion="6000" groupcooldown="2000" needlearn="0" script="attack/fierce berserk.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="support" spellid="20" name="Find Person" words="exiva" lvl="8" mana="20" aggressive="0" playernameparam="1" params="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="searchPlayer">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Knight" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
<vocation name="Elite Knight" />
</instant>
<instant group="attack" spellid="19" name="Fire Wave" words="exevo flam hur" lvl="18" mana="25" direction="1" exhaustion="4000" groupcooldown="2000" needlearn="0" script="attack/fire wave.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="attack" spellid="89" name="Flame Strike" words="exori flam" lvl="14" mana="20" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="attack/flame strike.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="support" spellid="42" name="Food" words="exevo pan" lvl="14" mana="120" soul="1" exhaustion="2000" groupcooldown="2000" aggressive="0" needlearn="0" script="support/food.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="59" name="Front Sweep" words="exori min" lvl="70" mana="200" prem="1" needweapon="1" direction="1" exhaustion="6000" groupcooldown="2000" needlearn="0" script="attack/front sweep.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="attack" spellid="23" name="Great Energy Beam" words="exevo gran vis lux" lvl="29" mana="110" direction="1" exhaustion="6000" groupcooldown="2000" needlearn="0" script="attack/great energy beam.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="support" spellid="11" name="Great Light" words="utevo gran lux" lvl="13" mana="60" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/great light.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Knight" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
<vocation name="Elite Knight" />
</instant>
<instant group="attack" spellid="106" name="Groundshaker" words="exori mas" lvl="33" mana="160" prem="1" needweapon="1" exhaustion="8000" groupcooldown="2000" needlearn="0" script="attack/groundshaker.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="support" spellid="6" name="Haste" words="utani hur" lvl="14" mana="60" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/haste.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Knight" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
<vocation name="Elite Knight" />
</instant>
<instant group="healing" spellid="84" name="Heal Friend" words="exura sio" lvl="18" mana="140" prem="1" aggressive="0" blockwalls="1" needtarget="1" playernameparam="1" params="1" exhaustion="1000" groupcooldown="1000" needlearn="0" script="healing/heal friend.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="support" spellid="128" name="Heal Party" words="utura mas sio" lvl="32" mana="120" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="party/heal.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="24" name="Hell's Core" words="exevo gran mas flam" lvl="60" mana="1100" prem="1" exhaustion="40000" groupcooldown="4000" selftarget="1" needlearn="0" script="attack/hells core.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="attack" spellid="143" name="Holy Flash" words="utori san" lvl="70" mana="30" range="3" aggressive="1" blockwalls="1" needtarget="1" exhaustion="40000" groupcooldown="2000" needlearn="0" script="attack/holy flash.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="attack" spellid="112" name="Ice Strike" words="exori frigo" lvl="15" mana="20" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="attack/ice strike.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="121" name="Ice Wave" words="exevo frigo hur" lvl="18" mana="25" direction="1" exhaustion="4000" groupcooldown="2000" needlearn="0" script="attack/ice wave.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="138" name="Ignite" words="utori flam" lvl="26" mana="30" range="3" aggressive="1" blockwalls="1" needtarget="1" exhaustion="30000" groupcooldown="2000" needlearn="0" script="attack/ignite.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="attack" spellid="141" name="Inflict Wound" words="utori kor" lvl="40" mana="30" range="1" aggressive="1" blockwalls="1" needtarget="1" exhaustion="30000" groupcooldown="2000" needlearn="0" script="attack/inflict wound.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="healing" spellid="2" name="Intense Healing" words="exura gran" lvl="20" mana="70" aggressive="0" selftarget="1" exhaustion="1000" groupcooldown="1000" needlearn="0" script="healing/intense healing.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
</instant>
<instant group="healing" spellid="160" name="Intense Recovery" words="utura gran" lvl="100" mana="165" aggressive="0" selftarget="1" exhaustion="60000" groupcooldown="1000" needlearn="0" script="healing/intense recovery.lua">
<vocation name="Paladin" />
<vocation name="Knight" />
<vocation name="Royal Paladin" />
<vocation name="Elite Knight" />
</instant>
<instant group="healing" spellid="158" name="Intense Wound Cleansing" words="exura gran ico" lvl="80" mana="200" prem="1" selftarget="1" aggressive="0" exhaustion="600000" groupcooldown="1000" needlearn="0" script="healing/intense wound cleansing.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="support" spellid="45" name="Invisibility" words="utana vid" lvl="35" mana="440" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/invisible.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="support" spellid="81" name="Levitate" words="exani hur" lvl="12" mana="50" prem="1" aggressive="0" exhaustion="2000" groupcooldown="2000" params="1" needlearn="0" function="Levitate">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Knight" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
<vocation name="Elite Knight" />
</instant>
<instant group="support" spellid="10" name="Light" words="utevo lux" lvl="8" mana="20" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/light.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Knight" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
<vocation name="Elite Knight" />
</instant>
<instant group="healing" spellid="1" name="Light Healing" words="exura" lvl="8" mana="20" aggressive="0" selftarget="1" exhaustion="1000" groupcooldown="1000" needlearn="0" script="healing/light healing.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
</instant>
<instant group="attack" spellid="149" name="Lightning" words="exori amp vis" lvl="55" mana="60" prem="1" range="4" casterTargetOrDirection="1" blockwalls="1" exhaustion="8000" groupcooldown="2000" needlearn="0" script="attack/lightning.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="support" spellid="76" name="Magic Rope" words="exani tera" lvl="9" mana="20" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/magic rope.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Knight" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
<vocation name="Elite Knight" />
</instant>
<instant group="support" spellid="44" name="Magic Shield" words="utamo vita" lvl="14" mana="50" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/magic shield.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="healing" spellid="82" name="Mass Healing" words="exura gran mas res" lvl="36" mana="150" prem="1" aggressive="0" exhaustion="2000" groupcooldown="1000" needlearn="0" script="healing/mass healing.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="148" name="Physical Strike" words="exori moe ico" lvl="16" mana="20" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="attack/physical strike.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="167" name="Practise Fire Wave" words="exevo dis flam hur" lvl="1" mana="5" direction="1" exhaustion="4000" groupcooldown="2000" needlearn="0" script="attack/practise fire wave.lua">
<vocation name="None" />
</instant>
<instant group="healing" spellid="166" name="Practise Healing" words="exura dis" lvl="1" mana="5" aggressive="0" selftarget="1" exhaustion="1000" groupcooldown="1000" needlearn="0" script="healing/practise healing.lua">
<vocation name="None" />
</instant>
<instant group="support" spellid="127" name="Protect Party" words="utamo mas sio" lvl="32" mana="90" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="party/protect.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="support" spellid="132" name="Protector" words="utamo tempo" lvl="55" mana="200" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/protector.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="attack" spellid="119" name="Rage of the Skies" words="exevo gran mas vis" lvl="55" mana="600" selftarget="1" prem="1" exhaustion="40000" groupcooldown="4000" needlearn="0" script="attack/rage of the skies.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="healing" spellid="159" name="Recovery" words="utura" lvl="50" mana="75" aggressive="0" selftarget="1" exhaustion="60000" groupcooldown="1000" needlearn="0" script="healing/recovery.lua">
<vocation name="Paladin" />
<vocation name="Knight" />
<vocation name="Royal Paladin" />
<vocation name="Elite Knight" />
</instant>
<instant group="healing" spellid="36" name="Salvation" words="exura gran san" lvl="60" mana="210" prem="1" selftarget="1" aggressive="0" exhaustion="1000" groupcooldown="1000" needlearn="0" script="healing/salvation.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="support" spellid="135" name="Sharpshooter" words="utito tempo san" lvl="60" mana="450" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/sharpshooter.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="attack" spellid="151" name="Strong Energy Strike" words="exori gran vis" lvl="80" mana="60" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="8000" groupcooldown="2000" needlearn="0" script="attack/strong energy strike.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="attack" spellid="57" name="Strong Ethereal Spear" words="exori gran con" lvl="90" mana="55" prem="1" range="7" needtarget="1" exhaustion="8000" groupcooldown="2000" blockwalls="1" needlearn="0" script="attack/strong ethereal spear.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="attack" spellid="150" name="Strong Flame Strike" words="exori gran flam" lvl="70" mana="60" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="8000" groupcooldown="2000" needlearn="0" script="attack/strong flame strike.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="support" spellid="39" name="Strong Haste" words="utani gran hur" lvl="20" mana="100" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/strong haste.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="152" name="Strong Ice Strike" words="exori gran frigo" lvl="80" mana="60" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="8000" groupcooldown="2000" needlearn="0" script="attack/strong ice strike.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="43" name="Strong Ice Wave" words="exevo gran frigo hur" lvl="40" mana="170" direction="1" exhaustion="8000" groupcooldown="2000" needlearn="0" script="attack/strong ice wave.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="153" name="Strong Terra Strike" words="exori gran tera" lvl="70" mana="60" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="8000" groupcooldown="2000" needlearn="0" script="attack/strong terra strike.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="support" spellid="9" name="Summon Creature" words="utevo res" lvl="25" params="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="summonMonster">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="support" spellid="134" name="Swift Foot" words="utamo tempo san" lvl="55" mana="400" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/swift foot.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</instant>
<instant group="attack" spellid="113" name="Terra Strike" words="exori tera" lvl="13" mana="20" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="attack/terra strike.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="120" name="Terra Wave" words="exevo tera hur" lvl="38" mana="210" direction="1" exhaustion="4000" groupcooldown="2000" needlearn="0" script="attack/terra wave.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="support" spellid="126" name="Train Party" words="utito mas sio" lvl="32" mana="60" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="party/train.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="attack" spellid="155" name="Ultimate Energy Strike" words="exori max vis" lvl="100" mana="100" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="30000" groupcooldown="4000" needlearn="0" script="attack/ultimate energy strike.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="attack" spellid="154" name="Ultimate Flame Strike" words="exori max flam" lvl="90" mana="100" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="30000" groupcooldown="4000" needlearn="0" script="attack/ultimate flame strike.lua">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</instant>
<instant group="healing" spellid="3" name="Ultimate Healing" words="exura vita" lvl="30" mana="160" aggressive="0" selftarget="1" exhaustion="1000" groupcooldown="1000" needlearn="0" script="healing/ultimate healing.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="156" name="Ultimate Ice Strike" words="exori max frigo" lvl="100" mana="100" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="30000" groupcooldown="4000" needlearn="0" script="attack/ultimate ice strike.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="support" spellid="75" name="Ultimate Light" words="utevo vis lux" lvl="26" mana="140" prem="1" aggressive="0" selftarget="1" exhaustion="2000" groupcooldown="2000" needlearn="0" script="support/ultimate light.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="attack" spellid="157" name="Ultimate Terra Strike" words="exori max tera" lvl="90" mana="100" prem="1" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="30000" groupcooldown="4000" needlearn="0" script="attack/ultimate terra strike.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<instant group="healing" spellid="123" name="Wound Cleansing" words="exura ico" lvl="10" mana="40" prem="0" selftarget="1" aggressive="0" exhaustion="1000" groupcooldown="1000" needlearn="0" script="healing/wound cleansing.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="attack" spellid="107" name="Whirlwind Throw" words="exori hur" lvl="28" mana="40" prem="1" range="5" needtarget="1" blockwalls="1" needweapon="1" exhaustion="6000" groupcooldown="2000" needlearn="0" script="attack/whirlwind throw.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
</instant>
<instant group="attack" spellid="56" name="Wrath of Nature" words="exevo gran mas tera" lvl="55" mana="700" prem="1" selftarget="1" exhaustion="40000" groupcooldown="4000" needlearn="0" script="attack/wrath of nature.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</instant>
<!-- Attack Runes -->
<rune group="attack" spellid="26" name="Poison Field" id="2285" allowfaruse="1" charges="3" lvl="14" maglv="0" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/poison field.lua" />
<rune group="attack" spellid="91" name="Poison Bomb" id="2286" allowfaruse="1" charges="2" lvl="25" maglv="4" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/poison bomb.lua" />
<rune group="attack" spellid="32" name="Poison Wall" id="2289" allowfaruse="1" charges="4" lvl="29" maglv="5" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/poison wall.lua" />
<rune group="attack" spellid="25" name="Fire Field" id="2301" allowfaruse="1" charges="3" lvl="15" maglv="1" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/fire field.lua" />
<rune group="attack" spellid="17" name="Firebomb" id="2305" allowfaruse="1" charges="2" lvl="27" maglv="5" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/fire bomb.lua" />
<rune group="attack" spellid="28" name="Fire Wall" id="2303" allowfaruse="1" charges="4" lvl="33" maglv="6" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/fire wall.lua" />
<rune group="attack" spellid="50" name="Soulfire" id="2308" allowfaruse="1" charges="3" lvl="27" maglv="7" exhaustion="2000" groupcooldown="2000" needtarget="1" blocktype="solid" script="attack/soul fire.lua" />
<rune group="attack" spellid="15" name="Fireball" id="2302" allowfaruse="1" charges="5" lvl="27" maglv="4" exhaustion="2000" groupcooldown="2000" needtarget="1" blocktype="solid" script="attack/fireball.lua" />
<rune group="attack" spellid="16" name="Great Fireball" id="2304" allowfaruse="1" charges="4" lvl="30" maglv="4" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/great fireball.lua" />
<rune group="attack" spellid="27" name="Energy Field" id="2277" allowfaruse="1" charges="3" lvl="18" maglv="3" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/energy field.lua" />
<rune group="attack" spellid="55" name="Energybomb" id="2262" allowfaruse="1" charges="2" lvl="37" maglv="10" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/energy bomb.lua" />
<rune group="attack" spellid="33" name="Energy Wall" id="2279" allowfaruse="1" charges="4" lvl="41" maglv="9" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/energy wall.lua" />
<rune group="attack" spellid="7" name="Light Magic Missile" id="2287" allowfaruse="1" charges="10" lvl="15" exhaustion="2000" groupcooldown="2000" maglv="0" needtarget="1" blocktype="solid" script="attack/light magic missile.lua" />
<!--<rune group="attack" spellid="7" name="Lightest Magic Missile" id="2287" allowfaruse="1" charges="10" lvl="1" exhaustion="2000" groupcooldown="2000" maglv="0" needtarget="1" blocktype="solid" script="attack/lightest magic missile.lua" />-->
<rune group="attack" spellid="8" name="Heavy Magic Missile" id="2311" allowfaruse="1" charges="10" lvl="25" exhaustion="2000" groupcooldown="2000" maglv="3" needtarget="1" blocktype="solid" script="attack/heavy magic missile.lua" />
<rune group="attack" spellid="18" name="Explosion" id="2313" allowfaruse="1" charges="6" lvl="31" maglv="6" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="attack/explosion.lua" />
<rune group="attack" spellid="21" name="Sudden Death" id="2268" allowfaruse="1" charges="3" lvl="45" maglv="15" exhaustion="2000" groupcooldown="2000" needtarget="1" blocktype="solid" script="attack/sudden death.lua" />
<rune group="attack" spellid="114" name="Icicle" id="2271" allowfaruse="1" charges="5" lvl="28" maglv="4" exhaustion="2000" groupcooldown="2000" needtarget="1" script="attack/icicle.lua" />
<rune group="attack" spellid="115" name="Avalanche" id="2274" allowfaruse="1" charges="4" lvl="30" maglv="4" exhaustion="2000" groupcooldown="2000" script="attack/avalanche.lua" />
<rune group="attack" spellid="116" name="Stone Shower" id="2288" allowfaruse="1" charges="4" lvl="28" maglv="4" exhaustion="2000" groupcooldown="2000" script="attack/stone shower.lua" />
<rune group="attack" spellid="117" name="Thunderstorm" id="2315" allowfaruse="1" charges="4" lvl="28" maglv="4" exhaustion="2000" groupcooldown="2000" script="attack/thunderstorm.lua" />
<rune group="attack" spellid="77" name="Stalagmite" id="2292" allowfaruse="1" charges="10" lvl="24" maglv="3" exhaustion="2000" groupcooldown="2000" needtarget="1" script="attack/stalagmite.lua" />
<rune group="attack" spellid="130" name="Holy Missile" id="2295" allowfaruse="1" charges="5" lvl="27" maglv="4" exhaustion="2000" groupcooldown="2000" needtarget="1" blocktype="solid" script="attack/holy missile.lua">
<vocation name="Paladin" />
<vocation name="Royal Paladin" showInDescription="0" />
</rune>
<rune group="attack" spellid="86" name="Magic Wall" id="2293" allowfaruse="1" charges="3" lvl="32" maglv="9" exhaustion="2000" groupcooldown="2000" blocktype="all" script="support/magic wall rune.lua" />
<!-- Healing Runes -->
<rune group="healing" spellid="31" name="Antidote Rune" id="2266" allowfaruse="1" charges="1" lvl="15" maglv="0" exhaustion="2000" groupcooldown="2000" aggressive="0" needtarget="1" blocktype="solid" script="healing/antidote rune.lua" />
<rune group="healing" spellid="4" name="Intense Healing Rune" id="2265" allowfaruse="1" charges="1" lvl="15" maglv="1" exhaustion="2000" groupcooldown="2000" aggressive="0" needtarget="1" blocktype="solid" script="healing/intense healing rune.lua" />
<rune group="healing" spellid="5" name="Ultimate Healing Rune" id="2273" allowfaruse="1" charges="1" lvl="24" maglv="4" exhaustion="2000" groupcooldown="2000" aggressive="0" needtarget="1" blocktype="solid" script="healing/ultimate healing rune.lua" />
<!-- Summon Runes -->
<rune group="support" spellid="12" name="Convince Creature" id="2290" allowfaruse="1" charges="1" lvl="16" maglv="5" exhaustion="2000" groupcooldown="2000" needtarget="1" blocktype="solid" function="convince" />
<rune group="support" spellid="83" name="Animate Dead" id="2316" allowfaruse="1" charges="1" lvl="27" maglv="4" exhaustion="2000" groupcooldown="2000" blocktype="solid" script="support/animate dead rune.lua" />
<!-- Support Runes -->
<rune group="support" spellid="78" name="Desintegrate" id="2310" allowfaruse="0" charges="3" lvl="21" maglv="4" exhaustion="2000" groupcooldown="2000" range="1" script="support/desintegrate rune.lua" />
<rune group="support" spellid="30" name="Destroy Field" id="2261" allowfaruse="1" charges="3" lvl="17" maglv="3" exhaustion="2000" groupcooldown="2000" aggressive="0" range="5" script="support/destroy field rune.lua" />
<rune group="support" spellid="14" name="Chameleon" id="2291" allowfaruse="1" charges="1" lvl="27" maglv="4" exhaustion="2000" groupcooldown="2000" aggressive="0" selftarget="1" blocktype="solid" function="chameleon" />
<rune group="support" spellid="94" name="Wild Growth" id="2269" allowfaruse="1" charges="2" lvl="27" maglv="8" exhaustion="2000" groupcooldown="2000" blocktype="all" script="support/wild growth rune.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" showInDescription="0" />
</rune>
<rune group="support" spellid="54" name="Paralyze" id="2278" allowfaruse="1" charges="1" lvl="54" maglv="18" exhaustion="2000" groupcooldown="2000" mana="1400" needtarget="1" blocktype="solid" script="support/paralyze rune.lua">
<vocation name="Druid" />
<vocation name="Elder Druid" showInDescription="0" />
</rune>
<!-- Conjure Spells -->
<conjure group="support" name="Blank Rune" words="adori blank" lvl="20" mana="50" soul="1" conjureId="2260" conjureCount="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</conjure>
<conjure group="support" spellid="51" name="Conjure Arrow" words="exevo con" lvl="13" mana="100" soul="1" conjureId="2544" conjureCount="10" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureItem">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</conjure>
<conjure group="support" spellid="48" name="Conjure Poisoned Arrow" words="exevo con pox" lvl="16" mana="130" soul="2" conjureId="2545" conjureCount="7" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureItem">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</conjure>
<conjure group="support" spellid="79" name="Conjure Bolt" words="exevo con mort" lvl="17" mana="140" soul="2" prem="1" conjureId="2543" conjureCount="5" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureItem">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</conjure>
<conjure group="support" spellid="108" name="Conjure Sniper Arrow" words="exevo con hur" lvl="24" mana="160" soul="3" prem="1" conjureId="7364" conjureCount="5" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureItem">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</conjure>
<conjure group="support" spellid="49" name="Conjure Explosive Arrow" words="exevo con flam" lvl="25" mana="290" soul="3" conjureId="2546" conjureCount="8" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureItem">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</conjure>
<conjure group="support" spellid="109" name="Conjure Piercing Bolt" words="exevo con grav" lvl="33" mana="180" soul="3" prem="1" conjureId="7363" conjureCount="5" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureItem">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</conjure>
<conjure group="support" spellid="92" name="Enchant Staff" words="exeta vis" lvl="41" mana="80" prem="1" conjureId="2433" reagentId="2401" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureItem">
<vocation name="Master Sorcerer" />
</conjure>
<conjure group="support" spellid="110" name="Enchant Spear" words="exeta con" lvl="45" mana="350" soul="3" prem="1" conjureId="7367" reagentId="2389" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureItem">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</conjure>
<conjure group="support" spellid="95" name="Conjure Power Bolt" words="exevo con vis" lvl="59" mana="700" soul="4" prem="1" conjureId="2547" conjureCount="10" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureItem">
<vocation name="Royal Paladin" />
</conjure>
<conjure name="Poison Field" words="adevo grav pox" lvl="14" mana="200" soul="1" reagentId="2260" conjureId="2285" conjureCount="3" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Light Magic Missile" words="adori min vis" lvl="15" mana="120" soul="1" reagentId="2260" conjureId="2287" conjureCount="10" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<!--<conjure name="Lightest Magic Missile" words="adori dis min vis" lvl="1" mana="5" soul="0" reagentId="2260" conjureId="2287" conjureCount="10" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="None" />
</conjure>-->
<conjure name="Fire Field" words="adevo grav flam" lvl="15" mana="240" soul="1" reagentId="2260" conjureId="2301" conjureCount="3" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Fireball" words="adori flam" lvl="27" mana="460" soul="3" prem="1" reagentId="2260" conjureId="2302" conjureCount="5" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</conjure>
<conjure name="Energy Field" words="adevo grav vis" lvl="18" mana="320" soul="2" reagentId="2260" conjureId="2277" conjureCount="3" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Stalagmite" words="adori tera" lvl="24" mana="400" soul="2" prem="2" reagentId="2260" conjureId="2292" conjureCount="10" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Great Fireball" words="adori mas flam" lvl="30" mana="530" soul="3" reagentId="2260" conjureId="2304" conjureCount="4" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</conjure>
<conjure name="Heavy Magic Missile" words="adori vis" lvl="25" mana="350" soul="2" reagentId="2260" conjureId="2311" conjureCount="10" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Poison Bomb" words="adevo mas pox" lvl="25" mana="520" soul="2" prem="1" reagentId="2260" conjureId="2286" conjureCount="2" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Firebomb" words="adevo mas flam" lvl="27" mana="600" soul="4" reagentId="2260" conjureId="2305" conjureCount="2" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Soulfire" words="adevo res flam" lvl="27" mana="600" soul="3" prem="1" reagentId="2260" conjureId="2308" conjureCount="3" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Poison Wall" words="adevo mas grav pox" lvl="29" mana="640" soul="3" reagentId="2260" conjureId="2289" conjureCount="4" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Explosion" words="adevo mas hur" lvl="31" mana="570" soul="4" reagentId="2260" conjureId="2313" conjureCount="6" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Fire Wall" words="adevo mas grav flam" lvl="33" mana="780" soul="4" reagentId="2260" conjureId="2303" conjureCount="4" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Energybomb" words="adevo mas vis" lvl="37" mana="880" soul="5" prem="1" reagentId="2260" conjureId="2262" conjureCount="2" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</conjure>
<conjure name="Energy Wall" words="adevo mas grav vis" lvl="41" mana="1000" soul="5" reagentId="2260" conjureId="2279" conjureCount="4" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Sudden Death" words="adori gran mort" lvl="45" mana="985" soul="5" reagentId="2260" conjureId="2268" conjureCount="3" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</conjure>
<conjure name="Antidote Rune" words="adana pox" lvl="15" mana="200" soul="1" reagentId="2260" conjureId="2266" conjureCount="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Intense Healing Rune" words="adura gran" lvl="15" mana="240" soul="2" reagentId="2260" conjureId="2265" conjureCount="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Ultimate Healing Rune" words="adura vita" lvl="24" mana="400" soul="3" reagentId="2260" conjureId="2273" conjureCount="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Convince Creature" words="adeta sio" lvl="16" mana="200" soul="3" reagentId="2260" conjureId="2290" conjureCount="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Animate Dead" words="adana mort" lvl="27" mana="600" soul="5" prem="1" reagentId="2260" conjureId="2316" conjureCount="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Chameleon" words="adevo ina" lvl="27" mana="600" soul="2" reagentId="2260" conjureId="2291" conjureCount="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Destroy Field" words="adito grav" lvl="17" mana="120" soul="2" reagentId="2260" conjureId="2261" conjureCount="3" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
</conjure>
<conjure name="Desintegrate" words="adito tera" lvl="21" mana="200" soul="3" prem="1" reagentId="2260" conjureId="2310" conjureCount="3" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Paladin" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
<vocation name="Royal Paladin" />
</conjure>
<conjure name="Magic Wall" words="adevo grav tera" lvl="32" mana="750" soul="5" prem="1" reagentId="2260" conjureId="2293" conjureCount="3" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</conjure>
<conjure name="Wild Growth" words="adevo grav vita" lvl="27" mana="600" soul="5" prem="1" reagentId="2260" conjureId="2269" conjureCount="2" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Paralyze" words="adana ani" lvl="54" mana="1400" soul="3" prem="1" reagentId="2260" conjureId="2278" conjureCount="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Icicle" words="adori frigo" lvl="28" mana="460" soul="3" prem="1" reagentId="2260" conjureId="2271" conjureCount="5" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Avalanche" words="adori mas frigo" lvl="30" mana="530" soul="3" reagentId="2260" conjureId="2274" conjureCount="4" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Stone Shower" words="adori mas tera" lvl="28" mana="430" soul="3" prem="1" reagentId="2260" conjureId="2288" conjureCount="4" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Druid" />
<vocation name="Elder Druid" />
</conjure>
<conjure name="Thunderstorm" words="adori mas vis" lvl="28" mana="430" soul="3" prem="1" reagentId="2260" conjureId="2315" conjureCount="4" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Sorcerer" />
<vocation name="Master Sorcerer" />
</conjure>
<conjure name="Holy Missile" words="adori san" lvl="27" mana="350" soul="3" prem="1" reagentId="2260" conjureId="2295" conjureCount="5" exhaustion="2000" groupcooldown="2000" needlearn="0" function="conjureRune">
<vocation name="Paladin" />
<vocation name="Royal Paladin" />
</conjure>
<!-- House Spells -->
<instant spellid="71" name="House Guest List" words="aleta sio" selftarget="1" aggressive="0" function="editHouseGuest" />
<instant spellid="72" name="House Subowner List" words="aleta som" selftarget="1" aggressive="0" function="editHouseSubOwner" />
<instant spellid="73" name="House Door List" words="aleta grav" selftarget="1" aggressive="0" function="editHouseDoor" />
<instant spellid="74" name="House Kick" words="alana sio" params="1" aggressive="0" function="houseKick" />
<!-- Monster Spells -->
<instant name="ghastly dragon curse" words="###1" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/ghastly dragon curse.lua" />
<instant name="djinn electrify" words="###2" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/djinn electrify.lua" />
<instant name="energy elemental electrify" words="###3" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/energy elemental electrify.lua" />
<instant name="massive energy elemental electrify" words="###4" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/massive energy elemental electrify.lua" />
<instant name="massive fire elemental soulfire" words="###5" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/massive fire elemental soulfire.lua" />
<instant name="hellfire fighter soulfire" words="###6" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/hellfire fighter soulfire.lua" />
<instant name="hellspawn soulfire" words="###7" aggressive="1" blockwalls="1" range="7" needtarget="1" needlearn="1" script="monster/hellspawn soulfire.lua" />
<instant name="spectre drown" words="###8" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/spectre drown.lua" />
<instant name="phantasm drown" words="###9" direction="1" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/phantasm drown.lua" />
<instant name="undead dragon curse" words="###10" direction="1" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/undead dragon curse.lua" />
<instant name="draken abomination curse" words="###11" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/draken abomination curse.lua" />
<instant name="lancer beetle curse" words="###12" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/lancer beetle curse.lua" />
<instant name="lizard magistratus curse" words="###13" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/lizard magistratus curse.lua" />
<instant name="death blob curse" words="###14" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/death blob curse.lua" />
<instant name="choking fear drown" words="###15" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/choking fear drown.lua" />
<instant name="blightwalker curse" words="###16" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/blightwalker curse.lua" />
<instant name="sea serpent drown" words="###17" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/sea serpent drown.lua" />
<instant name="young sea serpent drown" words="###18" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/young sea serpent drown.lua" />
<instant name="quara constrictor freeze" words="###19" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/quara constrictor freeze.lua" />
<instant name="quara constrictor electrify" words="###20" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/quara constrictor electrify.lua" />
<instant name="cliff strider electrify" words="###21" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/cliff strider electrify.lua" />
<instant name="war golem electrify" words="###22" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/war golem electrify.lua" />
<instant name="souleater drown" words="###23" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/souleater drown.lua" />
<instant name="mutated bat curse" words="###24" direction="1" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/mutated bat curse.lua" />
<instant name="vulcongra soulfire" words="###25" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/vulcongra soulfire.lua" />
<instant name="lava golem soulfire" words="###26" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/lava golem soulfire.lua" />
<instant name="magma crawler soulfire" words="###27" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/magma crawler soulfire.lua" />
<instant name="war golem skill reducer" words="###28" direction="1" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/war golem skill reducer.lua" />
<instant name="silencer skill reducer" words="###29" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/silencer skill reducer.lua" />
<instant name="warlock skill reducer" words="###30" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/warlock skill reducer.lua" />
<instant name="cliff strider skill reducer" words="###31" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/cliff strider skill reducer.lua" />
<instant name="stampor skill reducer" words="###32" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/stampor skill reducer.lua" />
<instant name="diabolic imp skill reducer" words="###33" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/diabolic imp skill reducer.lua" />
<instant name="dark torturer skill reducer" words="###34" direction="1" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/dark torturer skill reducer.lua" />
<instant name="forest fury skill reducer" words="###35" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/forest fury skill reducer.lua" />
<instant name="demon outcast skill reducer" words="###36" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/demon outcast skill reducer.lua" />
<instant name="fury skill reducer" words="###37" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/fury skill reducer.lua" />
<instant name="barbarian brutetamer skill reducer" words="###38" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/barbarian brutetamer skill reducer.lua" />
<instant name="deepling spellsinger skill reducer" words="###39" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/deepling spellsinger skill reducer.lua" />
<instant name="werewolf skill reducer" words="###40" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/werewolf skill reducer.lua" />
<instant name="ice golem skill reducer" words="###41" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/ice golem skill reducer.lua" />
<instant name="feversleep skill reducer" words="###42" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/feversleep skill reducer.lua" />
<instant name="shock head skill reducer 1" words="###43" aggressive="1" blockwalls="1" needtarget="1" needlearn="1" script="monster/shock head skill reducer 1.lua" />
<instant name="shock head skill reducer 2" words="###44" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/shock head skill reducer 2.lua" />
<instant name="enslaved dwarf skill reducer 1" words="###45" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/enslaved dwarf skill reducer 1.lua" />
<instant name="enslaved dwarf skill reducer 2" words="###46" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/enslaved dwarf skill reducer 2.lua" />
<instant name="djinn cancel invisibility" words="###47" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/djinn cancel invisibility.lua" />
<instant name="betrayed wraith skill reducer" words="###48" direction="1" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/betrayed wraith skill reducer.lua" />
<instant name="pirate corsair skill reducer" words="###49" direction="1" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="monster/pirate corsair skill reducer.lua" />
</spells>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<stages>
<config enabled="0" />
<stage minlevel="1" maxlevel="8" multiplier="7" />
<stage minlevel="9" maxlevel="20" multiplier="6" />
<stage minlevel="21" maxlevel="50" multiplier="5" />
<stage minlevel="51" maxlevel="100" multiplier="4" />
<stage minlevel="101" multiplier="5" />
</stages>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,91 @@
<?php
$time = time();
if (!isset($version)) $version = '1.6';
if (!function_exists("elapsedTime")) {
function elapsedTime($l_start = false, $l_time = false) {
if ($l_start === false) global $l_start;
if ($l_time === false) global $l_time;
$l_time = microtime(true);
return round(($l_time - $l_start), 4);
}
}
// ALTER TABLE `znote_accounts` ADD `active_email` TINYINT(4) NOT NULL DEFAULT '0' AFTER `active`;
$install = "
<h2>Install:</h2>
<ol>
<li>
<p>
Make sure you have imported TFS database. (OTdir/schema.sql OR OTdir/schemas/mysql.sql OR OTdir/forgottenserver.sql)
</p>
</li>
<li>Import the <a href='/engine/database/znote_schema.sql'>Znote AAC schema</a> to a <b>TFS database in phpmyadmin</b>.</li>
<li>
<p>
Edit config.php with correct mysql connection details.
</p>
</li>
</ol>
";
$connect = new mysqli($config['sqlHost'], $config['sqlUser'], $config['sqlPassword'], $config['sqlDatabase']);
if ($connect->connect_errno) {
die("Failed to connect to MySQL: (" . $connect->connect_errno . ") " . $connect->connect_error . $install);
}
function mysql_znote_escape_string($escapestr) {
global $connect;
return mysqli_real_escape_string($connect, $escapestr);
}
// Select single row from database
function mysql_select_single($query) {
global $connect;
global $aacQueries;
$aacQueries++;
global $accQueriesData;
$accQueriesData[] = "[" . elapsedTime() . "] " . $query;
$result = mysqli_query($connect,$query) or die(var_dump($query)."<br>(query - <font color='red'>SQL error</font>) <br>Type: <b>select_single</b> (select single row from database)<br><br>".mysqli_error($connect));
$row = mysqli_fetch_assoc($result);
return !empty($row) ? $row : false;
}
// Selecting multiple rows from database.
function mysql_select_multi($query){
global $connect;
global $aacQueries;
$aacQueries++;
global $accQueriesData;
$accQueriesData[] = "[" . elapsedTime() . "] " . $query;
$array = array();
$results = mysqli_query($connect,$query) or die(var_dump($query)."<br>(query - <font color='red'>SQL error</font>) <br>Type: <b>select_multi</b> (select multiple rows from database)<br><br>".mysqli_error($connect));
while($row = mysqli_fetch_assoc($results)) {
$array[] = $row;
}
return !empty($array) ? $array : false;
}
//////
// Query database without expecting returned results
// - mysql update
function mysql_update($query){ voidQuery($query); }
// mysql insert
function mysql_insert($query){ voidQuery($query); }
// mysql delete
function mysql_delete($query){ voidQuery($query); }
// Send a void query
function voidQuery($query) {
global $connect;
global $aacQueries;
$aacQueries++;
global $accQueriesData;
$accQueriesData[] = "[" . elapsedTime() . "] " . $query;
mysqli_query($connect,$query) or die(var_dump($query)."<br>(query - <font color='red'>SQL error</font>) <br>Type: <b>voidQuery</b> (voidQuery is used for update, insert or delete from database)<br><br>".mysqli_error($connect));
}
?>

View File

@@ -0,0 +1,312 @@
-- Start of Znote AAC database schema
SET @znote_version = '1.6';
CREATE TABLE IF NOT EXISTS `znote` (
`id` int NOT NULL AUTO_INCREMENT,
`version` varchar(30) NOT NULL COMMENT 'Znote AAC version',
`installed` int NOT NULL,
`cached` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_accounts` (
`id` int NOT NULL AUTO_INCREMENT,
`account_id` int NOT NULL,
`ip` bigint UNSIGNED NOT NULL,
`created` int NOT NULL,
`points` int DEFAULT 0,
`cooldown` int DEFAULT 0,
`active` tinyint NOT NULL DEFAULT '0',
`active_email` tinyint NOT NULL DEFAULT '0',
`activekey` int NOT NULL DEFAULT '0',
`flag` varchar(20) NOT NULL,
`secret` char(16) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_news` (
`id` int NOT NULL AUTO_INCREMENT,
`title` varchar(30) NOT NULL,
`text` text NOT NULL,
`date` int NOT NULL,
`pid` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_images` (
`id` int NOT NULL AUTO_INCREMENT,
`title` varchar(30) NOT NULL,
`desc` text NOT NULL,
`date` int NOT NULL,
`status` int NOT NULL,
`image` varchar(50) NOT NULL,
`delhash` varchar(30) NOT NULL,
`account_id` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_paypal` (
`id` int NOT NULL AUTO_INCREMENT,
`txn_id` varchar(30) NOT NULL,
`email` varchar(255) NOT NULL,
`accid` int NOT NULL,
`price` int NOT NULL,
`points` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_paygol` (
`id` int NOT NULL AUTO_INCREMENT,
`account_id` int NOT NULL,
`price` int NOT NULL,
`points` int NOT NULL,
`message_id` varchar(255) NOT NULL,
`service_id` varchar(255) NOT NULL,
`shortcode` varchar(255) NOT NULL,
`keyword` varchar(255) NOT NULL,
`message` varchar(255) NOT NULL,
`sender` varchar(255) NOT NULL,
`operator` varchar(255) NOT NULL,
`country` varchar(255) NOT NULL,
`currency` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_players` (
`id` int NOT NULL AUTO_INCREMENT,
`player_id` int NOT NULL,
`created` int NOT NULL,
`hide_char` tinyint NOT NULL,
`comment` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_player_reports` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`posx` int NOT NULL,
`posy` int NOT NULL,
`posz` int NOT NULL,
`report_description` varchar(255) NOT NULL,
`date` int NOT NULL,
`status` tinyint NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_changelog` (
`id` int NOT NULL AUTO_INCREMENT,
`text` varchar(255) NOT NULL,
`time` int NOT NULL,
`report_id` int NOT NULL,
`status` tinyint NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_shop` (
`id` int NOT NULL AUTO_INCREMENT,
`type` int NOT NULL,
`itemid` int DEFAULT NULL,
`count` int NOT NULL DEFAULT '1',
`description` varchar(255) NOT NULL,
`points` int NOT NULL DEFAULT '10',
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_shop_logs` (
`id` int NOT NULL AUTO_INCREMENT,
`account_id` int NOT NULL,
`player_id` int NOT NULL,
`type` int NOT NULL,
`itemid` int NOT NULL,
`count` int NOT NULL,
`points` int NOT NULL,
`time` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_shop_orders` (
`id` int NOT NULL AUTO_INCREMENT,
`account_id` int NOT NULL,
`type` int NOT NULL,
`itemid` int NOT NULL,
`count` int NOT NULL,
`time` int NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_visitors` (
`id` int NOT NULL AUTO_INCREMENT,
`ip` bigint NOT NULL,
`value` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_visitors_details` (
`id` int NOT NULL AUTO_INCREMENT,
`ip` bigint NOT NULL,
`time` int NOT NULL,
`type` tinyint NOT NULL,
`account_id` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
-- Forum 1/3 (boards)
CREATE TABLE IF NOT EXISTS `znote_forum` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`access` tinyint NOT NULL,
`closed` tinyint NOT NULL,
`hidden` tinyint NOT NULL,
`guild_id` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
-- Forum 2/3 (threads)
CREATE TABLE IF NOT EXISTS `znote_forum_threads` (
`id` int NOT NULL AUTO_INCREMENT,
`forum_id` int NOT NULL,
`player_id` int NOT NULL,
`player_name` varchar(50) NOT NULL,
`title` varchar(50) NOT NULL,
`text` text NOT NULL,
`created` int NOT NULL,
`updated` int NOT NULL,
`sticky` tinyint NOT NULL,
`hidden` tinyint NOT NULL,
`closed` tinyint NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
-- Forum 3/3 (posts)
CREATE TABLE IF NOT EXISTS `znote_forum_posts` (
`id` int NOT NULL AUTO_INCREMENT,
`thread_id` int NOT NULL,
`player_id` int NOT NULL,
`player_name` varchar(50) NOT NULL,
`text` text NOT NULL,
`created` int NOT NULL,
`updated` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
-- Pending characters for deletion
CREATE TABLE IF NOT EXISTS `znote_deleted_characters` (
`id` int NOT NULL AUTO_INCREMENT,
`original_account_id` int NOT NULL,
`character_name` varchar(255) NOT NULL,
`time` datetime NOT NULL,
`done` tinyint NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_guild_wars` (
`id` int NOT NULL AUTO_INCREMENT,
`limit` int NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
-- Helpdesk system
CREATE TABLE IF NOT EXISTS `znote_tickets` (
`id` int NOT NULL AUTO_INCREMENT,
`owner` int NOT NULL,
`username` varchar(32) CHARACTER SET latin1 NOT NULL,
`subject` text CHARACTER SET latin1 NOT NULL,
`message` text CHARACTER SET latin1 NOT NULL,
`ip` bigint NOT NULL,
`creation` int NOT NULL,
`status` varchar(20) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_tickets_replies` (
`id` int NOT NULL AUTO_INCREMENT,
`tid` int NOT NULL,
`username` varchar(32) CHARACTER SET latin1 NOT NULL,
`message` text CHARACTER SET latin1 NOT NULL,
`created` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `znote_global_storage` (
`key` varchar(32) NOT NULL,
`value` TEXT NOT NULL,
UNIQUE (`key`)
) ENGINE=InnoDB;
-- Character auction system
CREATE TABLE IF NOT EXISTS `znote_auction_player` (
`id` int NOT NULL AUTO_INCREMENT,
`player_id` int NOT NULL,
`original_account_id` int NOT NULL,
`bidder_account_id` int NOT NULL,
`time_begin` int NOT NULL,
`time_end` int NOT NULL,
`price` int NOT NULL,
`bid` int NOT NULL,
`deposit` int NOT NULL,
`sold` tinyint NOT NULL,
`claimed` tinyint NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
-- Populate basic info
INSERT INTO `znote` (`version`, `installed`) VALUES
(@znote_version, UNIX_TIMESTAMP(CURDATE()));
-- Add default forum boards
INSERT INTO `znote_forum` (`name`, `access`, `closed`, `hidden`, `guild_id`) VALUES
('Staff Board', '4', '0', '0', '0'),
('Tutors Board', '2', '0', '0', '0'),
('Discussion', '1', '0', '0', '0'),
('Feedback', '1', '0', '1', '0');
-- Convert existing accounts in database to be Znote AAC compatible
INSERT INTO `znote_accounts` (`account_id`, `ip`, `created`, `flag`)
SELECT
`a`.`id` AS `account_id`,
0 AS `ip`,
UNIX_TIMESTAMP(CURDATE()) AS `created`,
'' AS `flag`
FROM `accounts` AS `a`
LEFT JOIN `znote_accounts` AS `z`
ON `a`.`id` = `z`.`account_id`
WHERE `z`.`created` IS NULL;
-- Convert existing players in database to be Znote AAC compatible
INSERT INTO `znote_players` (`player_id`, `created`, `hide_char`, `comment`)
SELECT
`p`.`id` AS `player_id`,
UNIX_TIMESTAMP(CURDATE()) AS `created`,
0 AS `hide_char`,
'' AS `comment`
FROM `players` AS `p`
LEFT JOIN `znote_players` AS `z`
ON `p`.`id` = `z`.`player_id`
WHERE `z`.`created` IS NULL;
-- Delete duplicate account records
DELETE `d` FROM `znote_accounts` AS `d`
INNER JOIN (
SELECT `i`.`account_id`,
MAX(`i`.`id`) AS `retain`
FROM `znote_accounts` AS `i`
GROUP BY `i`.`account_id`
HAVING COUNT(`i`.`id`) > 1
) AS `x`
ON `d`.`account_id` = `x`.`account_id`
AND `d`.`id` != `x`.`retain`;
-- Delete duplicate player records
DELETE `d` FROM `znote_players` AS `d`
INNER JOIN (
SELECT `i`.`player_id`,
MAX(`i`.`id`) AS `retain`
FROM `znote_players` AS `i`
GROUP BY `i`.`player_id`
HAVING COUNT(`i`.`id`) > 1
) AS `x`
ON `d`.`player_id` = `x`.`player_id`
AND `d`.`id` != `x`.`retain`;
-- End of Znote AAC database schema

View File

@@ -0,0 +1,8 @@
<footer>
&copy; Znote AAC.
<?php
$finish = microtime(true);
$total_time = round(($finish - $start), 4);
echo 'Server date and clock is: '. getClock(false, true) .' Page generated in '. $total_time .' seconds. ';
?>
</footer>

View File

@@ -0,0 +1,167 @@
<?php
class Cache
{
protected $_file = false;
protected $_lifespan = 0;
protected $_content;
protected $_memory = false;
protected $_canMemory = false;
const EXT = '.cache.php';
/**
* @param string $file
* @access public
* @return void
**/
public function __construct($file) {
$cfg = config('cache');
$this->setExpiration($cfg['lifespan']);
if (function_exists('apcu_fetch')) {
$this->_canMemory = true;
$this->_memory = $cfg['memory'];
}
$this->_file = $file . self::EXT;
if (!$this->_memory && $cfg['memory']) die("
<p><strong>Configuration error!</strong>
<br>Cannot save cache to memory, but it is configured to do so.
<br>You need to enable PHP extension APCu to enable memory cache.
<br>Install it or set \$config['cache']['memory'] to false!
<br><strong>Ubuntu install:</strong> sudo apt install php-apcu</p>
");
}
/**
* Sets the cache expiration limit (IMPORTANT NOTE: seconds, NOT ms!).
*
* @param integer $span
* @access public
* @return void
**/
public function setExpiration($span) {
$this->_lifespan = $span;
}
/**
* Enable or disable memory RAM storage.
*
* @param bool $bool
* @access public
* @return bool $status
**/
public function useMemory($bool) {
if ($bool and $this->_canMemory) {
$this->_memory = true;
return true;
}
$this->_memory = false;
return false;
}
/**
* Set the content you'd like to cache.
*
* @param mixed $content
* @access public
* @return void
**/
public function setContent($content) {
$this->_content = (!$this->_memory && strtolower(gettype($content)) == 'array') ? json_encode($content) : $content;
}
/**
* Validates whether it is time to refresh the cache data or not.
*
* @access public
* @return boolean
**/
public function hasExpired() {
if ($this->_memory) {
return !apcu_exists($this->_file);
}
if (is_file($this->_file) && time() < filemtime($this->_file) + $this->_lifespan) {
return false;
}
return true;
}
/**
* Returns remaining time before scoreboard will update itself.
*
* @access public
* @return integer
**/
public function remainingTime() {
$remaining = 0;
if ($this->_memory) {
if (apcu_exists($this->_file)) {
$meta = apcu_cache_info();
foreach ($meta['cache_list'] AS $item) {
if ($item['info'] == $this->_file) {
$remaining = ($item['creation_time'] + $item['ttl']) - time();
return ($remaining > 0) ? $remaining : 0;
}
}
}
return $remaining;
}
if (!$this->hasExpired()) {
$remaining = (filemtime($this->_file) + $this->_lifespan) - time();
}
return $remaining;
}
/**
* Saves the content into its appropriate cache file.
*
* @access public
* @return void
**/
public function save() {
if ($this->_memory) {
return apcu_store($this->_file, $this->_content, $this->_lifespan);
}
$handle = fopen($this->_file, 'w');
fwrite($handle, $this->_content);
fclose($handle);
}
/**
* Loads the content from a specified cache file.
*
* @access public
* @return mixed
**/
public function load() {
if ($this->_memory) {
return apcu_fetch($this->_file);
}
if (!is_file($this->_file)) {
return false;
}
ob_start();
include_once($this->_file);
$content = ob_get_clean();
if (!isset($content) && strlen($content) == 0) {
return false;
}
if ($content = json_decode($content, true)) {
return (array) $content;
} else {
return $content;
}
}
}

View File

@@ -0,0 +1,613 @@
<?php
function setSession($key, $data) {
global $sessionPrefix;
$_SESSION[$sessionPrefix.$key] = $data;
}
function getSession($key) {
global $sessionPrefix;
return (isset($_SESSION[$sessionPrefix.$key])) ? $_SESSION[$sessionPrefix.$key] : false;
}
// Fetch and sanitize POST and GET values
function getValue($value) {
return (!empty($value)) ? sanitize($value) : false;
}
function SendGet($getArray, $location = 'error.php') {
$string = "";
$count = 0;
foreach ($getArray as $getKey => $getValue) {
if ($count > 0) $string .= '&';
$string .= "{$getKey}={$getValue}";
}
header("Location: {$location}?{$string}");
exit();
}
// Sweet error reporting
function data_dump($print = false, $var = false, $title = false) {
if ($title !== false) echo "<pre><font color='red' size='5'>$title</font><br>";
else echo '<pre>';
if ($print !== false) {
echo 'Print: - ';
print_r($print);
echo "<br>";
}
if ($var !== false) {
echo 'Var_dump: - ';
var_dump($var);
}
echo '</pre><br>';
}
function accountAccess($accountId, $TFS) {
$accountId = (int)$accountId;
$access = 0;
// TFS 0.3/4
$yourChars = mysql_select_multi("SELECT `name`, `group_id`, `account_id` FROM `players` WHERE `account_id`='$accountId';");
if ($yourChars !== false) {
foreach ($yourChars as $char) {
if ($TFS === 'TFS_03' || $TFS === 'OTHIRE') {
if ($char['group_id'] > $access) $access = $char['group_id'];
} else {
if ($char['group_id'] > 1) {
if ($access == 0) {
$acc = mysql_select_single("SELECT `type` FROM `accounts` WHERE `id`='". $char['account_id'] ."' LIMIT 1;");
$access = $acc['type'];
}
}
}
}
if ($access == 0) $access++;
return $access;
} else return false;
//
}
// Generate recovery key
function generate_recovery_key($lenght) {
$lenght = (int)$lenght;
$tmp = rand(1000, 9000);
$tmp += time();
$tmp = sha1($tmp);
$results = '';
for ($i = 0; $i < $lenght; $i++) $results = $results.''.$tmp[$i];
return $results;
}
// Calculate discount
function calculate_discount($orig, $new) {
$orig = (int)$orig;
$new = (int)$new;
$tmp = '';
if ($new >= $orig) {
if ($new != $orig) {
$calc = ($new/$orig) - 1;
$calc *= 100;
$tmp = '+'. floor($calc) .'%';
} else $tmp = '0%';
} else {
$calc = 1 - ($new/$orig);
$calc *= 100;
$tmp = '-'. floor($calc) .'%';
}
return $tmp;
}
// Proper URLs
function url($path = false) {
$folder = dirname($_SERVER['SCRIPT_NAME']);
return config('site_url') . '/' . $path;
}
function getCache() {
$results = mysql_select_single("SELECT `cached` FROM `znote`;");
return ($results !== false) ? $results['cached'] : false;
}
function setCache($time) {
$time = (int)$time;
mysql_update("UPDATE `znote` set `cached`='$time'");
}
// Get visitor basic data
function znote_visitors_get_data() {
return mysql_select_multi("SELECT `ip`, `value` FROM `znote_visitors` ORDER BY `id` DESC LIMIT 1000;");
}
// Set visitor basic data
function znote_visitor_set_data($visitor_data) {
$exist = false;
$ip = getIPLong();
foreach ((array)$visitor_data as $row) {
if ($ip == $row['ip']) {
$exist = true;
$value = $row['value'];
}
}
if ($exist && isset($value)) {
// Update the value
$value++;
mysql_update("UPDATE `znote_visitors` SET `value` = '$value' WHERE `ip` = '$ip'");
} else {
// Insert new row
mysql_insert("INSERT INTO `znote_visitors` (`ip`, `value`) VALUES ('$ip', '1')");
}
}
// Get visitor basic data
function znote_visitors_get_detailed_data($cache_time) {
$period = (int)time() - (int)$cache_time;
return mysql_select_multi("SELECT `ip`, `time`, `type`, `account_id` FROM `znote_visitors_details` WHERE `time` >= '$period' LIMIT 0, 50");
}
function znote_visitor_insert_detailed_data($type) {
$type = (int)$type;
/*
type 0 = normal visits
type 1 = register form
type 2 = character creation
type 3 = fetch highscores
type 4 = search character
*/
$time = time();
$ip = getIPLong();
if (user_logged_in()) {
$acc = (int)getSession('user_id');
mysql_insert("INSERT INTO `znote_visitors_details` (`ip`, `time`, `type`, `account_id`) VALUES ('$ip', '$time', '$type', '$acc')");
} else mysql_insert("INSERT INTO `znote_visitors_details` (`ip`, `time`, `type`, `account_id`) VALUES ('$ip', '$time', '$type', '0')");
}
function something () {
// Make acc data compatible:
$ip = getIPLong();
}
// Secret token
function create_token() {
echo 'Checking whether to create token or not<br />';
#if (empty($_SESSION['token'])) {
echo 'Creating token<br />';
$token = sha1(uniqid(time(), true));
$token2 = $token;
var_dump($token, $token2);
$_SESSION['token'] = $token2;
#}
echo "<input type=\"hidden\" name=\"token\" value=\"". $_SESSION['token'] ."\" />";
}
function reset_token() {
echo 'Reseting token<br />';
unset($_SESSION['token']);
}
// Time based functions
// 60 seconds to 1 minute
function second_to_minute($seconds) {
return ($seconds / 60);
}
// 1 minute to 60 seconds
function minute_to_seconds($minutes) {
return ($minutes * 60);
}
// 60 minutes to 1 hour
function minute_to_hour($minutes) {
return ($minutes / 60);
}
// 1 hour to 60 minutes
function hour_to_minute($hours) {
return ($hour * 60);
}
// seconds / 60 / 60 = hours.
function seconds_to_hours($seconds) {
$minutes = second_to_minute($seconds);
$hours = minute_to_hour($minutes);
return $hours;
}
function remaining_seconds_to_clock($seconds) {
return date("(H:i)",time() + $seconds);
}
/**
* Check if name contains more than configured max words
*
* @param string $string
* @return string|boolean
*/
function validate_name($string) {
return (str_word_count(trim($string)) > config('maxW')) ? false : trim($string);
}
// Checks if an IPv4(or localhost IPv6) address is valid
function validate_ip($ip) {
$ipL = safeIp2Long($ip);
$ipR = long2ip((int)$ipL);
if ($ip === $ipR) {
return true;
} elseif ($ip=='::1') {
return true;
} else {
return false;
}
}
// Fetch a config value. Etc config('vocations') will return vocation array from config.php.
function config($value) {
global $config;
return $config[$value];
}
// Some functions uses several configurations from config.php, so it sounds
// smarter to give them the whole array instead of calling the function all the time.
function fullConfig() {
global $config;
return $config;
}
// Capitalize Every Word In String.
function format_character_name($name) {
return ucwords(strtolower($name));
}
// Gets you the actual IP address even from users behind ISP proxies and so on.
function getIP() {
/*
$IP = '';
if (getenv('HTTP_CLIENT_IP')) {
$IP =getenv('HTTP_CLIENT_IP');
} elseif (getenv('HTTP_X_FORWARDED_FOR')) {
$IP =getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('HTTP_X_FORWARDED')) {
$IP =getenv('HTTP_X_FORWARDED');
} elseif (getenv('HTTP_FORWARDED_FOR')) {
$IP =getenv('HTTP_FORWARDED_FOR');
} elseif (getenv('HTTP_FORWARDED')) {
$IP = getenv('HTTP_FORWARDED');
} else {
$IP = $_SERVER['REMOTE_ADDR'];
} */
return $_SERVER['REMOTE_ADDR'];
}
function safeIp2Long($ip) {
return sprintf('%u', ip2long($ip));
}
// Gets you the actual IP address even from users in long type
function getIPLong() {
return safeIp2Long(getIP());
}
// Deprecated, just use count($array) instead.
function array_length($ar) {
$r = 1;
foreach($ar as $a) {
$r++;
}
return $r;
}
// Parameter: level, returns experience for that level from an experience table.
function level_to_experience($level) {
return 50/3*(pow($level, 3) - 6*pow($level, 2) + 17*$level - 12);
}
// Parameter: players.hide_char returns: Status word inside a font with class identifier so it can be designed later on by CSS.
function hide_char_to_name($id) {
$id = (int)$id;
if ($id == 1) {
return 'hidden';
} else {
return 'visible';
}
}
// Parameter: players.online returns: Status word inside a font with class identifier so it can be designed later on by CSS.
function online_id_to_name($id) {
$id = (int)$id;
if ($id == 1) {
return '<font class="status_online">ONLINE</font>';
} else {
return '<font class="status_offline">offline</font>';
}
}
// Parameter: players.vocation_id. Returns: Configured vocation name.
function vocation_id_to_name($id) {
$vocations = config('vocations');
return (isset($vocations[$id]['name'])) ? $vocations[$id]['name'] : "{$id} - Unknown";
}
// Parameter: players.name. Returns: Configured vocation id.
function vocation_name_to_id($name) {
$vocations = config('vocations');
foreach ($vocations as $id => $vocation)
if ($vocation['name'] == $name)
return $id;
return false;
}
// Parameter: players.group_id. Returns: Configured group name.
function group_id_to_name($id) {
$positions = config('ingame_positions');
return ($positions[$id] >= 0) ? $positions[$id] : false;
}
function gender_exist($gender) {
// Range of allowed gender ids, fromid toid
if ($gender >= 0 && $gender <= 1) {
return true;
} else {
return false;
}
}
function skillid_to_name($skillid) {
$skillname = array(
0 => 'fist fighting',
1 => 'club fighting',
2 => 'sword fighting',
3 => 'axe fighting',
4 => 'distance fighting',
5 => 'shielding',
6 => 'fishing',
7 => 'experience', // Hardcoded, does not actually exist in database as a skillid.
8 => 'magic level' // Hardcoded, does not actually exist in database as a skillid.
);
return ($skillname[$skillid] >= 0) ? $skillname[$skillid] : false;
}
// Parameter: players.town_id. Returns: Configured town name.
function town_id_to_name($id) {
$towns = config('towns');
return (array_key_exists($id, $towns)) ? $towns[$id] : 'Missing Town';
}
// Unless you have an internal mail server then mail sending will not be supported in this version.
function email($to, $subject, $body) {
mail($to, $subject, $body, 'From: TEST');
}
function logged_in_redirect() {
if (user_logged_in() === true) {
header('Location: myaccount.php');
}
}
function protect_page() {
if (user_logged_in() === false) {
header('Location: protected.php');
exit();
}
}
// When function is called, you will be redirected to protect_page and deny access to rest of page, as long as you are not admin.
function admin_only($user_data) {
// Chris way
$gotAccess = is_admin($user_data);
if ($gotAccess == false) {
logged_in_redirect();
exit();
}
}
function is_admin($user_data) {
if (config('ServerEngine') === 'OTHIRE')
return in_array($user_data['id'], config('page_admin_access')) ? true : false;
else
return in_array($user_data['name'], config('page_admin_access')) ? true : false;
}
function array_sanitize(&$item) {
$item = htmlentities(strip_tags(mysql_znote_escape_string($item)));
}
function sanitize($data) {
return htmlentities(strip_tags(mysql_znote_escape_string($data)));
}
function output_errors($errors) {
return '<ul><li>'. implode('</li><li>', $errors) .'</li></ul>';
}
// Resize images
function resize_imagex($file, $width, $height) {
list($w, $h) = getimagesize($file['tmp']);
$ratio = max($width/$w, $height/$h);
$h = ceil($height / $ratio);
$x = ($w - $width / $ratio) / 2;
$w = ceil($width / $ratio);
$path = 'engine/guildimg/'.$file['new_name'];
$imgString = file_get_contents($file['tmp']);
$image = imagecreatefromstring($imgString);
$tmp = imagecreatetruecolor($width, $height);
imagecopyresampled($tmp, $image,
0, 0,
$x, 0,
$width, $height,
$w, $h);
imagegif($tmp, $path);
imagedestroy($image);
imagedestroy($tmp);
return true;
}
// Guild logo upload security
function check_image($image) {
$image_data = array('new_name' => $_GET['name'].'.gif', 'name' => $image['name'], 'tmp' => $image['tmp_name'], 'error' => $image['error'], 'size' => $image['size'], 'type' => $image['type']);
// First security check, quite useless but still do its job
if ($image_data['type'] === 'image/gif') {
// Second security check, lets go
$check = getimagesize($image_data['tmp']);
if ($check) {
// Third
if ($check['mime'] === 'image/gif') {
$path_info = pathinfo($image_data['name']);
// Last one
if ($path_info['extension'] === 'gif') {
// Resize image
$img = resize_imagex($image_data, 100, 100);
if ($img) {
header('Location: guilds.php?name='. $_GET['name']);
exit();
}
} else {
header('Location: guilds.php?error=Only gif images accepted, you uploaded:['.$path_info['extension'].'].&name='. $_GET['name']);
exit();
}
} else {
header('Location: guilds.php?error=Only gif images accepted, you uploaded:['.$check['mime'].'].&name='. $_GET['name']);
exit();
}
} else {
header('Location: guilds.php?error=Uploaded image is invalid.&name='. $_GET['name']);
exit();
}
} else {
header('Location: guilds.php?error=Only gif images are accepted, you uploaded:['.$image_data['type'].'].&name='. $_GET['name']);
exit();
}
}
// Check guild logo
function logo_exists($guild) {
$guild = sanitize($guild);
if (file_exists('engine/guildimg/'.$guild.'.gif')) {
echo'engine/guildimg/'.$guild.'.gif';
} else {
echo'engine/guildimg/default@logo.gif';
}
}
function generateRandomString($length = 16) {
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
function verifyGoogleReCaptcha($postResponse = null) {
if(!isset($postResponse) || empty($postResponse)) {
return false;
}
$recaptcha_api_url = 'https://www.google.com/recaptcha/api/siteverify';
$secretKey = config('captcha_secret_key');
$ip = $_SERVER['REMOTE_ADDR'];
$params = 'secret='.$secretKey.'&response='.$postResponse.'&remoteip='.$ip;
$useCurl = config('captcha_use_curl');
if($useCurl) {
$curl_connection = curl_init($recaptcha_api_url);
curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $params);
$response = curl_exec($curl_connection);
curl_close($curl_connection);
} else {
$response = file_get_contents($recaptcha_api_url . '?' . $params);
}
$json = json_decode($response);
return isset($json->success) && $json->success;
}
// html encoding function (encode any string to valid UTF-8 HTML)
function hhb_tohtml(/*string*/ $str)/*:string*/ {
return htmlentities($str, ENT_QUOTES | ENT_HTML401 | ENT_SUBSTITUTE | ENT_DISALLOWED, 'UTF-8', true);
}
// php5-compatibile version of php7's random_bytes()
// $crypto_strong: a boolean value that determines if the algorithm used was "cryptographically strong"
function random_bytes_compat($length, &$crypto_strong = null) {
$crypto_strong = false;
if (!is_int($length)) {
throw new \InvalidArgumentException("argument 1 must be an int, is " . gettype($length));
}
if ($length < 0) {
throw new \InvalidArgumentException("length must be >= 0");
}
if (is_callable("random_bytes")) {
$crypto_strong = true;
return random_bytes($length);
}
if (is_callable("openssl_random_pseudo_bytes")) {
return openssl_random_pseudo_bytes($length, $crypto_strong);
}
$ret = @file_get_contents("/dev/urandom", false, null, 0, $length);
if (is_string($ret) && strlen($ret) === $length) {
$crypto_strong = true;
return $ret;
}
// fallback to non-cryptographically-secure mt_rand() implementation...
$crypto_strong = false;
$ret = "";
for ($i = 0; $i < $length; ++$i) {
$ret .= chr(mt_rand(0, 255));
}
return $ret;
}
// hash_equals legacy support < 5.6
if(!function_exists('hash_equals')) {
function hash_equals($str1, $str2) {
if(strlen($str1) != strlen($str2)) {
return false;
}
$res = $str1 ^ $str2;
$ret = 0;
for($i = strlen($res) - 1; $i >= 0; $i--) {
$ret |= ord($res[$i]);
}
return !$ret;
}
}
?>

View File

@@ -0,0 +1,34 @@
<?php
/* Returns a PHP array $id => 'name'
$items = getItemList();
echo $items[2160]; // Returns 'Crystal Coin'
*/
function getItemList() {
return parseItems();
}
function getItemById($id) {
$items = parseItems();
if(isset($items[$id])) {
return $items[$id];
}
return false;
}
function parseItems() {
$file = Config('server_path') . '/data/items/items.xml';
if (file_exists($file)) {
$itemList = array();
$items = simplexml_load_file($file);
// Create our parsed item list
foreach ($items->children() as $item) {
if ($item['id'] && $item['name'] != NULL) {
$itemList[(int)$item['id']] = (string)$item['name'];
}
}
return $itemList;
}
return $file;
}
?>

View File

@@ -0,0 +1,99 @@
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
class Mail {
protected $_config = false;
/**
* @param array $config
* @access public
* @return void
**/
public function __construct($config) {
$this->_config = $config;
}
/**
* Sets the cache expiration limit (IMPORTANT NOTE: seconds, NOT ms!).
*
* @param string $to, string $title, string $text, string $accname
* @access public
* @return boolean
**/
public function sendMail($to, $title, $text, $accname = '') {
//SMTP needs accurate times, and the PHP time zone MUST be set
//This should be done in your php.ini, but this is how to do it if you don't have access to that
//date_default_timezone_set('Etc/UTC');
require_once __DIR__.'/../../PHPMailer/src/Exception.php';
require_once __DIR__.'/../../PHPMailer/src/PHPMailer.php';
require_once __DIR__.'/../../PHPMailer/src/SMTP.php';
//Create a new PHPMailer instance
$mail = new PHPMailer();
//Tell PHPMailer to use SMTP
$mail->isSMTP();
//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = ($this->_config['debug']) ? 2 : 0;
//Ask for HTML-friendly debug output
$mail->Debugoutput = 'html';
//Set the hostname of the mail server
$mail->Host = $this->_config['host'];
//Set the SMTP port number - likely to be 25, 465 or 587
$mail->Port = $this->_config['port'];
//Whether to use SMTP authentication
$mail->SMTPAuth = true;
$mail->SMTPSecure = $this->_config['securityType'];
//Username to use for SMTP authentication
$mail->Username = $this->_config['username'];
//Password to use for SMTP authentication
$mail->Password = $this->_config['password'];
//Set who the message is to be sent from
$mail->setFrom($this->_config['email'], $this->_config['fromName']);
//Set who the message is to be sent to
$mail->addAddress($to, $accname);
//Set the subject line
$mail->Subject = $title;
// Body
$mail->Body = $text;
// Convert HTML -> plain for legacy mail recievers
// Create new lines instead of <br> html tags.
$text = str_replace("<br>", "\n", $text);
$text = str_replace("<br\>", "\n", $text);
$text = str_replace("<br \>", "\n", $text);
// Then get rid of the rest of the html tags.
$text = strip_tags($text);
//Replace the plain text body with one created manually
$mail->AltBody = $text;
//send the message, check for errors
$status = false;
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
exit();
} else {
$status = true;
}
return $status;
}
}

View File

@@ -0,0 +1,285 @@
<?php
/** https://github.com/Voronenko/PHPOTP/blob/08cda9cb9c30b7242cf0b3a9100a6244a2874927/code/base32static.php
* Encode in Base32 based on RFC 4648.
* Requires 20% more space than base64
* Great for case-insensitive filesystems like Windows and URL's (except for = char which can be excluded using the pad option for urls)
*
* @package default
* @author Bryan Ruiz
**/
class Base32Static {
private static $map = array(
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
'=' // padding character
);
private static $flippedMap = array(
'A'=>'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 'H'=>'7',
'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 'O'=>'14', 'P'=>'15',
'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 'W'=>'22', 'X'=>'23',
'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', '6'=>'30', '7'=>'31'
);
/**
* Use padding false when encoding for urls
*
* @return base32 encoded string
* @author Bryan Ruiz
**/
public static function encode($input, $padding = true) {
if(empty($input)) return "";
$input = str_split($input);
$binaryString = "";
for($i = 0; $i < count($input); $i++) {
$binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, '0', STR_PAD_LEFT);
}
$fiveBitBinaryArray = str_split($binaryString, 5);
$base32 = "";
$i=0;
while($i < count($fiveBitBinaryArray)) {
$base32 .= self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5,'0'), 2, 10)];
$i++;
}
if($padding && ($x = strlen($binaryString) % 40) != 0) {
if($x == 8) $base32 .= str_repeat(self::$map[32], 6);
else if($x == 16) $base32 .= str_repeat(self::$map[32], 4);
else if($x == 24) $base32 .= str_repeat(self::$map[32], 3);
else if($x == 32) $base32 .= self::$map[32];
}
return $base32;
}
public static function decode($input) {
if(empty($input)) return;
$paddingCharCount = substr_count($input, self::$map[32]);
$allowedValues = array(6,4,3,1,0);
if(!in_array($paddingCharCount, $allowedValues)) return false;
for($i=0; $i<4; $i++){
if($paddingCharCount == $allowedValues[$i] &&
substr($input, -($allowedValues[$i])) != str_repeat(self::$map[32], $allowedValues[$i])) return false;
}
$input = str_replace('=','', $input);
$input = str_split($input);
$binaryString = "";
for($i=0; $i < count($input); $i = $i+8) {
$x = "";
if(!in_array($input[$i], self::$map)) return false;
for($j=0; $j < 8; $j++) {
$x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
}
$eightBits = str_split($x, 8);
for($z = 0; $z < count($eightBits); $z++) {
$binaryString .= ( ($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48 ) ? $y:"";
}
}
return $binaryString;
}
}
// http://www.faqs.org/rfcs/rfc6238.html
// https://github.com/Voronenko/PHPOTP/blob/08cda9cb9c30b7242cf0b3a9100a6244a2874927/code/rfc6238.php
// Local changes: http -> https, consistent indentation, 200x200 -> 300x300 QR image size, PHP end tag
class TokenAuth6238 {
/**
* verify
*
* @param string $secretkey Secret clue (base 32).
* @return bool True if success, false if failure
*/
public static function verify($secretkey, $code, $rangein30s = 3) {
$key = base32static::decode($secretkey);
$unixtimestamp = time()/30;
for($i=-($rangein30s); $i<=$rangein30s; $i++) {
$checktime = (int)($unixtimestamp+$i);
$thiskey = self::oath_hotp($key, $checktime);
if ((int)$code == self::oath_truncate($thiskey,6)) {
return true;
}
}
return false;
}
public static function getTokenCode($secretkey,$rangein30s = 3) {
$result = "";
$key = base32static::decode($secretkey);
$unixtimestamp = time()/30;
for($i=-($rangein30s); $i<=$rangein30s; $i++) {
$checktime = (int)($unixtimestamp+$i);
$thiskey = self::oath_hotp($key, $checktime);
$result = $result." # ".self::oath_truncate($thiskey,6);
}
return $result;
}
public static function getTokenCodeDebug($secretkey,$rangein30s = 3) {
$result = "";
print "<br/>SecretKey: $secretkey <br/>";
$key = base32static::decode($secretkey);
print "Key(base 32 decode): $key <br/>";
$unixtimestamp = time()/30;
print "UnixTimeStamp (time()/30): $unixtimestamp <br/>";
for($i=-($rangein30s); $i<=$rangein30s; $i++) {
$checktime = (int)($unixtimestamp+$i);
print "Calculating oath_hotp from (int)(unixtimestamp +- 30sec offset): $checktime basing on secret key<br/>";
$thiskey = self::oath_hotp($key, $checktime, true);
print "======================================================<br/>";
print "CheckTime: $checktime oath_hotp:".$thiskey."<br/>";
$result = $result." # ".self::oath_truncate($thiskey,6,true);
}
return $result;
}
public static function getBarCodeUrl($username, $domain, $secretkey, $issuer) {
$url = "https://chart.apis.google.com/chart";
$url = $url."?chs=300x300&chld=M|0&cht=qr&chl=otpauth://totp/";
$url = $url.$username . "@" . $domain . "%3Fsecret%3D" . $secretkey . '%26issuer%3D' . rawurlencode($issuer);
return $url;
}
public static function generateRandomClue($length = 16) {
$b32 = "234567QWERTYUIOPASDFGHJKLZXCVBNM";
$s = "";
for ($i = 0; $i < $length; $i++)
$s .= $b32[rand(0,31)];
return $s;
}
private static function hotp_tobytestream($key) {
$result = array();
$last = strlen($key);
for ($i = 0; $i < $last; $i = $i + 2) {
$x = $key[$i] + $key[$i + 1];
$x = strtoupper($x);
$x = hexdec($x);
$result = $result.chr($x);
}
return $result;
}
private static function oath_hotp ($key, $counter, $debug=false) {
$result = "";
$orgcounter = $counter;
$cur_counter = array(0,0,0,0,0,0,0,0);
if ($debug) {
print "Packing counter $counter (".dechex($counter).")into binary string - pay attention to hex representation of key and binary representation<br/>";
}
for($i=7;$i>=0;$i--) { // C for unsigned char, * for repeating to the end of the input data
$cur_counter[$i] = pack ('C*', $counter);
if ($debug) {
print $cur_counter[$i]."(".dechex(ord($cur_counter[$i])).")"." from $counter <br/>";
}
$counter = $counter >> 8;
}
if ($debug) {
foreach ($cur_counter as $char) {
print ord($char) . " ";
}
print "<br/>";
}
$binary = implode($cur_counter);
// Pad to 8 characters
str_pad($binary, 8, chr(0), STR_PAD_LEFT);
if ($debug) {
print "Prior to HMAC calculation pad with zero on the left until 8 characters.<br/>";
print "Calculate sha1 HMAC(Hash-based Message Authentication Code http://en.wikipedia.org/wiki/HMAC).<br/>";
print "hash_hmac ('sha1', $binary, $key)<br/>";
}
$result = hash_hmac ('sha1', $binary, $key);
if ($debug) {
print "Result: $result <br/>";
}
return $result;
}
private static function oath_truncate($hash, $length = 6, $debug=false) {
$result="";
// Convert to dec
if($debug) {
print "converting hex hash into characters<br/>";
}
$hashcharacters = str_split($hash,2);
if($debug) {
print_r($hashcharacters);
print "<br/>and convert to decimals:<br/>";
}
for ($j=0; $j<count($hashcharacters); $j++) {
$hmac_result[]=hexdec($hashcharacters[$j]);
}
if($debug) {
print_r($hmac_result);
}
// http://php.net/manual/ru/function.hash-hmac.php
// adopted from brent at thebrent dot net 21-May-2009 08:17 comment
$offset = $hmac_result[19] & 0xf;
if($debug) {
print "Calculating offset as 19th element of hmac:".$hmac_result[19]."<br/>";
print "offset:".$offset;
}
$result = (
(($hmac_result[$offset+0] & 0x7f) << 24 ) |
(($hmac_result[$offset+1] & 0xff) << 16 ) |
(($hmac_result[$offset+2] & 0xff) << 8 ) |
($hmac_result[$offset+3] & 0xff)
) % pow(10,$length);
return $result;
}
}
?>

View File

@@ -0,0 +1,89 @@
<?php
// List of characters: $, {}, []
class Token {
public static function generate() {
$token = sha1(uniqid(time(), true));
$_SESSION['token'] = $token;
}
/**
* Displays a random token to prevent CSRF attacks.
*
* @access public
* @static true
* @return void
**/
public static function create() {
echo '<input type="hidden" name="token" value="' . self::get() . '" />';
}
/**
* Returns the active token, if there is one.
*
* @access public
* @static true
* @return mixed
**/
public static function get() {
return isset($_SESSION['token']) ? $_SESSION['token'] : false;
}
/**
* Validates whether the active token is valid or not.
*
* @param string $post
* @access public
* @static true
* @return boolean
**/
public static function isValid($post) {
if (config('use_token')) {
// Token doesn't exist yet, return false.
if (!self::get()) {
return false;
}
// Token was invalid, return false.
if ($post == $_SESSION['old_token'] || $post == $_SESSION['token']) {
//self::_reset();
return true;
} else {
return false;
}
} else {
return true;
}
}
/**
* Destroys the active token.
*
* @access protected
* @static true
* @return void
**/
protected static function _reset() {
unset($_SESSION['token']);
}
/**
* Displays information on both the post token and the session token.
*
* @param string $post
* @access public
* @static true
* @return void
**/
public static function debug($post) {
echo '<pre>', var_dump(array(
'post' => $post,
'old_token' => $_SESSION['old_token'],
'token' => self::get()
)), '</pre>';
}
}
?>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -0,0 +1,175 @@
<?php if (version_compare(phpversion(), '5.6', '<')) die('PHP version 5.6 or higher is required.');
$l_time = microtime(true);
$l_start = $l_time;
function elapsedTime($l_start = false, $l_time = false) {
if ($l_start === false) global $l_start;
if ($l_time === false) global $l_time;
$l_time = explode(' ', microtime());
$l_finish = $l_time[1] + $l_time[0];
return round(($l_finish - $l_start), 4);
}
$time = time();
$version = '1.6';
$aacQueries = 0;
$accQueriesData = array();
session_start();
ob_start();
require_once 'config.php';
$sessionPrefix = $config['session_prefix'];
if ($config['paypal']['enabled'] || $config['use_captcha']) {
$curlcheck = extension_loaded('curl');
if (!$curlcheck) die("php cURL is not enabled. It is required to for paypal or captcha services.<br>1. Find your php.ini file.<br>2. Uncomment extension=php_curl<br>Restart web server.<br><br><b>If you don't want this then disable paypal & use_captcha in config.php.</b>");
}
if ($config['use_captcha'] && !extension_loaded('openssl')) {
die("php openSSL is not enabled. It is required to for captcha services.<br>1. Find your php.ini file.<br>2. Uncomment extension=php_openssl<br>Restart web server.<br><br><b>If you don't want this then disable use_captcha in config.php.</b>");
}
// References ( & ) works as an alias for a variable,
// they point to the same memmory, instead of duplicating it.
if (!isset($config['TFSVersion'])) $config['TFSVersion'] = &$config['ServerEngine'];
if (!isset($config['ServerEngine'])) $config['ServerEngine'] = &$config['TFSVersion'];
require_once 'database/connect.php';
require_once 'function/general.php';
require_once 'function/users.php';
require_once 'function/cache.php';
require_once 'function/mail.php';
require_once 'function/token.php';
require_once 'function/itemparser/itemlistparser.php';
if (isset($_SESSION['token'])) {
$_SESSION['old_token'] = $_SESSION['token'];
}
Token::generate();
$tfs_10_hasPremDays = true; // https://github.com/otland/forgottenserver/pull/2813
if (user_logged_in() === true) {
$session_user_id = getSession('user_id');
if ($config['ServerEngine'] !== 'OTHIRE') {
if ($config['ServerEngine'] == 'TFS_10') {
$hasPremDays = mysql_select_single("SHOW COLUMNS from `accounts` WHERE `Field` = 'premdays'");
if ($hasPremDays === false) {
$tfs_10_hasPremDays = false;
$user_data = user_data($session_user_id, 'id', 'name', 'password', 'email', 'premium_ends_at');
$user_data['premdays'] = ($user_data['premium_ends_at'] - time() > 0) ? floor(($user_data['premium_ends_at'] - time()) / 86400) : 0;
} else {
$user_data = user_data($session_user_id, 'id', 'name', 'password', 'email', 'premdays');
}
} else {
$user_data = user_data($session_user_id, 'id', 'name', 'password', 'email', 'premdays');
}
} else
$user_data = user_data($session_user_id, 'id', 'password', 'email', 'premend');
$user_znote_data = user_znote_account_data($session_user_id, 'ip', 'created', 'points', 'cooldown', 'flag' ,'active_email');
}
$errors = array();
// Log IP
if ($config['log_ip']) {
$visitor_config = $config['ip_security'];
$flush = $config['flush_ip_logs'];
if ($flush != false) {
$timef = $time - $flush;
if (getCache() < $timef) {
$timef = $time - $visitor_config['time_period'];
mysql_delete("DELETE FROM znote_visitors_details WHERE time <= '$timef'");
setCache($time);
}
}
$visitor_data = znote_visitors_get_data();
znote_visitor_set_data($visitor_data); // update or insert data
znote_visitor_insert_detailed_data(0); // detailed data
$visitor_detailed = znote_visitors_get_detailed_data($visitor_config['time_period']);
// max activity
$v_activity = 0;
$v_register = 0;
$v_highscore = 0;
$v_c_char = 0;
$v_s_char = 0;
$v_form = 0;
foreach ((array)$visitor_detailed as $v_d) {
// Activity
if ($v_d['ip'] == getIPLong()) {
// count each type of visit
switch ($v_d['type']) {
case 0: // max activity
$v_activity++;
break;
case 1: // account registered
$v_register++;
$v_form++;
break;
case 2: // character creations
$v_c_char++;
$v_form++;
break;
case 3: // Highscore fetched
$v_highscore++;
$v_form++;
break;
case 4: // character searched
$v_s_char++;
$v_form++;
break;
case 5: // Other forms (login.?)
$v_form++;
break;
}
}
}
// Deny access if activity is too high
if ($v_activity > $visitor_config['max_activity']) die("Chill down. Your web activity is too big. max_activity");
if ($v_register > $visitor_config['max_account']) die("Chill down. You can't create multiple accounts that fast. max_account");
if ($v_c_char > $visitor_config['max_character']) die("Chill down. Your web activity is too big. max_character");
if ($v_form > $visitor_config['max_post']) die("Chill down. Your web activity is too big. max_post");
//var_dump($v_activity, $v_register, $v_highscore, $v_c_char, $v_s_char, $v_form);
//echo ' <--- IP logging activity past 10 seconds.';
}
// Sub page override system
$filename = explode('/', $_SERVER['SCRIPT_NAME']);
$filename = $filename[count($filename) - 1];
$page_filename = str_replace('.php', '', $filename);
if ($config['allowSubPages']) {
require_once 'layout/sub.php';
if (isset($subpages) && !empty($subpages)) {
foreach ($subpages as $page) {
if ($page['override'] && $page['file'] === $filename) {
require_once 'layout/overall/header.php';
require_once 'layout/sub/'.$page['file'];
require_once 'layout/overall/footer.php';
exit;
}
}
} else {
?>
<div style="background-color: white; padding: 20px; width: 100%; float:left;">
<h2 style="color: black;">Old layout!</h2>
<p style="color: black;">The layout is running an outdated sub system which is not compatible with this version of Znote AAC.</p>
<p style="color: black;">The file /layout/sub.php is outdated.
<br>Please update it to look like <a style="color: orange;" target="_BLANK" href="https://github.com/Znote/ZnoteAAC/blob/master/layout/sub.php">THIS.</a>
</p>
</div>
<?php
}
}
?>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,135 @@
/* NicEdit - Micro Inline WYSIWYG
* Copyright 2007-2008 Brian Kirchoff
*
* NicEdit is distributed under the terms of the MIT license
* For more information visit http://nicedit.com/
* Do not remove this copyright message
*/
var bkExtend=function(){var A=arguments;if(A.length==1){A=[this,A[0]]}for(var B in A[1]){A[0][B]=A[1][B]}return A[0]};function bkClass(){}bkClass.prototype.construct=function(){};bkClass.extend=function(C){var A=function(){if(arguments[0]!==bkClass){return this.construct.apply(this,arguments)}};var B=new this(bkClass);bkExtend(B,C);A.prototype=B;A.extend=this.extend;return A};var bkElement=bkClass.extend({construct:function(B,A){if(typeof (B)=="string"){B=(A||document).createElement(B)}B=$BK(B);return B},appendTo:function(A){A.appendChild(this);return this},appendBefore:function(A){A.parentNode.insertBefore(this,A);return this},addEvent:function(B,A){bkLib.addEvent(this,B,A);return this},setContent:function(A){this.innerHTML=A;return this},pos:function(){var C=curtop=0;var B=obj=this;if(obj.offsetParent){do{C+=obj.offsetLeft;curtop+=obj.offsetTop}while(obj=obj.offsetParent)}var A=(!window.opera)?parseInt(this.getStyle("border-width")||this.style.border)||0:0;return[C+A,curtop+A+this.offsetHeight]},noSelect:function(){bkLib.noSelect(this);return this},parentTag:function(A){var B=this;do{if(B&&B.nodeName&&B.nodeName.toUpperCase()==A){return B}B=B.parentNode}while(B);return false},hasClass:function(A){return this.className.match(new RegExp("(\\s|^)nicEdit-"+A+"(\\s|$)"))},addClass:function(A){if(!this.hasClass(A)){this.className+=" nicEdit-"+A}return this},removeClass:function(A){if(this.hasClass(A)){this.className=this.className.replace(new RegExp("(\\s|^)nicEdit-"+A+"(\\s|$)")," ")}return this},setStyle:function(A){var B=this.style;for(var C in A){switch(C){case"float":B.cssFloat=B.styleFloat=A[C];break;case"opacity":B.opacity=A[C];B.filter="alpha(opacity="+Math.round(A[C]*100)+")";break;case"className":this.className=A[C];break;default:B[C]=A[C]}}return this},getStyle:function(A,C){var B=(!C)?document.defaultView:C;if(this.nodeType==1){return(B&&B.getComputedStyle)?B.getComputedStyle(this,null).getPropertyValue(A):this.currentStyle[bkLib.camelize(A)]}},remove:function(){this.parentNode.removeChild(this);return this},setAttributes:function(A){for(var B in A){this[B]=A[B]}return this}});var bkLib={isMSIE:(navigator.appVersion.indexOf("MSIE")!=-1),addEvent:function(C,B,A){(C.addEventListener)?C.addEventListener(B,A,false):C.attachEvent("on"+B,A)},toArray:function(C){var B=C.length,A=new Array(B);while(B--){A[B]=C[B]}return A},noSelect:function(B){if(B.setAttribute&&B.nodeName.toLowerCase()!="input"&&B.nodeName.toLowerCase()!="textarea"){B.setAttribute("unselectable","on")}for(var A=0;A<B.childNodes.length;A++){bkLib.noSelect(B.childNodes[A])}},camelize:function(A){return A.replace(/\-(.)/g,function(B,C){return C.toUpperCase()})},inArray:function(A,B){return(bkLib.search(A,B)!=null)},search:function(A,C){for(var B=0;B<A.length;B++){if(A[B]==C){return B}}return null},cancelEvent:function(A){A=A||window.event;if(A.preventDefault&&A.stopPropagation){A.preventDefault();A.stopPropagation()}return false},domLoad:[],domLoaded:function(){if(arguments.callee.done){return }arguments.callee.done=true;for(i=0;i<bkLib.domLoad.length;i++){bkLib.domLoad[i]()}},onDomLoaded:function(A){this.domLoad.push(A);if(document.addEventListener){document.addEventListener("DOMContentLoaded",bkLib.domLoaded,null)}else{if(bkLib.isMSIE){document.write("<style>.nicEdit-main p { margin: 0; }</style><script id=__ie_onload defer "+((location.protocol=="https:")?"src='javascript:void(0)'":"src=//0")+"><\/script>");$BK("__ie_onload").onreadystatechange=function(){if(this.readyState=="complete"){bkLib.domLoaded()}}}}window.onload=bkLib.domLoaded}};function $BK(A){if(typeof (A)=="string"){A=document.getElementById(A)}return(A&&!A.appendTo)?bkExtend(A,bkElement.prototype):A}var bkEvent={addEvent:function(A,B){if(B){this.eventList=this.eventList||{};this.eventList[A]=this.eventList[A]||[];this.eventList[A].push(B)}return this},fireEvent:function(){var A=bkLib.toArray(arguments),C=A.shift();if(this.eventList&&this.eventList[C]){for(var B=0;B<this.eventList[C].length;B++){this.eventList[C][B].apply(this,A)}}}};function __(A){return A}Function.prototype.closure=function(){var A=this,B=bkLib.toArray(arguments),C=B.shift();return function(){if(typeof (bkLib)!="undefined"){return A.apply(C,B.concat(bkLib.toArray(arguments)))}}};Function.prototype.closureListener=function(){var A=this,C=bkLib.toArray(arguments),B=C.shift();return function(E){E=E||window.event;if(E.target){var D=E.target}else{var D=E.srcElement}return A.apply(B,[E,D].concat(C))}};
var nicEditorConfig = bkClass.extend({
buttons : {
'bold' : {name : __('Click to Bold'), command : 'Bold', tags : ['B','STRONG'], css : {'font-weight' : 'bold'}, key : 'b'},
'italic' : {name : __('Click to Italic'), command : 'Italic', tags : ['EM','I'], css : {'font-style' : 'italic'}, key : 'i'},
'underline' : {name : __('Click to Underline'), command : 'Underline', tags : ['U'], css : {'text-decoration' : 'underline'}, key : 'u'},
'left' : {name : __('Left Align'), command : 'justifyleft', noActive : true},
'center' : {name : __('Center Align'), command : 'justifycenter', noActive : true},
'right' : {name : __('Right Align'), command : 'justifyright', noActive : true},
'justify' : {name : __('Justify Align'), command : 'justifyfull', noActive : true},
'ol' : {name : __('Insert Ordered List'), command : 'insertorderedlist', tags : ['OL']},
'ul' : {name : __('Insert Unordered List'), command : 'insertunorderedlist', tags : ['UL']},
'subscript' : {name : __('Click to Subscript'), command : 'subscript', tags : ['SUB']},
'superscript' : {name : __('Click to Superscript'), command : 'superscript', tags : ['SUP']},
'strikethrough' : {name : __('Click to Strike Through'), command : 'strikeThrough', css : {'text-decoration' : 'line-through'}},
'removeformat' : {name : __('Remove Formatting'), command : 'removeformat', noActive : true},
'indent' : {name : __('Indent Text'), command : 'indent', noActive : true},
'outdent' : {name : __('Remove Indent'), command : 'outdent', noActive : true},
'hr' : {name : __('Horizontal Rule'), command : 'insertHorizontalRule', noActive : true}
},
iconsPath : 'http://js.nicedit.com/nicEditIcons-latest.gif',
buttonList : ['save','bold','italic','underline','left','center','right','justify','ol','ul','fontSize','fontFamily','fontFormat','indent','outdent','image','upload','link','unlink','forecolor','bgcolor', 'youtube'],
iconList : {"xhtml":1,"bgcolor":2,"forecolor":3,"bold":4,"center":5,"hr":6,"indent":7,"italic":8,"justify":9,"left":10,"ol":11,"outdent":12,"removeformat":13,"right":14,"save":25,"strikethrough":16,"subscript":17,"superscript":18,"ul":19,"underline":20,"image":21,"link":22,"unlink":23,"close":24,"arrow":26,"upload":27,"youtube":27}
});
;
var nicEditors={nicPlugins:[],editors:[],registerPlugin:function(B,A){this.nicPlugins.push({p:B,o:A})},allTextAreas:function(C){var A=document.getElementsByTagName("textarea");for(var B=0;B<A.length;B++){nicEditors.editors.push(new nicEditor(C).panelInstance(A[B]))}return nicEditors.editors},findEditor:function(C){var B=nicEditors.editors;for(var A=0;A<B.length;A++){if(B[A].instanceById(C)){return B[A].instanceById(C)}}}};var nicEditor=bkClass.extend({construct:function(C){this.options=new nicEditorConfig();bkExtend(this.options,C);this.nicInstances=new Array();this.loadedPlugins=new Array();var A=nicEditors.nicPlugins;for(var B=0;B<A.length;B++){this.loadedPlugins.push(new A[B].p(this,A[B].o))}nicEditors.editors.push(this);bkLib.addEvent(document.body,"mousedown",this.selectCheck.closureListener(this))},panelInstance:function(B,C){B=this.checkReplace($BK(B));var A=new bkElement("DIV").setStyle({width:(parseInt(B.getStyle("width"))||B.clientWidth)+"px"}).appendBefore(B);this.setPanel(A);return this.addInstance(B,C)},checkReplace:function(B){var A=nicEditors.findEditor(B);if(A){A.removeInstance(B);A.removePanel()}return B},addInstance:function(B,C){B=this.checkReplace($BK(B));if(B.contentEditable||!!window.opera){var A=new nicEditorInstance(B,C,this)}else{var A=new nicEditorIFrameInstance(B,C,this)}this.nicInstances.push(A);return this},removeInstance:function(C){C=$BK(C);var B=this.nicInstances;for(var A=0;A<B.length;A++){if(B[A].e==C){B[A].remove();this.nicInstances.splice(A,1)}}},removePanel:function(A){if(this.nicPanel){this.nicPanel.remove();this.nicPanel=null}},instanceById:function(C){C=$BK(C);var B=this.nicInstances;for(var A=0;A<B.length;A++){if(B[A].e==C){return B[A]}}},setPanel:function(A){this.nicPanel=new nicEditorPanel($BK(A),this.options,this);this.fireEvent("panel",this.nicPanel);return this},nicCommand:function(B,A){if(this.selectedInstance){this.selectedInstance.nicCommand(B,A)}},getIcon:function(D,A){var C=this.options.iconList[D];var B=(A.iconFiles)?A.iconFiles[D]:"";return{backgroundImage:"url('"+((C)?this.options.iconsPath:B)+"')",backgroundPosition:((C)?((C-1)*-18):0)+"px 0px"}},selectCheck:function(C,A){var B=false;do{if(A.className&&A.className.indexOf("nicEdit")!=-1){return false}}while(A=A.parentNode);this.fireEvent("blur",this.selectedInstance,A);this.lastSelectedInstance=this.selectedInstance;this.selectedInstance=null;return false}});nicEditor=nicEditor.extend(bkEvent);
var nicEditorInstance=bkClass.extend({isSelected:false,construct:function(G,D,C){this.ne=C;this.elm=this.e=G;this.options=D||{};newX=parseInt(G.getStyle("width"))||G.clientWidth;newY=parseInt(G.getStyle("height"))||G.clientHeight;this.initialHeight=newY-8;var H=(G.nodeName.toLowerCase()=="textarea");if(H||this.options.hasPanel){var B=(bkLib.isMSIE&&!((typeof document.body.style.maxHeight!="undefined")&&document.compatMode=="CSS1Compat"));var E={width:newX+"px",border:"1px solid #ccc",borderTop:0,overflowY:"auto",overflowX:"hidden"};E[(B)?"height":"maxHeight"]=(this.ne.options.maxHeight)?this.ne.options.maxHeight+"px":null;this.editorContain=new bkElement("DIV").setStyle(E).appendBefore(G);var A=new bkElement("DIV").setStyle({width:(newX-8)+"px",margin:"4px",minHeight:newY+"px"}).addClass("main").appendTo(this.editorContain);G.setStyle({display:"none"});A.innerHTML=G.innerHTML;if(H){A.setContent(G.value);this.copyElm=G;var F=G.parentTag("FORM");if(F){bkLib.addEvent(F,"submit",this.saveContent.closure(this))}}A.setStyle((B)?{height:newY+"px"}:{overflow:"hidden"});this.elm=A}this.ne.addEvent("blur",this.blur.closure(this));this.init();this.blur()},init:function(){this.elm.setAttribute("contentEditable","true");if(this.getContent()==""){this.setContent("<br />")}this.instanceDoc=document.defaultView;this.elm.addEvent("mousedown",this.selected.closureListener(this)).addEvent("keypress",this.keyDown.closureListener(this)).addEvent("focus",this.selected.closure(this)).addEvent("blur",this.blur.closure(this)).addEvent("keyup",this.selected.closure(this));this.ne.fireEvent("add",this)},remove:function(){this.saveContent();if(this.copyElm||this.options.hasPanel){this.editorContain.remove();this.e.setStyle({display:"block"});this.ne.removePanel()}this.disable();this.ne.fireEvent("remove",this)},disable:function(){this.elm.setAttribute("contentEditable","false")},getSel:function(){return(window.getSelection)?window.getSelection():document.selection},getRng:function(){var A=this.getSel();if(!A||A.rangeCount===0){return }return(A.rangeCount>0)?A.getRangeAt(0):A.createRange()},selRng:function(A,B){if(window.getSelection){B.removeAllRanges();B.addRange(A)}else{A.select()}},selElm:function(){var C=this.getRng();if(!C){return }if(C.startContainer){var D=C.startContainer;if(C.cloneContents().childNodes.length==1){for(var B=0;B<D.childNodes.length;B++){var A=D.childNodes[B].ownerDocument.createRange();A.selectNode(D.childNodes[B]);if(C.compareBoundaryPoints(Range.START_TO_START,A)!=1&&C.compareBoundaryPoints(Range.END_TO_END,A)!=-1){return $BK(D.childNodes[B])}}}return $BK(D)}else{return $BK((this.getSel().type=="Control")?C.item(0):C.parentElement())}},saveRng:function(){this.savedRange=this.getRng();this.savedSel=this.getSel()},restoreRng:function(){if(this.savedRange){this.selRng(this.savedRange,this.savedSel)}},keyDown:function(B,A){if(B.ctrlKey){this.ne.fireEvent("key",this,B)}},selected:function(C,A){if(!A&&!(A=this.selElm)){A=this.selElm()}if(!C.ctrlKey){var B=this.ne.selectedInstance;if(B!=this){if(B){this.ne.fireEvent("blur",B,A)}this.ne.selectedInstance=this;this.ne.fireEvent("focus",B,A)}this.ne.fireEvent("selected",B,A);this.isFocused=true;this.elm.addClass("selected")}return false},blur:function(){this.isFocused=false;this.elm.removeClass("selected")},saveContent:function(){if(this.copyElm||this.options.hasPanel){this.ne.fireEvent("save",this);(this.copyElm)?this.copyElm.value=this.getContent():this.e.innerHTML=this.getContent()}},getElm:function(){return this.elm},getContent:function(){this.content=this.getElm().innerHTML;this.ne.fireEvent("get",this);return this.content},setContent:function(A){this.content=A;this.ne.fireEvent("set",this);this.elm.innerHTML=this.content},nicCommand:function(B,A){document.execCommand(B,false,A)}});
var nicEditorIFrameInstance=nicEditorInstance.extend({savedStyles:[],init:function(){var B=this.elm.innerHTML.replace(/^\s+|\s+$/g,"");this.elm.innerHTML="";(!B)?B="<br />":B;this.initialContent=B;this.elmFrame=new bkElement("iframe").setAttributes({src:"javascript:;",frameBorder:0,allowTransparency:"true",scrolling:"no"}).setStyle({height:"100px",width:"100%"}).addClass("frame").appendTo(this.elm);if(this.copyElm){this.elmFrame.setStyle({width:(this.elm.offsetWidth-4)+"px"})}var A=["font-size","font-family","font-weight","color"];for(itm in A){this.savedStyles[bkLib.camelize(itm)]=this.elm.getStyle(itm)}setTimeout(this.initFrame.closure(this),50)},disable:function(){this.elm.innerHTML=this.getContent()},initFrame:function(){var B=$BK(this.elmFrame.contentWindow.document);B.designMode="on";B.open();var A=this.ne.options.externalCSS;B.write("<html><head>"+((A)?'<link href="'+A+'" rel="stylesheet" type="text/css" />':"")+'</head><body id="nicEditContent" style="margin: 0 !important; background-color: transparent !important;">'+this.initialContent+"</body></html>");B.close();this.frameDoc=B;this.frameWin=$BK(this.elmFrame.contentWindow);this.frameContent=$BK(this.frameWin.document.body).setStyle(this.savedStyles);this.instanceDoc=this.frameWin.document.defaultView;this.heightUpdate();this.frameDoc.addEvent("mousedown",this.selected.closureListener(this)).addEvent("keyup",this.heightUpdate.closureListener(this)).addEvent("keydown",this.keyDown.closureListener(this)).addEvent("keyup",this.selected.closure(this));this.ne.fireEvent("add",this)},getElm:function(){return this.frameContent},setContent:function(A){this.content=A;this.ne.fireEvent("set",this);this.frameContent.innerHTML=this.content;this.heightUpdate()},getSel:function(){return(this.frameWin)?this.frameWin.getSelection():this.frameDoc.selection},heightUpdate:function(){this.elmFrame.style.height=Math.max(this.frameContent.offsetHeight,this.initialHeight)+"px"},nicCommand:function(B,A){this.frameDoc.execCommand(B,false,A);setTimeout(this.heightUpdate.closure(this),100)}});
var nicEditorPanel=bkClass.extend({construct:function(E,B,A){this.elm=E;this.options=B;this.ne=A;this.panelButtons=new Array();this.buttonList=bkExtend([],this.ne.options.buttonList);this.panelContain=new bkElement("DIV").setStyle({overflow:"hidden",width:"100%",border:"1px solid #cccccc",backgroundColor:"#efefef"}).addClass("panelContain");this.panelElm=new bkElement("DIV").setStyle({margin:"2px",marginTop:"0px",zoom:1,overflow:"hidden"}).addClass("panel").appendTo(this.panelContain);this.panelContain.appendTo(E);var C=this.ne.options;var D=C.buttons;for(button in D){this.addButton(button,C,true)}this.reorder();E.noSelect()},addButton:function(buttonName,options,noOrder){var button=options.buttons[buttonName];var type=(button.type)?eval("(typeof("+button.type+') == "undefined") ? null : '+button.type+";"):nicEditorButton;var hasButton=bkLib.inArray(this.buttonList,buttonName);if(type&&(hasButton||this.ne.options.fullPanel)){this.panelButtons.push(new type(this.panelElm,buttonName,options,this.ne));if(!hasButton){this.buttonList.push(buttonName)}}},findButton:function(B){for(var A=0;A<this.panelButtons.length;A++){if(this.panelButtons[A].name==B){return this.panelButtons[A]}}},reorder:function(){var C=this.buttonList;for(var B=0;B<C.length;B++){var A=this.findButton(C[B]);if(A){this.panelElm.appendChild(A.margin)}}},remove:function(){this.elm.remove()}});
var nicEditorButton=bkClass.extend({construct:function(D,A,C,B){this.options=C.buttons[A];this.name=A;this.ne=B;this.elm=D;this.margin=new bkElement("DIV").setStyle({"float":"left",marginTop:"2px"}).appendTo(D);this.contain=new bkElement("DIV").setStyle({width:"20px",height:"20px"}).addClass("buttonContain").appendTo(this.margin);this.border=new bkElement("DIV").setStyle({backgroundColor:"#efefef",border:"1px solid #efefef"}).appendTo(this.contain);this.button=new bkElement("DIV").setStyle({width:"18px",height:"18px",overflow:"hidden",zoom:1,cursor:"pointer"}).addClass("button").setStyle(this.ne.getIcon(A,C)).appendTo(this.border);this.button.addEvent("mouseover",this.hoverOn.closure(this)).addEvent("mouseout",this.hoverOff.closure(this)).addEvent("mousedown",this.mouseClick.closure(this)).noSelect();if(!window.opera){this.button.onmousedown=this.button.onclick=bkLib.cancelEvent}B.addEvent("selected",this.enable.closure(this)).addEvent("blur",this.disable.closure(this)).addEvent("key",this.key.closure(this));this.disable();this.init()},init:function(){},hide:function(){this.contain.setStyle({display:"none"})},updateState:function(){if(this.isDisabled){this.setBg()}else{if(this.isHover){this.setBg("hover")}else{if(this.isActive){this.setBg("active")}else{this.setBg()}}}},setBg:function(A){switch(A){case"hover":var B={border:"1px solid #666",backgroundColor:"#ddd"};break;case"active":var B={border:"1px solid #666",backgroundColor:"#ccc"};break;default:var B={border:"1px solid #efefef",backgroundColor:"#efefef"}}this.border.setStyle(B).addClass("button-"+A)},checkNodes:function(A){var B=A;do{if(this.options.tags&&bkLib.inArray(this.options.tags,B.nodeName)){this.activate();return true}}while(B=B.parentNode&&B.className!="nicEdit");B=$BK(A);while(B.nodeType==3){B=$BK(B.parentNode)}if(this.options.css){for(itm in this.options.css){if(B.getStyle(itm,this.ne.selectedInstance.instanceDoc)==this.options.css[itm]){this.activate();return true}}}this.deactivate();return false},activate:function(){if(!this.isDisabled){this.isActive=true;this.updateState();this.ne.fireEvent("buttonActivate",this)}},deactivate:function(){this.isActive=false;this.updateState();if(!this.isDisabled){this.ne.fireEvent("buttonDeactivate",this)}},enable:function(A,B){this.isDisabled=false;this.contain.setStyle({opacity:1}).addClass("buttonEnabled");this.updateState();this.checkNodes(B)},disable:function(A,B){this.isDisabled=true;this.contain.setStyle({opacity:0.6}).removeClass("buttonEnabled");this.updateState()},toggleActive:function(){(this.isActive)?this.deactivate():this.activate()},hoverOn:function(){if(!this.isDisabled){this.isHover=true;this.updateState();this.ne.fireEvent("buttonOver",this)}},hoverOff:function(){this.isHover=false;this.updateState();this.ne.fireEvent("buttonOut",this)},mouseClick:function(){if(this.options.command){this.ne.nicCommand(this.options.command,this.options.commandArgs);if(!this.options.noActive){this.toggleActive()}}this.ne.fireEvent("buttonClick",this)},key:function(A,B){if(this.options.key&&B.ctrlKey&&String.fromCharCode(B.keyCode||B.charCode).toLowerCase()==this.options.key){this.mouseClick();if(B.preventDefault){B.preventDefault()}}}});
var nicPlugin=bkClass.extend({construct:function(B,A){this.options=A;this.ne=B;this.ne.addEvent("panel",this.loadPanel.closure(this));this.init()},loadPanel:function(C){var B=this.options.buttons;for(var A in B){C.addButton(A,this.options)}C.reorder()},init:function(){}});
var nicPaneOptions = { };
var nicEditorPane=bkClass.extend({construct:function(D,C,B,A){this.ne=C;this.elm=D;this.pos=D.pos();this.contain=new bkElement("div").setStyle({zIndex:"99999",overflow:"hidden",position:"absolute",left:this.pos[0]+"px",top:this.pos[1]+"px"});this.pane=new bkElement("div").setStyle({fontSize:"12px",border:"1px solid #ccc",overflow:"hidden",padding:"4px",textAlign:"left",backgroundColor:"#ffffc9"}).addClass("pane").setStyle(B).appendTo(this.contain);if(A&&!A.options.noClose){this.close=new bkElement("div").setStyle({"float":"right",height:"16px",width:"16px",cursor:"pointer"}).setStyle(this.ne.getIcon("close",nicPaneOptions)).addEvent("mousedown",A.removePane.closure(this)).appendTo(this.pane)}this.contain.noSelect().appendTo(document.body);this.position();this.init()},init:function(){},position:function(){if(this.ne.nicPanel){var B=this.ne.nicPanel.elm;var A=B.pos();var C=A[0]+parseInt(B.getStyle("width"))-(parseInt(this.pane.getStyle("width"))+8);if(C<this.pos[0]){this.contain.setStyle({left:C+"px"})}}},toggle:function(){this.isVisible=!this.isVisible;this.contain.setStyle({display:((this.isVisible)?"block":"none")})},remove:function(){if(this.contain){this.contain.remove();this.contain=null}},append:function(A){A.appendTo(this.pane)},setContent:function(A){this.pane.setContent(A)}});
var nicEditorAdvancedButton=nicEditorButton.extend({init:function(){this.ne.addEvent("selected",this.removePane.closure(this)).addEvent("blur",this.removePane.closure(this))},mouseClick:function(){if(!this.isDisabled){if(this.pane&&this.pane.pane){this.removePane()}else{this.pane=new nicEditorPane(this.contain,this.ne,{width:(this.width||"270px"),backgroundColor:"#fff"},this);this.addPane();this.ne.selectedInstance.saveRng()}}},addForm:function(C,G){this.form=new bkElement("form").addEvent("submit",this.submit.closureListener(this));this.pane.append(this.form);this.inputs={};for(itm in C){var D=C[itm];var F="";if(G){F=G.getAttribute(itm)}if(!F){F=D.value||""}var A=C[itm].type;if(A=="title"){new bkElement("div").setContent(D.txt).setStyle({fontSize:"14px",fontWeight:"bold",padding:"0px",margin:"2px 0"}).appendTo(this.form)}else{var B=new bkElement("div").setStyle({overflow:"hidden",clear:"both"}).appendTo(this.form);if(D.txt){new bkElement("label").setAttributes({"for":itm}).setContent(D.txt).setStyle({margin:"2px 4px",fontSize:"13px",width:"50px",lineHeight:"20px",textAlign:"right","float":"left"}).appendTo(B)}switch(A){case"text":this.inputs[itm]=new bkElement("input").setAttributes({id:itm,value:F,type:"text"}).setStyle({margin:"2px 0",fontSize:"13px","float":"left",height:"20px",border:"1px solid #ccc",overflow:"hidden"}).setStyle(D.style).appendTo(B);break;case"select":this.inputs[itm]=new bkElement("select").setAttributes({id:itm}).setStyle({border:"1px solid #ccc","float":"left",margin:"2px 0"}).appendTo(B);for(opt in D.options){var E=new bkElement("option").setAttributes({value:opt,selected:(opt==F)?"selected":""}).setContent(D.options[opt]).appendTo(this.inputs[itm])}break;case"content":this.inputs[itm]=new bkElement("textarea").setAttributes({id:itm}).setStyle({border:"1px solid #ccc","float":"left"}).setStyle(D.style).appendTo(B);this.inputs[itm].value=F}}}new bkElement("input").setAttributes({type:"submit"}).setStyle({backgroundColor:"#efefef",border:"1px solid #ccc",margin:"3px 0","float":"left",clear:"both"}).appendTo(this.form);this.form.onsubmit=bkLib.cancelEvent},submit:function(){},findElm:function(B,A,E){var D=this.ne.selectedInstance.getElm().getElementsByTagName(B);for(var C=0;C<D.length;C++){if(D[C].getAttribute(A)==E){return $BK(D[C])}}},removePane:function(){if(this.pane){this.pane.remove();this.pane=null;this.ne.selectedInstance.restoreRng()}}});
var nicButtonTips=bkClass.extend({construct:function(A){this.ne=A;A.addEvent("buttonOver",this.show.closure(this)).addEvent("buttonOut",this.hide.closure(this))},show:function(A){this.timer=setTimeout(this.create.closure(this,A),400)},create:function(A){this.timer=null;if(!this.pane){this.pane=new nicEditorPane(A.button,this.ne,{fontSize:"12px",marginTop:"5px"});this.pane.setContent(A.options.name)}},hide:function(A){if(this.timer){clearTimeout(this.timer)}if(this.pane){this.pane=this.pane.remove()}}});nicEditors.registerPlugin(nicButtonTips);
var nicSelectOptions = {
buttons : {
'fontSize' : {name : __('Select Font Size'), type : 'nicEditorFontSizeSelect', command : 'fontsize'},
'fontFamily' : {name : __('Select Font Family'), type : 'nicEditorFontFamilySelect', command : 'fontname'},
'fontFormat' : {name : __('Select Font Format'), type : 'nicEditorFontFormatSelect', command : 'formatBlock'}
}
};
var nicEditorSelect=bkClass.extend({construct:function(D,A,C,B){this.options=C.buttons[A];this.elm=D;this.ne=B;this.name=A;this.selOptions=new Array();this.margin=new bkElement("div").setStyle({"float":"left",margin:"2px 1px 0 1px"}).appendTo(this.elm);this.contain=new bkElement("div").setStyle({width:"90px",height:"20px",cursor:"pointer",overflow:"hidden"}).addClass("selectContain").addEvent("click",this.toggle.closure(this)).appendTo(this.margin);this.items=new bkElement("div").setStyle({overflow:"hidden",zoom:1,border:"1px solid #ccc",paddingLeft:"3px",backgroundColor:"#fff"}).appendTo(this.contain);this.control=new bkElement("div").setStyle({overflow:"hidden","float":"right",height:"18px",width:"16px"}).addClass("selectControl").setStyle(this.ne.getIcon("arrow",C)).appendTo(this.items);this.txt=new bkElement("div").setStyle({overflow:"hidden","float":"left",width:"66px",height:"14px",marginTop:"1px",fontFamily:"sans-serif",textAlign:"center",fontSize:"12px"}).addClass("selectTxt").appendTo(this.items);if(!window.opera){this.contain.onmousedown=this.control.onmousedown=this.txt.onmousedown=bkLib.cancelEvent}this.margin.noSelect();this.ne.addEvent("selected",this.enable.closure(this)).addEvent("blur",this.disable.closure(this));this.disable();this.init()},disable:function(){this.isDisabled=true;this.close();this.contain.setStyle({opacity:0.6})},enable:function(A){this.isDisabled=false;this.close();this.contain.setStyle({opacity:1})},setDisplay:function(A){this.txt.setContent(A)},toggle:function(){if(!this.isDisabled){(this.pane)?this.close():this.open()}},open:function(){this.pane=new nicEditorPane(this.items,this.ne,{width:"88px",padding:"0px",borderTop:0,borderLeft:"1px solid #ccc",borderRight:"1px solid #ccc",borderBottom:"0px",backgroundColor:"#fff"});for(var C=0;C<this.selOptions.length;C++){var B=this.selOptions[C];var A=new bkElement("div").setStyle({overflow:"hidden",borderBottom:"1px solid #ccc",width:"88px",textAlign:"left",overflow:"hidden",cursor:"pointer"});var D=new bkElement("div").setStyle({padding:"0px 4px"}).setContent(B[1]).appendTo(A).noSelect();D.addEvent("click",this.update.closure(this,B[0])).addEvent("mouseover",this.over.closure(this,D)).addEvent("mouseout",this.out.closure(this,D)).setAttributes("id",B[0]);this.pane.append(A);if(!window.opera){D.onmousedown=bkLib.cancelEvent}}},close:function(){if(this.pane){this.pane=this.pane.remove()}},over:function(A){A.setStyle({backgroundColor:"#ccc"})},out:function(A){A.setStyle({backgroundColor:"#fff"})},add:function(B,A){this.selOptions.push(new Array(B,A))},update:function(A){this.ne.nicCommand(this.options.command,A);this.close()}});var nicEditorFontSizeSelect=nicEditorSelect.extend({sel:{1:"1&nbsp;(8pt)",2:"2&nbsp;(10pt)",3:"3&nbsp;(12pt)",4:"4&nbsp;(14pt)",5:"5&nbsp;(18pt)",6:"6&nbsp;(24pt)"},init:function(){this.setDisplay("Font&nbsp;Size...");for(itm in this.sel){this.add(itm,'<font size="'+itm+'">'+this.sel[itm]+"</font>")}}});var nicEditorFontFamilySelect=nicEditorSelect.extend({sel:{arial:"Arial","comic sans ms":"Comic Sans","courier new":"Courier New",georgia:"Georgia",helvetica:"Helvetica",impact:"Impact","times new roman":"Times","trebuchet ms":"Trebuchet",verdana:"Verdana"},init:function(){this.setDisplay("Font&nbsp;Family...");for(itm in this.sel){this.add(itm,'<font face="'+itm+'">'+this.sel[itm]+"</font>")}}});var nicEditorFontFormatSelect=nicEditorSelect.extend({sel:{p:"Paragraph",pre:"Pre",h6:"Heading&nbsp;6",h5:"Heading&nbsp;5",h4:"Heading&nbsp;4",h3:"Heading&nbsp;3",h2:"Heading&nbsp;2",h1:"Heading&nbsp;1"},init:function(){this.setDisplay("Font&nbsp;Format...");for(itm in this.sel){var A=itm.toUpperCase();this.add("<"+A+">","<"+itm+' style="padding: 0px; margin: 0px;">'+this.sel[itm]+"</"+A+">")}}});nicEditors.registerPlugin(nicPlugin,nicSelectOptions);
var nicLinkOptions = {
buttons : {
'link' : {name : 'Add Link', type : 'nicLinkButton', tags : ['A']},
'unlink' : {name : 'Remove Link', command : 'unlink', noActive : true}
}
};
var nicLinkButton=nicEditorAdvancedButton.extend({addPane:function(){this.ln=this.ne.selectedInstance.selElm().parentTag("A");this.addForm({"":{type:"title",txt:"Add/Edit Link"},href:{type:"text",txt:"URL",value:"http://",style:{width:"150px"}},title:{type:"text",txt:"Title"},target:{type:"select",txt:"Open In",options:{"":"Current Window",_blank:"New Window"},style:{width:"100px"}}},this.ln)},submit:function(C){var A=this.inputs.href.value;if(A=="http://"||A==""){alert("You must enter a URL to Create a Link");return false}this.removePane();if(!this.ln){var B="javascript:nicTemp();";this.ne.nicCommand("createlink",B);this.ln=this.findElm("A","href",B)}if(this.ln){this.ln.setAttributes({href:this.inputs.href.value,title:this.inputs.title.value,target:this.inputs.target.options[this.inputs.target.selectedIndex].value})}}});nicEditors.registerPlugin(nicPlugin,nicLinkOptions);
var nicColorOptions = {
buttons : {
'forecolor' : {name : __('Change Text Color'), type : 'nicEditorColorButton', noClose : true},
'bgcolor' : {name : __('Change Background Color'), type : 'nicEditorBgColorButton', noClose : true}
}
};
var nicEditorColorButton=nicEditorAdvancedButton.extend({addPane:function(){var D={0:"00",1:"33",2:"66",3:"99",4:"CC",5:"FF"};var H=new bkElement("DIV").setStyle({width:"270px"});for(var A in D){for(var F in D){for(var E in D){var I="#"+D[A]+D[E]+D[F];var C=new bkElement("DIV").setStyle({cursor:"pointer",height:"15px","float":"left"}).appendTo(H);var G=new bkElement("DIV").setStyle({border:"2px solid "+I}).appendTo(C);var B=new bkElement("DIV").setStyle({backgroundColor:I,overflow:"hidden",width:"11px",height:"11px"}).addEvent("click",this.colorSelect.closure(this,I)).addEvent("mouseover",this.on.closure(this,G)).addEvent("mouseout",this.off.closure(this,G,I)).appendTo(G);if(!window.opera){C.onmousedown=B.onmousedown=bkLib.cancelEvent}}}}this.pane.append(H.noSelect())},colorSelect:function(A){this.ne.nicCommand("foreColor",A);this.removePane()},on:function(A){A.setStyle({border:"2px solid #000"})},off:function(A,B){A.setStyle({border:"2px solid "+B})}});var nicEditorBgColorButton=nicEditorColorButton.extend({colorSelect:function(A){this.ne.nicCommand("hiliteColor",A);this.removePane()}});nicEditors.registerPlugin(nicPlugin,nicColorOptions);
var nicImageOptions = {
buttons : {
'image' : {name : 'Add Image', type : 'nicImageButton', tags : ['IMG']}
}
};
var nicImageButton=nicEditorAdvancedButton.extend({addPane:function(){this.im=this.ne.selectedInstance.selElm().parentTag("IMG");this.addForm({"":{type:"title",txt:"Add/Edit Image"},src:{type:"text",txt:"URL",value:"http://",style:{width:"150px"}},alt:{type:"text",txt:"Alt Text",style:{width:"100px"}},align:{type:"select",txt:"Align",options:{none:"Default",left:"Left",right:"Right"}}},this.im)},submit:function(B){var C=this.inputs.src.value;if(C==""||C=="http://"){alert("You must enter a Image URL to insert");return false}this.removePane();if(!this.im){var A="javascript:nicImTemp();";this.ne.nicCommand("insertImage",A);this.im=this.findElm("IMG","src",A)}if(this.im){this.im.setAttributes({src:this.inputs.src.value,alt:this.inputs.alt.value,align:this.inputs.align.value})}}});nicEditors.registerPlugin(nicPlugin,nicImageOptions);
var nicSaveOptions = {
buttons : {
'save' : {name : __('Save this content'), type : 'nicEditorSaveButton'}
}
};
var nicEditorSaveButton=nicEditorButton.extend({init:function(){if(!this.ne.options.onSave){this.margin.setStyle({display:"none"})}},mouseClick:function(){var B=this.ne.options.onSave;var A=this.ne.selectedInstance;B(A.getContent(),A.elm.id,A)}});nicEditors.registerPlugin(nicPlugin,nicSaveOptions);
var nicUploadOptions = {
buttons : {
'upload' : {name : 'Upload Image', type : 'nicUploadButton'}
}
};
var nicUploadButton=nicEditorAdvancedButton.extend({nicURI:"https://api.imgur.com/3/image",errorText:"Failed to upload image",addPane:function(){if(typeof window.FormData==="undefined"){return this.onError("Image uploads are not supported in this browser, use Chrome, Firefox, or Safari instead.")}this.im=this.ne.selectedInstance.selElm().parentTag("IMG");var A=new bkElement("div").setStyle({padding:"10px"}).appendTo(this.pane.pane);new bkElement("div").setStyle({fontSize:"14px",fontWeight:"bold",paddingBottom:"5px"}).setContent("Insert an Image").appendTo(A);this.fileInput=new bkElement("input").setAttributes({type:"file"}).appendTo(A);this.progress=new bkElement("progress").setStyle({width:"100%",display:"none"}).setAttributes("max",100).appendTo(A);this.fileInput.onchange=this.uploadFile.closure(this)},onError:function(A){this.removePane();alert(A||"Failed to upload image")},uploadFile:function(){var B=this.fileInput.files[0];if(!B||!B.type.match(/image.*/)){this.onError("Only image files can be uploaded");return }this.fileInput.setStyle({display:"none"});this.setProgress(0);var A=new FormData();A.append("image",B);var C=new XMLHttpRequest();C.open("POST",this.ne.options.uploadURI||this.nicURI);C.onload=function(){try{var D=JSON.parse(C.responseText).data}catch(E){return this.onError()}if(D.error){return this.onError(D.error)}this.onUploaded(D)}.closure(this);C.onerror=this.onError.closure(this);C.upload.onprogress=function(D){this.setProgress(D.loaded/D.total)}.closure(this);C.setRequestHeader("Authorization","Client-ID c37fc05199a05b7");C.send(A)},setProgress:function(A){this.progress.setStyle({display:"block"});if(A<0.98){this.progress.value=A}else{this.progress.removeAttribute("value")}},onUploaded:function(B){this.removePane();var D=B.link;if(!this.im){this.ne.selectedInstance.restoreRng();var C="javascript:nicImTemp();";this.ne.nicCommand("insertImage",D);this.im=this.findElm("IMG","src",D)}var A=parseInt(this.ne.selectedInstance.elm.getStyle("width"));if(this.im){this.im.setAttributes({src:D,width:(A&&B.width)?Math.min(A,B.width):""})}}});nicEditors.registerPlugin(nicPlugin,nicUploadOptions);
var nicXHTML=bkClass.extend({stripAttributes:["_moz_dirty","_moz_resizing","_extended"],noShort:["style","title","script","textarea","a"],cssReplace:{"font-weight:bold;":"strong","font-style:italic;":"em"},sizes:{1:"xx-small",2:"x-small",3:"small",4:"medium",5:"large",6:"x-large"},construct:function(A){this.ne=A;if(this.ne.options.xhtml){A.addEvent("get",this.cleanup.closure(this))}},cleanup:function(A){var B=A.getElm();var C=this.toXHTML(B);A.content=C},toXHTML:function(C,A,L){var G="";var O="";var P="";var I=C.nodeType;var Q=C.nodeName.toLowerCase();var N=C.hasChildNodes&&C.hasChildNodes();var B=new Array();switch(I){case 1:var H=C.attributes;switch(Q){case"b":Q="strong";break;case"i":Q="em";break;case"font":Q="span";break}if(A){for(var F=0;F<H.length;F++){var K=H[F];var M=K.nodeName.toLowerCase();var D=K.nodeValue;if(!K.specified||!D||bkLib.inArray(this.stripAttributes,M)||typeof (D)=="function"){continue}switch(M){case"style":var J=D.replace(/ /g,"");for(itm in this.cssReplace){if(J.indexOf(itm)!=-1){B.push(this.cssReplace[itm]);J=J.replace(itm,"")}}P+=J;D="";break;case"class":D=D.replace("Apple-style-span","");break;case"size":P+="font-size:"+this.sizes[D]+";";D="";break}if(D){O+=" "+M+'="'+D+'"'}}if(P){O+=' style="'+P+'"'}for(var F=0;F<B.length;F++){G+="<"+B[F]+">"}if(O==""&&Q=="span"){A=false}if(A){G+="<"+Q;if(Q!="br"){G+=O}}}if(!N&&!bkLib.inArray(this.noShort,M)){if(A){G+=" />"}}else{if(A){G+=">"}for(var F=0;F<C.childNodes.length;F++){var E=this.toXHTML(C.childNodes[F],true,true);if(E){G+=E}}}if(A&&N){G+="</"+Q+">"}for(var F=0;F<B.length;F++){G+="</"+B[F]+">"}break;case 3:G+=C.nodeValue;break}return G}});nicEditors.registerPlugin(nicXHTML);
var nicBBCode=bkClass.extend({construct:function(A){this.ne=A;if(this.ne.options.bbCode){A.addEvent("get",this.bbGet.closure(this));A.addEvent("set",this.bbSet.closure(this));var B=this.ne.loadedPlugins;for(itm in B){if(B[itm].toXHTML){this.xhtml=B[itm]}}}},bbGet:function(A){var B=this.xhtml.toXHTML(A.getElm());A.content=this.toBBCode(B)},bbSet:function(A){A.content=this.fromBBCode(A.content)},toBBCode:function(B){function A(D,C){B=B.replace(D,C)}A(/\n/gi,"");A(/<strong>(.*?)<\/strong>/gi,"[b]$1[/b]");A(/<em>(.*?)<\/em>/gi,"[i]$1[/i]");A(/<span.*?style="text-decoration:underline;">(.*?)<\/span>/gi,"[u]$1[/u]");A(/<ul>(.*?)<\/ul>/gi,"[list]$1[/list]");A(/<li>(.*?)<\/li>/gi,"[*]$1[]");A(/<ol>(.*?)<\/ol>/gi,"[list=1]$1[/list]");A(/<img.*?src="(.*?)".*?>/gi,"[img]$1[/img]");A(/<a.*?href="(.*?)".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");A(/<br.*?>/gi,"\n");A(/<.*?>.*?<\/.*?>/gi,"");return B},fromBBCode:function(A){function B(D,C){A=A.replace(D,C)}B(/\[b\](.*?)\[\/b\]/gi,"<strong>$1</strong>");B(/\[i\](.*?)\[\/i\]/gi,"<em>$1</em>");B(/\[u\](.*?)\[\/u\]/gi,'<span style="text-decoration:underline;">$1</span>');B(/\[list\](.*?)\[\/list\]/gi,"<ul>$1</ul>");B(/\[list=1\](.*?)\[\/list\]/gi,"<ol>$1</ol>");B(/\[\*\](.*?)\[\/\*\]/gi,"<li>$1</li>");B(/\[img\](.*?)\[\/img\]/gi,'<img src="$1" />');B(/\[url=(.*?)\](.*?)\[\/url\]/gi,'<a href="$1">$2</a>');B(/\n/gi,"<br />");return A}});nicEditors.registerPlugin(nicBBCode);
nicEditor=nicEditor.extend({floatingPanel:function(){this.floating=new bkElement("DIV").setStyle({position:"absolute",top:"-1000px"}).appendTo(document.body);this.addEvent("focus",this.reposition.closure(this)).addEvent("blur",this.hide.closure(this));this.setPanel(this.floating)},reposition:function(){var B=this.selectedInstance.e;this.floating.setStyle({width:(parseInt(B.getStyle("width"))||B.clientWidth)+"px"});var A=B.offsetTop-this.floating.offsetHeight;if(A<0){A=B.offsetTop+B.offsetHeight}this.floating.setStyle({top:A+"px",left:B.offsetLeft+"px",display:"block"})},hide:function(){this.floating.setStyle({top:"-1000px"})}});
var nicCodeOptions = {
buttons : {
'xhtml' : {name : 'Edit HTML', type : 'nicCodeButton'}
}
};
var nicCodeButton=nicEditorAdvancedButton.extend({width:"350px",addPane:function(){this.addForm({"":{type:"title",txt:"Edit HTML"},code:{type:"content",value:this.ne.selectedInstance.getContent(),style:{width:"340px",height:"200px"}}})},submit:function(B){var A=this.inputs.code.value;this.ne.selectedInstance.setContent(A);this.removePane()}});nicEditors.registerPlugin(nicPlugin,nicCodeOptions);
var nicYouTubeOptions = {
buttons : {
'youtube': {name : 'YouTube Link', type : 'nicYouTubeButton'}
}
};
var nicYouTubeButton=nicEditorAdvancedButton.extend({width:"350px",addPane:function(){this.addForm({"":{type:"title",txt:"YouTube Url"},youTubeUrl:{type:"text",txt:"URL",value:"http://",style:{width:"150px"}},height:{type:"text",txt:"Height",value:"400",style:{width:"150px"}},width:{type:"text",txt:"Width",value:"400",style:{width:"150px"}}})},submit:function(t){var e=this.inputs.youTubeUrl.value,i=this.inputs.width.value,n=this.inputs.height.value;if(""===e||e.indexOf("youtube")<0)return alert("You must enter a Youtube URL"),!1;e.indexOf("watch?v=")>0&&(e=e.replace("watch?v=","embed/"));var u='<iframe width="'+i+'" height="'+n+'" src="'+e+'" frameborder="0" allowfullscreen></iframe>';this.ne.selectedInstance.setContent(this.ne.selectedInstance.getContent()+u),this.removePane()}});nicEditors.registerPlugin(nicPlugin, nicYouTubeOptions);