Addition of collection system.

Contributed by iDesy.
This commit is contained in:
MobiusDevelopment 2021-05-19 10:20:55 +00:00
parent bf6eb75074
commit 4e3762f353
54 changed files with 4924 additions and 15 deletions

View File

@ -0,0 +1,6 @@
DROP TABLE IF EXISTS `collection_favorites`;
CREATE TABLE IF NOT EXISTS `collection_favorites` (
`accountName` VARCHAR(45) NOT NULL DEFAULT '',
`collectionId` int(3) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`accountName`,`collectionId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

View File

@ -0,0 +1,8 @@
DROP TABLE IF EXISTS `collections`;
CREATE TABLE IF NOT EXISTS `collections` (
`accountName` VARCHAR(45) NOT NULL DEFAULT '',
`itemId` int(11) UNSIGNED NOT NULL DEFAULT 0,
`collectionId` int(3) UNSIGNED NOT NULL DEFAULT 0,
`index` tinyint(3) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`accountName`,`collectionId`,`index`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

View File

@ -0,0 +1,658 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/CollectionData.xsd">
<collection id="1" optionId="35799" category="1">
<item id="80135" count="1" enchant_level="20" /> <!-- Enhanced Krishna Slasher -->
<item id="17418" count="1" enchant_level="20" /> <!-- Helios Slasher -->
<item id="18071" count="1" enchant_level="20" /> <!-- Blessed Helios Slasher -->
<item id="47951" count="300" enchant_level="0" /> <!-- Crystal of Determination -->
<item id="80130" count="20" enchant_level="0" /> <!-- Superior Weapon Augmenting Stone -->
</collection>
<collection id="2" optionId="35800" category="1">
<item id="80143" count="1" enchant_level="20" /> <!-- Enhanced Krishna Retributer -->
<item id="17426" count="1" enchant_level="20" /> <!-- Helios Retributer -->
<item id="18079" count="1" enchant_level="20" /> <!-- Blessed Helios Retributer -->
<item id="47951" count="300" enchant_level="0" /> <!-- Crystal of Determination -->
<item id="80130" count="20" enchant_level="0" /> <!-- Superior Weapon Augmenting Stone -->
</collection>
<collection id="3" optionId="35801" category="1">
<item id="80133" count="1" enchant_level="11" /> <!-- Enhanced Krishna Shaper -->
<item id="80134" count="1" enchant_level="11" /> <!-- Enhanced Krishna Cutter -->
<item id="80136" count="1" enchant_level="11" /> <!-- Enhanced Krishna Avenger -->
<item id="80130" count="20" enchant_level="0" /> <!-- Superior Weapon Augmenting Stone -->
</collection>
<collection id="4" optionId="35802" category="1">
<item id="80137" count="1" enchant_level="5" /> <!-- Enhanced Krishna Fighter -->
<item id="80138" count="1" enchant_level="5" /> <!-- Enhanced Krishna Stormer -->
</collection>
<collection id="5" optionId="35803" category="1">
<item id="80145" count="1" enchant_level="11" /> <!-- Enhanced Krishna Dual Daggers -->
<item id="80144" count="1" enchant_level="11" /> <!-- Enhanced Krishna Dual Swords -->
<item id="80103" count="1" enchant_level="11" /> <!-- Krishna Dual Blunt Weapons -->
<item id="80130" count="20" enchant_level="0" /> <!-- Superior Weapon Augmenting Stone -->
</collection>
<collection id="6" optionId="35804" category="1">
<item id="80139" count="1" enchant_level="13" /> <!-- Enhanced Krishna Thrower -->
<item id="80140" count="1" enchant_level="13" /> <!-- Enhanced Krishna Guardian -->
<item id="80130" count="20" enchant_level="0" /> <!-- Superior Weapon Augmenting Stone -->
</collection>
<collection id="7" optionId="35805" category="1">
<item id="80141" count="1" enchant_level="11" /> <!-- Enhanced Krishna Buster -->
<item id="80142" count="1" enchant_level="11" /> <!-- Enhanced Krishna Caster -->
<item id="80143" count="1" enchant_level="11" /> <!-- Enhanced Krishna Retributer -->
<item id="80130" count="20" enchant_level="0" /> <!-- Superior Weapon Augmenting Stone -->
</collection>
<collection id="8" optionId="35806" category="1">
<item id="80135" count="1" enchant_level="23" /> <!-- Enhanced Krishna Slasher -->
<item id="80130" count="40" enchant_level="0" /> <!-- Superior Weapon Augmenting Stone -->
<item id="36386" count="30" enchant_level="0" /> <!-- Giant's Scroll: Enchant R-grade Weapon -->
</collection>
<collection id="9" optionId="35807" category="1">
<item id="80143" count="1" enchant_level="23" /> <!-- Enhanced Krishna Retributer -->
<item id="80130" count="40" enchant_level="0" /> <!-- Superior Weapon Augmenting Stone -->
<item id="36386" count="30" enchant_level="0" /> <!-- Giant's Scroll: Enchant R-grade Weapon -->
</collection>
<collection id="10" optionId="35808" category="1">
<item id="17416" count="1" enchant_level="13" /> <!-- Helios Shaper -->
<item id="18069" count="1" enchant_level="13" /> <!-- Blessed Helios Shaper -->
<item id="17417" count="1" enchant_level="13" /> <!-- Helios Cutter -->
<item id="18070" count="1" enchant_level="13" /> <!-- Blessed Helios Cutter -->
<item id="17419" count="1" enchant_level="13" /> <!-- Helios Avenger -->
<item id="18072" count="1" enchant_level="13" /> <!-- Blessed Helios Avenger -->
<item id="17526" count="12" enchant_level="0" /> <!-- Scroll: Enchant R-grade Weapon -->
<item id="47951" count="1200" enchant_level="0" /> <!-- Crystal of Determination -->
</collection>
<collection id="11" optionId="35809" category="1">
<item id="17420" count="1" enchant_level="16" /> <!-- Helios Fighter -->
<item id="18073" count="1" enchant_level="16" /> <!-- Blessed Helios Fighter -->
<item id="17421" count="1" enchant_level="16" /> <!-- Helios Stormer -->
<item id="18074" count="1" enchant_level="16" /> <!-- Blessed Helios Stormer -->
<item id="17526" count="12" enchant_level="0" /> <!-- Scroll: Enchant R-grade Weapon -->
<item id="47951" count="1200" enchant_level="0" /> <!-- Crystal of Determination -->
</collection>
<collection id="12" optionId="35810" category="1">
<item id="17428" count="1" enchant_level="16" /> <!-- Helios Dual Daggers -->
<item id="18081" count="1" enchant_level="16" /> <!-- Blessed Helios Dual Daggers -->
<item id="17427" count="1" enchant_level="16" /> <!-- Helios Dual Swords -->
<item id="18080" count="1" enchant_level="16" /> <!-- Blessed Helios Dual Swords -->
<item id="17429" count="1" enchant_level="16" /> <!-- Helios Dual Blunt Weapons -->
<item id="18082" count="1" enchant_level="16" /> <!-- Blessed Helios Dual Blunt Weapons -->
<item id="17526" count="12" enchant_level="0" /> <!-- Scroll: Enchant R-grade Weapon -->
</collection>
<collection id="13" optionId="35811" category="1">
<item id="17422" count="1" enchant_level="16" /> <!-- Helios Thrower -->
<item id="18075" count="1" enchant_level="16" /> <!-- Blessed Helios Thrower -->
<item id="17423" count="1" enchant_level="16" /> <!-- Helios Guardian -->
<item id="18076" count="1" enchant_level="16" /> <!-- Blessed Helios Guardian -->
<item id="17526" count="12" enchant_level="0" /> <!-- Scroll: Enchant R-grade Weapon -->
</collection>
<collection id="14" optionId="35812" category="1">
<item id="17424" count="1" enchant_level="14" /> <!-- Helios Buster -->
<item id="18077" count="1" enchant_level="14" /> <!-- Blessed Helios Buster -->
<item id="17425" count="1" enchant_level="8" /> <!-- Helios Caster -->
<item id="18078" count="1" enchant_level="8" /> <!-- Blessed Helios Caster -->
<item id="17426" count="1" enchant_level="8" /> <!-- Helios Retributer -->
<item id="18079" count="1" enchant_level="8" /> <!-- Blessed Helios Retributer -->
<item id="17526" count="72" enchant_level="0" /> <!-- Scroll: Enchant R-grade Weapon -->
<item id="47951" count="1200" enchant_level="0" /> <!-- Crystal of Determination -->
</collection>
<collection id="15" optionId="35813" category="1">
<item id="80090" count="1" enchant_level="9" /> <!-- Krishna Shaper -->
<item id="17417" count="1" enchant_level="4" /> <!-- Helios Cutter -->
<item id="18070" count="1" enchant_level="4" /> <!-- Blessed Helios Cutter -->
<item id="19440" count="3000" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="16" optionId="35814" category="1">
<item id="80102" count="1" enchant_level="16" /> <!-- Krishna Dual Daggers -->
<item id="80096" count="1" enchant_level="9" /> <!-- Krishna Thrower -->
<item id="17428" count="1" enchant_level="4" /> <!-- Helios Dual Daggers -->
<item id="17422" count="1" enchant_level="4" /> <!-- Helios Thrower -->
<item id="18075" count="1" enchant_level="4" /> <!-- Blessed Helios Thrower -->
<item id="19440" count="3000" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="17" optionId="35815" category="1">
<item id="80100" count="1" enchant_level="16" /> <!-- Krishna Retributer -->
<item id="17426" count="1" enchant_level="9" /> <!-- Helios Retributer -->
<item id="18079" count="1" enchant_level="9" /> <!-- Blessed Helios Retributer -->
<item id="19440" count="3000" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="18" optionId="35816" category="1">
<item id="80098" count="1" enchant_level="9" /> <!-- Krishna Buster -->
<item id="80099" count="1" enchant_level="4" /> <!-- Krishna Caster -->
<item id="17424" count="1" enchant_level="4" /> <!-- Helios Buster -->
<item id="18077" count="1" enchant_level="4" /> <!-- Blessed Helios Buster -->
<item id="17425" count="1" enchant_level="4" /> <!-- Helios Caster -->
<item id="18078" count="1" enchant_level="4" /> <!-- Blessed Helios Caster -->
<item id="19440" count="3000" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="19" optionId="35817" category="1">
<item id="17418" count="1" enchant_level="0" /> <!-- Helios Slasher -->
<item id="18071" count="1" enchant_level="0" /> <!-- Blessed Helios Slasher -->
<item id="47951" count="200" enchant_level="0" /> <!-- Crystal of Determination -->
<item id="36386" count="10" enchant_level="0" /> <!-- Giant's Scroll: Enchant R-grade Weapon -->
<item id="19447" count="10" enchant_level="0" /> <!-- Blessed Scroll: Enchant R-grade Weapon -->
<item id="17526" count="10" enchant_level="0" /> <!-- Scroll: Enchant R-grade Weapon -->
</collection>
<collection id="20" optionId="35818" category="1">
<item id="17426" count="1" enchant_level="0" /> <!-- Helios Retributer -->
<item id="18079" count="1" enchant_level="0" /> <!-- Blessed Helios Retributer -->
<item id="36731" count="35" enchant_level="0" /> <!-- Giant's Energy Spirit Stone -->
</collection>
<collection id="21" optionId="35819" category="1">
<item id="17421" count="1" enchant_level="0" /> <!-- Helios Stormer -->
<item id="18074" count="1" enchant_level="0" /> <!-- Blessed Helios Stormer -->
<item id="36731" count="35" enchant_level="0" /> <!-- Giant's Energy Spirit Stone -->
</collection>
<collection id="22" optionId="35820" category="1">
<item id="17422" count="1" enchant_level="0" /> <!-- Helios Thrower -->
<item id="18075" count="1" enchant_level="0" /> <!-- Blessed Helios Thrower -->
<item id="45932" count="35" enchant_level="0" /> <!-- Top-grade Weapon Augmenting Stone -->
<item id="80130" count="5" enchant_level="0" /> <!-- Superior Weapon Augmenting Stone -->
</collection>
<collection id="23" optionId="35821" category="1">
<item id="17429" count="1" enchant_level="0" /> <!-- Helios Dual Blunt Weapons -->
<item id="18082" count="1" enchant_level="0" /> <!-- Blessed Helios Dual Blunt Weapons -->
<item id="45932" count="35" enchant_level="0" /> <!-- Top-grade Weapon Augmenting Stone -->
<item id="80130" count="5" enchant_level="0" /> <!-- Superior Weapon Augmenting Stone -->
</collection>
<collection id="24" optionId="35822" category="1">
<item id="47951" count="120" enchant_level="0" /> <!-- Crystal of Determination -->
<item id="17526" count="6" enchant_level="0" /> <!-- Scroll: Enchant R-grade Weapon -->
<item id="19440" count="300" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="25" optionId="35823" category="2">
<item id="80190" count="1" enchant_level="10" /> <!-- Enchanted Leviathan Breastplate - Heavy armor -->
<item id="80196" count="1" enchant_level="10" /> <!-- Enchanted Leviathan Leather Armor - Light armor -->
<item id="80201" count="1" enchant_level="10" /> <!-- Enchanted Leviathan Tunic - Robe -->
</collection>
<collection id="26" optionId="35824" category="2">
<item id="80189" count="1" enchant_level="14" /> <!-- Enchanted Leviathan Helmet - Heavy armor -->
<item id="17436" count="1" enchant_level="14" /> <!-- Eternal Leather Helmet - Light armor -->
<item id="19912" count="1" enchant_level="14" /> <!-- Blessed Eternal Leather Helmet - Reinforced light armor -->
<item id="81728" count="240" enchant_level="0" /> <!-- Armor Augmenting Stone -->
<item id="47952" count="800" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="19440" count="800" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="27" optionId="35825" category="2">
<item id="80189" count="1" enchant_level="6" /> <!-- Enchanted Leviathan Helmet - Heavy armor -->
<item id="80190" count="1" enchant_level="6" /> <!-- Enchanted Leviathan Breastplate - Heavy armor -->
<item id="80191" count="1" enchant_level="6" /> <!-- Enchanted Leviathan Gaiters - Heavy armor -->
<item id="80192" count="1" enchant_level="6" /> <!-- Enchanted Leviathan Gauntlets - Heavy armor -->
<item id="80193" count="1" enchant_level="6" /> <!-- Enchanted Leviathan Boots - Heavy armor -->
</collection>
<collection id="28" optionId="35826" category="2">
<item id="80195" count="1" enchant_level="10" /> <!-- Enchanted Leviathan Leather Helmet - Light armor -->
<item id="80196" count="1" enchant_level="10" /> <!-- Enchanted Leviathan Leather Armor - Light armor -->
<item id="80197" count="1" enchant_level="10" /> <!-- Enchanted Leviathan Leather Leggings - Light armor -->
<item id="80198" count="1" enchant_level="10" /> <!-- Enchanted Leviathan Leather Gloves - Light armor -->
<item id="80199" count="1" enchant_level="10" /> <!-- Enchanted Leviathan Leather Boots - Light armor -->
</collection>
<collection id="29" optionId="35827" category="2">
<item id="80200" count="1" enchant_level="6" /> <!-- Enchanted Leviathan Circlet - Robe -->
<item id="80201" count="1" enchant_level="6" /> <!-- Enchanted Leviathan Tunic - Robe -->
<item id="80202" count="1" enchant_level="6" /> <!-- Enchanted Leviathan Stockings - Robe -->
<item id="80203" count="1" enchant_level="6" /> <!-- Enchanted Leviathan Gloves - Robe -->
<item id="80204" count="1" enchant_level="6" /> <!-- Enchanted Leviathan Shoes - Robe -->
</collection>
<collection id="30" optionId="35828" category="2">
<item id="80319" count="1" enchant_level="16" /> <!-- Enchanted Leviathan Sigil -->
<item id="17446" count="1" enchant_level="13" /> <!-- Eternal Sigil -->
<item id="18099" count="1" enchant_level="13" /> <!-- Blessed Eternal Sigil -->
<item id="47952" count="120" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="17527" count="20" enchant_level="0" /> <!-- Scroll: Enchant R-grade Armor -->
<item id="19440" count="1300" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="31" optionId="35829" category="2">
<item id="80194" count="1" enchant_level="12" /> <!-- Enchanted Leviathan Shield -->
<item id="17435" count="1" enchant_level="8" /> <!-- Eternal Shield -->
<item id="18088" count="1" enchant_level="8" /> <!-- Blessed Eternal Shield -->
<item id="47952" count="120" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="17527" count="20" enchant_level="0" /> <!-- Scroll: Enchant R-grade Armor -->
<item id="19440" count="400" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="32" optionId="35830" category="2">
<item id="35002" count="1" enchant_level="12" /> <!-- Dark Eternal Helmet - Reinforced heavy armor -->
<item id="35003" count="1" enchant_level="6" /> <!-- Dark Eternal Breastplate - Reinforced heavy armor -->
<item id="35004" count="1" enchant_level="6" /> <!-- Dark Eternal Gaiters - Reinforced heavy armor -->
<item id="35005" count="1" enchant_level="6" /> <!-- Dark Eternal Gauntlets - Reinforced heavy armor -->
<item id="35006" count="1" enchant_level="6" /> <!-- Dark Eternal Boots - Reinforced heavy armor -->
<item id="19440" count="1400" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="33" optionId="35831" category="2">
<item id="17436" count="1" enchant_level="10" /> <!-- Eternal Leather Helmet - Light armor -->
<item id="19912" count="1" enchant_level="10" /> <!-- Blessed Eternal Leather Helmet - Reinforced light armor -->
<item id="17437" count="1" enchant_level="10" /> <!-- Eternal Leather Armor - Light armor -->
<item id="18090" count="1" enchant_level="10" /> <!-- Blessed Eternal Leather Armor - Light armor -->
<item id="17438" count="1" enchant_level="10" /> <!-- Eternal Leather Leggings - Light armor -->
<item id="19914" count="1" enchant_level="10" /> <!-- Blessed Eternal Leather Leggings - Reinforced light armor -->
<item id="17439" count="1" enchant_level="10" /> <!-- Eternal Leather Gloves - Light armor -->
<item id="19915" count="1" enchant_level="10" /> <!-- Blessed Eternal Leather Gloves - Reinforced light armor -->
<item id="17440" count="1" enchant_level="10" /> <!-- Eternal Leather Boots - Light armor -->
<item id="19916" count="1" enchant_level="10" /> <!-- Blessed Eternal Leather Boots - Reinforced light armor -->
</collection>
<collection id="34" optionId="35832" category="2">
<item id="35043" count="1" enchant_level="12" /> <!-- Bloody Eternal Circlet - Reinforced robe -->
<item id="35044" count="1" enchant_level="6" /> <!-- Bloody Eternal Tunic - Reinforced robe -->
<item id="35045" count="1" enchant_level="6" /> <!-- Bloody Eternal Stockings - Reinforced robe -->
<item id="35046" count="1" enchant_level="6" /> <!-- Bloody Eternal Gloves - Reinforced robe -->
<item id="35047" count="1" enchant_level="6" /> <!-- Bloody Eternal Shoes - Reinforced robe -->
</collection>
<collection id="35" optionId="35833" category="2">
<item id="17430" count="1" enchant_level="3" /> <!-- Eternal Helmet - Heavy armor -->
<item id="19698" count="1" enchant_level="3" /> <!-- Blessed Eternal Helmet - Reinforced heavy armor -->
<item id="47952" count="650" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="36389" count="10" enchant_level="0" /> <!-- Giant's Scroll: Enchant R-grade Armor -->
<item id="19448" count="10" enchant_level="0" /> <!-- Blessed Scroll: Enchant R-grade Armor -->
<item id="17527" count="10" enchant_level="0" /> <!-- Scroll: Enchant R-grade Armor -->
</collection>
<collection id="36" optionId="35834" category="2">
<item id="80196" count="1" enchant_level="3" /> <!-- Enchanted Leviathan Leather Armor - Light armor -->
<item id="17436" count="1" enchant_level="0" /> <!-- Eternal Leather Helmet - Light armor -->
<item id="19912" count="1" enchant_level="0" /> <!-- Blessed Eternal Leather Helmet - Reinforced light armor -->
<item id="81728" count="20" enchant_level="0" /> <!-- Armor Augmenting Stone -->
</collection>
<collection id="37" optionId="35835" category="2">
<item id="80202" count="1" enchant_level="3" /> <!-- Enchanted Leviathan Stockings - Robe -->
<item id="47952" count="400" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="36389" count="8" enchant_level="0" /> <!-- Giant's Scroll: Enchant R-grade Armor -->
<item id="19448" count="6" enchant_level="0" /> <!-- Blessed Scroll: Enchant R-grade Armor -->
<item id="17527" count="3" enchant_level="0" /> <!-- Scroll: Enchant R-grade Armor -->
</collection>
<collection id="38" optionId="35836" category="2">
<item id="80203" count="1" enchant_level="3" /> <!-- Enchanted Leviathan Gloves - Robe -->
<item id="47952" count="400" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="36389" count="8" enchant_level="0" /> <!-- Giant's Scroll: Enchant R-grade Armor -->
<item id="19448" count="6" enchant_level="0" /> <!-- Blessed Scroll: Enchant R-grade Armor -->
<item id="17527" count="3" enchant_level="0" /> <!-- Scroll: Enchant R-grade Armor -->
</collection>
<collection id="39" optionId="35837" category="2">
<item id="80193" count="1" enchant_level="3" /> <!-- Enchanted Leviathan Boots - Heavy armor -->
<item id="47952" count="400" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="36389" count="8" enchant_level="0" /> <!-- Giant's Scroll: Enchant R-grade Armor -->
<item id="19448" count="6" enchant_level="0" /> <!-- Blessed Scroll: Enchant R-grade Armor -->
<item id="17527" count="3" enchant_level="0" /> <!-- Scroll: Enchant R-grade Armor -->
</collection>
<collection id="40" optionId="35838" category="2">
<item id="80194" count="1" enchant_level="3" /> <!-- Enchanted Leviathan Shield -->
<item id="47952" count="400" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="36389" count="8" enchant_level="0" /> <!-- Giant's Scroll: Enchant R-grade Armor -->
<item id="19448" count="6" enchant_level="0" /> <!-- Blessed Scroll: Enchant R-grade Armor -->
<item id="17527" count="3" enchant_level="0" /> <!-- Scroll: Enchant R-grade Armor -->
</collection>
<collection id="41" optionId="35839" category="2">
<item id="17433" count="1" enchant_level="12" /> <!-- Eternal Gauntlets - Heavy armor -->
<item id="19701" count="1" enchant_level="12" /> <!-- Blessed Eternal Gauntlets - Reinforced heavy armor -->
<item id="17434" count="1" enchant_level="12" /> <!-- Eternal Boots - Heavy armor -->
<item id="19702" count="1" enchant_level="12" /> <!-- Blessed Eternal Boots - Reinforced heavy armor -->
<item id="17527" count="28" enchant_level="0" /> <!-- Scroll: Enchant R-grade Armor -->
<item id="47952" count="1700" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="19440" count="1600" enchant_level="0" /> <!-- R-grade Gemstone -->
<item id="81728" count="116" enchant_level="0" /> <!-- Armor Augmenting Stone -->
</collection>
<collection id="42" optionId="35840" category="2">
<item id="17439" count="1" enchant_level="12" /> <!-- Eternal Leather Gloves - Light armor -->
<item id="19915" count="1" enchant_level="12" /> <!-- Blessed Eternal Leather Gloves - Reinforced light armor -->
<item id="17440" count="1" enchant_level="12" /> <!-- Eternal Leather Boots - Light armor -->
<item id="19916" count="1" enchant_level="12" /> <!-- Blessed Eternal Leather Boots - Reinforced light armor -->
<item id="17527" count="28" enchant_level="0" /> <!-- Scroll: Enchant R-grade Armor -->
<item id="47952" count="800" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="19440" count="800" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="43" optionId="35841" category="2">
<item id="17444" count="1" enchant_level="12" /> <!-- Eternal Gloves - Robe -->
<item id="19712" count="1" enchant_level="12" /> <!-- Blessed Eternal Gloves - Reinforced robe -->
<item id="17445" count="1" enchant_level="12" /> <!-- Eternal Shoes - Robe -->
<item id="19713" count="1" enchant_level="12" /> <!-- Blessed Eternal Shoes - Reinforced robe -->
<item id="17527" count="28" enchant_level="0" /> <!-- Scroll: Enchant R-grade Armor -->
<item id="47952" count="800" enchant_level="0" /> <!-- Crystal of Protection -->
<item id="19440" count="800" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="44" optionId="35842" category="2">
<item id="17436" count="1" enchant_level="7" /> <!-- Eternal Leather Helmet - Light armor -->
<item id="19912" count="1" enchant_level="7" /> <!-- Blessed Eternal Leather Helmet - Reinforced light armor -->
<item id="17437" count="1" enchant_level="7" /> <!-- Eternal Leather Armor - Light armor -->
<item id="19913" count="1" enchant_level="7" /> <!-- Blessed Eternal Leather Armor - Reinforced light armor -->
<item id="17438" count="1" enchant_level="7" /> <!-- Eternal Leather Leggings - Light armor -->
<item id="19914" count="1" enchant_level="7" /> <!-- Blessed Eternal Leather Leggings - Reinforced light armor -->
<item id="17439" count="1" enchant_level="7" /> <!-- Eternal Leather Gloves - Light armor -->
<item id="19915" count="1" enchant_level="7" /> <!-- Blessed Eternal Leather Gloves - Reinforced light armor -->
<item id="17440" count="1" enchant_level="7" /> <!-- Eternal Leather Boots - Light armor -->
<item id="19916" count="1" enchant_level="7" /> <!-- Blessed Eternal Leather Boots - Reinforced light armor -->
</collection>
<collection id="45" optionId="35843" category="2">
<item id="80195" count="1" enchant_level="5" /> <!-- Enchanted Leviathan Leather Helmet - Light armor -->
<item id="80196" count="1" enchant_level="5" /> <!-- Enchanted Leviathan Leather Armor - Light armor -->
<item id="80197" count="1" enchant_level="5" /> <!-- Enchanted Leviathan Leather Leggings - Light armor -->
<item id="80198" count="1" enchant_level="5" /> <!-- Enchanted Leviathan Leather Gloves - Light armor -->
<item id="80199" count="1" enchant_level="5" /> <!-- Enchanted Leviathan Leather Boots - Light armor -->
</collection>
<collection id="46" optionId="35844" category="3">
<item id="81381" count="1" enchant_level="1" /> <!-- Dragon's Necklace - Battle Lv. 3 -->
<item id="81384" count="1" enchant_level="1" /> <!-- Dragon's Earring - Guardian Lv. 3 -->
<item id="81387" count="1" enchant_level="1" /> <!-- Dragon's Ring - Potential Lv. 3 -->
</collection>
<collection id="47" optionId="35845" category="3">
<item id="48669" count="1" enchant_level="8" /> <!-- Angel's Necklace -->
<item id="81212" count="1" enchant_level="8" /> <!-- Angel's Necklace -->
<item id="48841" count="1" enchant_level="8" /> <!-- Angel's Earring -->
<item id="81213" count="1" enchant_level="8" /> <!-- Angel's Earring -->
<item id="81154" count="1" enchant_level="8" /> <!-- Angel's Ring -->
<item id="81214" count="1" enchant_level="8" /> <!-- Angel's Ring -->
</collection>
<collection id="48" optionId="35846" category="3">
<item id="19464" count="1" enchant_level="12" /> <!-- Blessed Valakas' Necklace -->
<item id="47916" count="1" enchant_level="0" /> <!-- Nevit's Cloak of Light Box - 30-day -->
</collection>
<collection id="49" optionId="35847" category="3">
<item id="19463" count="1" enchant_level="12" /> <!-- Blessed Antharas' Earring -->
<item id="80134" count="1" enchant_level="0" /> <!-- Enhanced Krishna Cutter -->
</collection>
<collection id="50" optionId="35848" category="3">
<item id="36946" count="1" enchant_level="12" /> <!-- Lindvior's Earring -->
<item id="80142" count="1" enchant_level="0" /> <!-- Enhanced Krishna Caster -->
</collection>
<collection id="51" optionId="35849" category="3">
<item id="81784" count="1" enchant_level="6" /> <!-- Blessed Angel's Necklace -->
<item id="81796" count="1" enchant_level="6" /> <!-- Blessed Angel's Necklace -->
<item id="47494" count="20" enchant_level="0" /> <!-- Selenite -->
</collection>
<collection id="52" optionId="35850" category="3">
<item id="81788" count="1" enchant_level="6" /> <!-- Blessed Angel's Earring -->
<item id="81800" count="1" enchant_level="6" /> <!-- Blessed Angel's Earring -->
<item id="47494" count="20" enchant_level="0" /> <!-- Selenite -->
</collection>
<collection id="53" optionId="35851" category="3">
<item id="81792" count="1" enchant_level="6" /> <!-- Blessed Angel's Ring -->
<item id="81804" count="1" enchant_level="6" /> <!-- Blessed Angel's Ring -->
<item id="47494" count="40" enchant_level="0" /> <!-- Selenite -->
</collection>
<collection id="54" optionId="35852" category="3">
<item id="48669" count="1" enchant_level="4" /> <!-- Angel's Necklace -->
<item id="81212" count="1" enchant_level="4" /> <!-- Angel's Necklace -->
<item id="48669" count="1" enchant_level="6" /> <!-- Angel's Necklace -->
<item id="81212" count="1" enchant_level="6" /> <!-- Angel's Necklace -->
<item id="48669" count="1" enchant_level="8" /> <!-- Angel's Necklace -->
<item id="81212" count="1" enchant_level="8" /> <!-- Angel's Necklace -->
</collection>
<collection id="55" optionId="35853" category="3">
<item id="48841" count="1" enchant_level="4" /> <!-- Angel's Earring -->
<item id="81213" count="1" enchant_level="4" /> <!-- Angel's Earring -->
<item id="48841" count="1" enchant_level="5" /> <!-- Angel's Earring -->
<item id="81213" count="1" enchant_level="5" /> <!-- Angel's Earring -->
<item id="48841" count="1" enchant_level="6" /> <!-- Angel's Earring -->
<item id="81213" count="1" enchant_level="6" /> <!-- Angel's Earring -->
<item id="48841" count="1" enchant_level="7" /> <!-- Angel's Earring -->
<item id="81213" count="1" enchant_level="7" /> <!-- Angel's Earring -->
</collection>
<collection id="56" optionId="35854" category="3">
<item id="81154" count="1" enchant_level="4" /> <!-- Angel's Ring -->
<item id="81214" count="1" enchant_level="4" /> <!-- Angel's Ring -->
<item id="81154" count="1" enchant_level="5" /> <!-- Angel's Ring -->
<item id="81214" count="1" enchant_level="5" /> <!-- Angel's Ring -->
<item id="81154" count="1" enchant_level="7" /> <!-- Angel's Ring -->
<item id="81214" count="1" enchant_level="7" /> <!-- Angel's Ring -->
</collection>
<collection id="57" optionId="35855" category="3">
<item id="48864" count="1" enchant_level="4" /> <!-- Fallen Angel's Ring -->
<item id="48864" count="1" enchant_level="5" /> <!-- Fallen Angel's Ring -->
<item id="48864" count="1" enchant_level="6" /> <!-- Fallen Angel's Ring -->
<item id="48864" count="1" enchant_level="7" /> <!-- Fallen Angel's Ring -->
<item id="48864" count="1" enchant_level="9" /> <!-- Fallen Angel's Ring -->
</collection>
<collection id="58" optionId="35856" category="3">
<item id="48669" count="1" enchant_level="2" /> <!-- Angel's Necklace -->
<item id="81212" count="1" enchant_level="2" /> <!-- Angel's Necklace -->
<item id="48841" count="1" enchant_level="2" /> <!-- Angel's Earring -->
<item id="81213" count="1" enchant_level="2" /> <!-- Angel's Earring -->
<item id="81154" count="1" enchant_level="2" /> <!-- Angel's Ring -->
<item id="81214" count="1" enchant_level="2" /> <!-- Angel's Ring -->
<item id="48668" count="70" enchant_level="0" /> <!-- Scroll: Enchant Angel Accessory -->
<item id="81729" count="30" enchant_level="0" /> <!-- Accessory Augmenting Stone -->
</collection>
<collection id="59" optionId="35857" category="4">
<item id="48577" count="1" enchant_level="0" /> <!-- Superior Seed Bracelet Lv. 4 -->
<item id="47866" count="20" enchant_level="0" /> <!-- Star Sign -->
</collection>
<collection id="60" optionId="35858" category="4">
<item id="48576" count="1" enchant_level="0" /> <!-- Superior Seed Bracelet Lv. 3 -->
<item id="47866" count="54" enchant_level="0" /> <!-- Star Sign -->
<item id="47552" count="1300" enchant_level="0" /> <!-- Powerful Fish -->
<item id="80839" count="54" enchant_level="0" /> <!-- Crystal of Dawn -->
</collection>
<collection id="61" optionId="35859" category="4">
<item id="35564" count="1" enchant_level="0" /> <!-- Ruler's Authority - Lv. 1 -->
<item id="48418" count="1" enchant_level="0" /> <!-- Authority Ornament -->
</collection>
<collection id="62" optionId="35860" category="4">
<item id="29546" count="1" enchant_level="0" /> <!-- Enhanced La Vie En Rose's Brooch -->
<item id="81361" count="258" enchant_level="0" /> <!-- Blessed Scroll: Enchant Brooch -->
<item id="80839" count="50" enchant_level="0" /> <!-- Crystal of Dawn -->
</collection>
<collection id="63" optionId="35861" category="4">
<item id="48493" count="1" enchant_level="0" /> <!-- Dragon Rind Leather Shirt -->
<item id="48498" count="484" enchant_level="0" /> <!-- Blessed Scroll: Enchant Dragon Shirt -->
<item id="80839" count="50" enchant_level="0" /> <!-- Crystal of Dawn -->
</collection>
<collection id="64" optionId="35862" category="4">
<item id="48204" count="1" enchant_level="4" /> <!-- Radiant Warrior's Circlet -->
<item id="48207" count="1" enchant_level="4" /> <!-- Radiant Wizard's Circlet -->
<item id="48210" count="1" enchant_level="3" /> <!-- Radiant Knight's Circlet -->
</collection>
<collection id="65" optionId="35863" category="4">
<item id="81153" count="1" enchant_level="4" /> <!-- Navaris Mask -->
<item id="48583" count="9" enchant_level="0" /> <!-- Giant's Scroll: Enchant Mask -->
</collection>
<collection id="66" optionId="35864" category="4">
<item id="81695" count="1" enchant_level="0" /> <!-- Improved Artifact Book - Lv. 3 -->
<item id="81694" count="34" enchant_level="0" /> <!-- Blessed Scroll: Enchant Artifact Book -->
</collection>
<collection id="67" optionId="35865" category="4">
<item id="48211" count="15" enchant_level="0" /> <!-- Blessed Scroll: Enchant Circlet -->
<item id="48498" count="4" enchant_level="0" /> <!-- Blessed Scroll: Enchant Dragon Shirt -->
<item id="81361" count="4" enchant_level="0" /> <!-- Blessed Scroll: Enchant Brooch -->
<item id="48841" count="1" enchant_level="6" /> <!-- Angel's Earring -->
<item id="81213" count="1" enchant_level="6" /> <!-- Angel's Earring -->
<item id="81706" count="4" enchant_level="0" /> <!-- Scroll: Enchant Superior Seed Bracelet -->
<item id="81694" count="4" enchant_level="0" /> <!-- Blessed Scroll: Enchant Artifact Book -->
</collection>
<collection id="68" optionId="35866" category="4">
<item id="80837" count="1" enchant_level="5" /> <!-- Superior Kaliel's Bracelet -->
<item id="80838" count="668" enchant_level="0" /> <!-- Blessed Scroll: Enchant Kaliel's Bracelet -->
<item id="80839" count="62" enchant_level="0" /> <!-- Crystal of Dawn -->
</collection>
<collection id="69" optionId="35867" category="4">
<item id="80837" count="1" enchant_level="2" /> <!-- Superior Kaliel's Bracelet -->
<item id="36186" count="7" enchant_level="0" /> <!-- Energy of Desire -->
<item id="34989" count="1" enchant_level="0" /> <!-- Talisman of Longing -->
<item id="19440" count="800" enchant_level="0" /> <!-- R-grade Gemstone -->
</collection>
<collection id="70" optionId="35868" category="4">
<item id="48060" count="1" enchant_level="0" /> <!-- Elementary Seed Bracelet -->
<item id="48215" count="30" enchant_level="0" /> <!-- Circlet Augmenting Stone -->
<item id="28484" count="30" enchant_level="0" /> <!-- Brooch Augmenting Stone -->
</collection>
<collection id="71" optionId="35869" category="4">
<item id="80835" count="1" enchant_level="0" /> <!-- Kaliel's Bracelet -->
<item id="48060" count="1" enchant_level="0" /> <!-- Elementary Seed Bracelet -->
<item id="38768" count="1" enchant_level="0" /> <!-- La Vie En Rose's Brooch Lv. 1 -->
<item id="48954" count="1" enchant_level="0" /> <!-- Artifact Book - Lv. 1 -->
</collection>
<collection id="72" optionId="35870" category="4">
<item id="48584" count="1" enchant_level="5" /> <!-- Savior's Mask -->
<item id="48582" count="10" enchant_level="0" /> <!-- Scroll: Enchant Mask -->
</collection>
<collection id="73" optionId="35871" category="5">
<item id="81628" count="1" enchant_level="0" /> <!-- Superior Blue Cat's Eye Lv. 4 -->
<item id="48831" count="100" enchant_level="0" /> <!-- Jewel Energy -->
</collection>
<collection id="74" optionId="35872" category="5">
<item id="81565" count="1" enchant_level="0" /> <!-- Superior Diamond Lv. 1 -->
<item id="81577" count="1" enchant_level="0" /> <!-- Superior Pearl Lv. 3 -->
</collection>
<collection id="75" optionId="35873" category="5">
<item id="39572" count="1" enchant_level="0" /> <!-- Talisman of Insanity -->
<item id="34989" count="1" enchant_level="0" /> <!-- Talisman of Longing -->
<item id="47420" count="7" enchant_level="0" /> <!-- Energy of Longing -->
</collection>
<collection id="76" optionId="35874" category="5">
<item id="48678" count="5" enchant_level="0" /> <!-- High-grade Talisman of Attribute Attack Pack - Critical Damage for standard attacks -->
<item id="48677" count="5" enchant_level="0" /> <!-- High-grade Skill Power Talisman Pack - Skill Critical Damage -->
<item id="48679" count="5" enchant_level="0" /> <!-- High-grade Skill Cooldown Talisman Pack - P. Def./M. Def. -->
</collection>
<collection id="77" optionId="35875" category="5">
<item id="80942" count="1" enchant_level="5" /> <!-- Greater Agathion Gemini Charm -->
<item id="80946" count="1" enchant_level="5" /> <!-- Greater Agathion Sagittarius Charm -->
</collection>
<collection id="78" optionId="35876" category="5">
<item id="80936" count="1" enchant_level="2" /> <!-- Greater Agathion Virgo Charm -->
<item id="80937" count="1" enchant_level="2" /> <!-- Greater Agathion Capricorn Charm -->
<item id="80932" count="10" enchant_level="0" /> <!-- Greater Zodiac Agathion's Book of Growth -->
</collection>
<collection id="79" optionId="35877" category="5">
<item id="48957" count="1" enchant_level="5" /> <!-- Artifact - P. Atk. - Attack -->
<item id="80647" count="1" enchant_level="5" /> <!-- Artifact - Standard Attack Critical Damage - Attack -->
<item id="80636" count="158" enchant_level="0" /> <!-- Artifact Crystal -->
</collection>
<collection id="80" optionId="35878" category="5">
<item id="48957" count="1" enchant_level="5" /> <!-- Artifact - P. Atk. - Attack -->
<item id="80648" count="1" enchant_level="5" /> <!-- Artifact - P. Skill Critical Damage - Attack -->
<item id="80636" count="35" enchant_level="0" /> <!-- Artifact Crystal -->
</collection>
<collection id="81" optionId="35879" category="5">
<item id="81433" count="1" enchant_level="5" /> <!-- Artifact - Attribute Resistance - Defense -->
<item id="80652" count="1" enchant_level="5" /> <!-- Artifact - Sword Resistance - Protection -->
<item id="80636" count="158" enchant_level="0" /> <!-- Artifact Crystal -->
</collection>
<collection id="82" optionId="35880" category="5">
<item id="80650" count="1" enchant_level="5" /> <!-- Artifact - Bow Resistance - Protection -->
<item id="48963" count="1" enchant_level="5" /> <!-- Artifact - Max HP - Protection -->
<item id="80636" count="35" enchant_level="0" /> <!-- Artifact Crystal -->
</collection>
<collection id="83" optionId="35881" category="5">
<item id="48965" count="1" enchant_level="5" /> <!-- Artifact - Acquired XP - Support -->
<item id="80653" count="1" enchant_level="5" /> <!-- Artifact - Vitality Bonus - Support -->
<item id="80636" count="158" enchant_level="0" /> <!-- Artifact Crystal -->
</collection>
<collection id="84" optionId="35882" category="5">
<item id="80655" count="1" enchant_level="5" /> <!-- Artifact - Skill MP Consumption - Support -->
<item id="48967" count="1" enchant_level="5" /> <!-- Artifact - Speed - Support -->
<item id="80636" count="35" enchant_level="0" /> <!-- Artifact Crystal -->
</collection>
<collection id="85" optionId="35883" category="5">
<item id="48971" count="1" enchant_level="5" /> <!-- Artifact - P. Accuracy - Balance -->
<item id="48972" count="1" enchant_level="5" /> <!-- Artifact - M. Accuracy - Balance -->
<item id="80636" count="35" enchant_level="0" /> <!-- Artifact Crystal -->
</collection>
<collection id="86" optionId="35884" category="5">
<item id="80661" count="1" enchant_level="7" /> <!-- Artifact - Atk. Spd. - Balance -->
<item id="80662" count="1" enchant_level="7" /> <!-- Artifact - Casting Spd. - Balance -->
<item id="48977" count="1" enchant_level="5" /> <!-- Artifact - Received Damage When Immobilized - Balance -->
<item id="81431" count="1" enchant_level="6" /> <!-- Artifact - P. Skill Power - Attack -->
<item id="81432" count="1" enchant_level="6" /> <!-- Artifact - M. Skill Power - Attack -->
</collection>
<collection id="87" optionId="35885" category="5">
<item id="80144" count="1" enchant_level="3" /> <!-- Enhanced Krishna Dual Swords -->
<item id="48878" count="1" enchant_level="0" /> <!-- Forgotten Spellbook Chapter 3 -->
<item id="39738" count="10" enchant_level="0" /> <!-- Rune Stone -->
</collection>
<collection id="88" optionId="35886" category="5">
<item id="80133" count="1" enchant_level="3" /> <!-- Enhanced Krishna Shaper -->
<item id="48877" count="5" enchant_level="0" /> <!-- Forgotten Spellbook Chapter 2 -->
<item id="48876" count="5" enchant_level="0" /> <!-- Forgotten Spellbook Chapter 1 -->
</collection>
<collection id="89" optionId="35887" category="5">
<item id="80141" count="1" enchant_level="3" /> <!-- Enhanced Krishna Buster -->
<item id="48876" count="12" enchant_level="0" /> <!-- Forgotten Spellbook Chapter 1 -->
<item id="39738" count="30" enchant_level="0" /> <!-- Rune Stone -->
</collection>
<collection id="90" optionId="35888" category="5">
<item id="46449" count="1" enchant_level="0" /> <!-- Kain's Soul Crystal Lv. 6 -->
</collection>
<collection id="91" optionId="35889" category="5">
<item id="46465" count="1" enchant_level="0" /> <!-- Mermoden's Soul Crystal Lv. 7 -->
</collection>
<collection id="92" optionId="35890" category="5">
<item id="81089" count="1" enchant_level="0" /> <!-- Legendary Dye Lv. 5 (P. Skill Power) - STR +5, DEX +5, CHA +4 -->
<item id="81119" count="1" enchant_level="0" /> <!-- Legendary Dye Lv. 5 (M. Skill Power) - INT +5, WIT +5, CHA +4 -->
<item id="81134" count="10" enchant_level="0" /> <!-- Crystal of Dyes -->
<item id="80762" count="610" enchant_level="0" /> <!-- Dye Powder -->
</collection>
<collection id="93" optionId="35891" category="5">
<item id="81056" count="1" enchant_level="0" /> <!-- Legendary Dye Lv. 2 (P. Atk.) - STR +3, DEX +3, CHA +1 -->
<item id="81096" count="1" enchant_level="0" /> <!-- Legendary Dye Lv. 2 (M. Atk.) - INT +3, WIT +3, CHA +1 -->
<item id="80762" count="410" enchant_level="0" /> <!-- Dye Powder -->
</collection>
<collection id="94" optionId="35892" category="7">
<item id="48954" count="1" enchant_level="0" /> <!-- Artifact Book - Lv. 1 -->
<item id="35567" count="10" enchant_level="0" /> <!-- Dark Armor Enhancement Stone -->
<item id="35563" count="30" enchant_level="0" /> <!-- Giant's Energy -->
<item id="35562" count="30" enchant_level="0" /> <!-- Destructive Energy -->
</collection>
<collection id="95" optionId="35893" category="7">
<item id="48491" count="1" enchant_level="0" /> <!-- Dragon Skin Shirt -->
<item id="35569" count="10" enchant_level="0" /> <!-- Bloody Armor Enhancement Stone -->
<item id="35563" count="30" enchant_level="0" /> <!-- Giant's Energy -->
<item id="35562" count="30" enchant_level="0" /> <!-- Destructive Energy -->
</collection>
<collection id="96" optionId="35894" category="7">
<item id="9558" count="3" enchant_level="0" /> <!-- Fire Jewel -->
<item id="9559" count="3" enchant_level="0" /> <!-- Water Jewel -->
<item id="9560" count="3" enchant_level="0" /> <!-- Earth Jewel -->
<item id="9561" count="3" enchant_level="0" /> <!-- Wind Jewel -->
<item id="9563" count="3" enchant_level="0" /> <!-- Holy Jewel -->
<item id="38768" count="1" enchant_level="0" /> <!-- La Vie En Rose's Brooch Lv. 1 -->
</collection>
<collection id="97" optionId="35895" category="5">
<item id="28440" count="1" enchant_level="0" /> <!-- Sayha's Talisman Lv. 4 -->
<item id="29060" count="1" enchant_level="0" /> <!-- Sayha's Talisman Lv. 4 -->
<item id="28447" count="45" enchant_level="0" /> <!-- Sayha's Talisman Pack -->
<item id="29067" count="45" enchant_level="0" /> <!-- Sayha's Talisman Pack -->
</collection>
<collection id="98" optionId="35896" category="5">
<item id="39644" count="1" enchant_level="0" /> <!-- Venir's Talisman Lv. 11 -->
</collection>
<collection id="99" optionId="35897" category="7">
<item id="81215" count="500" enchant_level="0" /> <!-- Aether -->
<item id="17371" count="200" enchant_level="0" /> <!-- R-grade Crystal -->
</collection>
<collection id="100" optionId="35898" category="7">
<item id="81837" count="1" enchant_level="0" /> <!-- Bloody Soul Orb - Lv. 1 -->
<item id="81840" count="1" enchant_level="0" /> <!-- Bloody Soul Orb - Lv. 4 -->
<item id="81847" count="1" enchant_level="0" /> <!-- Orb of Abyss -->
<item id="81858" count="1" enchant_level="0" /> <!-- Orb of Darkness -->
</collection>
<collection id="101" optionId="35899" category="6">
<item id="81839" count="1" enchant_level="0" /> <!-- Bloody Soul Orb - Lv. 3 -->
<item id="81841" count="1" enchant_level="0" /> <!-- Bloody Soul Orb - Lv. 5 -->
<item id="81844" count="1" enchant_level="0" /> <!-- Bloody Soul Orb - Lv. 8 -->
<item id="81846" count="1" enchant_level="0" /> <!-- Bloody Soul Orb - Lv. 10 -->
</collection>
<collection id="102" optionId="35900" category="6">
<item id="81844" count="1" enchant_level="0" /> <!-- Bloody Soul Orb - Lv. 8 -->
<item id="81845" count="1" enchant_level="0" /> <!-- Bloody Soul Orb - Lv. 9 -->
</collection>
<collection id="103" optionId="35901" category="6">
<item id="81848" count="1" enchant_level="0" /> <!-- Orb of Abyss - Lv. 1 -->
<item id="81850" count="1" enchant_level="0" /> <!-- Orb of Abyss - Lv. 3 -->
<item id="81854" count="1" enchant_level="0" /> <!-- Orb of Abyss - Lv. 7 -->
</collection>
<collection id="104" optionId="35902" category="6">
<item id="81860" count="1" enchant_level="0" /> <!-- Orb of Darkness - Lv. 2 -->
<item id="81861" count="1" enchant_level="0" /> <!-- Orb of Darkness - Lv. 3 -->
<item id="81864" count="1" enchant_level="0" /> <!-- Orb of Darkness - Lv. 6 -->
<item id="81865" count="1" enchant_level="0" /> <!-- Orb of Darkness - Lv. 7 -->
</collection>
<collection id="105" optionId="35903" category="6">
<item id="81890" count="1" enchant_level="0" /> <!-- Anniversary Badge of Lv. 120 -->
</collection>
<collection id="106" optionId="35904" category="6">
<item id="81890" count="1" enchant_level="0" /> <!-- Anniversary Badge of Lv. 120 -->
</collection>
<collection id="109" optionId="35908" category="3">
<item id="47216" count="1" enchant_level="12" /> <!-- Ruler's Ring of Authority -->
<item id="81729" count="30" enchant_level="0" /> <!-- Accessory Augmenting Stone -->
</collection>
<collection id="110" optionId="35909" category="3">
<item id="47218" count="1" enchant_level="12" /> <!-- Ring of the Truth-Seeker -->
<item id="81729" count="30" enchant_level="0" /> <!-- Accessory Augmenting Stone -->
</collection>
</list>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element name="collection" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="item" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:int" name="id" />
<xs:attribute type="xs:int" name="count" use="required"/>
<xs:attribute type="xs:int" name="enchant_level" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:integer" name="id" use="required" />
<xs:attribute type="xs:integer" name="optionId" use="required" />
<xs:attribute type="xs:integer" name="category" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -59,6 +59,7 @@ import org.l2jmobius.gameserver.data.xml.ClanHallData;
import org.l2jmobius.gameserver.data.xml.ClanMasteryData;
import org.l2jmobius.gameserver.data.xml.ClanShopData;
import org.l2jmobius.gameserver.data.xml.ClassListData;
import org.l2jmobius.gameserver.data.xml.CollectionData;
import org.l2jmobius.gameserver.data.xml.CombinationItemsData;
import org.l2jmobius.gameserver.data.xml.CubicData;
import org.l2jmobius.gameserver.data.xml.DailyMissionData;
@ -283,6 +284,7 @@ public class GameServer
FishingData.getInstance();
HennaData.getInstance();
PrimeShopData.getInstance();
CollectionData.getInstance();
PcCafePointsManager.getInstance();
AppearanceItemData.getInstance();
AlchemyData.getInstance();

View File

@ -0,0 +1,136 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.data.xml;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.l2jmobius.commons.util.IXmlReader;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.holders.CollectionDataHolder;
import org.l2jmobius.gameserver.model.holders.ItemCollectionData;
import org.l2jmobius.gameserver.model.items.Item;
/**
* Written by Berezkin Nikolay, on 04.05.2021
*/
public class CollectionData implements IXmlReader
{
private static final Logger LOGGER = Logger.getLogger(CollectionData.class.getName());
private static final Map<Integer, CollectionDataHolder> _collections = new HashMap<>();
protected CollectionData()
{
load();
}
@Override
public void load()
{
_collections.clear();
parseDatapackFile("data/CollectionData.xml");
if (!_collections.isEmpty())
{
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _collections.size() + " collections.");
}
else
{
LOGGER.info(getClass().getSimpleName() + ": System is disabled.");
}
}
@Override
public void parseDocument(Document doc, File f)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("collection".equalsIgnoreCase(d.getNodeName()))
{
NamedNodeMap attrs = d.getAttributes();
Node att;
final StatSet set = new StatSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
final int id = parseInteger(attrs, "id");
final int optionId = parseInteger(attrs, "optionId");
final int category = parseInteger(attrs, "category");
List<ItemCollectionData> items = new ArrayList<>();
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
attrs = b.getAttributes();
if ("item".equalsIgnoreCase(b.getNodeName()))
{
final int itemId = parseInteger(attrs, "id");
final long itemCount = parseLong(attrs, "count", 1L);
final int itemEnchantLevel = parseInteger(attrs, "enchant_level", 0);
final Item item = ItemTable.getInstance().getTemplate(itemId);
if (item == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Item template null for itemId: " + itemId + " collection item: " + id);
continue;
}
items.add(new ItemCollectionData(itemId, itemCount, itemEnchantLevel));
}
}
_collections.put(id, new CollectionDataHolder(id, optionId, category, items));
}
}
}
}
}
public CollectionDataHolder getCollection(int id)
{
return _collections.get(id);
}
public Collection<CollectionDataHolder> getCollections()
{
return _collections.values();
}
public static CollectionData getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final CollectionData INSTANCE = new CollectionData();
}
}

View File

@ -68,10 +68,12 @@ import org.l2jmobius.gameserver.data.xml.AdminData;
import org.l2jmobius.gameserver.data.xml.AttendanceRewardData;
import org.l2jmobius.gameserver.data.xml.CategoryData;
import org.l2jmobius.gameserver.data.xml.ClassListData;
import org.l2jmobius.gameserver.data.xml.CollectionData;
import org.l2jmobius.gameserver.data.xml.ExperienceData;
import org.l2jmobius.gameserver.data.xml.HennaData;
import org.l2jmobius.gameserver.data.xml.NpcData;
import org.l2jmobius.gameserver.data.xml.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.OptionData;
import org.l2jmobius.gameserver.data.xml.PetDataTable;
import org.l2jmobius.gameserver.data.xml.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.PlayerXpPercentLostData;
@ -218,10 +220,12 @@ import org.l2jmobius.gameserver.model.fishing.Fishing;
import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import org.l2jmobius.gameserver.model.holders.AutoPlaySettingsHolder;
import org.l2jmobius.gameserver.model.holders.AutoUseSettingsHolder;
import org.l2jmobius.gameserver.model.holders.CollectionDataHolder;
import org.l2jmobius.gameserver.model.holders.DamageTakenHolder;
import org.l2jmobius.gameserver.model.holders.ItemHolder;
import org.l2jmobius.gameserver.model.holders.ItemSkillHolder;
import org.l2jmobius.gameserver.model.holders.MovieHolder;
import org.l2jmobius.gameserver.model.holders.PlayerCollectionData;
import org.l2jmobius.gameserver.model.holders.PlayerEventHolder;
import org.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
import org.l2jmobius.gameserver.model.holders.RecipeHolder;
@ -253,6 +257,7 @@ import org.l2jmobius.gameserver.model.olympiad.Hero;
import org.l2jmobius.gameserver.model.olympiad.OlympiadGameManager;
import org.l2jmobius.gameserver.model.olympiad.OlympiadGameTask;
import org.l2jmobius.gameserver.model.olympiad.OlympiadManager;
import org.l2jmobius.gameserver.model.options.Options;
import org.l2jmobius.gameserver.model.punishment.PunishmentAffect;
import org.l2jmobius.gameserver.model.punishment.PunishmentTask;
import org.l2jmobius.gameserver.model.punishment.PunishmentType;
@ -415,6 +420,14 @@ public class PlayerInstance extends Playable
// Character Shortcut SQL String Definitions:
private static final String DELETE_CHAR_SHORTCUTS = "DELETE FROM character_shortcuts WHERE charId=? AND class_index=?";
// Character Collections list
private static final String DELETE_COLLECTION = "DELETE FROM collections WHERE accountName=?";
private static final String INSERT_COLLECTION = "REPLACE INTO collections (`accountName`, `itemId`, `collectionId`, `index`) VALUES (?, ?, ?, ?)";
private static final String RESTORE_COLLECTION = "SELECT * FROM collections WHERE accountName=? ORDER BY `index`";
private static final String DELETE_COLLECTION_FAVORITE = "DELETE FROM collection_favorites WHERE accountName=?";
private static final String INSERT_COLLECTION_FAVORITE = "REPLACE INTO collection_favorites (`accountName`, `collectionId`) VALUES (?, ?)";
private static final String RESTORE_COLLECTION_FAVORITE = "SELECT * FROM collection_favorites WHERE accountName=?";
// Character Recipe List Save
private static final String DELETE_CHAR_RECIPE_SHOP = "DELETE FROM character_recipeshoplist WHERE charId=?";
private static final String INSERT_CHAR_RECIPE_SHOP = "REPLACE INTO character_recipeshoplist (`charId`, `recipeId`, `price`, `index`) VALUES (?, ?, ?, ?)";
@ -889,6 +902,9 @@ public class PlayerInstance extends Playable
private int _homunculusDefBonus;
private float _homunculusCritBonus;
private final List<PlayerCollectionData> _collections = new ArrayList<>();
private final List<Integer> _collectionFavorites = new ArrayList<>();
private final List<QuestTimer> _questTimers = new ArrayList<>();
private final List<TimerHolder<?>> _timerHolders = new ArrayList<>();
@ -6944,6 +6960,11 @@ public class PlayerInstance extends Playable
restoreRecipeShopList();
}
// Restore collections.
restoreCollections();
restoreCollectionBonuses();
restoreCollectionFavorites();
// Load Premium Item List.
loadPremiumItemList();
@ -7091,6 +7112,10 @@ public class PlayerInstance extends Playable
storeRecipeShopList();
}
// Store collections.
storeCollections();
storeCollectionFavorites();
final PlayerVariables vars = getScript(PlayerVariables.class);
if (vars != null)
{
@ -14400,6 +14425,165 @@ public class PlayerInstance extends Playable
return Math.max(getVariables().getLong(PlayerVariables.HUNTING_ZONE_ENTRY + zoneId, 0), 0);
}
public List<PlayerCollectionData> getCollections()
{
return _collections;
}
public List<Integer> getCollectionFavorites()
{
return _collectionFavorites;
}
public void addCollectionFavorite(Integer id)
{
_collectionFavorites.add(id);
}
public void removeCollectionFavorite(Integer id)
{
_collectionFavorites.remove(id);
}
public void storeCollections()
{
try (Connection con = DatabaseFactory.getConnection())
{
try (PreparedStatement st = con.prepareStatement(DELETE_COLLECTION))
{
st.setString(1, getAccountNamePlayer());
st.execute();
}
try (PreparedStatement st = con.prepareStatement(INSERT_COLLECTION))
{
_collections.forEach(data ->
{
try
{
st.setString(1, getAccountNamePlayer());
st.setInt(2, data.getItemId());
st.setInt(3, data.getCollectionId());
st.setInt(4, data.getIndex());
st.addBatch();
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not store collection for playerId " + getObjectId() + ": ", e);
}
});
st.executeBatch();
con.commit();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not store collection for playerId " + getObjectId() + ": ", e);
}
}
public void storeCollectionFavorites()
{
try (Connection con = DatabaseFactory.getConnection())
{
try (PreparedStatement st = con.prepareStatement(DELETE_COLLECTION_FAVORITE))
{
st.setString(1, getAccountNamePlayer());
st.execute();
}
try (PreparedStatement st = con.prepareStatement(INSERT_COLLECTION_FAVORITE))
{
_collectionFavorites.forEach(data ->
{
try
{
st.setString(1, getAccountNamePlayer());
st.setInt(2, data);
st.addBatch();
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not store collection favorite for playerId " + getObjectId() + ": ", e);
}
});
st.executeBatch();
con.commit();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not store collection favorite for playerId " + getObjectId() + ": ", e);
}
}
private void restoreCollections()
{
if (_collections != null)
{
_collections.clear();
}
try (Connection con = DatabaseFactory.getConnection();
PreparedStatement statement = con.prepareStatement(RESTORE_COLLECTION))
{
statement.setString(1, getAccountNamePlayer());
try (ResultSet rset = statement.executeQuery())
{
while (rset.next())
{
_collections.add(new PlayerCollectionData(rset.getInt("collectionId"), rset.getInt("itemId"), rset.getInt("index")));
}
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not restore collection list data for playerId: " + getObjectId(), e);
}
}
private void restoreCollectionBonuses()
{
getCollections().stream().map(PlayerCollectionData::getCollectionId).collect(Collectors.toSet()).forEach(uniqueCollection ->
{
final List<PlayerCollectionData> currentProgress = getCollections().stream().filter(it -> it.getCollectionId() == uniqueCollection).collect(Collectors.toList());
final CollectionDataHolder template = CollectionData.getInstance().getCollection(uniqueCollection);
if (currentProgress.size() == template.getItems().size())
{
final Options options = OptionData.getInstance().getOptions(template.getOptionId());
if (options != null)
{
options.apply(this);
}
}
});
}
private void restoreCollectionFavorites()
{
if (_collectionFavorites != null)
{
_collectionFavorites.clear();
}
try (Connection con = DatabaseFactory.getConnection();
PreparedStatement statement = con.prepareStatement(RESTORE_COLLECTION_FAVORITE))
{
statement.setString(1, getAccountNamePlayer());
try (ResultSet rset = statement.executeQuery())
{
while (rset.next())
{
_collectionFavorites.add(rset.getInt("collectionId"));
}
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not restore collection favorite list data for playerId: " + getObjectId(), e);
}
}
public int getHomunculusHpBonus()
{
return _homunculusHpBonus;

View File

@ -0,0 +1,58 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.model.holders;
import java.util.List;
/**
* Written by Berezkin Nikolay, on 04.05.2021
*/
public class CollectionDataHolder
{
private final int _collectionId;
private final int _optionId;
private final int _category;
private final List<ItemCollectionData> _items;
public CollectionDataHolder(int collectionId, int optionId, int category, List<ItemCollectionData> items)
{
_collectionId = collectionId;
_optionId = optionId;
_category = category;
_items = items;
}
public int getCollectionId()
{
return _collectionId;
}
public int getOptionId()
{
return _optionId;
}
public int getCategory()
{
return _category;
}
public List<ItemCollectionData> getItems()
{
return _items;
}
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.model.holders;
/**
* Written by Berezkin Nikolay, on 04.05.2021
*/
public class ItemCollectionData
{
private final int _enchantLevel;
private final int _itemId;
private final long _count;
public ItemCollectionData(int itemId, long count, int enchantLevel)
{
_itemId = itemId;
_count = count;
_enchantLevel = enchantLevel;
}
public int getItemId()
{
return _itemId;
}
public int getEnchantLevel()
{
return _enchantLevel;
}
public long getCount()
{
return _count;
}
}

View File

@ -0,0 +1,26 @@
package org.l2jmobius.gameserver.model.holders;
/**
* Written by Berezkin Nikolay, on 04.05.2021
*/
public class PlayerCollectionData {
public int getCollectionId() {
return collectionId;
}
public int getItemId() {
return itemId;
}
public int getIndex() {
return index;
}
private final int collectionId, itemId, index;
public PlayerCollectionData(int collectionId, int itemId, int index) {
this.collectionId = collectionId;
this.itemId = itemId;
this.index = index;
}
}

View File

@ -52,6 +52,13 @@ import org.l2jmobius.gameserver.network.clientpackets.ceremonyofchaos.RequestCan
import org.l2jmobius.gameserver.network.clientpackets.ceremonyofchaos.RequestCuriousHouseHtml;
import org.l2jmobius.gameserver.network.clientpackets.ceremonyofchaos.RequestJoinCuriousHouse;
import org.l2jmobius.gameserver.network.clientpackets.classchange.ExRequestClassChange;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestExCollectionOpenUI;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionCloseUI;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionFavoriteList;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionReceiveReward;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionRegister;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionUpdateFavorite;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestExCollectionList;
import org.l2jmobius.gameserver.network.clientpackets.commission.RequestCommissionBuyInfo;
import org.l2jmobius.gameserver.network.clientpackets.commission.RequestCommissionBuyItem;
import org.l2jmobius.gameserver.network.clientpackets.commission.RequestCommissionCancel;
@ -615,14 +622,14 @@ public enum ExIncomingPackets implements IIncomingPackets<GameClient>
EX_STEADY_GET_REWARD(0x1D7, null, ConnectionState.IN_GAME),
EX_PET_RANKING_MY_INFO(0x1D8, null, ConnectionState.IN_GAME),
EX_PET_RANKING_LIST(0x1D9, null, ConnectionState.IN_GAME),
EX_COLLECTION_OPEN_UI(0x1DA, null, ConnectionState.IN_GAME),
EX_COLLECTION_CLOSE_UI(0x1DB, null, ConnectionState.IN_GAME),
EX_COLLECTION_LIST(0x1DC, null, ConnectionState.IN_GAME),
EX_COLLECTION_UPDATE_FAVORITE(0x1DD, null, ConnectionState.IN_GAME),
EX_COLLECTION_FAVORITE_LIST(0x1DE, null, ConnectionState.IN_GAME),
EX_COLLECTION_OPEN_UI(0x1DA, RequestExCollectionOpenUI::new, ConnectionState.IN_GAME),
EX_COLLECTION_CLOSE_UI(0x1DB, RequestCollectionCloseUI::new, ConnectionState.IN_GAME),
EX_COLLECTION_LIST(0x1DC, RequestExCollectionList::new, ConnectionState.IN_GAME),
EX_COLLECTION_UPDATE_FAVORITE(0x1DD, RequestCollectionUpdateFavorite::new, ConnectionState.IN_GAME),
EX_COLLECTION_FAVORITE_LIST(0x1DE, RequestCollectionFavoriteList::new, ConnectionState.IN_GAME),
EX_COLLECTION_SUMMARY(0x1DF, null, ConnectionState.IN_GAME),
EX_COLLECTION_REGISTER(0x1E0, null, ConnectionState.IN_GAME),
EX_COLLECTION_RECEIVE_REWARD(0x1E1, null, ConnectionState.IN_GAME),
EX_COLLECTION_REGISTER(0x1E0, RequestCollectionRegister::new, ConnectionState.IN_GAME),
EX_COLLECTION_RECEIVE_REWARD(0x1E1, RequestCollectionReceiveReward::new, ConnectionState.IN_GAME),
EX_PVPBOOK_SHARE_REVENGE_LIST(0x1E2, null, ConnectionState.IN_GAME),
EX_PVPBOOK_SHARE_REVENGE_REQ_SHARE_REVENGEINFO(0x1E3, null, ConnectionState.IN_GAME),
EX_PVPBOOK_SHARE_REVENGE_KILLER_LOCATION(0x1E4, null, ConnectionState.IN_GAME),

View File

@ -0,0 +1,47 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionCloseUI;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestCollectionCloseUI implements IClientIncomingPacket
{
@Override
public boolean read(GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
player.sendPacket(new ExCollectionCloseUI());
}
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionFavoriteList;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestCollectionFavoriteList implements IClientIncomingPacket
{
@Override
public boolean read(GameClient client, PacketReader packet)
{
packet.readC(); // ?
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
player.sendPacket(new ExCollectionFavoriteList());
}
}

View File

@ -0,0 +1,38 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
/**
* Written by Berezkin Nikolay, on 13.04.2021
*/
public class RequestCollectionReceiveReward implements IClientIncomingPacket
{
@Override
public boolean read(GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(GameClient client)
{
}
}

View File

@ -0,0 +1,74 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.data.xml.CollectionData;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.holders.PlayerCollectionData;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionComplete;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionRegister;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestCollectionRegister implements IClientIncomingPacket
{
private int _collectionId;
private int _index;
private int _itemObjId;
@Override
public boolean read(GameClient client, PacketReader packet)
{
_collectionId = packet.readH();
_index = packet.readD();
_itemObjId = packet.readD();
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
final ItemInstance item = player.getInventory().getItemByObjectId(_itemObjId);
if (item == null)
{
player.sendMessage("Item not found.");
return;
}
player.destroyItemByItemId("Collection", item.getId(), 1, player, true);
player.sendPacket(new ExCollectionRegister(_collectionId, _index, item));
player.getCollections().add(new PlayerCollectionData(_collectionId, item.getId(), _index));
if (CollectionData.getInstance().getCollection(_collectionId).getItems().size() == player.getCollections().stream().filter(it -> it.getCollectionId() == _collectionId).count())
{
player.sendPacket(new ExCollectionComplete(_collectionId));
}
}
}

View File

@ -0,0 +1,59 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionUpdateFavorite;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestCollectionUpdateFavorite implements IClientIncomingPacket
{
private int _isAdd;
private int _collectionId;
@Override
public boolean read(GameClient client, PacketReader packet)
{
_isAdd = packet.readC();
_collectionId = packet.readH();
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
if (_isAdd == 1)
{
player.addCollectionFavorite(_collectionId);
}
else
{
player.removeCollectionFavorite(_collectionId);
}
player.sendPacket(new ExCollectionUpdateFavorite(_isAdd, _collectionId));
}
}

View File

@ -0,0 +1,50 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionList;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestExCollectionList implements IClientIncomingPacket
{
private int _category;
@Override
public boolean read(GameClient client, PacketReader packet)
{
_category = packet.readC();
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
player.sendPacket(new ExCollectionList(_category));
}
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionOpenUI;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestExCollectionOpenUI implements IClientIncomingPacket
{
@Override
public boolean read(GameClient client, PacketReader packet)
{
packet.readC(); // 1 = isClosed
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
player.setTarget(null);
player.sendPacket(new ExCollectionOpenUI());
}
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionCloseUI implements IClientOutgoingPacket
{
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_CLOSE_UI.writeId(packet);
packet.writeC(0x00);
return true;
}
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 13.04.2021
*/
public class ExCollectionComplete implements IClientOutgoingPacket
{
private final int _collectionId;
public ExCollectionComplete(int collectionId)
{
_collectionId = collectionId;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_COMPLETE.writeId(packet);
packet.writeH(_collectionId);
return true;
}
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionFavoriteList implements IClientOutgoingPacket
{
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_FAVORITE_LIST.writeId(packet);
packet.writeD(0x00);
return true;
}
}

View File

@ -0,0 +1,84 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.CollectionData;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.holders.PlayerCollectionData;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionInfo implements IClientOutgoingPacket
{
final PlayerInstance _playerInstance;
final List<PlayerCollectionData> _categoryList;
final Set<Integer> _collections;
final List<Integer> _favoriteList;
final int _category;
public ExCollectionInfo(PlayerInstance playerInstance, int category)
{
_playerInstance = playerInstance;
_categoryList = playerInstance.getCollections().stream().filter(it -> CollectionData.getInstance().getCollection(it.getCollectionId()).getCategory() == category).collect(Collectors.toList());
_collections = _categoryList.stream().map(PlayerCollectionData::getCollectionId).collect(Collectors.toSet());
_favoriteList = playerInstance.getCollectionFavorites();
_category = category;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_INFO.writeId(packet);
packet.writeD(_collections.size()); // size
for (Integer collection : _collections)
{
final List<PlayerCollectionData> collectionCurrent = _categoryList.stream().filter(it -> it.getCollectionId() == collection).collect(Collectors.toList());
packet.writeD(collectionCurrent.size());
for (PlayerCollectionData current : collectionCurrent)
{
packet.writeC(current.getIndex());
packet.writeD(current.getItemId());
packet.writeH(CollectionData.getInstance().getCollection(collection).getItems().get(current.getIndex()).getEnchantLevel()); // enchant level
packet.writeC(0); // unk flag for item
packet.writeD(1); // count
}
packet.writeH(collection);
}
packet.writeD(_favoriteList.size()); // favourite size
for (int favoriteCollection : _favoriteList)
{
packet.writeH(favoriteCollection);
}
packet.writeD(0);
// loop unk
// 1 h
// d
// h
// loop end
packet.writeC(_category);
packet.writeH(0);
return true;
}
}

View File

@ -0,0 +1,43 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionList implements IClientOutgoingPacket
{
private final int _category;
public ExCollectionList(int category)
{
_category = category;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_LIST.writeId(packet);
packet.writeC(_category);
packet.writeD(0);// size & loop body
return true;
}
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionOpenUI implements IClientOutgoingPacket
{
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_OPEN_UI.writeId(packet);
packet.writeC(0);// unk and may be unk D too
return true;
}
}

View File

@ -0,0 +1,55 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionRegister implements IClientOutgoingPacket
{
private final int _collectionId;
private final int _index;
private final ItemInstance _item;
public ExCollectionRegister(int collectionId, int index, ItemInstance item)
{
_collectionId = collectionId;
_index = index;
_item = item;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_REGISTER.writeId(packet);
packet.writeH(_collectionId);
packet.writeC(1);
packet.writeC(0x0E);
packet.writeC(0);
packet.writeC(_index);
packet.writeD(_item.getId());
packet.writeH(0);
packet.writeC(0);
packet.writeD(0);
return true;
}
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionUpdateFavorite implements IClientOutgoingPacket
{
private final int _isAdd;
private final int _collectionId;
public ExCollectionUpdateFavorite(int isAdd, int collectionId)
{
_isAdd = isAdd;
_collectionId = collectionId;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_UPDATE_FAVORITE.writeId(packet);
packet.writeC(_isAdd);
packet.writeH(_collectionId);
return true;
}
}

View File

@ -116,7 +116,7 @@ Homunculus Ch. 2: https://eu.4game.com/patchnotes/lineage2/270/
-New augment system
Return of the Queen Ant: https://eu.4game.com/patchnotes/lineage2/293/
-Login support
-Collection system
Events:
-Birth of Draco

View File

@ -0,0 +1,6 @@
DROP TABLE IF EXISTS `collection_favorites`;
CREATE TABLE IF NOT EXISTS `collection_favorites` (
`accountName` VARCHAR(45) NOT NULL DEFAULT '',
`collectionId` int(3) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`accountName`,`collectionId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

View File

@ -0,0 +1,8 @@
DROP TABLE IF EXISTS `collections`;
CREATE TABLE IF NOT EXISTS `collections` (
`accountName` VARCHAR(45) NOT NULL DEFAULT '',
`itemId` int(11) UNSIGNED NOT NULL DEFAULT 0,
`collectionId` int(3) UNSIGNED NOT NULL DEFAULT 0,
`index` tinyint(3) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`accountName`,`collectionId`,`index`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element name="collection" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="item" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:int" name="id" />
<xs:attribute type="xs:int" name="count" use="required"/>
<xs:attribute type="xs:int" name="enchant_level" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:integer" name="id" use="required" />
<xs:attribute type="xs:integer" name="optionId" use="required" />
<xs:attribute type="xs:integer" name="category" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -58,6 +58,7 @@ import org.l2jmobius.gameserver.data.xml.CategoryData;
import org.l2jmobius.gameserver.data.xml.ClanHallData;
import org.l2jmobius.gameserver.data.xml.ClanRewardData;
import org.l2jmobius.gameserver.data.xml.ClassListData;
import org.l2jmobius.gameserver.data.xml.CollectionData;
import org.l2jmobius.gameserver.data.xml.CombinationItemsData;
import org.l2jmobius.gameserver.data.xml.CubicData;
import org.l2jmobius.gameserver.data.xml.DailyMissionData;
@ -293,6 +294,7 @@ public class GameServer
LimitShopData.getInstance();
LimitShopCraftData.getInstance();
LimitShopClanData.getInstance();
CollectionData.getInstance();
PcCafePointsManager.getInstance();
AppearanceItemData.getInstance();
CommissionManager.getInstance();

View File

@ -0,0 +1,136 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.data.xml;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.l2jmobius.commons.util.IXmlReader;
import org.l2jmobius.gameserver.data.ItemTable;
import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.holders.CollectionDataHolder;
import org.l2jmobius.gameserver.model.holders.ItemCollectionData;
import org.l2jmobius.gameserver.model.items.Item;
/**
* Written by Berezkin Nikolay, on 04.05.2021
*/
public class CollectionData implements IXmlReader
{
private static final Logger LOGGER = Logger.getLogger(CollectionData.class.getName());
private static final Map<Integer, CollectionDataHolder> _collections = new HashMap<>();
protected CollectionData()
{
load();
}
@Override
public void load()
{
_collections.clear();
parseDatapackFile("data/CollectionData.xml");
if (!_collections.isEmpty())
{
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _collections.size() + " collections.");
}
else
{
LOGGER.info(getClass().getSimpleName() + ": System is disabled.");
}
}
@Override
public void parseDocument(Document doc, File f)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("collection".equalsIgnoreCase(d.getNodeName()))
{
NamedNodeMap attrs = d.getAttributes();
Node att;
final StatSet set = new StatSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
final int id = parseInteger(attrs, "id");
final int optionId = parseInteger(attrs, "optionId");
final int category = parseInteger(attrs, "category");
List<ItemCollectionData> items = new ArrayList<>();
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
attrs = b.getAttributes();
if ("item".equalsIgnoreCase(b.getNodeName()))
{
final int itemId = parseInteger(attrs, "id");
final long itemCount = parseLong(attrs, "count", 1L);
final int itemEnchantLevel = parseInteger(attrs, "enchant_level", 0);
final Item item = ItemTable.getInstance().getTemplate(itemId);
if (item == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Item template null for itemId: " + itemId + " collection item: " + id);
continue;
}
items.add(new ItemCollectionData(itemId, itemCount, itemEnchantLevel));
}
}
_collections.put(id, new CollectionDataHolder(id, optionId, category, items));
}
}
}
}
}
public CollectionDataHolder getCollection(int id)
{
return _collections.get(id);
}
public Collection<CollectionDataHolder> getCollections()
{
return _collections.values();
}
public static CollectionData getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final CollectionData INSTANCE = new CollectionData();
}
}

View File

@ -71,10 +71,12 @@ import org.l2jmobius.gameserver.data.xml.AdminData;
import org.l2jmobius.gameserver.data.xml.AttendanceRewardData;
import org.l2jmobius.gameserver.data.xml.CategoryData;
import org.l2jmobius.gameserver.data.xml.ClassListData;
import org.l2jmobius.gameserver.data.xml.CollectionData;
import org.l2jmobius.gameserver.data.xml.ExperienceData;
import org.l2jmobius.gameserver.data.xml.HennaData;
import org.l2jmobius.gameserver.data.xml.NpcData;
import org.l2jmobius.gameserver.data.xml.NpcNameLocalisationData;
import org.l2jmobius.gameserver.data.xml.OptionData;
import org.l2jmobius.gameserver.data.xml.PetDataTable;
import org.l2jmobius.gameserver.data.xml.PlayerTemplateData;
import org.l2jmobius.gameserver.data.xml.PlayerXpPercentLostData;
@ -225,11 +227,13 @@ import org.l2jmobius.gameserver.model.fishing.Fishing;
import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder;
import org.l2jmobius.gameserver.model.holders.AutoPlaySettingsHolder;
import org.l2jmobius.gameserver.model.holders.AutoUseSettingsHolder;
import org.l2jmobius.gameserver.model.holders.CollectionDataHolder;
import org.l2jmobius.gameserver.model.holders.DamageTakenHolder;
import org.l2jmobius.gameserver.model.holders.ElementalSpiritDataHolder;
import org.l2jmobius.gameserver.model.holders.ItemHolder;
import org.l2jmobius.gameserver.model.holders.ItemSkillHolder;
import org.l2jmobius.gameserver.model.holders.MovieHolder;
import org.l2jmobius.gameserver.model.holders.PlayerCollectionData;
import org.l2jmobius.gameserver.model.holders.PlayerEventHolder;
import org.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
import org.l2jmobius.gameserver.model.holders.SellBuffHolder;
@ -261,6 +265,7 @@ import org.l2jmobius.gameserver.model.olympiad.Hero;
import org.l2jmobius.gameserver.model.olympiad.OlympiadGameManager;
import org.l2jmobius.gameserver.model.olympiad.OlympiadGameTask;
import org.l2jmobius.gameserver.model.olympiad.OlympiadManager;
import org.l2jmobius.gameserver.model.options.Options;
import org.l2jmobius.gameserver.model.punishment.PunishmentAffect;
import org.l2jmobius.gameserver.model.punishment.PunishmentTask;
import org.l2jmobius.gameserver.model.punishment.PunishmentType;
@ -428,6 +433,14 @@ public class PlayerInstance extends Playable
// Character Shortcut SQL String Definitions:
private static final String DELETE_CHAR_SHORTCUTS = "DELETE FROM character_shortcuts WHERE charId=? AND class_index=?";
// Character Collections list:
private static final String DELETE_COLLECTION = "DELETE FROM collections WHERE accountName=?";
private static final String INSERT_COLLECTION = "REPLACE INTO collections (`accountName`, `itemId`, `collectionId`, `index`) VALUES (?, ?, ?, ?)";
private static final String RESTORE_COLLECTION = "SELECT * FROM collections WHERE accountName=? ORDER BY `index`";
private static final String DELETE_COLLECTION_FAVORITE = "DELETE FROM collection_favorites WHERE accountName=?";
private static final String INSERT_COLLECTION_FAVORITE = "REPLACE INTO collection_favorites (`accountName`, `collectionId`) VALUES (?, ?)";
private static final String RESTORE_COLLECTION_FAVORITE = "SELECT * FROM collection_favorites WHERE accountName=?";
// Character Recipe List Save:
private static final String DELETE_CHAR_RECIPE_SHOP = "DELETE FROM character_recipeshoplist WHERE charId=?";
private static final String INSERT_CHAR_RECIPE_SHOP = "REPLACE INTO character_recipeshoplist (`charId`, `recipeId`, `price`, `index`) VALUES (?, ?, ?, ?)";
@ -899,6 +912,9 @@ public class PlayerInstance extends Playable
private PlayerRandomCraft _randomCraft = null;
private final List<PlayerCollectionData> _collections = new ArrayList<>();
private final List<Integer> _collectionFavorites = new ArrayList<>();
private final List<QuestTimer> _questTimers = new ArrayList<>();
private final List<TimerHolder<?>> _timerHolders = new ArrayList<>();
@ -6912,6 +6928,11 @@ public class PlayerInstance extends Playable
restoreRecipeShopList();
}
// Restore collections.
restoreCollections();
restoreCollectionBonuses();
restoreCollectionFavorites();
// Load Premium Item List.
loadPremiumItemList();
@ -7059,6 +7080,10 @@ public class PlayerInstance extends Playable
storeRecipeShopList();
}
// Store collections.
storeCollections();
storeCollectionFavorites();
final PlayerVariables vars = getScript(PlayerVariables.class);
if (vars != null)
{
@ -14577,4 +14602,163 @@ public class PlayerInstance extends Playable
{
return _randomCraft;
}
public List<PlayerCollectionData> getCollections()
{
return _collections;
}
public List<Integer> getCollectionFavorites()
{
return _collectionFavorites;
}
public void addCollectionFavorite(Integer id)
{
_collectionFavorites.add(id);
}
public void removeCollectionFavorite(Integer id)
{
_collectionFavorites.remove(id);
}
public void storeCollections()
{
try (Connection con = DatabaseFactory.getConnection())
{
try (PreparedStatement st = con.prepareStatement(DELETE_COLLECTION))
{
st.setString(1, getAccountNamePlayer());
st.execute();
}
try (PreparedStatement st = con.prepareStatement(INSERT_COLLECTION))
{
_collections.forEach(data ->
{
try
{
st.setString(1, getAccountNamePlayer());
st.setInt(2, data.getItemId());
st.setInt(3, data.getCollectionId());
st.setInt(4, data.getIndex());
st.addBatch();
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not store collection for playerId " + getObjectId() + ": ", e);
}
});
st.executeBatch();
con.commit();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not store collection for playerId " + getObjectId() + ": ", e);
}
}
public void storeCollectionFavorites()
{
try (Connection con = DatabaseFactory.getConnection())
{
try (PreparedStatement st = con.prepareStatement(DELETE_COLLECTION_FAVORITE))
{
st.setString(1, getAccountNamePlayer());
st.execute();
}
try (PreparedStatement st = con.prepareStatement(INSERT_COLLECTION_FAVORITE))
{
_collectionFavorites.forEach(data ->
{
try
{
st.setString(1, getAccountNamePlayer());
st.setInt(2, data);
st.addBatch();
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not store collection favorite for playerId " + getObjectId() + ": ", e);
}
});
st.executeBatch();
con.commit();
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not store collection favorite for playerId " + getObjectId() + ": ", e);
}
}
private void restoreCollections()
{
if (_collections != null)
{
_collections.clear();
}
try (Connection con = DatabaseFactory.getConnection();
PreparedStatement statement = con.prepareStatement(RESTORE_COLLECTION))
{
statement.setString(1, getAccountNamePlayer());
try (ResultSet rset = statement.executeQuery())
{
while (rset.next())
{
_collections.add(new PlayerCollectionData(rset.getInt("collectionId"), rset.getInt("itemId"), rset.getInt("index")));
}
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not restore collection list data for playerId: " + getObjectId(), e);
}
}
private void restoreCollectionBonuses()
{
getCollections().stream().map(PlayerCollectionData::getCollectionId).collect(Collectors.toSet()).forEach(uniqueCollection ->
{
final List<PlayerCollectionData> currentProgress = getCollections().stream().filter(it -> it.getCollectionId() == uniqueCollection).collect(Collectors.toList());
final CollectionDataHolder template = CollectionData.getInstance().getCollection(uniqueCollection);
if (currentProgress.size() == template.getItems().size())
{
final Options options = OptionData.getInstance().getOptions(template.getOptionId());
if (options != null)
{
options.apply(this);
}
}
});
}
private void restoreCollectionFavorites()
{
if (_collectionFavorites != null)
{
_collectionFavorites.clear();
}
try (Connection con = DatabaseFactory.getConnection();
PreparedStatement statement = con.prepareStatement(RESTORE_COLLECTION_FAVORITE))
{
statement.setString(1, getAccountNamePlayer());
try (ResultSet rset = statement.executeQuery())
{
while (rset.next())
{
_collectionFavorites.add(rset.getInt("collectionId"));
}
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, "Could not restore collection favorite list data for playerId: " + getObjectId(), e);
}
}
}

View File

@ -0,0 +1,58 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.model.holders;
import java.util.List;
/**
* Written by Berezkin Nikolay, on 04.05.2021
*/
public class CollectionDataHolder
{
private final int _collectionId;
private final int _optionId;
private final int _category;
private final List<ItemCollectionData> _items;
public CollectionDataHolder(int collectionId, int optionId, int category, List<ItemCollectionData> items)
{
_collectionId = collectionId;
_optionId = optionId;
_category = category;
_items = items;
}
public int getCollectionId()
{
return _collectionId;
}
public int getOptionId()
{
return _optionId;
}
public int getCategory()
{
return _category;
}
public List<ItemCollectionData> getItems()
{
return _items;
}
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.model.holders;
/**
* Written by Berezkin Nikolay, on 04.05.2021
*/
public class ItemCollectionData
{
private final int _enchantLevel;
private final int _itemId;
private final long _count;
public ItemCollectionData(int itemId, long count, int enchantLevel)
{
_itemId = itemId;
_count = count;
_enchantLevel = enchantLevel;
}
public int getItemId()
{
return _itemId;
}
public int getEnchantLevel()
{
return _enchantLevel;
}
public long getCount()
{
return _count;
}
}

View File

@ -0,0 +1,26 @@
package org.l2jmobius.gameserver.model.holders;
/**
* Written by Berezkin Nikolay, on 04.05.2021
*/
public class PlayerCollectionData {
public int getCollectionId() {
return collectionId;
}
public int getItemId() {
return itemId;
}
public int getIndex() {
return index;
}
private final int collectionId, itemId, index;
public PlayerCollectionData(int collectionId, int itemId, int index) {
this.collectionId = collectionId;
this.itemId = itemId;
this.index = index;
}
}

View File

@ -46,6 +46,13 @@ import org.l2jmobius.gameserver.network.clientpackets.ceremonyofchaos.RequestCan
import org.l2jmobius.gameserver.network.clientpackets.ceremonyofchaos.RequestCuriousHouseHtml;
import org.l2jmobius.gameserver.network.clientpackets.ceremonyofchaos.RequestJoinCuriousHouse;
import org.l2jmobius.gameserver.network.clientpackets.classchange.ExRequestClassChange;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestExCollectionOpenUI;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionCloseUI;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionFavoriteList;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionReceiveReward;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionRegister;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestCollectionUpdateFavorite;
import org.l2jmobius.gameserver.network.clientpackets.collection.RequestExCollectionList;
import org.l2jmobius.gameserver.network.clientpackets.commission.RequestCommissionBuyInfo;
import org.l2jmobius.gameserver.network.clientpackets.commission.RequestCommissionBuyItem;
import org.l2jmobius.gameserver.network.clientpackets.commission.RequestCommissionCancel;
@ -616,14 +623,14 @@ public enum ExIncomingPackets implements IIncomingPackets<GameClient>
EX_STEADY_GET_REWARD(0x1D7, null, ConnectionState.IN_GAME),
EX_PET_RANKING_MY_INFO(0x1D8, null, ConnectionState.IN_GAME),
EX_PET_RANKING_LIST(0x1D9, null, ConnectionState.IN_GAME),
EX_COLLECTION_OPEN_UI(0x1DA, null, ConnectionState.IN_GAME),
EX_COLLECTION_CLOSE_UI(0x1DB, null, ConnectionState.IN_GAME),
EX_COLLECTION_LIST(0x1DC, null, ConnectionState.IN_GAME),
EX_COLLECTION_UPDATE_FAVORITE(0x1DD, null, ConnectionState.IN_GAME),
EX_COLLECTION_FAVORITE_LIST(0x1DE, null, ConnectionState.IN_GAME),
EX_COLLECTION_OPEN_UI(0x1DA, RequestExCollectionOpenUI::new, ConnectionState.IN_GAME),
EX_COLLECTION_CLOSE_UI(0x1DB, RequestCollectionCloseUI::new, ConnectionState.IN_GAME),
EX_COLLECTION_LIST(0x1DC, RequestExCollectionList::new, ConnectionState.IN_GAME),
EX_COLLECTION_UPDATE_FAVORITE(0x1DD, RequestCollectionUpdateFavorite::new, ConnectionState.IN_GAME),
EX_COLLECTION_FAVORITE_LIST(0x1DE, RequestCollectionFavoriteList::new, ConnectionState.IN_GAME),
EX_COLLECTION_SUMMARY(0x1DF, null, ConnectionState.IN_GAME),
EX_COLLECTION_REGISTER(0x1E0, null, ConnectionState.IN_GAME),
EX_COLLECTION_RECEIVE_REWARD(0x1E1, null, ConnectionState.IN_GAME),
EX_COLLECTION_REGISTER(0x1E0, RequestCollectionRegister::new, ConnectionState.IN_GAME),
EX_COLLECTION_RECEIVE_REWARD(0x1E1, RequestCollectionReceiveReward::new, ConnectionState.IN_GAME),
EX_PVPBOOK_SHARE_REVENGE_LIST(0x1E2, null, ConnectionState.IN_GAME),
EX_PVPBOOK_SHARE_REVENGE_REQ_SHARE_REVENGEINFO(0x1E3, null, ConnectionState.IN_GAME),
EX_PVPBOOK_SHARE_REVENGE_KILLER_LOCATION(0x1E4, null, ConnectionState.IN_GAME),

View File

@ -0,0 +1,47 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionCloseUI;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestCollectionCloseUI implements IClientIncomingPacket
{
@Override
public boolean read(GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
player.sendPacket(new ExCollectionCloseUI());
}
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionFavoriteList;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestCollectionFavoriteList implements IClientIncomingPacket
{
@Override
public boolean read(GameClient client, PacketReader packet)
{
packet.readC(); // ?
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
player.sendPacket(new ExCollectionFavoriteList());
}
}

View File

@ -0,0 +1,38 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
/**
* Written by Berezkin Nikolay, on 13.04.2021
*/
public class RequestCollectionReceiveReward implements IClientIncomingPacket
{
@Override
public boolean read(GameClient client, PacketReader packet)
{
return true;
}
@Override
public void run(GameClient client)
{
}
}

View File

@ -0,0 +1,74 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.data.xml.CollectionData;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.holders.PlayerCollectionData;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionComplete;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionRegister;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestCollectionRegister implements IClientIncomingPacket
{
private int _collectionId;
private int _index;
private int _itemObjId;
@Override
public boolean read(GameClient client, PacketReader packet)
{
_collectionId = packet.readH();
_index = packet.readD();
_itemObjId = packet.readD();
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
final ItemInstance item = player.getInventory().getItemByObjectId(_itemObjId);
if (item == null)
{
player.sendMessage("Item not found.");
return;
}
player.destroyItemByItemId("Collection", item.getId(), 1, player, true);
player.sendPacket(new ExCollectionRegister(_collectionId, _index, item));
player.getCollections().add(new PlayerCollectionData(_collectionId, item.getId(), _index));
if (CollectionData.getInstance().getCollection(_collectionId).getItems().size() == player.getCollections().stream().filter(it -> it.getCollectionId() == _collectionId).count())
{
player.sendPacket(new ExCollectionComplete(_collectionId));
}
}
}

View File

@ -0,0 +1,59 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionUpdateFavorite;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestCollectionUpdateFavorite implements IClientIncomingPacket
{
private int _isAdd;
private int _collectionId;
@Override
public boolean read(GameClient client, PacketReader packet)
{
_isAdd = packet.readC();
_collectionId = packet.readH();
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
if (_isAdd == 1)
{
player.addCollectionFavorite(_collectionId);
}
else
{
player.removeCollectionFavorite(_collectionId);
}
player.sendPacket(new ExCollectionUpdateFavorite(_isAdd, _collectionId));
}
}

View File

@ -0,0 +1,50 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionList;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestExCollectionList implements IClientIncomingPacket
{
private int _category;
@Override
public boolean read(GameClient client, PacketReader packet)
{
_category = packet.readC();
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
player.sendPacket(new ExCollectionList(_category));
}
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.clientpackets.collection;
import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
import org.l2jmobius.gameserver.network.serverpackets.collection.ExCollectionOpenUI;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class RequestExCollectionOpenUI implements IClientIncomingPacket
{
@Override
public boolean read(GameClient client, PacketReader packet)
{
packet.readC(); // 1 = isClosed
return true;
}
@Override
public void run(GameClient client)
{
final PlayerInstance player = client.getPlayer();
if (player == null)
{
return;
}
player.setTarget(null);
player.sendPacket(new ExCollectionOpenUI());
}
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionCloseUI implements IClientOutgoingPacket
{
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_CLOSE_UI.writeId(packet);
packet.writeC(0x00);
return true;
}
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 13.04.2021
*/
public class ExCollectionComplete implements IClientOutgoingPacket
{
private final int _collectionId;
public ExCollectionComplete(int collectionId)
{
_collectionId = collectionId;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_COMPLETE.writeId(packet);
packet.writeH(_collectionId);
return true;
}
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionFavoriteList implements IClientOutgoingPacket
{
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_FAVORITE_LIST.writeId(packet);
packet.writeD(0x00);
return true;
}
}

View File

@ -0,0 +1,84 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.CollectionData;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.holders.PlayerCollectionData;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionInfo implements IClientOutgoingPacket
{
final PlayerInstance _playerInstance;
final List<PlayerCollectionData> _categoryList;
final Set<Integer> _collections;
final List<Integer> _favoriteList;
final int _category;
public ExCollectionInfo(PlayerInstance playerInstance, int category)
{
_playerInstance = playerInstance;
_categoryList = playerInstance.getCollections().stream().filter(it -> CollectionData.getInstance().getCollection(it.getCollectionId()).getCategory() == category).collect(Collectors.toList());
_collections = _categoryList.stream().map(PlayerCollectionData::getCollectionId).collect(Collectors.toSet());
_favoriteList = playerInstance.getCollectionFavorites();
_category = category;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_INFO.writeId(packet);
packet.writeD(_collections.size()); // size
for (Integer collection : _collections)
{
final List<PlayerCollectionData> collectionCurrent = _categoryList.stream().filter(it -> it.getCollectionId() == collection).collect(Collectors.toList());
packet.writeD(collectionCurrent.size());
for (PlayerCollectionData current : collectionCurrent)
{
packet.writeC(current.getIndex());
packet.writeD(current.getItemId());
packet.writeH(CollectionData.getInstance().getCollection(collection).getItems().get(current.getIndex()).getEnchantLevel()); // enchant level
packet.writeC(0); // unk flag for item
packet.writeD(1); // count
}
packet.writeH(collection);
}
packet.writeD(_favoriteList.size()); // favourite size
for (int favoriteCollection : _favoriteList)
{
packet.writeH(favoriteCollection);
}
packet.writeD(0);
// loop unk
// 1 h
// d
// h
// loop end
packet.writeC(_category);
packet.writeH(0);
return true;
}
}

View File

@ -0,0 +1,43 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionList implements IClientOutgoingPacket
{
private final int _category;
public ExCollectionList(int category)
{
_category = category;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_LIST.writeId(packet);
packet.writeC(_category);
packet.writeD(0);// size & loop body
return true;
}
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionOpenUI implements IClientOutgoingPacket
{
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_OPEN_UI.writeId(packet);
packet.writeC(0);// unk and may be unk D too
return true;
}
}

View File

@ -0,0 +1,55 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionRegister implements IClientOutgoingPacket
{
private final int _collectionId;
private final int _index;
private final ItemInstance _item;
public ExCollectionRegister(int collectionId, int index, ItemInstance item)
{
_collectionId = collectionId;
_index = index;
_item = item;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_REGISTER.writeId(packet);
packet.writeH(_collectionId);
packet.writeC(1);
packet.writeC(0x0E);
packet.writeC(0);
packet.writeC(_index);
packet.writeD(_item.getId());
packet.writeH(0);
packet.writeC(0);
packet.writeD(0);
return true;
}
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.network.serverpackets.collection;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.network.OutgoingPackets;
import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
/**
* Written by Berezkin Nikolay, on 12.04.2021
*/
public class ExCollectionUpdateFavorite implements IClientOutgoingPacket
{
private final int _isAdd;
private final int _collectionId;
public ExCollectionUpdateFavorite(int isAdd, int collectionId)
{
_isAdd = isAdd;
_collectionId = collectionId;
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_COLLECTION_UPDATE_FAVORITE.writeId(packet);
packet.writeC(_isAdd);
packet.writeH(_collectionId);
return true;
}
}

View File

@ -124,6 +124,7 @@ Dwelling of Spirits: https://eu.4game.com/patchnotes/lineage2essence/261/
Sylph: https://eu.4game.com/patchnotes/lineage2essence/281/
-Sylph creation support
-Collection system
Customs:
-Newbie Helper NPC location info